Added a first data logging implementation.
authormoel.mich
Sun, 11 Aug 2013 21:26:56 +0000
changeset 42046c056e76130
parent 419 07d44b20bbd4
child 421 055a9ec117d2
Added a first data logging implementation.
GUI/MainForm.Designer.cs
GUI/MainForm.cs
OpenHardwareMonitor.csproj
Properties/AssemblyVersion.cs
Utilities/Logger.cs
     1.1 --- a/GUI/MainForm.Designer.cs	Sun Aug 04 06:54:46 2013 +0000
     1.2 +++ b/GUI/MainForm.Designer.cs	Sun Aug 11 21:26:56 2013 +0000
     1.3 @@ -4,7 +4,7 @@
     1.4    License, v. 2.0. If a copy of the MPL was not distributed with this
     1.5    file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.6   
     1.7 -  Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
     1.8 +  Copyright (C) 2009-2013 Michael Möller <mmoeller@openhardwaremonitor.org>
     1.9  	
    1.10  */
    1.11  
    1.12 @@ -95,6 +95,7 @@
    1.13        this.timer = new System.Windows.Forms.Timer(this.components);
    1.14        this.splitContainer = new OpenHardwareMonitor.GUI.SplitContainerAdv();
    1.15        this.treeView = new Aga.Controls.Tree.TreeViewAdv();
    1.16 +      this.logSensorsMenuItem = new System.Windows.Forms.MenuItem();
    1.17        this.splitContainer.Panel1.SuspendLayout();
    1.18        this.splitContainer.SuspendLayout();
    1.19        this.SuspendLayout();
    1.20 @@ -355,7 +356,8 @@
    1.21              this.temperatureUnitsMenuItem,
    1.22              this.plotLocationMenuItem,
    1.23              this.webMenuItemSeparator,
    1.24 -            this.webMenuItem});
    1.25 +            this.webMenuItem,
    1.26 +            this.logSensorsMenuItem});
    1.27        this.optionsMenuItem.Text = "Options";
    1.28        // 
    1.29        // startMinMenuItem
    1.30 @@ -432,7 +434,7 @@
    1.31        this.plotRightMenuItem.RadioCheck = true;
    1.32        this.plotRightMenuItem.Text = "Right";
    1.33        // 
    1.34 -      // MenuItem4
    1.35 +      // webMenuItemSeparator
    1.36        // 
    1.37        this.webMenuItemSeparator.Index = 7;
    1.38        this.webMenuItemSeparator.Text = "-";
    1.39 @@ -537,6 +539,11 @@
    1.40        this.treeView.MouseMove += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseMove);
    1.41        this.treeView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseUp);
    1.42        // 
    1.43 +      // logSensorsMenuItem
    1.44 +      // 
    1.45 +      this.logSensorsMenuItem.Index = 9;
    1.46 +      this.logSensorsMenuItem.Text = "Log Sensors";
    1.47 +      // 
    1.48        // MainForm
    1.49        // 
    1.50        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    1.51 @@ -620,6 +627,7 @@
    1.52      private System.Windows.Forms.MenuItem gpuMenuItem;
    1.53      private System.Windows.Forms.MenuItem fanControllerMenuItem;
    1.54      private System.Windows.Forms.MenuItem ramMenuItem;
    1.55 +    private System.Windows.Forms.MenuItem logSensorsMenuItem;
    1.56    }
    1.57  }
    1.58  
     2.1 --- a/GUI/MainForm.cs	Sun Aug 04 06:54:46 2013 +0000
     2.2 +++ b/GUI/MainForm.cs	Sun Aug 11 21:26:56 2013 +0000
     2.3 @@ -66,6 +66,9 @@
     2.4      private UserOption runWebServer;
     2.5      private HttpServer server;
     2.6  
     2.7 +    private UserOption logSensors;
     2.8 +    private Logger logger;
     2.9 +
    2.10      private bool selectionDragging = false;
    2.11  
    2.12      public MainForm() {      
    2.13 @@ -277,6 +280,10 @@
    2.14            server.StopHTTPListener();
    2.15        };
    2.16  
    2.17 +      logSensors = new UserOption("logSensorsMenuItem", false, logSensorsMenuItem,
    2.18 +        settings);
    2.19 +      logger = new Logger(computer);
    2.20 +
    2.21        InitializePlotForm();
    2.22  
    2.23        startupMenuItem.Visible = startupManager.IsAvailable;
    2.24 @@ -500,6 +507,9 @@
    2.25  
    2.26        if (wmiProvider != null)
    2.27          wmiProvider.Update();
    2.28 +
    2.29 +      if (logSensors.Value)
    2.30 +        logger.Log();
    2.31      }
    2.32  
    2.33      private void SaveConfiguration() {
     3.1 --- a/OpenHardwareMonitor.csproj	Sun Aug 04 06:54:46 2013 +0000
     3.2 +++ b/OpenHardwareMonitor.csproj	Sun Aug 11 21:26:56 2013 +0000
     3.3 @@ -125,6 +125,7 @@
     3.4      <Compile Include="GUI\UserRadioGroup.cs" />
     3.5      <Compile Include="Properties\AssemblyVersion.cs" />
     3.6      <Compile Include="Utilities\HttpServer.cs" />
     3.7 +    <Compile Include="Utilities\Logger.cs" />
     3.8      <Compile Include="Utilities\PersistentSettings.cs" />
     3.9      <Compile Include="Properties\AssemblyInfo.cs" />
    3.10      <Compile Include="GUI\AboutBox.cs">
     4.1 --- a/Properties/AssemblyVersion.cs	Sun Aug 04 06:54:46 2013 +0000
     4.2 +++ b/Properties/AssemblyVersion.cs	Sun Aug 11 21:26:56 2013 +0000
     4.3 @@ -10,5 +10,5 @@
     4.4  
     4.5  using System.Reflection;
     4.6  
     4.7 -[assembly: AssemblyVersion("0.6.0.7")]
     4.8 -[assembly: AssemblyInformationalVersion("0.6.0.7 Alpha")]
     4.9 \ No newline at end of file
    4.10 +[assembly: AssemblyVersion("0.6.0.8")]
    4.11 +[assembly: AssemblyInformationalVersion("0.6.0.8 Alpha")]
    4.12 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/Utilities/Logger.cs	Sun Aug 11 21:26:56 2013 +0000
     5.3 @@ -0,0 +1,169 @@
     5.4 +/*
     5.5 + 
     5.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     5.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     5.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5.9 + 
    5.10 +	Copyright (C) 2013 Michael Möller <mmoeller@openhardwaremonitor.org>
    5.11 +
    5.12 +*/
    5.13 +
    5.14 +using System;
    5.15 +using System.Collections.Generic;
    5.16 +using System.Globalization;
    5.17 +using System.IO;
    5.18 +using System.Linq;
    5.19 +using OpenHardwareMonitor.Hardware;
    5.20 +
    5.21 +namespace OpenHardwareMonitor.Utilities {
    5.22 +  public class Logger {
    5.23 +
    5.24 +    private const string fileNameFormat = 
    5.25 +      "OpenHardwareMonitorLog-{0:yyyy-MM-dd}.csv";
    5.26 +
    5.27 +    private readonly IComputer computer;
    5.28 +
    5.29 +    private DateTime day = DateTime.MinValue;
    5.30 +    private string fileName;
    5.31 +    private ISensor[] sensors;
    5.32 +
    5.33 +    public Logger(IComputer computer) {
    5.34 +      this.computer = computer;
    5.35 +      this.computer.HardwareAdded += HardwareAdded;
    5.36 +      this.computer.HardwareRemoved += HardwareRemoved;    
    5.37 +    }
    5.38 +
    5.39 +    private void HardwareRemoved(IHardware hardware) {
    5.40 +      hardware.SensorRemoved -= SensorRemoved;
    5.41 +      foreach (ISensor sensor in hardware.Sensors)
    5.42 +        SensorRemoved(sensor);
    5.43 +      foreach (IHardware subHardware in hardware.SubHardware)
    5.44 +        HardwareRemoved(subHardware);
    5.45 +    }
    5.46 +
    5.47 +    private void HardwareAdded(IHardware hardware) {
    5.48 +      hardware.SensorRemoved += SensorRemoved;
    5.49 +      foreach (IHardware subHardware in hardware.SubHardware)
    5.50 +        HardwareAdded(subHardware);
    5.51 +    }
    5.52 +
    5.53 +    private void SensorRemoved(ISensor sensor) {
    5.54 +      for (int i = 0; i < sensors.Length; i++) {
    5.55 +        if (sensor == sensors[i])
    5.56 +          sensors[i] = null;
    5.57 +      }
    5.58 +    }
    5.59 +
    5.60 +    private static string GetFileName(DateTime date) {
    5.61 +      return AppDomain.CurrentDomain.BaseDirectory +
    5.62 +        Path.DirectorySeparatorChar + string.Format(fileNameFormat, date);
    5.63 +    }
    5.64 +
    5.65 +    private void AddSensorRemovedHandler() {
    5.66 +      for (int i = 0; i < sensors.Length; i++) {
    5.67 +        ISensor sensor = sensors[i];
    5.68 +        int index = i;
    5.69 +        SensorEventHandler handler = null;        
    5.70 +        handler = s => {
    5.71 +          if (s != sensor) 
    5.72 +            return;
    5.73 +
    5.74 +          sensors[index] = null;
    5.75 +          sensor.Hardware.SensorRemoved -= handler;          
    5.76 +        };
    5.77 +        sensor.Hardware.SensorRemoved += handler;
    5.78 +      }
    5.79 +    }
    5.80 +
    5.81 +    private bool OpenExistingLogFile() {
    5.82 +      if (!File.Exists(fileName))
    5.83 +        return false;
    5.84 +
    5.85 +      string[] identifiers;
    5.86 +      try {
    5.87 +        String line;
    5.88 +        using (StreamReader reader = new StreamReader(fileName)) 
    5.89 +          line = reader.ReadLine(); 
    5.90 +       
    5.91 +        if (string.IsNullOrEmpty(line))
    5.92 +          return false;
    5.93 +        
    5.94 +        identifiers = line.Split(',').Skip(1).ToArray();
    5.95 +      } catch {
    5.96 +        return false;
    5.97 +      }
    5.98 +
    5.99 +      if (identifiers.Length == 0)
   5.100 +        return false;
   5.101 +
   5.102 +      sensors = new ISensor[identifiers.Length];
   5.103 +      SensorVisitor visitor = new SensorVisitor(sensor => {
   5.104 +        for (int i = 0; i < identifiers.Length; i++)
   5.105 +          if (sensor.Identifier.ToString() == identifiers[i])
   5.106 +            sensors[i] = sensor;
   5.107 +      });
   5.108 +      visitor.VisitComputer(computer);
   5.109 +      return true;
   5.110 +    }
   5.111 +
   5.112 +    private void CreateNewLogFile() {
   5.113 +      IList<ISensor> list = new List<ISensor>();
   5.114 +      SensorVisitor visitor = new SensorVisitor(sensor => {
   5.115 +        list.Add(sensor);
   5.116 +      });
   5.117 +      visitor.VisitComputer(computer);
   5.118 +      sensors = list.ToArray();      
   5.119 +
   5.120 +      using (StreamWriter writer = new StreamWriter(fileName, false)) {
   5.121 +        writer.Write(",");
   5.122 +        for (int i = 0; i < sensors.Length; i++) {
   5.123 +          writer.Write(sensors[i].Identifier);
   5.124 +          if (i < sensors.Length - 1)
   5.125 +            writer.Write(",");
   5.126 +          else
   5.127 +            writer.WriteLine();
   5.128 +        }
   5.129 +
   5.130 +        writer.Write("Time,");
   5.131 +        for (int i = 0; i < sensors.Length; i++) {
   5.132 +          writer.Write('"');
   5.133 +          writer.Write(sensors[i].Name);
   5.134 +          writer.Write('"');
   5.135 +          if (i < sensors.Length - 1)
   5.136 +            writer.Write(",");
   5.137 +          else
   5.138 +            writer.WriteLine();
   5.139 +        }
   5.140 +      }
   5.141 +    }
   5.142 +
   5.143 +    public void Log() {
   5.144 +      var now = DateTime.Now;
   5.145 +      if (day != now.Date) {
   5.146 +        day = now.Date;
   5.147 +        fileName = GetFileName(day);
   5.148 +
   5.149 +        if (!OpenExistingLogFile())
   5.150 +          CreateNewLogFile();
   5.151 +      }
   5.152 +
   5.153 +      using (StreamWriter writer = new StreamWriter(fileName, true)) {
   5.154 +        writer.Write(now.ToString("G", CultureInfo.InvariantCulture));
   5.155 +        writer.Write(",");
   5.156 +        for (int i = 0; i < sensors.Length; i++) {
   5.157 +          if (sensors[i] != null) {
   5.158 +            float? value = sensors[i].Value;
   5.159 +            if (value.HasValue)
   5.160 +              writer.Write(
   5.161 +                value.Value.ToString("R", CultureInfo.InvariantCulture));
   5.162 +          }
   5.163 +          if (i < sensors.Length - 1)
   5.164 +            writer.Write(",");
   5.165 +          else
   5.166 +            writer.WriteLine();
   5.167 +        }
   5.168 +      }
   5.169 +
   5.170 +    }
   5.171 +  }
   5.172 +}