Added a first implementation for the Heatmaster fan controller.
1.1 --- a/GUI/HardwareNode.cs Tue Aug 17 21:44:02 2010 +0000
1.2 +++ b/GUI/HardwareNode.cs Sun Aug 22 21:53:11 2010 +0000
1.3 @@ -68,6 +68,9 @@
1.4 case HardwareType.HDD:
1.5 this.Image = Utilities.EmbeddedResources.GetImage("hdd.png");
1.6 break;
1.7 + case HardwareType.Heatmaster:
1.8 + this.Image = Utilities.EmbeddedResources.GetImage("bigng.png");
1.9 + break;
1.10 case HardwareType.Mainboard:
1.11 this.Image = Utilities.EmbeddedResources.GetImage("mainboard.png");
1.12 break;
2.1 --- a/Hardware/Computer.cs Tue Aug 17 21:44:02 2010 +0000
2.2 +++ b/Hardware/Computer.cs Sun Aug 22 21:53:11 2010 +0000
2.3 @@ -99,8 +99,9 @@
2.4 Add(new Mainboard.MainboardGroup(settings));
2.5 Add(new CPU.CPUGroup(settings));
2.6 Add(new ATI.ATIGroup(settings));
2.7 - Add(new Nvidia.NvidiaGroup(settings));
2.8 + Add(new Nvidia.NvidiaGroup(settings));
2.9 Add(new TBalancer.TBalancerGroup(settings));
2.10 + Add(new Heatmaster.HeatmasterGroup(settings));
2.11
2.12 if (hddEnabled)
2.13 Add(new HDD.HDDGroup(settings));
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/Hardware/Heatmaster/Heatmaster.cs Sun Aug 22 21:53:11 2010 +0000
3.3 @@ -0,0 +1,287 @@
3.4 +/*
3.5 +
3.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
3.7 +
3.8 + The contents of this file are subject to the Mozilla Public License Version
3.9 + 1.1 (the "License"); you may not use this file except in compliance with
3.10 + the License. You may obtain a copy of the License at
3.11 +
3.12 + http://www.mozilla.org/MPL/
3.13 +
3.14 + Software distributed under the License is distributed on an "AS IS" basis,
3.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
3.16 + for the specific language governing rights and limitations under the License.
3.17 +
3.18 + The Original Code is the Open Hardware Monitor code.
3.19 +
3.20 + The Initial Developer of the Original Code is
3.21 + Michael Möller <m.moeller@gmx.ch>.
3.22 + Portions created by the Initial Developer are Copyright (C) 2010
3.23 + the Initial Developer. All Rights Reserved.
3.24 +
3.25 + Contributor(s):
3.26 +
3.27 + Alternatively, the contents of this file may be used under the terms of
3.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
3.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
3.30 + in which case the provisions of the GPL or the LGPL are applicable instead
3.31 + of those above. If you wish to allow use of your version of this file only
3.32 + under the terms of either the GPL or the LGPL, and not to allow others to
3.33 + use your version of this file under the terms of the MPL, indicate your
3.34 + decision by deleting the provisions above and replace them with the notice
3.35 + and other provisions required by the GPL or the LGPL. If you do not delete
3.36 + the provisions above, a recipient may use your version of this file under
3.37 + the terms of any one of the MPL, the GPL or the LGPL.
3.38 +
3.39 +*/
3.40 +
3.41 +using System;
3.42 +using System.Collections.Generic;
3.43 +using System.IO;
3.44 +using System.IO.Ports;
3.45 +using System.Text;
3.46 +using System.Text.RegularExpressions;
3.47 +using System.Threading;
3.48 +
3.49 +namespace OpenHardwareMonitor.Hardware.Heatmaster {
3.50 + internal class Heatmaster : Hardware {
3.51 +
3.52 + private string portName;
3.53 + private SerialPort serialPort;
3.54 +
3.55 + private int hardwareRevision;
3.56 + private int firmwareRevision;
3.57 + private int firmwareCRC;
3.58 +
3.59 + private Sensor[] fans;
3.60 + private Sensor[] controls;
3.61 + private Sensor[] temperatures;
3.62 + private Sensor[] flows;
3.63 + private Sensor[] relays;
3.64 +
3.65 + private bool available = false;
3.66 +
3.67 + private string ReadLine(int timeout) {
3.68 + int i = 0;
3.69 + StringBuilder builder = new StringBuilder();
3.70 + while (i <= timeout) {
3.71 + while (serialPort.BytesToRead > 0) {
3.72 + byte b = (byte)serialPort.ReadByte();
3.73 + switch (b) {
3.74 + case 0xAA: return ((char)b).ToString();
3.75 + case 0x0D: return builder.ToString();
3.76 + default: builder.Append((char)b); break;
3.77 + }
3.78 + }
3.79 + i++;
3.80 + Thread.Sleep(1);
3.81 + }
3.82 + throw new TimeoutException();
3.83 + }
3.84 +
3.85 + private string ReadField(int device, char field) {
3.86 + serialPort.WriteLine("[0:" + device + "]R" + field);
3.87 + for (int i = 0; i < 5; i++) {
3.88 + string s = ReadLine(100);
3.89 + Match match = Regex.Match(s, @"-\[0:" + device.ToString() + @"\]R" +
3.90 + Regex.Escape(field.ToString()) + ":(.*)");
3.91 + if (match.Success)
3.92 + return match.Groups[1].Value;
3.93 + }
3.94 + return null;
3.95 + }
3.96 +
3.97 + private string ReadString(int device, char field) {
3.98 + string s = ReadField(device, field);
3.99 + if (s != null && s[0] == '"' && s[s.Length - 1] == '"')
3.100 + return s.Substring(1, s.Length - 2);
3.101 + else
3.102 + return null;
3.103 + }
3.104 +
3.105 + private int ReadInteger(int device, char field) {
3.106 + string s = ReadField(device, field);
3.107 + int i;
3.108 + if (int.TryParse(s, out i))
3.109 + return i;
3.110 + else
3.111 + return 0;
3.112 + }
3.113 +
3.114 + private bool WriteField(int device, char field, string value) {
3.115 + serialPort.WriteLine("[0:" + device + "]W" + field + ":" + value);
3.116 + for (int i = 0; i < 5; i++) {
3.117 + string s = ReadLine(100);
3.118 + Match match = Regex.Match(s, @"-\[0:" + device.ToString() + @"\]W" +
3.119 + Regex.Escape(field.ToString()) + ":" + value);
3.120 + if (match.Success)
3.121 + return true;
3.122 + }
3.123 + return false;
3.124 + }
3.125 +
3.126 + private bool WriteInteger(int device, char field, int value) {
3.127 + return WriteField(device, field, value.ToString());
3.128 + }
3.129 +
3.130 + private bool WriteString(int device, char field, string value) {
3.131 + return WriteField(device, field, '"' + value + '"');
3.132 + }
3.133 +
3.134 + public Heatmaster(string portName, ISettings settings) {
3.135 +
3.136 + this.portName = portName;
3.137 + try {
3.138 + serialPort = new SerialPort(portName, 38400, Parity.None, 8,
3.139 + StopBits.One);
3.140 + serialPort.Open();
3.141 + serialPort.NewLine = ((char)0x0D).ToString();
3.142 +
3.143 + hardwareRevision = ReadInteger(0, 'H');
3.144 + firmwareRevision = ReadInteger(0, 'V');
3.145 + firmwareCRC = ReadInteger(0, 'C');
3.146 +
3.147 + int fanCount = ReadInteger(32, '?');
3.148 + int temperatureCount = ReadInteger(48, '?');
3.149 + int flowCount = ReadInteger(64, '?');
3.150 + int relayCount = ReadInteger(80, '?');
3.151 +
3.152 + fans = new Sensor[fanCount];
3.153 + controls = new Sensor[fanCount];
3.154 + for (int i = 0; i < fanCount; i++) {
3.155 + int device = 33 + i;
3.156 + string name = ReadString(device, 'C');
3.157 + fans[i] = new Sensor(name, device, SensorType.Fan, this, settings);
3.158 + fans[i].Value = ReadInteger(device, 'R');
3.159 + ActivateSensor(fans[i]);
3.160 + controls[i] =
3.161 + new Sensor(name, device, SensorType.Control, this, settings);
3.162 + controls[i].Value = (100 / 255.0f) * ReadInteger(device, 'P');
3.163 + ActivateSensor(controls[i]);
3.164 + }
3.165 +
3.166 + for (int i = 0; i < fanCount; i++) {
3.167 + int device = 33 + i;
3.168 + string name = ReadString(device, 'C');
3.169 +
3.170 + fans[i].Value = ReadInteger(device, 'R');
3.171 + ActivateSensor(fans[i]);
3.172 + }
3.173 +
3.174 + temperatures = new Sensor[temperatureCount];
3.175 + for (int i = 0; i < temperatureCount; i++) {
3.176 + int device = 49 + i;
3.177 + string name = ReadString(device, 'C');
3.178 + temperatures[i] =
3.179 + new Sensor(name, device, SensorType.Temperature, this, settings);
3.180 + int value = ReadInteger(device, 'T');
3.181 + temperatures[i].Value = 0.1f * value;
3.182 + if (value != -32768)
3.183 + ActivateSensor(temperatures[i]);
3.184 + }
3.185 +
3.186 + flows = new Sensor[flowCount];
3.187 + for (int i = 0; i < flowCount; i++) {
3.188 + int device = 65 + i;
3.189 + string name = ReadString(device, 'C');
3.190 + flows[i] = new Sensor(name, device, SensorType.Flow, this, settings);
3.191 + flows[i].Value = 0.1f * ReadInteger(device, 'L');
3.192 + ActivateSensor(flows[i]);
3.193 + }
3.194 +
3.195 + relays = new Sensor[relayCount];
3.196 + for (int i = 0; i < relayCount; i++) {
3.197 + int device = 81 + i;
3.198 + string name = ReadString(device, 'C');
3.199 + relays[i] =
3.200 + new Sensor(name, device, SensorType.Control, this, settings);
3.201 + relays[i].Value = 100 * ReadInteger(device, 'S');
3.202 + ActivateSensor(relays[i]);
3.203 + }
3.204 +
3.205 + // set the update rate to 2 Hz
3.206 + WriteInteger(0, 'L', 2);
3.207 +
3.208 + available = true;
3.209 +
3.210 + } catch (IOException) { } catch (TimeoutException) { }
3.211 + }
3.212 +
3.213 + public override HardwareType HardwareType {
3.214 + get { return HardwareType.Heatmaster; }
3.215 + }
3.216 +
3.217 + public override Identifier Identifier {
3.218 + get {
3.219 + return new Identifier("heatmaster",
3.220 + serialPort.PortName.TrimStart(new char[]{'/'}).ToLowerInvariant());
3.221 + }
3.222 + }
3.223 +
3.224 + public override string Name {
3.225 + get { return "Heatmaster"; }
3.226 + }
3.227 +
3.228 + public override void Update() {
3.229 + if (!available)
3.230 + return;
3.231 +
3.232 + while (serialPort.BytesToRead > 0) {
3.233 + Match match = Regex.Match(ReadLine(0), @">\[0:(\d+)\]([0-9:\|-]+)");
3.234 + if (match.Success) {
3.235 + int device;
3.236 + if (int.TryParse(match.Groups[1].Value, out device)) {
3.237 + foreach (string s in match.Groups[2].Value.Split('|')) {
3.238 + string[] strings = s.Split(':');
3.239 + int[] ints = new int[strings.Length];
3.240 + for (int i = 0; i < ints.Length; i++)
3.241 + ints[i] = int.Parse(strings[i]);
3.242 + switch (device) {
3.243 + case 32:
3.244 + if (ints.Length == 3 && ints[0] <= fans.Length) {
3.245 + fans[ints[0] - 1].Value = ints[1];
3.246 + controls[ints[0] - 1].Value = (100 / 255.0f) * ints[2];
3.247 + }
3.248 + break;
3.249 + case 48:
3.250 + if (ints.Length == 2 && ints[0] <= temperatures.Length)
3.251 + temperatures[ints[0] - 1].Value = 0.1f * ints[1];
3.252 + break;
3.253 + case 64:
3.254 + if (ints.Length == 3 && ints[0] <= flows.Length)
3.255 + flows[ints[0] - 1].Value = 0.1f * ints[1];
3.256 + break;
3.257 + case 80:
3.258 + if (ints.Length == 2 && ints[0] <= relays.Length)
3.259 + relays[ints[0] - 1].Value = 100 * ints[1];
3.260 + break;
3.261 + }
3.262 + }
3.263 + }
3.264 + }
3.265 + }
3.266 + }
3.267 +
3.268 + public override string GetReport() {
3.269 + StringBuilder r = new StringBuilder();
3.270 +
3.271 + r.AppendLine("Heatmaster");
3.272 + r.AppendLine();
3.273 + r.Append("Port: ");
3.274 + r.AppendLine(portName);
3.275 + r.Append("Hardware Revision: ");
3.276 + r.AppendLine(hardwareRevision.ToString());
3.277 + r.Append("Firmware Revision: ");
3.278 + r.AppendLine(firmwareRevision.ToString());
3.279 + r.Append("Firmware CRC: ");
3.280 + r.AppendLine(firmwareCRC.ToString());
3.281 + r.AppendLine();
3.282 +
3.283 + return r.ToString();
3.284 + }
3.285 +
3.286 + public void Close() {
3.287 + serialPort.Close();
3.288 + }
3.289 + }
3.290 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/Hardware/Heatmaster/HeatmasterGroup.cs Sun Aug 22 21:53:11 2010 +0000
4.3 @@ -0,0 +1,172 @@
4.4 +/*
4.5 +
4.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
4.7 +
4.8 + The contents of this file are subject to the Mozilla Public License Version
4.9 + 1.1 (the "License"); you may not use this file except in compliance with
4.10 + the License. You may obtain a copy of the License at
4.11 +
4.12 + http://www.mozilla.org/MPL/
4.13 +
4.14 + Software distributed under the License is distributed on an "AS IS" basis,
4.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
4.16 + for the specific language governing rights and limitations under the License.
4.17 +
4.18 + The Original Code is the Open Hardware Monitor code.
4.19 +
4.20 + The Initial Developer of the Original Code is
4.21 + Michael Möller <m.moeller@gmx.ch>.
4.22 + Portions created by the Initial Developer are Copyright (C) 2010
4.23 + the Initial Developer. All Rights Reserved.
4.24 +
4.25 + Contributor(s):
4.26 +
4.27 + Alternatively, the contents of this file may be used under the terms of
4.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
4.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
4.30 + in which case the provisions of the GPL or the LGPL are applicable instead
4.31 + of those above. If you wish to allow use of your version of this file only
4.32 + under the terms of either the GPL or the LGPL, and not to allow others to
4.33 + use your version of this file under the terms of the MPL, indicate your
4.34 + decision by deleting the provisions above and replace them with the notice
4.35 + and other provisions required by the GPL or the LGPL. If you do not delete
4.36 + the provisions above, a recipient may use your version of this file under
4.37 + the terms of any one of the MPL, the GPL or the LGPL.
4.38 +
4.39 +*/
4.40 +
4.41 +using System;
4.42 +using System.Collections.Generic;
4.43 +using System.IO.Ports;
4.44 +using System.Text;
4.45 +using System.Threading;
4.46 +
4.47 +namespace OpenHardwareMonitor.Hardware.Heatmaster {
4.48 + internal class HeatmasterGroup : IGroup {
4.49 +
4.50 + private List<Heatmaster> hardware = new List<Heatmaster>();
4.51 + private StringBuilder report = new StringBuilder();
4.52 +
4.53 + private static string ReadLine(SerialPort port, int timeout) {
4.54 + int i = 0;
4.55 + StringBuilder builder = new StringBuilder();
4.56 + while (i < timeout) {
4.57 + while (port.BytesToRead > 0) {
4.58 + byte b = (byte)port.ReadByte();
4.59 + switch (b) {
4.60 + case 0xAA: return ((char)b).ToString();
4.61 + case 0x0D: return builder.ToString();
4.62 + default: builder.Append((char)b); break;
4.63 + }
4.64 + }
4.65 + i++;
4.66 + Thread.Sleep(1);
4.67 + }
4.68 + throw new TimeoutException();
4.69 + }
4.70 +
4.71 + public HeatmasterGroup(ISettings settings) {
4.72 +
4.73 + string[] portNames = SerialPort.GetPortNames();
4.74 + for (int i = portNames.Length - 1; i >= 0; i--) {
4.75 + try {
4.76 +
4.77 + SerialPort serialPort =
4.78 + new SerialPort(portNames[i], 38400, Parity.None, 8, StopBits.One);
4.79 + serialPort.NewLine = ((char)0x0D).ToString();
4.80 +
4.81 + bool isValid = false;
4.82 + report.Append("Port Name: "); report.AppendLine(portNames[i]);
4.83 +
4.84 + try {
4.85 + serialPort.Open();
4.86 + } catch (UnauthorizedAccessException) {
4.87 + report.AppendLine("Exception: Access Denied");
4.88 + }
4.89 +
4.90 + if (serialPort.IsOpen) {
4.91 + if (serialPort.CtsHolding) {
4.92 + serialPort.DiscardInBuffer();
4.93 + serialPort.DiscardOutBuffer();
4.94 + serialPort.Write(new byte[] { 0xAA }, 0, 1);
4.95 +
4.96 + int j = 0;
4.97 + while (serialPort.BytesToRead == 0 && j < 10) {
4.98 + Thread.Sleep(20);
4.99 + j++;
4.100 + }
4.101 + if (serialPort.BytesToRead > 0) {
4.102 + bool flag = false;
4.103 + while (serialPort.BytesToRead > 0 && !flag) {
4.104 + flag |= (serialPort.ReadByte() == 0xAA);
4.105 + }
4.106 + if (flag) {
4.107 + serialPort.WriteLine("[0:0]RH");
4.108 + try {
4.109 + int k = 0;
4.110 + int revision = 0;
4.111 + while (k < 5) {
4.112 + string line = ReadLine(serialPort, 100);
4.113 + if (line.StartsWith("-[0:0]RH:")) {
4.114 + int.TryParse(line.Substring(9), out revision);
4.115 + break;
4.116 + }
4.117 + k++;
4.118 + }
4.119 + isValid = (revision == 770);
4.120 + if (!isValid) {
4.121 + report.Append("Status: Wrong Hardware Revision " +
4.122 + revision.ToString());
4.123 + }
4.124 + } catch (TimeoutException) {
4.125 + report.AppendLine("Status: Timeout Reading Revision");
4.126 + }
4.127 + } else {
4.128 + report.AppendLine("Status: Wrong Startflag");
4.129 + }
4.130 + } else {
4.131 + report.AppendLine("Status: No Response");
4.132 + }
4.133 + } else {
4.134 + report.AppendLine("Status: Not Clear to Send");
4.135 + }
4.136 + serialPort.DiscardInBuffer();
4.137 + serialPort.Close();
4.138 + serialPort.Dispose();
4.139 + } else {
4.140 + report.AppendLine("Status: Port not Open");
4.141 + }
4.142 + if (isValid) {
4.143 + report.AppendLine("Status: OK");
4.144 + hardware.Add(new Heatmaster(portNames[i], settings));
4.145 + return;
4.146 + }
4.147 + } catch (Exception e) {
4.148 + report.AppendLine(e.ToString());
4.149 + }
4.150 + report.AppendLine();
4.151 + }
4.152 + }
4.153 +
4.154 + public IHardware[] Hardware {
4.155 + get {
4.156 + return hardware.ToArray();
4.157 + }
4.158 + }
4.159 +
4.160 + public string GetReport() {
4.161 + if (report.Length > 0) {
4.162 + report.Insert(0, "Serial Port Heatmaster" + Environment.NewLine +
4.163 + Environment.NewLine);
4.164 + report.AppendLine();
4.165 + return report.ToString();
4.166 + } else
4.167 + return null;
4.168 + }
4.169 +
4.170 + public void Close() {
4.171 + foreach (Heatmaster heatmaster in hardware)
4.172 + heatmaster.Close();
4.173 + }
4.174 + }
4.175 +}
5.1 --- a/Hardware/IHardware.cs Tue Aug 17 21:44:02 2010 +0000
5.2 +++ b/Hardware/IHardware.cs Sun Aug 22 21:53:11 2010 +0000
5.3 @@ -46,6 +46,7 @@
5.4 CPU,
5.5 GPU,
5.6 HDD,
5.7 + Heatmaster,
5.8 Mainboard,
5.9 SuperIO,
5.10 TBalancer
6.1 --- a/OpenHardwareMonitorLib.csproj Tue Aug 17 21:44:02 2010 +0000
6.2 +++ b/OpenHardwareMonitorLib.csproj Sun Aug 22 21:53:11 2010 +0000
6.3 @@ -71,6 +71,8 @@
6.4 <Compile Include="Hardware\HDD\HDD.cs" />
6.5 <Compile Include="Hardware\HDD\HDDGroup.cs" />
6.6 <Compile Include="Hardware\HDD\SMART.cs" />
6.7 + <Compile Include="Hardware\Heatmaster\Heatmaster.cs" />
6.8 + <Compile Include="Hardware\Heatmaster\HeatmasterGroup.cs" />
6.9 <Compile Include="Hardware\IComputer.cs" />
6.10 <Compile Include="Hardware\Identifier.cs" />
6.11 <Compile Include="Hardware\IElement.cs" />
6.12 @@ -128,6 +130,7 @@
6.13 <Install>true</Install>
6.14 </BootstrapperPackage>
6.15 </ItemGroup>
6.16 + <ItemGroup />
6.17 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
6.18 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
6.19 Other similar extension points exist, see Microsoft.Common.targets.
7.1 --- a/Properties/AssemblyVersion.cs Tue Aug 17 21:44:02 2010 +0000
7.2 +++ b/Properties/AssemblyVersion.cs Sun Aug 22 21:53:11 2010 +0000
7.3 @@ -38,5 +38,5 @@
7.4 using System;
7.5 using System.Reflection;
7.6
7.7 -[assembly: AssemblyVersion("0.1.37.3")]
7.8 -[assembly: AssemblyFileVersion("0.1.37.3")]
7.9 +[assembly: AssemblyVersion("0.1.37.4")]
7.10 +[assembly: AssemblyFileVersion("0.1.37.4")]