SensorCollector.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System.Collections.Concurrent;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using NLog;
  5. using OpenHardwareMonitor.Hardware;
  6. namespace OhmGraphite
  7. {
  8. public class SensorCollector : IGiveSensors
  9. {
  10. private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
  11. private readonly Computer _computer;
  12. private readonly IVisitor _updateVisitor = new UpdateVisitor();
  13. private readonly ConcurrentDictionary<Identifier, object> _ids =
  14. new ConcurrentDictionary<Identifier, object>();
  15. public SensorCollector(Computer computer) => _computer = computer;
  16. public void Open()
  17. {
  18. foreach (var hardware in _computer.Hardware)
  19. {
  20. HardwareAdded(hardware);
  21. }
  22. _computer.HardwareAdded += HardwareAdded;
  23. _computer.HardwareRemoved += HardwareRemoved;
  24. _computer.Open();
  25. }
  26. public void Close()
  27. {
  28. _computer.HardwareRemoved -= HardwareRemoved;
  29. _computer.HardwareAdded -= HardwareAdded;
  30. foreach (var hardware in _computer.Hardware)
  31. {
  32. HardwareRemoved(hardware);
  33. }
  34. _computer.Close();
  35. }
  36. public void Start() => Open();
  37. public void Dispose() => Close();
  38. private void HardwareAdded(IHardware hardware)
  39. {
  40. if (!_ids.TryAdd(hardware.Identifier, hardware))
  41. {
  42. Logger.Debug("Hardware previously added: {0}", hardware.Identifier);
  43. return;
  44. }
  45. Logger.Debug("Hardware added: {0}", hardware.Identifier);
  46. hardware.SensorAdded += SensorAdded;
  47. hardware.SensorRemoved += SensorRemoved;
  48. foreach (var sensor in hardware.Sensors)
  49. {
  50. SensorAdded(sensor);
  51. }
  52. foreach (var sub in hardware.SubHardware)
  53. {
  54. HardwareAdded(sub);
  55. }
  56. }
  57. private void HardwareRemoved(IHardware hardware)
  58. {
  59. _ids.TryRemove(hardware.Identifier, out _);
  60. Logger.Debug("Hardware removed: {0}", hardware.Identifier);
  61. hardware.SensorAdded -= SensorAdded;
  62. hardware.SensorRemoved -= SensorRemoved;
  63. foreach (var sensor in hardware.Sensors)
  64. {
  65. SensorRemoved(sensor);
  66. }
  67. foreach (var sub in hardware.SubHardware)
  68. {
  69. HardwareRemoved(sub);
  70. }
  71. }
  72. private void SensorAdded(ISensor sensor)
  73. {
  74. Logger.Debug(!_ids.TryAdd(sensor.Identifier, sensor) ?
  75. "Sensor previously added: {0}" : "Sensor added: {0}", sensor.Identifier);
  76. }
  77. private void SensorRemoved(ISensor sensor)
  78. {
  79. Logger.Debug("Sensor removed: {0}", sensor.Identifier);
  80. _ids.TryRemove(sensor.Identifier, out _);
  81. }
  82. public IEnumerable<ReportedValue> ReadAllSensors()
  83. {
  84. _computer.Accept(_updateVisitor);
  85. return _ids.Values.OfType<ISensor>().SelectMany(ReportedValues);
  86. }
  87. private static IEnumerable<ReportedValue> ReportedValues(ISensor sensor)
  88. {
  89. string id = sensor.Identifier.ToString();
  90. // Only report a value if the sensor was able to get a value
  91. // as 0 is different than "didn't read". For example, are the
  92. // fans really spinning at 0 RPM or was the value not read.
  93. if (!sensor.Value.HasValue)
  94. {
  95. Logger.Debug($"{id} did not have a value");
  96. }
  97. else if (float.IsNaN(sensor.Value.Value))
  98. {
  99. Logger.Debug($"{id} had a NaN value");
  100. }
  101. else if (float.IsInfinity(sensor.Value.Value))
  102. {
  103. Logger.Debug($"{id} had an infinite value");
  104. }
  105. else
  106. {
  107. yield return new ReportedValue(id,
  108. sensor.Name,
  109. sensor.Value.Value,
  110. sensor.SensorType,
  111. sensor.Hardware.Name,
  112. sensor.Hardware.HardwareType,
  113. sensor.Index);
  114. }
  115. }
  116. }
  117. }