Fixed a few stability issues in the logging implementation. Added support for logging sensors once the reappear.
     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-2013 Michael Möller <mmoeller@openhardwaremonitor.org>
 
    11 using System.Collections.Generic;
 
    12 using System.Globalization;
 
    16 namespace OpenHardwareMonitor.Hardware.LPC {
 
    18   internal class LMSensors {
 
    20     private readonly List<LMChip> lmChips = new List<LMChip>();
 
    23       string[] basePaths = Directory.GetDirectories("/sys/class/hwmon/");
 
    24       foreach (string basePath in basePaths) {
 
    25         foreach (string devicePath in new[] { "/device", "" }) {
 
    26           string path = basePath + devicePath;
 
    30             using (StreamReader reader = new StreamReader(path + "/name"))
 
    31               name = reader.ReadLine();
 
    32           } catch (IOException) { }
 
    36               lmChips.Add(new LMChip(Chip.ATK0110, path)); break;
 
    39               lmChips.Add(new LMChip(Chip.F71858, path)); break;
 
    41               lmChips.Add(new LMChip(Chip.F71862, path)); break;
 
    43               lmChips.Add(new LMChip(Chip.F71869, path)); break;
 
    45               lmChips.Add(new LMChip(Chip.F71869A, path)); break;
 
    47               lmChips.Add(new LMChip(Chip.F71882, path)); break;            
 
    49               lmChips.Add(new LMChip(Chip.F71889AD, path)); break;
 
    51               lmChips.Add(new LMChip(Chip.F71889ED, path)); break;
 
    53               lmChips.Add(new LMChip(Chip.F71889F, path)); break;
 
    55               lmChips.Add(new LMChip(Chip.F71808E, path)); break;
 
    58               lmChips.Add(new LMChip(Chip.IT8705F, path)); break;
 
    60               lmChips.Add(new LMChip(Chip.IT8712F, path)); break;
 
    62               lmChips.Add(new LMChip(Chip.IT8716F, path)); break;
 
    64               lmChips.Add(new LMChip(Chip.IT8718F, path)); break;
 
    66               lmChips.Add(new LMChip(Chip.IT8720F, path)); break;
 
    69               lmChips.Add(new LMChip(Chip.NCT6771F, path)); break;
 
    71               lmChips.Add(new LMChip(Chip.NCT6776F, path)); break;
 
    73               lmChips.Add(new LMChip(Chip.NCT6779D, path)); break;
 
    75               lmChips.Add(new LMChip(Chip.NCT6791D, path)); break;
 
    78               lmChips.Add(new LMChip(Chip.W83627EHF, path)); break;
 
    80               lmChips.Add(new LMChip(Chip.W83627DHG, path)); break;
 
    82               lmChips.Add(new LMChip(Chip.W83667HG, path)); break;
 
    84               lmChips.Add(new LMChip(Chip.W83627HF, path)); break;
 
    86               lmChips.Add(new LMChip(Chip.W83627THF, path)); break;
 
    88               lmChips.Add(new LMChip(Chip.W83687THF, path)); break;
 
    95       foreach (LMChip lmChip in lmChips)
 
    99     public ISuperIO[] SuperIO {
 
   101         return lmChips.ToArray();
 
   105     private class LMChip : ISuperIO {
 
   108       private readonly Chip chip;
 
   110       private readonly float?[] voltages;
 
   111       private readonly float?[] temperatures;
 
   112       private readonly float?[] fans;
 
   113       private readonly float?[] controls;
 
   115       private readonly FileStream[] voltageStreams;
 
   116       private readonly FileStream[] temperatureStreams;
 
   117       private readonly FileStream[] fanStreams;
 
   119       public Chip Chip { get { return chip; } }
 
   120       public float?[] Voltages { get { return voltages; } }
 
   121       public float?[] Temperatures { get { return temperatures; } }
 
   122       public float?[] Fans { get { return fans; } }
 
   123       public float?[] Controls { get { return controls; } }
 
   125       public LMChip(Chip chip, string path) {
 
   129         string[] voltagePaths = Directory.GetFiles(path, "in*_input");
 
   130         this.voltages = new float?[voltagePaths.Length];
 
   131         this.voltageStreams = new FileStream[voltagePaths.Length];
 
   132         for (int i = 0; i < voltagePaths.Length; i++)
 
   133           voltageStreams[i] = new FileStream(voltagePaths[i],
 
   134             FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
 
   136         string[] temperaturePaths = Directory.GetFiles(path, "temp*_input");
 
   137         this.temperatures = new float?[temperaturePaths.Length];
 
   138         this.temperatureStreams = new FileStream[temperaturePaths.Length];
 
   139         for (int i = 0; i < temperaturePaths.Length; i++)
 
   140           temperatureStreams[i] = new FileStream(temperaturePaths[i],
 
   141             FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
 
   143         string[] fanPaths = Directory.GetFiles(path, "fan*_input");
 
   144         this.fans = new float?[fanPaths.Length];
 
   145         this.fanStreams = new FileStream[fanPaths.Length];
 
   146         for (int i = 0; i < fanPaths.Length; i++)
 
   147           fanStreams[i] = new FileStream(fanPaths[i],
 
   148             FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
 
   150         this.controls = new float?[0];
 
   153       public byte? ReadGPIO(int index) {
 
   157       public void WriteGPIO(int index, byte value) { }
 
   159       public string GetReport() {
 
   163       public void SetControl(int index, byte? value) { }   
 
   165       private string ReadFirstLine(Stream stream) {
 
   166         StringBuilder sb = new StringBuilder();
 
   168           stream.Seek(0, SeekOrigin.Begin);
 
   169           int b = stream.ReadByte();
 
   170           while (b != -1 && b != 10) {
 
   172             b = stream.ReadByte();
 
   175         return sb.ToString();
 
   178       public void Update() {
 
   179         for (int i = 0; i < voltages.Length; i++) {
 
   180           string s = ReadFirstLine(voltageStreams[i]);
 
   182             voltages[i] = 0.001f *
 
   183               long.Parse(s, CultureInfo.InvariantCulture);
 
   189         for (int i = 0; i < temperatures.Length; i++) {
 
   190           string s = ReadFirstLine(temperatureStreams[i]);
 
   192             temperatures[i] = 0.001f *
 
   193               long.Parse(s, CultureInfo.InvariantCulture);
 
   195             temperatures[i] = null;
 
   199         for (int i = 0; i < fans.Length; i++) {
 
   200           string s = ReadFirstLine(fanStreams[i]);
 
   202             fans[i] = long.Parse(s, CultureInfo.InvariantCulture);
 
   209       public void Close() {
 
   210         foreach (FileStream stream in voltageStreams)
 
   212         foreach (FileStream stream in temperatureStreams)
 
   214         foreach (FileStream stream in fanStreams)