From 43fe810b26649c8273121a50b03c96dbe7f6ff09 Mon Sep 17 00:00:00 2001 From: Phyxion <7643972+Phyxion@users.noreply.github.com> Date: Mon, 4 May 2020 12:01:11 +0200 Subject: [PATCH] Switch to HidSharp Fixes #219 Fixes #166 --- .../Controller/AeroCool/AeroCoolGroup.cs | 6 +- .../Hardware/Controller/AeroCool/P7-H1.cs | 91 +++++++++------- .../AquaComputer/AquaComputerGroup.cs | 11 +- .../Controller/AquaComputer/AquastreamXT.cs | 101 ++++++++++-------- .../Hardware/Controller/AquaComputer/MPS.cs | 83 +++++++------- .../LibreHardwareMonitorLib.csproj | 3 +- 6 files changed, 161 insertions(+), 134 deletions(-) diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/AeroCoolGroup.cs b/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/AeroCoolGroup.cs index 810ea8d..f98f9b2 100644 --- a/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/AeroCoolGroup.cs +++ b/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/AeroCoolGroup.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Text; -using HidLibrary; +using HidSharp; namespace LibreHardwareMonitor.Hardware.Controller.AeroCool { @@ -19,9 +19,9 @@ namespace LibreHardwareMonitor.Hardware.Controller.AeroCool _report.AppendLine("AeroCool Hardware"); _report.AppendLine(); - foreach (HidDevice dev in HidDevices.Enumerate(0x2e97)) + foreach (HidDevice dev in DeviceList.Local.GetHidDevices(0x2E97)) { - int hubno = dev.Attributes.ProductId - 0x1000; + int hubno = dev.ProductID - 0x1000; if (dev.DevicePath.Contains("mi_02") && (hubno >= 1) && (hubno <= 8)) { var device = new P7H1(dev, settings); diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs b/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs index a07df77..5a49195 100644 --- a/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs +++ b/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs @@ -4,50 +4,86 @@ // All Rights Reserved. using System; -using HidLibrary; +using System.Threading.Tasks; +using HidSharp; namespace LibreHardwareMonitor.Hardware.Controller.AeroCool { - internal class P7H1 : Hardware + internal sealed class P7H1 : Hardware { + private const byte REPORT_ID = 0x0; private readonly HidDevice _device; - private readonly float[] _speeds = new float[5]; - private bool _running; private readonly Sensor[] _rpm = new Sensor[5]; - private const byte REPORT_ID = 0x0; - - public int HubNumber { get; private set; } + private readonly float[] _speeds = new float[5]; + private readonly HidStream _stream; + private bool _running; public P7H1(HidDevice dev, ISettings settings) : base("AeroCool P7-H1", new Identifier(dev.DevicePath), settings) { _device = dev; - HubNumber = _device.Attributes.ProductId - 0x1000; + HubNumber = _device.ProductID - 0x1000; Name = $"AeroCool P7-H1 #{HubNumber}"; - _device.OpenDevice(); - _device.MonitorDeviceEvents = true; - _running = true; - _device.Read(OnDataReady); - for (int i=0; i<5; i++) + if (_device.TryOpen(out _stream)) { - _rpm[i] = new Sensor($"Fan #{i+1}", i, SensorType.Fan, this, settings); - ActivateSensor(_rpm[i]); + _running = true; + + Task.Run(ReadStream); + + for (int i = 0; i < 5; i++) + { + _rpm[i] = new Sensor($"Fan #{i + 1}", i, SensorType.Fan, this, settings); + ActivateSensor(_rpm[i]); + } } } public override HardwareType HardwareType { - get + get { return HardwareType.AeroCool; } + } + + public int HubNumber { get; } + + private void ReadStream() + { + byte[] inputReportBuffer = new byte[_device.GetMaxInputReportLength()]; + + while (_running) { - return HardwareType.AeroCool; + IAsyncResult ar = null; + + while (_running) + { + ar ??= _stream.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, null, null); + + if (ar.IsCompleted) + { + int byteCount = _stream.EndRead(ar); + ar = null; + + if (byteCount == 16 && inputReportBuffer[0] == REPORT_ID) + { + for (int i = 0; i < 5; i++) + { + int speed = inputReportBuffer[i * 3 + 2] * 256 + inputReportBuffer[i * 3 + 3]; + _speeds[i] = speed; + } + } + } + else + { + ar.AsyncWaitHandle.WaitOne(1000); + } + } } } public override void Close() { _running = false; - _device.CloseDevice(); + _stream.Close(); base.Close(); } @@ -58,24 +94,5 @@ namespace LibreHardwareMonitor.Hardware.Controller.AeroCool _rpm[i].Value = _speeds[i]; } } - - private void OnDataReady(HidDeviceData report) - { - if (!_running) // Do not register eventhandler again if device stopped - return; - if (report.Status == HidDeviceData.ReadStatus.Success) - { - byte[] rawData = report.Data; - if(rawData.Length == 16 && rawData[0] == REPORT_ID) - { - for (int i = 0; i < 5; i++) - { - int speed = rawData[i * 3 + 2] * 256 + rawData[i * 3 + 3]; - _speeds[i] = (float)speed; - } - } - } - _device.Read(OnDataReady); - } } } diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquaComputerGroup.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquaComputerGroup.cs index 13b190d..7d0bf50 100644 --- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquaComputerGroup.cs +++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquaComputerGroup.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Text; -using HidLibrary; +using HidSharp; namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer { @@ -19,13 +19,12 @@ namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer _report.AppendLine("AquaComputer Hardware"); _report.AppendLine(); - foreach (HidDevice dev in HidDevices.Enumerate(0x0c70)) + foreach (HidDevice dev in DeviceList.Local.GetHidDevices(0x0c70)) { - dev.ReadProduct(out byte[] productNameBytes); - string productName = Encoding.Unicode.GetString(productNameBytes).Replace("\0", string.Empty); + string productName = dev.GetProductName(); productName = productName.Substring(0, 1).ToUpper() + productName.Substring(1); - switch (dev.Attributes.ProductId) + switch (dev.ProductID) { case 0xf0b6: { @@ -50,7 +49,7 @@ namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer } default: { - _report.AppendLine($"Unknown Hardware PID: {dev.Attributes.ProductHexId} Name: {productName}"); + _report.AppendLine($"Unknown Hardware PID: {dev.ProductID} Name: {productName}"); _report.AppendLine(); break; } diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs index c250794..94b5a75 100644 --- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs +++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs @@ -5,7 +5,7 @@ using System; using System.Diagnostics.CodeAnalysis; -using HidLibrary; +using HidSharp; namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer { @@ -16,58 +16,63 @@ namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer internal sealed class AquastreamXT : Hardware { - private readonly HidDevice _device; - private readonly Sensor _fanControl, _pumpPower, _pumpFlow; + private readonly Sensor _fanControl; private readonly Sensor[] _frequencies = new Sensor[2]; + private readonly Sensor _pumpFlow; + private readonly Sensor _pumpPower; + private readonly byte[] _rawData = new byte[64]; private readonly Sensor[] _rpmSensors = new Sensor[2]; + private readonly HidStream _stream; private readonly Sensor[] _temperatures = new Sensor[3]; private readonly Sensor[] _voltages = new Sensor[2]; - private byte[] _rawData; public AquastreamXT(HidDevice dev, ISettings settings) : base("Aquastream XT", new Identifier(dev.DevicePath), settings) { - _device = dev; - do + if (dev.TryOpen(out _stream)) { - _device.ReadFeatureData(out _rawData, 0x4); + do + { + _rawData[0] = 0x4; + _stream.GetFeature(_rawData); + } + while (_rawData[0] != 0x4); + + Name = $"Aquastream XT {Variant}"; + FirmwareVersion = BitConverter.ToUInt16(_rawData, 50); + + _temperatures[0] = new Sensor("External Fan VRM", 0, SensorType.Temperature, this, new ParameterDescription[0], settings); + ActivateSensor(_temperatures[0]); + _temperatures[1] = new Sensor("External", 1, SensorType.Temperature, this, new ParameterDescription[0], settings); + ActivateSensor(_temperatures[1]); + _temperatures[2] = new Sensor("Internal Water", 2, SensorType.Temperature, this, new ParameterDescription[0], settings); + ActivateSensor(_temperatures[2]); + + _voltages[0] = new Sensor("External Fan", 1, SensorType.Voltage, this, new ParameterDescription[0], settings); + ActivateSensor(_voltages[0]); + _voltages[1] = new Sensor("Pump", 2, SensorType.Voltage, this, new ParameterDescription[0], settings); + ActivateSensor(_voltages[1]); + + _pumpPower = new Sensor("Pump", 0, SensorType.Power, this, new ParameterDescription[0], settings); + ActivateSensor(_pumpPower); + + _pumpFlow = new Sensor("Pump", 0, SensorType.Flow, this, new ParameterDescription[0], settings); + ActivateSensor(_pumpFlow); + + _rpmSensors[0] = new Sensor("External Fan", 0, SensorType.Fan, this, new ParameterDescription[0], settings); + ActivateSensor(_rpmSensors[0]); + _rpmSensors[1] = new Sensor("Pump", 1, SensorType.Fan, this, new ParameterDescription[0], settings); + ActivateSensor(_rpmSensors[1]); + + _fanControl = new Sensor("External Fan", 0, SensorType.Control, this, new ParameterDescription[0], settings); + Control control = new Control(_fanControl, settings, 0, 100); + _fanControl.Control = control; + + ActivateSensor(_fanControl); + _frequencies[0] = new Sensor("Pump Frequency", 0, SensorType.Frequency, this, new ParameterDescription[0], settings); + ActivateSensor(_frequencies[0]); + _frequencies[1] = new Sensor("Pump MaxFrequency", 1, SensorType.Frequency, this, new ParameterDescription[0], settings); + ActivateSensor(_frequencies[1]); } - while (_rawData[0] != 0x4); - - Name = $"Aquastream XT {Variant}"; - FirmwareVersion = BitConverter.ToUInt16(_rawData, 50); - - _temperatures[0] = new Sensor("External Fan VRM", 0, SensorType.Temperature, this, new ParameterDescription[0], settings); - ActivateSensor(_temperatures[0]); - _temperatures[1] = new Sensor("External", 1, SensorType.Temperature, this, new ParameterDescription[0], settings); - ActivateSensor(_temperatures[1]); - _temperatures[2] = new Sensor("Internal Water", 2, SensorType.Temperature, this, new ParameterDescription[0], settings); - ActivateSensor(_temperatures[2]); - - _voltages[0] = new Sensor("External Fan", 1, SensorType.Voltage, this, new ParameterDescription[0], settings); - ActivateSensor(_voltages[0]); - _voltages[1] = new Sensor("Pump", 2, SensorType.Voltage, this, new ParameterDescription[0], settings); - ActivateSensor(_voltages[1]); - - _pumpPower = new Sensor("Pump", 0, SensorType.Power, this, new ParameterDescription[0], settings); - ActivateSensor(_pumpPower); - - _pumpFlow = new Sensor("Pump", 0, SensorType.Flow, this, new ParameterDescription[0], settings); - ActivateSensor(_pumpFlow); - - _rpmSensors[0] = new Sensor("External Fan", 0, SensorType.Fan, this, new ParameterDescription[0], settings); - ActivateSensor(_rpmSensors[0]); - _rpmSensors[1] = new Sensor("Pump", 1, SensorType.Fan, this, new ParameterDescription[0], settings); - ActivateSensor(_rpmSensors[1]); - - _fanControl = new Sensor("External Fan", 0, SensorType.Control, this, new ParameterDescription[0], settings); - Control control = new Control(_fanControl, settings, 0, 100); - _fanControl.Control = control; - - ActivateSensor(_fanControl); - _frequencies[0] = new Sensor("Pump Frequency", 0, SensorType.Frequency, this, new ParameterDescription[0], settings); - ActivateSensor(_frequencies[0]); - _frequencies[1] = new Sensor("Pump MaxFrequency", 1, SensorType.Frequency, this, new ParameterDescription[0], settings); - ActivateSensor(_frequencies[1]); } public ushort FirmwareVersion { get; private set; } @@ -106,17 +111,19 @@ namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer return "Standard"; } } - + public override void Close() { - _device.CloseDevice(); + _stream.Close(); + base.Close(); } //TODO: Check tested and fix unknown variables public override void Update() { - _device.ReadFeatureData(out _rawData, 0x4); + _rawData[0] = 0x4; + _stream.GetFeature(_rawData); if (_rawData[0] != 0x4) return; diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs index dfc0e59..0d5b0b5 100644 --- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs +++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs @@ -4,59 +4,50 @@ // All Rights Reserved. using System; -using HidLibrary; +using HidSharp; namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer { - internal class MPS : Hardware + internal sealed class MPS : Hardware { - #region USB - private HidDevice _device; - private byte[] _rawData; - public UInt16 FirmwareVersion { get; private set; } - #endregion - - private readonly Sensor _pumpFlow; - private readonly Sensor[] _temperatures = new Sensor[2]; - private const byte MPS_REPORT_ID = 0x2; - private UInt16 _externalTemperature = 0; - - private sealed class MPSDataIndexes - { - public const int PumpFlow = 35; - public const int ExternalTemperature = 43; - public const int InternalWaterTemperature = 45; - } + private readonly Sensor _pumpFlow; + private readonly byte[] _rawData = new byte[64]; + private readonly HidStream _stream; + private readonly Sensor[] _temperatures = new Sensor[2]; + + private ushort _externalTemperature; public MPS(HidDevice dev, ISettings settings) : base("MPS", new Identifier(dev.DevicePath), settings) { - _device = dev; - - do + if (dev.TryOpen(out _stream)) { - _device.ReadFeatureData(out _rawData, MPS_REPORT_ID); - } while (_rawData[0] != MPS_REPORT_ID); + do + { + _rawData[0] = MPS_REPORT_ID; + _stream.GetFeature(_rawData); + } + while (_rawData[0] != MPS_REPORT_ID); - Name = $"MPS"; - FirmwareVersion = ExtractFirmwareVersion(); + Name = "MPS"; + FirmwareVersion = ExtractFirmwareVersion(); - _temperatures[0] = new Sensor("External", 0, SensorType.Temperature, this, new ParameterDescription[0], settings); - ActivateSensor(_temperatures[0]); - _temperatures[1] = new Sensor("Internal Water", 1, SensorType.Temperature, this, new ParameterDescription[0], settings); - ActivateSensor(_temperatures[1]); + _temperatures[0] = new Sensor("External", 0, SensorType.Temperature, this, new ParameterDescription[0], settings); + ActivateSensor(_temperatures[0]); + _temperatures[1] = new Sensor("Internal Water", 1, SensorType.Temperature, this, new ParameterDescription[0], settings); + ActivateSensor(_temperatures[1]); - _pumpFlow = new Sensor("Pump", 0, SensorType.Flow, this, new ParameterDescription[0], settings); - ActivateSensor(_pumpFlow); + _pumpFlow = new Sensor("Pump", 0, SensorType.Flow, this, new ParameterDescription[0], settings); + ActivateSensor(_pumpFlow); + } } + public ushort FirmwareVersion { get; private set; } + public override HardwareType HardwareType { - get - { - return HardwareType.AquaComputer; - } + get { return HardwareType.AquaComputer; } } public string Status @@ -68,41 +59,53 @@ namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer { return $"Status: Untested Firmware Version {FirmwareVersion}! Please consider Updating to Version 1012"; } + return "Status: OK"; } } public override void Close() { - _device.CloseDevice(); + _stream.Close(); + base.Close(); } public override void Update() { - _device.ReadFeatureData(out _rawData, MPS_REPORT_ID); + _rawData[0] = MPS_REPORT_ID; + _stream.GetFeature(_rawData); if (_rawData[0] != MPS_REPORT_ID) return; + _pumpFlow.Value = BitConverter.ToUInt16(_rawData, MPSDataIndexes.PumpFlow) / 10f; _externalTemperature = BitConverter.ToUInt16(_rawData, MPSDataIndexes.ExternalTemperature); //sensor reading returns Int16.MaxValue (32767), when not connected - if (_externalTemperature != Int16.MaxValue) + if (_externalTemperature != short.MaxValue) { _temperatures[0].Value = _externalTemperature / 100f; } else + { _temperatures[0].Value = null; + } _temperatures[1].Value = BitConverter.ToUInt16(_rawData, MPSDataIndexes.InternalWaterTemperature) / 100f; - } private ushort ExtractFirmwareVersion() { return BitConverter.ToUInt16(_rawData, 3); } + + private sealed class MPSDataIndexes + { + public const int ExternalTemperature = 43; + public const int InternalWaterTemperature = 45; + public const int PumpFlow = 35; + } } } diff --git a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj index db6e338..2d70cc4 100644 --- a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj +++ b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj @@ -19,6 +19,7 @@ libre open hardware monitor monitoring system logging cpu gpu true https://github.com/LibreHardwareMonitor/LibreHardwareMonitor + latest @@ -160,7 +161,7 @@ - +