Browse Source

Switch sensor collector to use events

Nick Babcock 6 years ago
parent
commit
bd0947bdb6
2 changed files with 111 additions and 36 deletions
  1. 88 36
      OhmGraphite/SensorCollector.cs
  2. 23 0
      OhmGraphite/UpdateVisitor.cs

+ 88 - 36
OhmGraphite/SensorCollector.cs

@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using NLog;
 using NLog;
 using OpenHardwareMonitor.Hardware;
 using OpenHardwareMonitor.Hardware;
@@ -9,52 +10,103 @@ namespace OhmGraphite
     {
     {
         private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
         private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
         private readonly Computer _computer;
         private readonly Computer _computer;
+        private readonly IVisitor _updateVisitor = new UpdateVisitor();
+        private readonly IDictionary<Identifier, ISensor> _sensors = new ConcurrentDictionary<Identifier, ISensor>();
 
 
         public SensorCollector(Computer computer) => _computer = computer;
         public SensorCollector(Computer computer) => _computer = computer;
-        public void Open() => _computer.Open();
-        public void Close() => _computer.Close();
-        public IEnumerable<ReportedValue> ReadAllSensors() =>
-            _computer
-                .Hardware
-                .SelectMany(ReadHardware)
-                .SelectMany(ReadSensors);
+        public void Open()
+        {
+            foreach (var hardware in _computer.Hardware)
+            {
+                HardwareAdded(hardware);
+            }
+
+            _computer.HardwareAdded += HardwareAdded;
+            _computer.HardwareRemoved += HardwareRemoved;
+            _computer.Open();
+        }
 
 
-        private static IEnumerable<IHardware> ReadHardware(IHardware hardware)
+        public void Close()
         {
         {
-            yield return hardware;
-            foreach (var subHardware in hardware.SubHardware)
+            _computer.HardwareRemoved -= HardwareRemoved;
+            _computer.HardwareAdded -= HardwareAdded;
+            foreach (var hardware in _computer.Hardware)
             {
             {
-                foreach (var ware in ReadHardware(subHardware))
-                {
-                    yield return ware;
-                }
+                HardwareRemoved(hardware);
             }
             }
+            _computer.Close();
         }
         }
 
 
-        private static IEnumerable<ReportedValue> ReadSensors(IHardware hardware)
+        private void HardwareAdded(IHardware hardware)
         {
         {
-            hardware.Update();
+            Logger.Debug("Hardware added: {0}", hardware.Identifier);
+            hardware.SensorAdded += Hardware_SensorAdded;
+            hardware.SensorRemoved += Hardware_SensorRemoved;
             foreach (var sensor in hardware.Sensors)
             foreach (var sensor in hardware.Sensors)
             {
             {
-                string id = sensor.Identifier.ToString();
-
-                // Only report a value if the sensor was able to get a value
-                // as 0 is different than "didn't read". For example, are the
-                // fans really spinning at 0 RPM or was the value not read.
-                if (sensor.Value.HasValue)
-                {
-                    yield return new ReportedValue(id,
-                        sensor.Name,
-                        sensor.Value.Value,
-                        sensor.SensorType,
-                        sensor.Hardware.Name,
-                        sensor.Hardware.HardwareType,
-                        sensor.Index);
-                }
-                else
-                {
-                    Logger.Debug($"{id} did not have a value");
-                }
+                Hardware_SensorAdded(sensor);
+            }
+
+            foreach (var sub in hardware.SubHardware)
+            {
+                HardwareAdded(sub);
+            }
+        }
+
+        private void HardwareRemoved(IHardware hardware)
+        {
+            Logger.Debug("Hardware removed: {0}", hardware.Identifier);
+            hardware.SensorAdded -= Hardware_SensorAdded;
+            hardware.SensorRemoved -= Hardware_SensorRemoved;
+            foreach (var sensor in hardware.Sensors)
+            {
+                Hardware_SensorRemoved(sensor);
+            }
+
+            foreach (var sub in hardware.SubHardware)
+            {
+                HardwareRemoved(sub);
+            }
+        }
+
+        private void Hardware_SensorAdded(ISensor sensor)
+        {
+            Logger.Debug("Sensor added: {0}", sensor.Identifier);
+            _sensors[sensor.Identifier] = sensor;
+        }
+
+        private void Hardware_SensorRemoved(ISensor sensor)
+        {
+            Logger.Debug("Sensor removed: {0}", sensor.Identifier);
+            _sensors.Remove(sensor.Identifier);
+        }
+
+        public IEnumerable<ReportedValue> ReadAllSensors()
+        {
+            _computer.Accept(_updateVisitor);
+            return _sensors.Values.SelectMany(ReportedValues);
+        }
+
+        private static IEnumerable<ReportedValue> ReportedValues(ISensor sensor)
+        {
+            string id = sensor.Identifier.ToString();
+
+            // Only report a value if the sensor was able to get a value
+            // as 0 is different than "didn't read". For example, are the
+            // fans really spinning at 0 RPM or was the value not read.
+            if (sensor.Value.HasValue)
+            {
+                yield return new ReportedValue(id,
+                    sensor.Name,
+                    sensor.Value.Value,
+                    sensor.SensorType,
+                    sensor.Hardware.Name,
+                    sensor.Hardware.HardwareType,
+                    sensor.Index);
+            }
+            else
+            {
+                Logger.Debug($"{id} did not have a value");
             }
             }
         }
         }
     }
     }

+ 23 - 0
OhmGraphite/UpdateVisitor.cs

@@ -0,0 +1,23 @@
+using OpenHardwareMonitor.Hardware;
+
+namespace OhmGraphite
+{
+    public class UpdateVisitor : IVisitor
+    {
+        public void VisitComputer(IComputer computer)
+        {
+            computer.Traverse(this);
+        }
+
+        public void VisitHardware(IHardware hardware)
+        {
+            hardware.Update();
+            foreach (var subHardware in hardware.SubHardware)
+                subHardware.Accept(this);
+        }
+
+        public void VisitSensor(ISensor sensor) { }
+
+        public void VisitParameter(IParameter parameter) { }
+    }
+}