Added base support Asus ROG Crosshair X670E Hero and PSU MSI MEG Ai1300P (#1575)
* Added base support matherboard Asus ROG Crosshair X670E Hero * Added base support PSU MSI MEG Ai1300P * Refactoring MSI PSU lib
This commit is contained in:
@@ -22,6 +22,7 @@ using LibreHardwareMonitor.Hardware.Memory;
|
||||
using LibreHardwareMonitor.Hardware.Motherboard;
|
||||
using LibreHardwareMonitor.Hardware.Network;
|
||||
using LibreHardwareMonitor.Hardware.Psu.Corsair;
|
||||
using LibreHardwareMonitor.Hardware.Psu.Msi;
|
||||
using LibreHardwareMonitor.Hardware.Storage;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware;
|
||||
@@ -250,10 +251,12 @@ public class Computer : IComputer
|
||||
if (value)
|
||||
{
|
||||
Add(new CorsairPsuGroup(_settings));
|
||||
Add(new MsiPsuGroup(_settings));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveType<CorsairPsuGroup>();
|
||||
RemoveType<MsiPsuGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +527,10 @@ public class Computer : IComputer
|
||||
Add(new NetworkGroup(_settings));
|
||||
|
||||
if (_psuEnabled)
|
||||
{
|
||||
Add(new CorsairPsuGroup(_settings));
|
||||
Add(new MsiPsuGroup(_settings));
|
||||
}
|
||||
|
||||
if (_batteryEnabled)
|
||||
Add(new BatteryGroup(_settings));
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// Copyright (C) 2024 demorfi<demorfi@gmail.com>
|
||||
// Copyright (C) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using HidSharp;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Psu.Msi;
|
||||
|
||||
internal sealed class MsiPsu : Hardware
|
||||
{
|
||||
private readonly HidDevice _device;
|
||||
private readonly List<PsuSensor> _sensors = [];
|
||||
|
||||
public MsiPsu(HidDevice device, ISettings settings, int index)
|
||||
: base("MSI PSU", new Identifier("psu", "msi", index.ToString()), settings)
|
||||
{
|
||||
_device = device;
|
||||
using HidStream stream = device.Open();
|
||||
UsbApi.FirmwareInfo fwInfo = UsbApi.FwInfo(stream);
|
||||
Name = $"{fwInfo.Vendor} {fwInfo.Product}";
|
||||
|
||||
AddSensors(settings);
|
||||
}
|
||||
|
||||
public override HardwareType HardwareType => HardwareType.Psu;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
using HidStream stream = _device.Open();
|
||||
float[] info = UsbApi.InfoList(stream);
|
||||
_sensors.ForEach(s => s.Update(info));
|
||||
}
|
||||
|
||||
private void AddSensors(ISettings settings)
|
||||
{
|
||||
int sensorIndex = 0;
|
||||
|
||||
_sensors.Add(new PsuSensor("Case", sensorIndex++, SensorType.Fan, this, settings, UsbApi.IndexInfo.FAN_RPM));
|
||||
_sensors.Add(new PsuSensor("Case", sensorIndex++, SensorType.Temperature, this, settings, UsbApi.IndexInfo.TEMP));
|
||||
|
||||
_sensors.Add(new PsuSensor("+12V", sensorIndex++, SensorType.Voltage, this, settings, UsbApi.IndexInfo.VOLTS_12));
|
||||
_sensors.Add(new PsuSensor("+12V", sensorIndex++, SensorType.Current, this, settings, UsbApi.IndexInfo.AMPS_12));
|
||||
|
||||
_sensors.Add(new PsuSensor("+5V", sensorIndex++, SensorType.Voltage, this, settings, UsbApi.IndexInfo.VOLTS_5));
|
||||
_sensors.Add(new PsuSensor("+5V", sensorIndex++, SensorType.Current, this, settings, UsbApi.IndexInfo.AMPS_5));
|
||||
|
||||
_sensors.Add(new PsuSensor("+3.3V", sensorIndex++, SensorType.Voltage, this, settings, UsbApi.IndexInfo.VOLTS_3V3));
|
||||
_sensors.Add(new PsuSensor("+3.3V", sensorIndex++, SensorType.Current, this, settings, UsbApi.IndexInfo.AMPS_3V3));
|
||||
|
||||
_sensors.Add(new PsuSensor("PSU Efficiency", sensorIndex++, SensorType.Level, this, settings, UsbApi.IndexInfo.EFFICIENCY));
|
||||
_sensors.Add(new PsuSensor("PSU Out", sensorIndex++, SensorType.Power, this, settings, UsbApi.IndexInfo.PSU_OUT));
|
||||
_sensors.Add(new PsuSensor("Total Runtime", sensorIndex++, SensorType.TimeSpan, this, settings, UsbApi.IndexInfo.RUNTIME, true));
|
||||
}
|
||||
|
||||
private class PsuSensor : Sensor
|
||||
{
|
||||
private readonly UsbApi.IndexInfo _indexInfo;
|
||||
|
||||
public PsuSensor(string name, int index, SensorType type, MsiPsu hardware, ISettings settings, UsbApi.IndexInfo indexInfo, bool noHistory = false)
|
||||
: base(name, index, false, type, hardware, null, settings, noHistory)
|
||||
{
|
||||
_indexInfo = indexInfo;
|
||||
hardware.ActivateSensor(this);
|
||||
}
|
||||
|
||||
public void Update(float[] info)
|
||||
{
|
||||
Value = info[(int)_indexInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// This Source Code Form is subject to the terms of the GNU Public License, v. 2.0.
|
||||
// Copyright (C) 2024 demorfi<demorfi@gmail.com>
|
||||
// Copyright (C) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using HidSharp;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Psu.Msi;
|
||||
|
||||
public class MsiPsuGroup : IGroup
|
||||
{
|
||||
private static readonly int[] _productIds =
|
||||
{
|
||||
0x56d4, // MEG Ai1300P
|
||||
};
|
||||
|
||||
private static readonly ushort _vendorId = 0x0db0;
|
||||
private readonly List<IHardware> _hardware;
|
||||
private readonly StringBuilder _report;
|
||||
|
||||
public MsiPsuGroup(ISettings settings)
|
||||
{
|
||||
_report = new StringBuilder();
|
||||
_report.AppendLine("MSI Ai series PSU Hardware");
|
||||
_report.AppendLine();
|
||||
|
||||
_hardware = new List<IHardware>();
|
||||
foreach (HidDevice dev in DeviceList.Local.GetHidDevices(_vendorId))
|
||||
{
|
||||
if (_productIds.Contains(dev.ProductID))
|
||||
{
|
||||
var device = new MsiPsu(dev, settings, _hardware.Count);
|
||||
_hardware.Add(device);
|
||||
_report.AppendLine($"Device name: {device.Name}");
|
||||
_report.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (_hardware.Count == 0)
|
||||
{
|
||||
_report.AppendLine("No MSI PSU Hardware found.");
|
||||
_report.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<IHardware> Hardware => _hardware;
|
||||
|
||||
public void Close()
|
||||
{
|
||||
foreach (IHardware iHardware in _hardware)
|
||||
{
|
||||
if (iHardware is Hardware hardware)
|
||||
hardware.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetReport()
|
||||
{
|
||||
return _report.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// Copyright (C) 2024 demorfi<demorfi@gmail.com>
|
||||
// Copyright (C) LibreHardwareMonitor and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using HidSharp;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Psu.Msi;
|
||||
|
||||
internal static class UsbApi
|
||||
{
|
||||
public enum IndexInfo : int
|
||||
{
|
||||
VOLTS_12V1 = 0,
|
||||
VOLTS_12V2 = 2,
|
||||
VOLTS_12V3 = 4,
|
||||
VOLTS_12V4 = 6,
|
||||
VOLTS_12V5 = 8,
|
||||
VOLTS_12 = 10,
|
||||
VOLTS_5 = 12,
|
||||
VOLTS_3V3 = 14,
|
||||
AMPS_12V1 = 1,
|
||||
AMPS_12V2 = 3,
|
||||
AMPS_12V3 = 5,
|
||||
AMPS_12V4 = 7,
|
||||
AMPS_12V5 = 9,
|
||||
AMPS_12 = 11,
|
||||
AMPS_5 = 13,
|
||||
AMPS_3V3 = 15,
|
||||
|
||||
PSU_OUT = 16,
|
||||
EFFICIENCY = 17,
|
||||
TEMP = 18,
|
||||
FAN_RPM = 19,
|
||||
RUNTIME = 20
|
||||
}
|
||||
|
||||
public static FirmwareInfo FwInfo(HidStream stream)
|
||||
{
|
||||
if (!Request(stream, new byte[2] { 0xFA, 0x51 }, out byte[] productArr, 1))
|
||||
throw new ProtocolError(stream.Device, "Can't read product name");
|
||||
|
||||
static string ArrayToString(byte[] ar)
|
||||
{
|
||||
return Encoding.ASCII.GetString(ar.TakeWhile(x => x != 0).ToArray());
|
||||
}
|
||||
|
||||
return new FirmwareInfo { Vendor = "MSI", Product = ArrayToString(productArr) };
|
||||
}
|
||||
|
||||
private static float Linear11ToFloat32(ushort val)
|
||||
{
|
||||
int exp = (short)val >> 11;
|
||||
int mant = ((short)(val & 0x7ff) << 5) >> 5;
|
||||
return mant * (float)Math.Pow(2, exp);
|
||||
}
|
||||
|
||||
private static bool Request(HidStream stream, byte[] command, out byte[] response, int offset = 0)
|
||||
{
|
||||
byte[] buffer = new byte[64];
|
||||
Array.Copy(command, 0, buffer, 1, 2);
|
||||
stream.Write(buffer);
|
||||
|
||||
byte[] reply = stream.Read();
|
||||
response = new byte[42];
|
||||
Array.Copy(reply, 2 + offset, response, 0, 42);
|
||||
|
||||
return reply[0] == buffer[0] && reply[1] == buffer[1];
|
||||
}
|
||||
|
||||
public static float[] InfoList(HidStream stream)
|
||||
{
|
||||
int length = Enum.GetNames(typeof(IndexInfo)).Length;
|
||||
float[] info = new float[length];
|
||||
|
||||
if (!Request(stream, new byte[2] { 0x51, 0xE0 }, out byte[] basic))
|
||||
throw new ProtocolError(stream.Device, "Can't read basic info");
|
||||
|
||||
// basic has information only about the first 20 sensors
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
byte[] replyData = new byte[4];
|
||||
Array.Copy(basic, (i * 2) + 1, replyData, 0, 2);
|
||||
info[i] = Linear11ToFloat32((ushort)BitConverter.ToInt32(replyData, 0));
|
||||
}
|
||||
|
||||
// runtime info
|
||||
Request(stream, new byte[2] { 0x51, 0xD1 }, out byte[] runtime);
|
||||
info[(int)IndexInfo.RUNTIME] = BitConverter.ToInt32(runtime, 0) / 100;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public struct FirmwareInfo
|
||||
{
|
||||
public string Vendor;
|
||||
public string Product;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user