Fixed Issue 368. Fixed Issue 369. Fixed Issue 370.
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-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
13 using System.Globalization;
15 using System.IO.Compression;
16 using OpenHardwareMonitor.Collections;
18 namespace OpenHardwareMonitor.Hardware {
20 internal class Sensor : ISensor {
22 private readonly string defaultName;
24 private readonly int index;
25 private readonly bool defaultHidden;
26 private readonly SensorType sensorType;
27 private readonly Hardware hardware;
28 private readonly ReadOnlyArray<IParameter> parameters;
29 private float? currentValue;
30 private float? minValue;
31 private float? maxValue;
32 private readonly RingCollection<SensorValue>
33 values = new RingCollection<SensorValue>();
34 private readonly ISettings settings;
35 private IControl control;
40 public Sensor(string name, int index, SensorType sensorType,
41 Hardware hardware, ISettings settings) :
42 this(name, index, sensorType, hardware, null, settings) { }
44 public Sensor(string name, int index, SensorType sensorType,
45 Hardware hardware, ParameterDescription[] parameterDescriptions,
47 this(name, index, false, sensorType, hardware,
48 parameterDescriptions, settings) { }
50 public Sensor(string name, int index, bool defaultHidden,
51 SensorType sensorType, Hardware hardware,
52 ParameterDescription[] parameterDescriptions, ISettings settings)
55 this.defaultHidden = defaultHidden;
56 this.sensorType = sensorType;
57 this.hardware = hardware;
58 Parameter[] parameters = new Parameter[parameterDescriptions == null ?
59 0 : parameterDescriptions.Length];
60 for (int i = 0; i < parameters.Length; i++ )
61 parameters[i] = new Parameter(parameterDescriptions[i], this, settings);
62 this.parameters = parameters;
64 this.settings = settings;
65 this.defaultName = name;
66 this.name = settings.GetValue(
67 new Identifier(Identifier, "name").ToString(), name);
69 GetSensorValuesFromSettings();
71 hardware.Closing += delegate(IHardware h) {
72 SetSensorValuesToSettings();
76 private void SetSensorValuesToSettings() {
77 using (MemoryStream m = new MemoryStream()) {
78 using (GZipStream c = new GZipStream(m, CompressionMode.Compress))
79 using (BufferedStream b = new BufferedStream(c, 65536))
80 using (BinaryWriter writer = new BinaryWriter(b)) {
82 foreach (SensorValue sensorValue in values) {
83 long v = sensorValue.Time.ToBinary();
86 writer.Write(sensorValue.Value);
90 settings.SetValue(new Identifier(Identifier, "values").ToString(),
91 Convert.ToBase64String(m.ToArray()));
95 private void GetSensorValuesFromSettings() {
96 string name = new Identifier(Identifier, "values").ToString();
97 string s = settings.GetValue(name, null);
100 byte[] array = Convert.FromBase64String(s);
102 DateTime now = DateTime.UtcNow;
103 using (MemoryStream m = new MemoryStream(array))
104 using (GZipStream c = new GZipStream(m, CompressionMode.Decompress))
105 using (BinaryReader reader = new BinaryReader(c)) {
109 t += reader.ReadInt64();
110 DateTime time = DateTime.FromBinary(t);
113 float value = reader.ReadSingle();
114 AppendValue(value, time);
116 } catch (EndOfStreamException) { }
119 if (values.Count > 0)
120 AppendValue(float.NaN, DateTime.UtcNow);
122 // remove the value string from the settings to reduce memory usage
123 settings.Remove(name);
126 private void AppendValue(float value, DateTime time) {
127 if (values.Count >= 2 && values.Last.Value == value &&
128 values[values.Count - 2].Value == value) {
129 values.Last = new SensorValue(value, time);
133 values.Append(new SensorValue(value, time));
136 public IHardware Hardware {
137 get { return hardware; }
140 public SensorType SensorType {
141 get { return sensorType; }
144 public Identifier Identifier {
146 return new Identifier(hardware.Identifier,
147 sensorType.ToString().ToLowerInvariant(),
148 index.ToString(CultureInfo.InvariantCulture));
157 if (!string.IsNullOrEmpty(value))
161 settings.SetValue(new Identifier(Identifier, "name").ToString(), name);
166 get { return index; }
169 public bool IsDefaultHidden {
170 get { return defaultHidden; }
173 public IReadOnlyArray<IParameter> Parameters {
174 get { return parameters; }
177 public float? Value {
182 DateTime now = DateTime.UtcNow;
183 while (values.Count > 0 && (now - values.First.Time).TotalDays > 1)
186 if (value.HasValue) {
190 AppendValue(sum / count, now);
196 this.currentValue = value;
197 if (minValue > value || !minValue.HasValue)
199 if (maxValue < value || !maxValue.HasValue)
204 public float? Min { get { return minValue; } }
205 public float? Max { get { return maxValue; } }
207 public void ResetMin() {
211 public void ResetMax() {
215 public IEnumerable<SensorValue> Values {
216 get { return values; }
219 public void Accept(IVisitor visitor) {
221 throw new ArgumentNullException("visitor");
222 visitor.VisitSensor(this);
225 public void Traverse(IVisitor visitor) {
226 foreach (IParameter parameter in parameters)
227 parameter.Accept(visitor);
230 public IControl Control {
235 this.control = value;