Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
13 using System.Globalization;
16 namespace OpenHardwareMonitor.Hardware.TBalancer {
17 internal class TBalancer : Hardware {
19 private readonly int portIndex;
20 private readonly byte protocolVersion;
21 private readonly Sensor[] digitalTemperatures = new Sensor[8];
22 private readonly Sensor[] analogTemperatures = new Sensor[4];
23 private readonly Sensor[] sensorhubTemperatures = new Sensor[6];
24 private readonly Sensor[] sensorhubFlows = new Sensor[2];
25 private readonly Sensor[] fans = new Sensor[4];
26 private readonly Sensor[] controls = new Sensor[4];
27 private readonly Sensor[] miniNGTemperatures = new Sensor[4];
28 private readonly Sensor[] miniNGFans = new Sensor[4];
29 private readonly Sensor[] miniNGControls = new Sensor[4];
30 private readonly List<ISensor> deactivating = new List<ISensor>();
32 private FT_HANDLE handle;
33 private byte[] data = new byte[285];
34 private byte[] primaryData = new byte[0];
35 private byte[] alternativeData = new byte[0];
37 public const byte STARTFLAG = 100;
38 public const byte ENDFLAG = 254;
40 private delegate void MethodDelegate();
41 private readonly MethodDelegate alternativeRequest;
43 public TBalancer(int portIndex, byte protocolVersion, ISettings settings)
44 : base("T-Balancer bigNG", new Identifier("bigng",
45 portIndex.ToString(CultureInfo.InvariantCulture)), settings)
48 this.portIndex = portIndex;
49 this.protocolVersion = protocolVersion;
51 ParameterDescription[] parameter = new [] {
52 new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
55 for (int i = 0; i < digitalTemperatures.Length; i++)
56 digitalTemperatures[i] = new Sensor("Digital Sensor " + i,
57 offset + i, SensorType.Temperature, this, parameter, settings);
58 offset += digitalTemperatures.Length;
60 for (int i = 0; i < analogTemperatures.Length; i++)
61 analogTemperatures[i] = new Sensor("Analog Sensor " + (i + 1),
62 offset + i, SensorType.Temperature, this, parameter, settings);
63 offset += analogTemperatures.Length;
65 for (int i = 0; i < sensorhubTemperatures.Length; i++)
66 sensorhubTemperatures[i] = new Sensor("Sensorhub Sensor " + i,
67 offset + i, SensorType.Temperature, this, parameter, settings);
68 offset += sensorhubTemperatures.Length;
70 for (int i = 0; i < miniNGTemperatures.Length; i++)
71 miniNGTemperatures[i] = new Sensor("miniNG #" + (i / 2 + 1) +
72 " Sensor " + (i % 2 + 1), offset + i, SensorType.Temperature,
73 this, parameter, settings);
74 offset += miniNGTemperatures.Length;
76 for (int i = 0; i < sensorhubFlows.Length; i++)
77 sensorhubFlows[i] = new Sensor("Flowmeter " + (i + 1),
78 i, SensorType.Flow, this, new [] {
79 new ParameterDescription("Impulse Rate",
80 "The impulse rate of the flowmeter in pulses/L", 509)
83 for (int i = 0; i < controls.Length; i++) {
84 controls[i] = new Sensor("Fan Channel " + i, i, SensorType.Control,
88 for (int i = 0; i < miniNGControls.Length; i++) {
89 miniNGControls[i] = new Sensor("miniNG #" + (i / 2 + 1) +
90 " Fan Channel " + (i % 2 + 1), 4 + i, SensorType.Control, this,
94 alternativeRequest = new MethodDelegate(DelayedAlternativeRequest);
100 protected override void ActivateSensor(ISensor sensor) {
101 deactivating.Remove(sensor);
102 base.ActivateSensor(sensor);
105 protected override void DeactivateSensor(ISensor sensor) {
106 if (deactivating.Contains(sensor)) {
107 deactivating.Remove(sensor);
108 base.DeactivateSensor(sensor);
109 } else if (active.Contains(sensor)) {
110 deactivating.Add(sensor);
114 private void ReadminiNG(int number) {
115 int offset = 1 + number * 65;
117 if (data[offset + 61] != ENDFLAG)
120 for (int i = 0; i < 2; i++) {
121 Sensor sensor = miniNGTemperatures[number * 2 + i];
122 if (data[offset + 7 + i] > 0) {
123 sensor.Value = 0.5f * data[offset + 7 + i] +
124 sensor.Parameters[0].Value;
125 ActivateSensor(sensor);
127 DeactivateSensor(sensor);
131 for (int i = 0; i < 2; i++) {
132 if (miniNGFans[number * 2 + i] == null)
133 miniNGFans[number * 2 + i] =
134 new Sensor("miniNG #" + (number + 1) + " Fan Channel " + (i + 1),
135 4 + number * 2 + i, SensorType.Fan, this, settings);
137 Sensor sensor = miniNGFans[number * 2 + i];
139 sensor.Value = 20.0f * data[offset + 43 + 2 * i];
140 ActivateSensor(sensor);
143 for (int i = 0; i < 2; i++) {
144 Sensor sensor = miniNGControls[number * 2 + i];
145 sensor.Value = data[offset + 15 + i];
146 ActivateSensor(sensor);
150 private void ReadData() {
151 FTD2XX.Read(handle, data);
153 if (data[0] != STARTFLAG) {
154 FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_RX);
158 if (data[1] == 255 || data[1] == 88) { // bigNG
160 if (data[274] != protocolVersion)
163 if (primaryData.Length == 0)
164 primaryData = new byte[data.Length];
165 data.CopyTo(primaryData, 0);
167 for (int i = 0; i < digitalTemperatures.Length; i++)
168 if (data[238 + i] > 0) {
169 digitalTemperatures[i].Value = 0.5f * data[238 + i] +
170 digitalTemperatures[i].Parameters[0].Value;
171 ActivateSensor(digitalTemperatures[i]);
173 DeactivateSensor(digitalTemperatures[i]);
176 for (int i = 0; i < analogTemperatures.Length; i++)
177 if (data[260 + i] > 0) {
178 analogTemperatures[i].Value = 0.5f * data[260 + i] +
179 analogTemperatures[i].Parameters[0].Value;
180 ActivateSensor(analogTemperatures[i]);
182 DeactivateSensor(analogTemperatures[i]);
185 for (int i = 0; i < sensorhubTemperatures.Length; i++)
186 if (data[246 + i] > 0) {
187 sensorhubTemperatures[i].Value = 0.5f * data[246 + i] +
188 sensorhubTemperatures[i].Parameters[0].Value;
189 ActivateSensor(sensorhubTemperatures[i]);
191 DeactivateSensor(sensorhubTemperatures[i]);
194 for (int i = 0; i < sensorhubFlows.Length; i++)
195 if (data[231 + i] > 0 && data[234] > 0) {
196 float pulsesPerSecond = (data[231 + i] * 4.0f) / data[234];
197 float pulsesPerLiter = sensorhubFlows[i].Parameters[0].Value;
198 sensorhubFlows[i].Value = pulsesPerSecond * 3600 / pulsesPerLiter;
199 ActivateSensor(sensorhubFlows[i]);
201 DeactivateSensor(sensorhubFlows[i]);
204 for (int i = 0; i < fans.Length; i++) {
205 float maxRPM = 11.5f * ((data[149 + 2 * i] << 8) | data[148 + 2 * i]);
208 fans[i] = new Sensor("Fan Channel " + i, i, SensorType.Fan,
209 this, new [] { new ParameterDescription("MaxRPM",
210 "Maximum revolutions per minute (RPM) of the fan.", maxRPM)
214 if ((data[136] & (1 << i)) == 0) // pwm mode
215 value = 0.02f * data[137 + i];
217 value = 0.01f * data[141 + i];
219 fans[i].Value = fans[i].Parameters[0].Value * value;
220 ActivateSensor(fans[i]);
222 controls[i].Value = 100 * value;
223 ActivateSensor(controls[i]);
226 } else if (data[1] == 253) { // miniNG #1
227 if (alternativeData.Length == 0)
228 alternativeData = new byte[data.Length];
229 data.CopyTo(alternativeData, 0);
233 if (data[66] == 253) // miniNG #2
238 public override HardwareType HardwareType {
239 get { return HardwareType.TBalancer; }
242 public override string GetReport() {
243 StringBuilder r = new StringBuilder();
245 r.AppendLine("T-Balancer bigNG");
247 r.Append("Port Index: ");
248 r.AppendLine(portIndex.ToString(CultureInfo.InvariantCulture));
251 r.AppendLine("Primary System Information Answer");
253 r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
255 for (int i = 0; i <= 0x11; i++) {
257 r.Append((i << 4).ToString("X3", CultureInfo.InvariantCulture));
259 for (int j = 0; j <= 0xF; j++) {
260 int index = ((i << 4) | j);
261 if (index < primaryData.Length) {
263 r.Append(primaryData[index].ToString("X2", CultureInfo.InvariantCulture));
270 if (alternativeData.Length > 0) {
271 r.AppendLine("Alternative System Information Answer");
273 r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
275 for (int i = 0; i <= 0x11; i++) {
277 r.Append((i << 4).ToString("X3", CultureInfo.InvariantCulture));
279 for (int j = 0; j <= 0xF; j++) {
280 int index = ((i << 4) | j);
281 if (index < alternativeData.Length) {
283 r.Append(alternativeData[index].ToString("X2", CultureInfo.InvariantCulture));
294 private void DelayedAlternativeRequest() {
295 System.Threading.Thread.Sleep(500);
296 FTD2XX.Write(handle, new byte[] { 0x37 });
300 FTD2XX.FT_Open(portIndex, out handle);
301 FTD2XX.FT_SetBaudRate(handle, 19200);
302 FTD2XX.FT_SetDataCharacteristics(handle, 8, 1, 0);
303 FTD2XX.FT_SetFlowControl(handle, FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11,
305 FTD2XX.FT_SetTimeouts(handle, 1000, 1000);
306 FTD2XX.FT_Purge(handle, FT_PURGE.FT_PURGE_ALL);
309 public override void Update() {
310 while (FTD2XX.BytesToRead(handle) >= 285)
312 if (FTD2XX.BytesToRead(handle) == 1)
313 FTD2XX.ReadByte(handle);
315 FTD2XX.Write(handle, new byte[] { 0x38 });
316 alternativeRequest.BeginInvoke(null, null);
319 public override void Close() {
320 FTD2XX.FT_Close(handle);