Hardware/Sensor.cs
changeset 298 96263190189a
parent 247 6dc755f1970e
child 314 d19c6b4d625e
     1.1 --- a/Hardware/Sensor.cs	Sat Jun 04 13:27:11 2011 +0000
     1.2 +++ b/Hardware/Sensor.cs	Sun Jun 19 12:41:18 2011 +0000
     1.3 @@ -16,7 +16,7 @@
     1.4  
     1.5    The Initial Developer of the Original Code is 
     1.6    Michael Möller <m.moeller@gmx.ch>.
     1.7 -  Portions created by the Initial Developer are Copyright (C) 2009-2010
     1.8 +  Portions created by the Initial Developer are Copyright (C) 2009-2011
     1.9    the Initial Developer. All Rights Reserved.
    1.10  
    1.11    Contributor(s):
    1.12 @@ -38,6 +38,8 @@
    1.13  using System;
    1.14  using System.Collections.Generic;
    1.15  using System.Globalization;
    1.16 +using System.IO;
    1.17 +using System.IO.Compression;
    1.18  using OpenHardwareMonitor.Collections;
    1.19  
    1.20  namespace OpenHardwareMonitor.Hardware {
    1.21 @@ -49,33 +51,31 @@
    1.22      private readonly int index;
    1.23      private readonly bool defaultHidden;
    1.24      private readonly SensorType sensorType;
    1.25 -    private readonly IHardware hardware;
    1.26 +    private readonly Hardware hardware;
    1.27      private readonly ReadOnlyArray<IParameter> parameters;
    1.28      private float? currentValue;
    1.29      private float? minValue;
    1.30      private float? maxValue;
    1.31 -    private readonly Queue<SensorValue> values =
    1.32 -      new Queue<SensorValue>(MAX_MINUTES * 15);
    1.33 +    private readonly RingCollection<SensorValue> 
    1.34 +      values = new RingCollection<SensorValue>();
    1.35      private readonly ISettings settings;
    1.36      private IControl control;
    1.37      
    1.38      private float sum;
    1.39      private int count;
    1.40 -
    1.41 -    private const int MAX_MINUTES = 120;
    1.42     
    1.43      public Sensor(string name, int index, SensorType sensorType,
    1.44 -      IHardware hardware, ISettings settings) : 
    1.45 +      Hardware hardware, ISettings settings) : 
    1.46        this(name, index, sensorType, hardware, null, settings) { }
    1.47  
    1.48      public Sensor(string name, int index, SensorType sensorType,
    1.49 -      IHardware hardware, ParameterDescription[] parameterDescriptions, 
    1.50 +      Hardware hardware, ParameterDescription[] parameterDescriptions, 
    1.51        ISettings settings) :
    1.52        this(name, index, false, sensorType, hardware,
    1.53          parameterDescriptions, settings) { }
    1.54  
    1.55      public Sensor(string name, int index, bool defaultHidden, 
    1.56 -      SensorType sensorType, IHardware hardware, 
    1.57 +      SensorType sensorType, Hardware hardware, 
    1.58        ParameterDescription[] parameterDescriptions, ISettings settings) 
    1.59      {           
    1.60        this.index = index;
    1.61 @@ -92,6 +92,59 @@
    1.62        this.defaultName = name; 
    1.63        this.name = settings.GetValue(
    1.64          new Identifier(Identifier, "name").ToString(), name);
    1.65 +
    1.66 +      GetSensorValuesFromSettings();
    1.67 +
    1.68 +      hardware.Closing += delegate(IHardware h) {
    1.69 +        SetSensorValuesToSettings();
    1.70 +      };
    1.71 +    }
    1.72 +
    1.73 +    private void SetSensorValuesToSettings() {
    1.74 +      using (MemoryStream m = new MemoryStream()) {
    1.75 +        using (GZipStream c = new GZipStream(m, CompressionMode.Compress))
    1.76 +        using (BinaryWriter writer = new BinaryWriter(c)) {
    1.77 +          foreach (SensorValue sensorValue in values) {
    1.78 +            writer.Write(sensorValue.Time.ToBinary());
    1.79 +            writer.Write(sensorValue.Value);
    1.80 +          }
    1.81 +        }
    1.82 +        settings.SetValue(new Identifier(Identifier, "values").ToString(),
    1.83 +           Convert.ToBase64String(m.ToArray()));
    1.84 +      }
    1.85 +    }
    1.86 +
    1.87 +    private void GetSensorValuesFromSettings() {
    1.88 +      string s = settings.GetValue(
    1.89 +        new Identifier(Identifier, "values").ToString(), null);
    1.90 +
    1.91 +      byte[] array = null;
    1.92 +      try {
    1.93 +        array = Convert.FromBase64String(s);
    1.94 +        using (MemoryStream m = new MemoryStream(array))
    1.95 +        using (GZipStream c = new GZipStream(m, CompressionMode.Decompress))
    1.96 +        using (BinaryReader reader = new BinaryReader(c)) {
    1.97 +          try {
    1.98 +            while (true) {
    1.99 +              DateTime time = DateTime.FromBinary(reader.ReadInt64());
   1.100 +              float value = reader.ReadSingle();
   1.101 +              AppendValue(value, time);
   1.102 +            }
   1.103 +          } catch (EndOfStreamException) { }
   1.104 +        }
   1.105 +      } catch { }
   1.106 +      if (values.Count > 0)
   1.107 +        AppendValue(float.NaN, DateTime.Now);
   1.108 +    }
   1.109 +
   1.110 +    private void AppendValue(float value, DateTime time) {
   1.111 +      if (values.Count >= 2 && values.Last.Value == value && 
   1.112 +        values[values.Count - 2].Value == value) {
   1.113 +        values.Last = new SensorValue(value, time);
   1.114 +        return;
   1.115 +      } 
   1.116 +
   1.117 +      values.Append(new SensorValue(value, time));
   1.118      }
   1.119  
   1.120      public IHardware Hardware {
   1.121 @@ -140,15 +193,15 @@
   1.122          return currentValue; 
   1.123        }
   1.124        set {
   1.125 -        while (values.Count > 0 && 
   1.126 -          (DateTime.Now - values.Peek().Time).TotalMinutes > MAX_MINUTES)
   1.127 -          values.Dequeue();
   1.128 +        DateTime now = DateTime.Now;
   1.129 +        while (values.Count > 0 && (now - values.First.Time).TotalDays > 1)
   1.130 +          values.Remove();
   1.131  
   1.132          if (value.HasValue) {
   1.133            sum += value.Value;
   1.134            count++;
   1.135            if (count == 4) {
   1.136 -            values.Enqueue(new SensorValue(sum / count, DateTime.Now));
   1.137 +            AppendValue(sum / count, now);
   1.138              sum = 0;
   1.139              count = 0;
   1.140            }