Hardware/Sensor.cs
author moel.mich
Sun, 01 Jul 2012 21:44:07 +0000
changeset 355 17dbf781401e
parent 314 d19c6b4d625e
child 358 7962499f9cd6
permissions -rw-r--r--
Added experimental support for Nuvoton NCT6779D super I/O chips.
     1 /*
     2  
     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/.
     6  
     7   Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Globalization;
    14 using System.IO;
    15 using System.IO.Compression;
    16 using OpenHardwareMonitor.Collections;
    17 
    18 namespace OpenHardwareMonitor.Hardware {
    19 
    20   internal class Sensor : ISensor {
    21 
    22     private readonly string defaultName;
    23     private string name;
    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;
    36     
    37     private float sum;
    38     private int count;
    39    
    40     public Sensor(string name, int index, SensorType sensorType,
    41       Hardware hardware, ISettings settings) : 
    42       this(name, index, sensorType, hardware, null, settings) { }
    43 
    44     public Sensor(string name, int index, SensorType sensorType,
    45       Hardware hardware, ParameterDescription[] parameterDescriptions, 
    46       ISettings settings) :
    47       this(name, index, false, sensorType, hardware,
    48         parameterDescriptions, settings) { }
    49 
    50     public Sensor(string name, int index, bool defaultHidden, 
    51       SensorType sensorType, Hardware hardware, 
    52       ParameterDescription[] parameterDescriptions, ISettings settings) 
    53     {           
    54       this.index = index;
    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;
    63 
    64       this.settings = settings;
    65       this.defaultName = name; 
    66       this.name = settings.GetValue(
    67         new Identifier(Identifier, "name").ToString(), name);
    68 
    69       GetSensorValuesFromSettings();
    70 
    71       hardware.Closing += delegate(IHardware h) {
    72         SetSensorValuesToSettings();
    73       };
    74     }
    75 
    76     private void SetSensorValuesToSettings() {
    77       using (MemoryStream m = new MemoryStream()) {
    78         using (GZipStream c = new GZipStream(m, CompressionMode.Compress))
    79         using (BinaryWriter writer = new BinaryWriter(c)) {
    80           foreach (SensorValue sensorValue in values) {
    81             writer.Write(sensorValue.Time.ToBinary());
    82             writer.Write(sensorValue.Value);
    83           }
    84         }
    85         settings.SetValue(new Identifier(Identifier, "values").ToString(),
    86            Convert.ToBase64String(m.ToArray()));
    87       }
    88     }
    89 
    90     private void GetSensorValuesFromSettings() {
    91       string s = settings.GetValue(
    92         new Identifier(Identifier, "values").ToString(), null);
    93 
    94       byte[] array = null;
    95       try {
    96         array = Convert.FromBase64String(s);
    97         using (MemoryStream m = new MemoryStream(array))
    98         using (GZipStream c = new GZipStream(m, CompressionMode.Decompress))
    99         using (BinaryReader reader = new BinaryReader(c)) {
   100           try {
   101             while (true) {
   102               DateTime time = DateTime.FromBinary(reader.ReadInt64());
   103               float value = reader.ReadSingle();
   104               AppendValue(value, time);
   105             }
   106           } catch (EndOfStreamException) { }
   107         }
   108       } catch { }
   109       if (values.Count > 0)
   110         AppendValue(float.NaN, DateTime.UtcNow);
   111     }
   112 
   113     private void AppendValue(float value, DateTime time) {
   114       if (values.Count >= 2 && values.Last.Value == value && 
   115         values[values.Count - 2].Value == value) {
   116         values.Last = new SensorValue(value, time);
   117         return;
   118       } 
   119 
   120       values.Append(new SensorValue(value, time));
   121     }
   122 
   123     public IHardware Hardware {
   124       get { return hardware; }
   125     }
   126 
   127     public SensorType SensorType {
   128       get { return sensorType; }
   129     }
   130 
   131     public Identifier Identifier {
   132       get {
   133         return new Identifier(hardware.Identifier,
   134           sensorType.ToString().ToLowerInvariant(),
   135           index.ToString(CultureInfo.InvariantCulture));
   136       }
   137     }
   138 
   139     public string Name {
   140       get { 
   141         return name; 
   142       }
   143       set {
   144         if (!string.IsNullOrEmpty(value)) 
   145           name = value;          
   146         else 
   147           name = defaultName;
   148         settings.SetValue(new Identifier(Identifier, "name").ToString(), name);
   149       }
   150     }
   151 
   152     public int Index {
   153       get { return index; }
   154     }
   155 
   156     public bool IsDefaultHidden {
   157       get { return defaultHidden; }
   158     }
   159 
   160     public IReadOnlyArray<IParameter> Parameters {
   161       get { return parameters; }
   162     }
   163 
   164     public float? Value {
   165       get { 
   166         return currentValue; 
   167       }
   168       set {
   169         DateTime now = DateTime.UtcNow;
   170         while (values.Count > 0 && (now - values.First.Time).TotalDays > 1)
   171           values.Remove();
   172 
   173         if (value.HasValue) {
   174           sum += value.Value;
   175           count++;
   176           if (count == 4) {
   177             AppendValue(sum / count, now);
   178             sum = 0;
   179             count = 0;
   180           }
   181         }
   182 
   183         this.currentValue = value;
   184         if (minValue > value || !minValue.HasValue)
   185           minValue = value;
   186         if (maxValue < value || !maxValue.HasValue)
   187           maxValue = value;
   188       }
   189     }
   190 
   191     public float? Min { get { return minValue; } }
   192     public float? Max { get { return maxValue; } }
   193 
   194     public void ResetMin() {
   195       minValue = null;
   196     }
   197 
   198     public void ResetMax() {
   199       maxValue = null;
   200     }
   201 
   202     public IEnumerable<SensorValue> Values {
   203       get { return values; }
   204     }    
   205 
   206     public void Accept(IVisitor visitor) {
   207       if (visitor == null)
   208         throw new ArgumentNullException("visitor");
   209       visitor.VisitSensor(this);
   210     }
   211 
   212     public void Traverse(IVisitor visitor) {
   213       foreach (IParameter parameter in parameters)
   214         parameter.Accept(visitor);
   215     }
   216 
   217     public IControl Control {
   218       get {
   219         return control;
   220       }
   221       internal set {
   222         this.control = value;
   223       }
   224     }
   225   }
   226 }