Merge tag 'v0.9.4'

# Conflicts:
#	LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs
This commit is contained in:
Vladimir
2024-11-28 23:42:13 +03:00
36 changed files with 971 additions and 535 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>0.9.3</Version>
<Version>0.9.4</Version>
<Copyright>LibreHardwareMonitor</Copyright>
</PropertyGroup>
</Project>
@@ -25,7 +25,7 @@
<PackageReference Include="TaskScheduler" Version="2.11.0" />
<PackageReference Include="OxyPlot.Core" Version="2.2.0" />
<PackageReference Include="OxyPlot.WindowsForms" Version="2.2.0" />
<PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="System.Management" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web" />
@@ -44,8 +44,8 @@
<Compile Update="UI\ParameterForm.Designer.cs">
<DependentUpon>ParameterForm.cs</DependentUpon>
</Compile>
<Compile Update="UI\PortForm.Designer.cs">
<DependentUpon>PortForm.cs</DependentUpon>
<Compile Update="UI\InterfacePortForm.Designer.cs">
<DependentUpon>InterfacePortForm.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
@@ -61,8 +61,8 @@
<EmbeddedResource Update="UI\ParameterForm.resx">
<DependentUpon>ParameterForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Update="UI\PortForm.resx">
<DependentUpon>PortForm.cs</DependentUpon>
<EmbeddedResource Update="UI\InterfacePortForm.resx">
<DependentUpon>InterfacePortForm.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
@@ -6,7 +6,7 @@
namespace LibreHardwareMonitor.UI
{
partial class PortForm
partial class InterfacePortForm
{
/// <summary>
/// Required designer variable.
@@ -34,7 +34,7 @@ namespace LibreHardwareMonitor.UI
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PortForm));
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InterfacePortForm));
this.portOKButton = new System.Windows.Forms.Button();
this.portCancelButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
@@ -44,12 +44,14 @@ namespace LibreHardwareMonitor.UI
this.webServerLinkLabel = new System.Windows.Forms.LinkLabel();
this.portNumericUpDn = new System.Windows.Forms.NumericUpDown();
this.label5 = new System.Windows.Forms.Label();
this.interfaceLabel = new System.Windows.Forms.Label();
this.interfaceComboBox = new System.Windows.Forms.ComboBox();
((System.ComponentModel.ISupportInitialize)(this.portNumericUpDn)).BeginInit();
this.SuspendLayout();
//
// portOKButton
//
this.portOKButton.Location = new System.Drawing.Point(244, 137);
this.portOKButton.Location = new System.Drawing.Point(244, 162);
this.portOKButton.Name = "portOKButton";
this.portOKButton.Size = new System.Drawing.Size(75, 23);
this.portOKButton.TabIndex = 0;
@@ -60,7 +62,7 @@ namespace LibreHardwareMonitor.UI
// portCancelButton
//
this.portCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.portCancelButton.Location = new System.Drawing.Point(162, 137);
this.portCancelButton.Location = new System.Drawing.Point(162, 162);
this.portCancelButton.Name = "portCancelButton";
this.portCancelButton.Size = new System.Drawing.Size(75, 23);
this.portCancelButton.TabIndex = 1;
@@ -71,7 +73,7 @@ namespace LibreHardwareMonitor.UI
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(13, 106);
this.label1.Location = new System.Drawing.Point(13, 131);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(377, 13);
this.label1.TabIndex = 3;
@@ -81,16 +83,16 @@ namespace LibreHardwareMonitor.UI
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(13, 9);
this.label2.Location = new System.Drawing.Point(13, 34);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(193, 13);
this.label2.Size = new System.Drawing.Size(190, 13);
this.label2.TabIndex = 4;
this.label2.Text = "Port number for the remote web server:";
this.label2.Text = "Port number for the remote web server:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(13, 39);
this.label3.Location = new System.Drawing.Point(13, 64);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(443, 13);
this.label3.TabIndex = 5;
@@ -100,7 +102,7 @@ namespace LibreHardwareMonitor.UI
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(13, 62);
this.label4.Location = new System.Drawing.Point(13, 86);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(262, 13);
this.label4.TabIndex = 6;
@@ -109,7 +111,7 @@ namespace LibreHardwareMonitor.UI
// webServerLinkLabel
//
this.webServerLinkLabel.AutoSize = true;
this.webServerLinkLabel.Location = new System.Drawing.Point(269, 62);
this.webServerLinkLabel.Location = new System.Drawing.Point(269, 86);
this.webServerLinkLabel.Name = "webServerLinkLabel";
this.webServerLinkLabel.Size = new System.Drawing.Size(55, 13);
this.webServerLinkLabel.TabIndex = 7;
@@ -119,7 +121,7 @@ namespace LibreHardwareMonitor.UI
//
// portNumericUpDn
//
this.portNumericUpDn.Location = new System.Drawing.Point(208, 7);
this.portNumericUpDn.Location = new System.Drawing.Point(208, 32);
this.portNumericUpDn.Maximum = new decimal(new int[] {
20000,
0,
@@ -144,18 +146,40 @@ namespace LibreHardwareMonitor.UI
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(13, 84);
this.label5.Location = new System.Drawing.Point(13, 109);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(304, 13);
this.label5.TabIndex = 9;
this.label5.Text = "You will have to start the server by clicking Run from the menu.";
//
// PortForm
// interfaceLabel
//
this.interfaceLabel.AutoSize = true;
this.interfaceLabel.Location = new System.Drawing.Point(14, 8);
this.interfaceLabel.Name = "interfaceLabel";
this.interfaceLabel.Size = new System.Drawing.Size(217, 13);
this.interfaceLabel.TabIndex = 10;
this.interfaceLabel.Text = "Network interface for the remote web server:";
//
// interfaceComboBox
//
this.interfaceComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.interfaceComboBox.FormattingEnabled = true;
this.interfaceComboBox.Location = new System.Drawing.Point(233, 6);
this.interfaceComboBox.Margin = new System.Windows.Forms.Padding(2);
this.interfaceComboBox.Name = "interfaceComboBox";
this.interfaceComboBox.Size = new System.Drawing.Size(221, 21);
this.interfaceComboBox.TabIndex = 11;
this.interfaceComboBox.SelectedIndexChanged += new System.EventHandler(this.interfaceComboBox_SelectedIndexChanged);
//
// InterfacePortForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.portCancelButton;
this.ClientSize = new System.Drawing.Size(466, 170);
this.ClientSize = new System.Drawing.Size(466, 202);
this.Controls.Add(this.interfaceComboBox);
this.Controls.Add(this.interfaceLabel);
this.Controls.Add(this.label5);
this.Controls.Add(this.portNumericUpDn);
this.Controls.Add(this.webServerLinkLabel);
@@ -169,7 +193,7 @@ namespace LibreHardwareMonitor.UI
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "PortForm";
this.Name = "InterfacePortForm";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Set Port";
@@ -191,5 +215,7 @@ namespace LibreHardwareMonitor.UI
private System.Windows.Forms.LinkLabel webServerLinkLabel;
private System.Windows.Forms.NumericUpDown portNumericUpDn;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label interfaceLabel;
private System.Windows.Forms.ComboBox interfaceComboBox;
}
}
@@ -9,36 +9,50 @@ using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Net.NetworkInformation;
namespace LibreHardwareMonitor.UI;
public partial class PortForm : Form
public partial class InterfacePortForm : Form
{
private readonly MainForm _parent;
private readonly string _localIP;
public PortForm(MainForm m)
private string _localIP;
public InterfacePortForm(MainForm m)
{
InitializeComponent();
_parent = m;
_localIP = GetLocalIP();
_localIP = LoadNetworkInterfaces(_parent.Server.ListenerIp);
}
private void PortTextBox_TextChanged(object sender, EventArgs e)
{
}
private string GetLocalIP()
private string LoadNetworkInterfaces(string selectedListenerIp)
{
IPHostEntry host;
string localIP = "?";
interfaceComboBox.Items.Clear();
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
localIP = ip.ToString();
interfaceComboBox.Items.Add(ip.ToString());
}
return localIP;
// select the last one by default to match the existing behavior
if (interfaceComboBox.Items.Count > 0)
{
interfaceComboBox.SelectedIndex = interfaceComboBox.Items.Count - 1;
} else
{
// default to ? just like previous version
interfaceComboBox.Items.Add("?");
interfaceComboBox.SelectedIndex = 0;
}
// check to see if the selected listener IP is in our list.
if (interfaceComboBox.Items.Contains(selectedListenerIp))
{
// default it to the previously selected IP.
interfaceComboBox.SelectedItem = selectedListenerIp;
}
return interfaceComboBox.SelectedItem as string;
}
private void PortNumericUpDn_ValueChanged(object sender, EventArgs e)
@@ -52,6 +66,7 @@ public partial class PortForm : Form
private void PortOKButton_Click(object sender, EventArgs e)
{
_parent.Server.ListenerPort = (int)portNumericUpDn.Value;
_parent.Server.ListenerIp = _localIP;
Close();
}
@@ -62,6 +77,7 @@ public partial class PortForm : Form
private void PortForm_Load(object sender, EventArgs e)
{
interfaceComboBox.SelectedValue = _parent.Server.ListenerIp;
portNumericUpDn.Value = _parent.Server.ListenerPort;
PortNumericUpDn_ValueChanged(null, null);
}
@@ -79,4 +95,11 @@ public partial class PortForm : Form
{
PortNumericUpDn_ValueChanged(null, null);
}
}
private void interfaceComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
_localIP = interfaceComboBox.SelectedItem as string;
PortNumericUpDn_ValueChanged(null, null);
}
}
+7 -7
View File
@@ -138,7 +138,7 @@ namespace LibreHardwareMonitor.UI
this.webMenuItemSeparator = new System.Windows.Forms.ToolStripSeparator();
this.webMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.runWebServerMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.serverPortMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.serverInterfacePortMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.authWebServerMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -938,7 +938,7 @@ namespace LibreHardwareMonitor.UI
//
this.webMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.runWebServerMenuItem,
this.serverPortMenuItem,
this.serverInterfacePortMenuItem,
this.authWebServerMenuItem});
this.webMenuItem.Name = "webMenuItem";
this.webMenuItem.Size = new System.Drawing.Size(221, 22);
@@ -952,10 +952,10 @@ namespace LibreHardwareMonitor.UI
//
// serverPortMenuItem
//
this.serverPortMenuItem.Name = "serverPortMenuItem";
this.serverPortMenuItem.Size = new System.Drawing.Size(153, 22);
this.serverPortMenuItem.Text = "Port";
this.serverPortMenuItem.Click += new System.EventHandler(this.ServerPortMenuItem_Click);
this.serverInterfacePortMenuItem.Name = "serverInterfacePortMenuItem";
this.serverInterfacePortMenuItem.Size = new System.Drawing.Size(153, 22);
this.serverInterfacePortMenuItem.Text = "Interface / Port";
this.serverInterfacePortMenuItem.Click += new System.EventHandler(this.ServerInterfacePortMenuItem_Click);
//
// authWebServerMenuItem
//
@@ -1141,7 +1141,7 @@ namespace LibreHardwareMonitor.UI
private ToolStripRadioButtonMenuItem splitPanelFixedSensorScalingMenuItem;
private System.Windows.Forms.ToolStripMenuItem webMenuItem;
private System.Windows.Forms.ToolStripMenuItem runWebServerMenuItem;
private System.Windows.Forms.ToolStripMenuItem serverPortMenuItem;
private System.Windows.Forms.ToolStripMenuItem serverInterfacePortMenuItem;
private System.Windows.Forms.ToolStripMenuItem menuItemFileHardware;
private System.Windows.Forms.ToolStripMenuItem mainboardMenuItem;
private System.Windows.Forms.ToolStripMenuItem cpuMenuItem;
+4 -2
View File
@@ -244,6 +244,7 @@ public sealed partial class MainForm : Form
fahrenheitMenuItem.Checked = !celsiusMenuItem.Checked;
Server = new HttpServer(_root,
_settings.GetValue("listenerIp", "?"),
_settings.GetValue("listenerPort", 8085),
_settings.GetValue("authenticationEnabled", false),
_settings.GetValue("authenticationUserName", ""),
@@ -878,6 +879,7 @@ public sealed partial class MainForm : Form
foreach (TreeColumn column in treeView.Columns)
_settings.SetValue("treeView.Columns." + column.Header + ".Width", column.Width);
_settings.SetValue("listenerIp", Server.ListenerIp);
_settings.SetValue("listenerPort", Server.ListenerPort);
_settings.SetValue("authenticationEnabled", Server.AuthEnabled);
_settings.SetValue("authenticationUserName", Server.UserName);
@@ -1296,9 +1298,9 @@ public sealed partial class MainForm : Form
}
}
private void ServerPortMenuItem_Click(object sender, EventArgs e)
private void ServerInterfacePortMenuItem_Click(object sender, EventArgs e)
{
new PortForm(this).ShowDialog();
new InterfacePortForm(this).ShowDialog();
}
private void AuthWebServerMenuItem_Click(object sender, EventArgs e)
+130 -86
View File
@@ -1,4 +1,4 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// 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) LibreHardwareMonitor and Contributors.
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
@@ -31,9 +31,10 @@ public class HttpServer
private readonly Node _root;
private Thread _listenerThread;
public HttpServer(Node node, int port, bool authEnabled = false, string userName = "", string password = "")
public HttpServer(Node node, string ip, int port, bool authEnabled = false, string userName = "", string password = "")
{
_root = node;
ListenerIp = ip;
ListenerPort = port;
AuthEnabled = authEnabled;
UserName = userName;
@@ -54,13 +55,14 @@ public class HttpServer
if (PlatformNotSupported)
return;
StopHttpListener();
_listener.Abort();
}
public bool AuthEnabled { get; set; }
public string ListenerIp { get; set; }
public int ListenerPort { get; set; }
public string Password
@@ -83,14 +85,31 @@ public class HttpServer
if (PlatformNotSupported)
return false;
try
{
if (_listener.IsListening)
return true;
// validate that the selected IP exists (it could have been previously selected before switching networks)
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
bool ipFound = false;
foreach (IPAddress ip in host.AddressList)
{
if (ListenerIp == ip.ToString())
{
ipFound = true;
break;
}
}
if (!ipFound)
{
// default to behavior of previous version if we don't know what interface to use.
ListenerIp = "+";
}
string prefix = "http://" + ListenerIp + ":" + ListenerPort + "/";
string prefix = "http://+:" + ListenerPort + "/";
_listener.Prefixes.Clear();
_listener.Prefixes.Add(prefix);
_listener.Realm = "Libre Hardware Monitor";
@@ -116,7 +135,6 @@ public class HttpServer
if (PlatformNotSupported)
return false;
try
{
_listenerThread?.Abort();
@@ -232,6 +250,8 @@ public class HttpServer
throw new ArgumentNullException("No value provided");
case "Get":
result["value"] = sNode.Sensor.Value;
result["min"] = sNode.Sensor.Min;
result["max"] = sNode.Sensor.Max;
result["format"] = sNode.Format;
break;
default:
@@ -253,7 +273,7 @@ public class HttpServer
//Currently the only supported base URL is http://localhost:8085/Sensor.
private string HandlePostRequest(HttpListenerRequest request)
{
JObject result = new JObject { ["result"] = "ok" };
JObject result = new() { ["result"] = "ok" };
try
{
@@ -279,7 +299,7 @@ public class HttpServer
#if DEBUG
return result.ToString(Newtonsoft.Json.Formatting.Indented);
#else
return result.ToString(Newtonsoft.Json.Formatting.None);
return result.ToString(Newtonsoft.Json.Formatting.None);
#endif
}
@@ -289,7 +309,6 @@ public class HttpServer
if (listener == null || !listener.IsListening)
return;
// Call EndGetContext to complete the asynchronous operation.
HttpListenerContext context;
try
@@ -360,6 +379,14 @@ public class HttpServer
return;
}
if (requestedFile.Contains("Sensor"))
{
JObject sensorResult = new();
HandleSensorRequest(request, sensorResult);
SendJsonSensor(context.Response, sensorResult);
return;
}
// default file to be served
if (string.IsNullOrEmpty(requestedFile))
requestedFile = "index.html";
@@ -412,38 +439,36 @@ public class HttpServer
name = "LibreHardwareMonitor.Resources." +
name.Replace("custom-theme", "custom_theme");
string[] names =
Assembly.GetExecutingAssembly().GetManifestResourceNames();
string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
for (int i = 0; i < names.Length; i++)
{
if (names[i].Replace('\\', '.') == name)
{
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(names[i]))
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(names[i]);
response.ContentType = GetContentType("." + ext);
response.ContentLength64 = stream.Length;
byte[] buffer = new byte[512 * 1024];
try
{
response.ContentType = GetContentType("." + ext);
response.ContentLength64 = stream.Length;
byte[] buffer = new byte[512 * 1024];
try
Stream output = response.OutputStream;
int len;
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
Stream output = response.OutputStream;
int len;
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
output.Close();
response.Close();
output.Write(buffer, 0, len);
}
catch (HttpListenerException)
{ }
catch (InvalidOperationException)
{ }
return;
output.Flush();
output.Close();
response.Close();
}
catch (HttpListenerException)
{ }
catch (InvalidOperationException)
{ }
return;
}
}
@@ -461,28 +486,27 @@ public class HttpServer
{
if (names[i].Replace('\\', '.') == name)
{
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(names[i]))
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(names[i]);
Image image = Image.FromStream(stream);
response.ContentType = "image/png";
try
{
Image image = Image.FromStream(stream);
response.ContentType = "image/png";
try
Stream output = response.OutputStream;
using (MemoryStream ms = new())
{
Stream output = response.OutputStream;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
ms.WriteTo(output);
}
output.Close();
image.Save(ms, ImageFormat.Png);
ms.WriteTo(output);
}
catch (HttpListenerException)
{ }
image.Dispose();
response.Close();
return;
output.Close();
}
catch (HttpListenerException)
{ }
image.Dispose();
response.Close();
return;
}
}
@@ -492,7 +516,7 @@ public class HttpServer
private void SendJson(HttpListenerResponse response, HttpListenerRequest request = null)
{
JObject json = new JObject();
JObject json = new();
int nodeIndex = 0;
@@ -503,12 +527,12 @@ public class HttpServer
json["Max"] = "Max";
json["ImageURL"] = string.Empty;
JArray children = new JArray { GenerateJsonForNode(_root, ref nodeIndex) };
json["Children"] = children;
json["Children"] = new JArray { GenerateJsonForNode(_root, ref nodeIndex) };
#if DEBUG
string responseContent = json.ToString(Newtonsoft.Json.Formatting.Indented);
#else
string responseContent = json.ToString(Newtonsoft.Json.Formatting.None);
string responseContent = json.ToString(Newtonsoft.Json.Formatting.None);
#endif
byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
@@ -532,13 +556,11 @@ public class HttpServer
{
if (acceptGzip)
{
using (var ms = new MemoryStream())
{
using (var zip = new GZipStream(ms, CompressionMode.Compress, true))
zip.Write(buffer, 0, buffer.Length);
using var ms = new MemoryStream();
using (var zip = new GZipStream(ms, CompressionMode.Compress, true))
zip.Write(buffer, 0, buffer.Length);
buffer = ms.ToArray();
}
buffer = ms.ToArray();
}
response.ContentLength64 = buffer.Length;
@@ -552,9 +574,35 @@ public class HttpServer
response.Close();
}
private void SendJsonSensor(HttpListenerResponse response, JObject sensorData)
{
// Convert the JObject to a JSON string
string responseContent = sensorData.ToString(Newtonsoft.Json.Formatting.None);
byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
// Add headers and set content type
response.AddHeader("Cache-Control", "no-cache");
response.AddHeader("Access-Control-Allow-Origin", "*");
response.ContentType = "application/json";
// Write the response content to the output stream
try
{
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
catch (HttpListenerException)
{ }
// Close the response
response.Close();
}
private JObject GenerateJsonForNode(Node n, ref int nodeIndex)
{
JObject jsonNode = new JObject
JObject jsonNode = new()
{
["id"] = nodeIndex++,
["Text"] = n.Text,
@@ -563,29 +611,28 @@ public class HttpServer
["Max"] = string.Empty
};
if (n is SensorNode sensorNode)
switch (n)
{
jsonNode["SensorId"] = sensorNode.Sensor.Identifier.ToString();
jsonNode["Type"] = sensorNode.Sensor.SensorType.ToString();
jsonNode["Min"] = sensorNode.Min;
jsonNode["Value"] = sensorNode.Value;
jsonNode["Max"] = sensorNode.Max;
jsonNode["ImageURL"] = "images/transparent.png";
}
else if (n is HardwareNode hardwareNode)
{
jsonNode["ImageURL"] = "images_icon/" + GetHardwareImageFile(hardwareNode);
}
else if (n is TypeNode typeNode)
{
jsonNode["ImageURL"] = "images_icon/" + GetTypeImageFile(typeNode);
}
else
{
jsonNode["ImageURL"] = "images_icon/computer.png";
case SensorNode sensorNode:
jsonNode["SensorId"] = sensorNode.Sensor.Identifier.ToString();
jsonNode["Type"] = sensorNode.Sensor.SensorType.ToString();
jsonNode["Min"] = sensorNode.Min;
jsonNode["Value"] = sensorNode.Value;
jsonNode["Max"] = sensorNode.Max;
jsonNode["ImageURL"] = "images/transparent.png";
break;
case HardwareNode hardwareNode:
jsonNode["ImageURL"] = "images_icon/" + GetHardwareImageFile(hardwareNode);
break;
case TypeNode typeNode:
jsonNode["ImageURL"] = "images_icon/" + GetTypeImageFile(typeNode);
break;
default:
jsonNode["ImageURL"] = "images_icon/computer.png";
break;
}
JArray children = new JArray();
JArray children = [];
foreach (Node child in n.Nodes)
{
children.Add(GenerateJsonForNode(child, ref nodeIndex));
@@ -690,12 +737,10 @@ public class HttpServer
private string ComputeSHA256(string text)
{
using (SHA256 hash = SHA256.Create())
{
return string.Concat(hash
.ComputeHash(Encoding.UTF8.GetBytes(text))
.Select(item => item.ToString("x2")));
}
using SHA256 hash = SHA256.Create();
return string.Concat(hash
.ComputeHash(Encoding.UTF8.GetBytes(text))
.Select(item => item.ToString("x2")));
}
public void Quit()
@@ -703,7 +748,6 @@ public class HttpServer
if (PlatformNotSupported)
return;
StopHttpListener();
_listener.Abort();
}
@@ -19,11 +19,12 @@ internal sealed class Battery : Hardware
private readonly Sensor _chargeDischargeCurrent;
private readonly Sensor _chargeDischargeRate;
private readonly Sensor _chargeLevel;
private readonly Sensor _degradationPercentage;
private readonly Sensor _degradationLevel;
private readonly Sensor _designedCapacity;
private readonly Sensor _fullChargedCapacity;
private readonly Sensor _remainingCapacity;
private readonly Sensor _remainingTime;
private readonly Sensor _temperature;
private readonly Sensor _voltage;
public Battery
@@ -34,7 +35,7 @@ internal sealed class Battery : Hardware
Kernel32.BATTERY_INFORMATION batteryInfo,
uint batteryTag,
ISettings settings) :
base(name, new Identifier("battery"), settings)
base(name, new Identifier("battery", $"{name.Replace(' ', '-')}_{batteryTag}"), settings)
{
Name = name;
Manufacturer = manufacturer;
@@ -72,61 +73,65 @@ internal sealed class Battery : Hardware
Chemistry = BatteryChemistry.Unknown;
}
DegradationLevel = 100f - (batteryInfo.FullChargedCapacity * 100f / batteryInfo.DesignedCapacity);
DesignedCapacity = batteryInfo.DesignedCapacity;
FullChargedCapacity = batteryInfo.FullChargedCapacity;
_designedCapacity = new Sensor("Designed Capacity", 0, SensorType.Energy, this, settings);
_fullChargedCapacity = new Sensor("Fully-Charged Capacity", 1, SensorType.Energy, this, settings);
_degradationLevel = new Sensor("Degradation Level", 1, SensorType.Level, this, settings);
_chargeLevel = new Sensor("Charge Level", 0, SensorType.Level, this, settings);
ActivateSensor(_chargeLevel);
_voltage = new Sensor("Voltage", 1, SensorType.Voltage, this, settings);
ActivateSensor(_voltage);
_chargeDischargeCurrent = new Sensor("Current", 2, SensorType.Current, this, settings);
ActivateSensor(_chargeDischargeCurrent);
_designedCapacity = new Sensor("Designed Capacity", 3, SensorType.Energy, this, settings);
ActivateSensor(_designedCapacity);
_fullChargedCapacity = new Sensor("Full Charged Capacity", 4, SensorType.Energy, this, settings);
ActivateSensor(_fullChargedCapacity);
_remainingCapacity = new Sensor("Remaining Capacity", 5, SensorType.Energy, this, settings);
ActivateSensor(_remainingCapacity);
_voltage = new Sensor("Voltage", 0, SensorType.Voltage, this, settings);
_remainingCapacity = new Sensor("Remaining Capacity", 2, SensorType.Energy, this, settings);
_chargeDischargeCurrent = new Sensor("Charge/Discharge Current", 0, SensorType.Current, this, settings);
_chargeDischargeRate = new Sensor("Charge/Discharge Rate", 0, SensorType.Power, this, settings);
ActivateSensor(_chargeDischargeRate);
_degradationPercentage = new Sensor("Degradation Level", 0, SensorType.Level, this, settings);
ActivateSensor(_degradationPercentage);
_remainingTime = new Sensor("Remaining Time (Estimated)", 0, SensorType.TimeSpan, this, settings);
ActivateSensor(_remainingTime);
_temperature = new Sensor("Battery Temperature", 0, SensorType.Temperature, this, settings);
if (batteryInfo.FullChargedCapacity is not Kernel32.BATTERY_UNKNOWN_CAPACITY &&
batteryInfo.DesignedCapacity is not Kernel32.BATTERY_UNKNOWN_CAPACITY)
{
_designedCapacity.Value = batteryInfo.DesignedCapacity;
_fullChargedCapacity.Value = batteryInfo.FullChargedCapacity;
_degradationLevel.Value = 100f - (batteryInfo.FullChargedCapacity * 100f / batteryInfo.DesignedCapacity);
DesignedCapacity = batteryInfo.DesignedCapacity;
FullChargedCapacity = batteryInfo.FullChargedCapacity;
ActivateSensor(_designedCapacity);
ActivateSensor(_fullChargedCapacity);
ActivateSensor(_degradationLevel);
}
}
public float ChargeDischargeCurrent { get; private set; }
public float? ChargeDischargeCurrent { get; private set; }
public float ChargeDischargeRate { get; private set; }
public float? ChargeDischargeRate { get; private set; }
public float ChargeLevel { get; private set; }
public float? ChargeLevel => _chargeLevel.Value;
public BatteryChemistry Chemistry { get; }
public float DegradationLevel { get; }
public float? DegradationLevel => _degradationLevel.Value;
public float DesignedCapacity { get; }
public float? DesignedCapacity { get; }
public float FullChargedCapacity { get; }
public float? FullChargedCapacity { get; }
public override HardwareType HardwareType => HardwareType.Battery;
public string Manufacturer { get; }
public float RemainingCapacity { get; private set; }
public float? RemainingCapacity => _remainingCapacity.Value;
public uint RemainingTime { get; private set; }
public float? RemainingTime => _remainingTime.Value;
public float Voltage { get; private set; }
public float? Temperature => _temperature.Value;
public float? Voltage => _voltage.Value;
private void ActivateSensorIfValueNotNull(ISensor sensor)
{
if (sensor.Value != null)
ActivateSensor(sensor);
else
DeactivateSensor(sensor);
}
public override void Update()
{
@@ -142,53 +147,55 @@ internal sealed class Battery : Hardware
out _,
IntPtr.Zero))
{
_designedCapacity.Value = Convert.ToSingle(_batteryInformation.DesignedCapacity);
_fullChargedCapacity.Value = Convert.ToSingle(_batteryInformation.FullChargedCapacity);
_remainingCapacity.Value = Convert.ToSingle(batteryStatus.Capacity);
RemainingCapacity = Convert.ToSingle(batteryStatus.Capacity);
_voltage.Value = Convert.ToSingle(batteryStatus.Voltage) / 1000f;
Voltage = Convert.ToSingle(batteryStatus.Voltage) / 1000f;
if (batteryStatus.Capacity != Kernel32.BATTERY_UNKNOWN_CAPACITY)
_remainingCapacity.Value = batteryStatus.Capacity;
else
_remainingCapacity.Value = null;
_chargeLevel.Value = _remainingCapacity.Value * 100f / _fullChargedCapacity.Value;
ChargeLevel = (_remainingCapacity.Value * 100f / _fullChargedCapacity.Value).GetValueOrDefault();
ChargeDischargeRate = batteryStatus.Rate / 1000f;
if (batteryStatus.Voltage is not Kernel32.BATTERY_UNKNOWN_VOLTAGE)
_voltage.Value = batteryStatus.Voltage / 1000f;
else
_voltage.Value = null;
switch (batteryStatus.Rate)
if (batteryStatus.Rate is Kernel32.BATTERY_UNKNOWN_RATE)
{
case > 0:
_chargeDischargeRate.Name = "Charge Rate";
_chargeDischargeRate.Value = batteryStatus.Rate / 1000f;
ChargeDischargeCurrent = null;
_chargeDischargeCurrent.Value = null;
_chargeDischargeCurrent.Name = "Charge Current";
_chargeDischargeCurrent.Value = _chargeDischargeRate.Value / _voltage.Value;
ChargeDischargeCurrent = (_chargeDischargeRate.Value / _voltage.Value).GetValueOrDefault();
break;
case < 0:
_chargeDischargeRate.Name = "Discharge Rate";
_chargeDischargeRate.Value = Math.Abs(batteryStatus.Rate / 1000f);
_chargeDischargeCurrent.Name = "Discharge Current";
_chargeDischargeCurrent.Value = _chargeDischargeRate.Value / _voltage.Value;
ChargeDischargeCurrent = (_chargeDischargeRate.Value / _voltage.Value).GetValueOrDefault();
break;
default:
_chargeDischargeRate.Name = "Charge/Discharge Rate";
_chargeDischargeRate.Value = 0f;
ChargeDischargeRate = 0f;
_chargeDischargeCurrent.Name = "Charge/Discharge Current";
_chargeDischargeCurrent.Value = 0f;
ChargeDischargeCurrent = 0f;
break;
ChargeDischargeRate = null;
_chargeDischargeRate.Value = null;
}
else
{
float rateWatts = batteryStatus.Rate / 1000f;
ChargeDischargeRate = rateWatts;
_chargeDischargeRate.Value = Math.Abs(rateWatts);
_degradationPercentage.Value = 100f - (_fullChargedCapacity.Value * 100f / _designedCapacity.Value);
float? current = rateWatts / _voltage.Value;
ChargeDischargeCurrent = current;
if (current is not null)
_chargeDischargeCurrent.Value = Math.Abs(current.Value);
else
_chargeDischargeCurrent.Value = null;
if (rateWatts > 0)
{
_chargeDischargeRate.Name = "Charge Rate";
_chargeDischargeCurrent.Name = "Charge Current";
}
else if (rateWatts < 0)
{
_chargeDischargeRate.Name = "Discharge Rate";
_chargeDischargeCurrent.Name = "Discharge Current";
}
else
{
_chargeDischargeRate.Name = "Charge/Discharge Rate";
_chargeDischargeCurrent.Name = "Charge/Discharge Current";
}
}
}
uint estimatedRunTime = 0;
@@ -204,17 +211,41 @@ internal sealed class Battery : Hardware
out _,
IntPtr.Zero))
{
RemainingTime = estimatedRunTime;
if (estimatedRunTime != Kernel32.BATTERY_UNKNOWN_TIME)
{
ActivateSensor(_remainingTime);
_remainingTime.Value = estimatedRunTime;
}
else
{
DeactivateSensor(_remainingTime);
}
_remainingTime.Value = null;
}
else
{
_remainingTime.Value = null;
}
uint temperature = 0;
bqi.InformationLevel = Kernel32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryTemperature;
if (Kernel32.DeviceIoControl(_batteryHandle,
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_INFORMATION,
ref bqi,
Marshal.SizeOf(bqi),
ref temperature,
Marshal.SizeOf<uint>(),
out _,
IntPtr.Zero))
{
_temperature.Value = (temperature / 10f) - 273.15f;
}
else
{
_temperature.Value = null;
}
ActivateSensorIfValueNotNull(_remainingCapacity);
ActivateSensorIfValueNotNull(_chargeLevel);
ActivateSensorIfValueNotNull(_voltage);
ActivateSensorIfValueNotNull(_chargeDischargeCurrent);
ActivateSensorIfValueNotNull(_chargeDischargeRate);
ActivateSensorIfValueNotNull(_remainingTime);
ActivateSensorIfValueNotNull(_temperature);
}
public override void Close()
@@ -17,6 +17,35 @@ internal class BatteryGroup : IGroup
{
private readonly List<Battery> _hardware = new();
static bool QueryStringFromBatteryInfo(SafeFileHandle battery, Kernel32.BATTERY_QUERY_INFORMATION bqi, out string value)
{
const int maxLoadString = 100;
value = null;
bool result = false;
IntPtr ptrString = Marshal.AllocHGlobal(maxLoadString);
if (Kernel32.DeviceIoControl(battery,
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_INFORMATION,
ref bqi,
Marshal.SizeOf(bqi),
ptrString,
maxLoadString,
out uint stringSizeBytes,
IntPtr.Zero))
{
// Use the value stored in stringSizeBytes to avoid relying on a
// terminator char.
// See https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/pull/1158#issuecomment-1979559929
int stringSizeChars = (int)stringSizeBytes / 2;
value = Marshal.PtrToStringUni(ptrString, stringSizeChars);
result = true;
}
Marshal.FreeHGlobal(ptrString);
return result;
}
public unsafe BatteryGroup(ISettings settings)
{
// No implementation for battery information on Unix systems
@@ -93,42 +122,12 @@ internal class BatteryGroup : IGroup
// Only batteries count.
if (bi.Capabilities.HasFlag(Kernel32.BatteryCapabilities.BATTERY_SYSTEM_BATTERY))
{
const int maxLoadString = 100;
IntPtr ptrDevName = Marshal.AllocCoTaskMem(maxLoadString);
bqi.InformationLevel = Kernel32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryDeviceName;
QueryStringFromBatteryInfo(battery, bqi, out string batteryName);
bqi.InformationLevel = Kernel32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryManufactureName;
QueryStringFromBatteryInfo(battery, bqi, out string manufacturer);
if (Kernel32.DeviceIoControl(battery,
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_INFORMATION,
ref bqi,
Marshal.SizeOf(bqi),
ptrDevName,
maxLoadString,
out _,
IntPtr.Zero))
{
IntPtr ptrManName = Marshal.AllocCoTaskMem(maxLoadString);
bqi.InformationLevel = Kernel32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryManufactureName;
if (Kernel32.DeviceIoControl(battery,
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_INFORMATION,
ref bqi,
Marshal.SizeOf(bqi),
ptrManName,
maxLoadString,
out _,
IntPtr.Zero))
{
string name = Marshal.PtrToStringUni(ptrDevName);
string manufacturer = Marshal.PtrToStringUni(ptrManName);
_hardware.Add(new Battery(name, manufacturer, battery, bi, bqi.BatteryTag, settings));
}
Marshal.FreeCoTaskMem(ptrManName);
}
Marshal.FreeCoTaskMem(ptrDevName);
_hardware.Add(new Battery(batteryName, manufacturer, battery, bi, bqi.BatteryTag, settings));
}
}
}
@@ -177,37 +176,55 @@ internal class BatteryGroup : IGroup
reportBuilder.Append("Battery #").Append(count).AppendLine(":")
.Append(" Name: ").AppendLine(bat.Name)
.Append(" Manufacturer: ").AppendLine(bat.Manufacturer)
.Append(" Chemistry: ").AppendLine(chemistry)
.Append(" Degradation Level: ").AppendFormat("{0:F2}", bat.DegradationLevel).AppendLine(" %")
.Append(" Designed Capacity: ").Append(bat.DesignedCapacity).AppendLine(" mWh")
.Append(" Full Charged Capacity: ").Append(bat.FullChargedCapacity).AppendLine(" mWh")
.Append(" Remaining Capacity: ").Append(bat.RemainingCapacity).AppendLine(" mWh")
.Append(" Charge Level: ").AppendFormat("{0:F2}", bat.RemainingCapacity * 100f / bat.FullChargedCapacity).AppendLine(" %")
.Append(" Voltage: ").AppendFormat("{0:F3}", bat.Voltage).AppendLine(" V");
.Append(" Chemistry: ").AppendLine(chemistry);
if (bat.RemainingTime != Kernel32.BATTERY_UNKNOWN_TIME)
if (bat.DegradationLevel.HasValue)
reportBuilder.Append(" Degradation Level: ").AppendFormat("{0:F2}", bat.DegradationLevel).AppendLine(" %");
if (bat.DesignedCapacity.HasValue)
reportBuilder.Append(" Designed Capacity: ").Append(bat.DesignedCapacity).AppendLine(" mWh");
if (bat.FullChargedCapacity.HasValue)
reportBuilder.Append(" Fully-Charged Capacity: ").Append(bat.FullChargedCapacity).AppendLine(" mWh");
if (bat.RemainingCapacity.HasValue)
reportBuilder.Append(" Remaining Capacity: ").Append(bat.RemainingCapacity).AppendLine(" mWh");
if (bat.ChargeLevel.HasValue)
reportBuilder.Append(" Charge Level: ").AppendFormat("{0:F2}", bat.ChargeLevel).AppendLine(" %");
if (bat.Voltage.HasValue)
reportBuilder.Append(" Voltage: ").AppendFormat("{0:F3}", bat.Voltage).AppendLine(" V");
if (bat.Temperature.HasValue)
reportBuilder.Append(" Temperature: ").AppendFormat("{0:F3}", bat.Temperature).AppendLine(" ºC");
if (bat.RemainingTime.HasValue)
reportBuilder.Append(" Remaining Time (Estimated): ").AppendFormat("{0:g}", TimeSpan.FromSeconds(bat.RemainingTime.Value)).AppendLine();
string cdRateSensorName;
string cdCurrentSensorName;
if (bat.ChargeDischargeRate > 0)
{
reportBuilder.Append(" Remaining Time (Estimated): ").AppendFormat("{0:g}", TimeSpan.FromSeconds(bat.RemainingTime)).AppendLine();
cdRateSensorName = " Charge Rate: ";
cdCurrentSensorName = " Charge Current: ";
}
else if (bat.ChargeDischargeRate < 0)
{
cdRateSensorName = " Discharge Rate: ";
cdCurrentSensorName = " Discharge Current: ";
}
else
{
cdRateSensorName = " Charge/Discharge Rate: ";
cdCurrentSensorName = " Charge/Discharge Current: ";
}
switch (bat.ChargeDischargeRate)
{
case > 0:
reportBuilder.Append(" Charge Rate: ").AppendFormat("{0:F1}", bat.ChargeDischargeRate).AppendLine(" W")
.Append(" Charge Current: ").AppendFormat("{0:F3}", bat.ChargeDischargeRate / bat.Voltage).AppendLine(" A");
if (bat.ChargeDischargeRate.HasValue)
reportBuilder.Append(cdRateSensorName).AppendFormat("{0:F1}", Math.Abs(bat.ChargeDischargeRate.Value)).AppendLine(" W");
break;
case < 0:
reportBuilder.Append(" Discharge Rate: ").AppendFormat("{0:F1}", Math.Abs(bat.ChargeDischargeRate)).AppendLine(" W")
.Append(" Discharge Current: ").AppendFormat("{0:F3}", Math.Abs(bat.ChargeDischargeRate) / bat.Voltage).AppendLine(" A");
break;
default:
reportBuilder.AppendLine(" Charge/Discharge Rate: 0 W")
.AppendLine(" Charge/Discharge Current: 0 A");
break;
}
if (bat.ChargeDischargeCurrent.HasValue)
reportBuilder.Append(cdCurrentSensorName).AppendFormat("{0:F3}", Math.Abs(bat.ChargeDischargeCurrent.Value)).AppendLine(" A");
reportBuilder.AppendLine();
count++;
@@ -19,7 +19,7 @@ internal sealed class P7H1 : Hardware
private readonly HidStream _stream;
private bool _running;
public P7H1(HidDevice dev, ISettings settings) : base("AeroCool P7-H1", new Identifier(dev.DevicePath), settings)
public P7H1(HidDevice dev, ISettings settings) : base("AeroCool P7-H1", new Identifier(dev), settings)
{
_device = dev;
HubNumber = _device.ProductID - 0x1000;
@@ -93,4 +93,4 @@ internal sealed class P7H1 : Hardware
_rpm[i].Value = _speeds[i];
}
}
}
}
@@ -20,20 +20,20 @@ internal sealed class AquastreamUltimate : Hardware
private readonly Sensor[] _powers = new Sensor[2];
private readonly Sensor[] _flows = new Sensor[2];
public AquastreamUltimate(HidDevice dev, ISettings settings) : base("AquastreamUltimate", new Identifier(dev.DevicePath), settings)
public AquastreamUltimate(HidDevice dev, ISettings settings) : base("AquastreamUltimate", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
// Reading output report instead of feature report, as the measurements are in the output report.
_stream.Read(_rawData);
FirmwareVersion = GetConvertedValue(0xD).GetValueOrDefault(0);
Name = "Aquastream ULTIMATE";
_temperatures[0] = new Sensor("Coolant", 0, SensorType.Temperature, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_temperatures[0]);
_temperatures[1] = new Sensor("External Sensor", 1, SensorType.Temperature, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_temperatures[1]);
@@ -88,20 +88,20 @@ internal sealed class AquastreamUltimate : Hardware
// Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
_rpmSensors[0].Value = GetConvertedValue(0x51) ; // Pump speed.
_rpmSensors[1].Value = GetConvertedValue(0x41+0x06); // Fan speed.
_rpmSensors[0].Value = GetConvertedValue(0x51); // Pump speed.
_rpmSensors[1].Value = GetConvertedValue(0x41 + 0x06); // Fan speed.
_temperatures[0].Value = GetConvertedValue(0x2D) / 100f; // Water temp.
_temperatures[1].Value = GetConvertedValue(0x2F) / 100f; // Ext sensor temp.
_voltages[0].Value = GetConvertedValue(0x3D) / 100f; // Pump input voltage.
_voltages[1].Value = GetConvertedValue(0x41+0x02) / 100f; // Fan output voltage.
_voltages[1].Value = GetConvertedValue(0x41 + 0x02) / 100f; // Fan output voltage.
_currents[0].Value = GetConvertedValue(0x53) / 1000f; // Pump current.
_currents[1].Value = GetConvertedValue(0x41+0x00) / 1000f; // Fan current.
_currents[1].Value = GetConvertedValue(0x41 + 0x00) / 1000f; // Fan current.
_powers[0].Value = GetConvertedValue(0x55) / 100f; // Pump power.
_powers[1].Value = GetConvertedValue(0x41+0x04) / 100f; // Fan power.
_powers[1].Value = GetConvertedValue(0x41 + 0x04) / 100f; // Fan power.
_flows[0].Value = GetConvertedValue(0x37); // Flow.
_flows[1].Value = GetConvertedValue(0x57) / 1000f; // Pressure.
@@ -111,7 +111,7 @@ internal sealed class AquastreamUltimate : Hardware
{
if (_rawData[index] == sbyte.MaxValue)
return null;
return Convert.ToUInt16(_rawData[index + 1] | (_rawData[index] << 8));
}
}
}
@@ -26,7 +26,7 @@ internal sealed class AquastreamXT : Hardware
private readonly Sensor[] _temperatures = new Sensor[3];
private readonly Sensor[] _voltages = new Sensor[2];
public AquastreamXT(HidDevice dev, ISettings settings) : base("Aquastream XT", new Identifier(dev.DevicePath), settings)
public AquastreamXT(HidDevice dev, ISettings settings) : base("Aquastream XT", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
@@ -129,7 +129,7 @@ internal sealed class AquastreamXT : Hardware
{
return;
}
if (_rawData[0] != 0x4)
return;
@@ -25,7 +25,7 @@ internal sealed class D5Next : Hardware
private readonly HidStream _stream;
private readonly Sensor[] _temperatures = new Sensor[1];
public D5Next(HidDevice dev, ISettings settings) : base("D5Next", new Identifier(dev.DevicePath), settings)
public D5Next(HidDevice dev, ISettings settings) : base("D5Next", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
@@ -27,7 +27,7 @@ internal sealed class Farbwerk : Hardware
private readonly Sensor[] _temperatures = new Sensor[TEMPERATURE_COUNT];
private readonly Sensor[] _colors = new Sensor[COLOR_VALUE_COUNT];
public Farbwerk(HidDevice dev, ISettings settings) : base("Farbwerk", new Identifier(dev.DevicePath), settings)
public Farbwerk(HidDevice dev, ISettings settings) : base("Farbwerk", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
@@ -20,7 +20,7 @@ internal sealed class HighFlowNext : Hardware
private readonly Sensor[] _voltages = new Sensor[2];
private readonly Sensor[] _alarms = new Sensor[4];
public HighFlowNext(HidDevice dev, ISettings settings) : base("high flow NEXT", new Identifier(dev.DevicePath), settings)
public HighFlowNext(HidDevice dev, ISettings settings) : base("high flow NEXT", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
@@ -93,7 +93,7 @@ internal sealed class HighFlowNext : Hardware
if (externalTempSensorConnected)
{
_temperatures[1].Value = rawExtTempValue / 100f;
_temperatures[1].Value = rawExtTempValue / 100f;
}
else
{
@@ -23,7 +23,7 @@ internal sealed class MPS : Hardware
private ushort _externalTemperature;
public MPS(HidDevice dev, ISettings settings) : base("MPS", new Identifier(dev.DevicePath), settings)
public MPS(HidDevice dev, ISettings settings) : base("MPS", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
@@ -18,30 +18,30 @@ internal sealed class Octo : Hardware
private readonly Sensor[] _currents = new Sensor[8];
private readonly Sensor[] _powers = new Sensor[8];
public Octo(HidDevice dev, ISettings settings) : base("Octo", new Identifier(dev.DevicePath), settings)
public Octo(HidDevice dev, ISettings settings) : base("Octo", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
//Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
Name = "OCTO";
FirmwareVersion = GetConvertedValue(OctoDataIndexes.FIRMWARE_VERSION).GetValueOrDefault(0);
// Initialize the 4 temperature sensors
for (int i = 0; i < 4; i++)
{
_temperatures[i] = new Sensor($"Temperature {i+1}", i, SensorType.Temperature, this, Array.Empty<ParameterDescription>(), settings);
_temperatures[i] = new Sensor($"Temperature {i + 1}", i, SensorType.Temperature, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_temperatures[i]);
}
// Initialize the 8 fan speed sensors
for (int i = 0; i < 8; i++)
{
_rpmSensors[i] = new Sensor($"Fan {i+1}", i, SensorType.Fan, this, Array.Empty<ParameterDescription>(), settings);
_rpmSensors[i] = new Sensor($"Fan {i + 1}", i, SensorType.Fan, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_rpmSensors[i]);
}
// Initialize the input voltage sensor
_voltages[0] = new Sensor("Input", 0, SensorType.Voltage, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_voltages[0]);
@@ -52,18 +52,18 @@ internal sealed class Octo : Hardware
_voltages[i] = new Sensor($"Fan {i}", i, SensorType.Voltage, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_voltages[i]);
}
// Initialize the 8 fan current sensors
for (int i = 0; i < 8; i++)
{
_currents[i] = new Sensor($"Fan {i+1}", i, SensorType.Current, this, Array.Empty<ParameterDescription>(), settings);
_currents[i] = new Sensor($"Fan {i + 1}", i, SensorType.Current, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_currents[i]);
}
// Initialize the 8 fan power sensors
for (int i = 0; i < 8; i++)
{
_powers[i] = new Sensor($"Fan {i+1}", i, SensorType.Power, this, Array.Empty<ParameterDescription>(), settings);
_powers[i] = new Sensor($"Fan {i + 1}", i, SensorType.Power, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_powers[i]);
}
}
@@ -86,7 +86,7 @@ internal sealed class Octo : Hardware
{
//Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
_temperatures[0].Value = GetConvertedValue(OctoDataIndexes.TEMP_1) / 100f; // Temp 1
_temperatures[1].Value = GetConvertedValue(OctoDataIndexes.TEMP_2) / 100f; // Temp 2
_temperatures[2].Value = GetConvertedValue(OctoDataIndexes.TEMP_3) / 100f; // Temp 3
@@ -100,7 +100,7 @@ internal sealed class Octo : Hardware
_rpmSensors[5].Value = GetConvertedValue(OctoDataIndexes.FAN_SPEED_6); // Fan 6 speed
_rpmSensors[6].Value = GetConvertedValue(OctoDataIndexes.FAN_SPEED_7); // Fan 7 speed
_rpmSensors[7].Value = GetConvertedValue(OctoDataIndexes.FAN_SPEED_8); // Fan 8 speed
_voltages[0].Value = GetConvertedValue(OctoDataIndexes.VOLTAGE) / 100f; // Input voltage
_voltages[1].Value = GetConvertedValue(OctoDataIndexes.FAN_VOLTAGE_1) / 100f; // Fan 1 voltage
_voltages[2].Value = GetConvertedValue(OctoDataIndexes.FAN_VOLTAGE_2) / 100f; // Fan 2 voltage
@@ -110,7 +110,7 @@ internal sealed class Octo : Hardware
_voltages[6].Value = GetConvertedValue(OctoDataIndexes.FAN_VOLTAGE_6) / 100f; // Fan 6 voltage
_voltages[7].Value = GetConvertedValue(OctoDataIndexes.FAN_VOLTAGE_7) / 100f; // Fan 7 voltage
_voltages[8].Value = GetConvertedValue(OctoDataIndexes.FAN_VOLTAGE_8) / 100f; // Fan 8 voltage
_currents[0].Value = GetConvertedValue(OctoDataIndexes.FAN_CURRENT_1) / 1000f; // Fan 1 current
_currents[1].Value = GetConvertedValue(OctoDataIndexes.FAN_CURRENT_2) / 1000f; // Fan 2 current
_currents[2].Value = GetConvertedValue(OctoDataIndexes.FAN_CURRENT_3) / 1000f; // Fan 3 current
@@ -119,7 +119,7 @@ internal sealed class Octo : Hardware
_currents[5].Value = GetConvertedValue(OctoDataIndexes.FAN_CURRENT_6) / 1000f; // Fan 6 current
_currents[6].Value = GetConvertedValue(OctoDataIndexes.FAN_CURRENT_7) / 1000f; // Fan 7 current
_currents[7].Value = GetConvertedValue(OctoDataIndexes.FAN_CURRENT_8) / 1000f; // Fan 8 current
_powers[0].Value = GetConvertedValue(OctoDataIndexes.FAN_POWER_1) / 100f; // Fan 1 power
_powers[1].Value = GetConvertedValue(OctoDataIndexes.FAN_POWER_2) / 100f; // Fan 2 power
_powers[2].Value = GetConvertedValue(OctoDataIndexes.FAN_POWER_3) / 100f; // Fan 3 power
@@ -133,7 +133,7 @@ internal sealed class Octo : Hardware
private sealed class OctoDataIndexes
{
public const int FIRMWARE_VERSION = 13;
public const int TEMP_1 = 61;
public const int TEMP_2 = 63;
public const int TEMP_3 = 65;
@@ -147,7 +147,7 @@ internal sealed class Octo : Hardware
public const int FAN_SPEED_6 = 198;
public const int FAN_SPEED_7 = 211;
public const int FAN_SPEED_8 = 224;
public const int FAN_POWER_1 = 131;
public const int FAN_POWER_2 = 144;
public const int FAN_POWER_3 = 157;
@@ -166,7 +166,7 @@ internal sealed class Octo : Hardware
public const int FAN_VOLTAGE_6 = 192;
public const int FAN_VOLTAGE_7 = 205;
public const int FAN_VOLTAGE_8 = 218;
public const int FAN_CURRENT_1 = 129;
public const int FAN_CURRENT_2 = 142;
public const int FAN_CURRENT_3 = 155;
@@ -181,7 +181,7 @@ internal sealed class Octo : Hardware
{
if (_rawData[index] == sbyte.MaxValue)
return null;
return Convert.ToUInt16(_rawData[index + 1] | (_rawData[index] << 8));
}
}
}
@@ -1,170 +1,170 @@
// 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) LibreHardwareMonitor and Contributors.
// All Rights Reserved.
using System;
using HidSharp;
namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer;
internal sealed class Quadro : Hardware
{
private readonly byte[] _rawData = new byte[210];
private readonly HidStream _stream;
private readonly Sensor[] _rpmSensors = new Sensor[4];
private readonly Sensor[] _temperatures = new Sensor[4];
private readonly Sensor[] _voltages = new Sensor[5];
private readonly Sensor[] _currents = new Sensor[4];
private readonly Sensor[] _powers = new Sensor[4];
private readonly Sensor[] _flows = new Sensor[1];
public Quadro(HidDevice dev, ISettings settings) : base("Quadro", new Identifier(dev.DevicePath), settings)
{
if (dev.TryOpen(out _stream))
{
//Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
Name = "QUADRO";
FirmwareVersion = GetConvertedValue(QuadroDataIndexes.FIRMWARE_VERSION).GetValueOrDefault(0);
// Initialize the 4 temperature sensors
for (int i = 0; i < 4; i++)
{
_temperatures[i] = new Sensor($"Temperature {i+1}", i, SensorType.Temperature, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_temperatures[i]);
}
// Initialize the input voltage sensor
_voltages[0] = new Sensor("Input", 0, SensorType.Voltage, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_voltages[0]);
// Initialize the flow sensor
_flows[0] = new Sensor("Flow", 0, SensorType.Flow, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_flows[0]);
// Initialize the 4 fan voltage sensors
for (int i = 1; i < 5; i++)
{
_voltages[i] = new Sensor($"Fan {i}", i, SensorType.Voltage, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_voltages[i]);
}
// Initialize the 4 fan current sensors
for (int i = 0; i < 4; i++)
{
_currents[i] = new Sensor($"Fan {i+1}", i, SensorType.Current, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_currents[i]);
}
// Initialize the 4 fan power sensors
for (int i = 0; i < 4; i++)
{
_powers[i] = new Sensor($"Fan {i+1}", i, SensorType.Power, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_powers[i]);
}
// Initialize the 4 fan speed sensors
for (int i = 0; i < 4; i++)
{
_rpmSensors[i] = new Sensor($"Fan {i + 1}", i, SensorType.Fan, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_rpmSensors[i]);
}
}
}
public ushort FirmwareVersion { get; }
public override HardwareType HardwareType
{
get { return HardwareType.Cooler; }
}
public override void Close()
{
_stream.Close();
base.Close();
}
public override void Update()
{
//Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
_temperatures[0].Value = GetConvertedValue(QuadroDataIndexes.TEMP_1) / 100f; // Temp 1
_temperatures[1].Value = GetConvertedValue(QuadroDataIndexes.TEMP_2) / 100f; // Temp 2
_temperatures[2].Value = GetConvertedValue(QuadroDataIndexes.TEMP_3) / 100f; // Temp 3
_temperatures[3].Value = GetConvertedValue(QuadroDataIndexes.TEMP_4) / 100f; // Temp 4
_voltages[0].Value = GetConvertedValue(QuadroDataIndexes.VOLTAGE) / 100f; // Input voltage
_flows[0].Value = GetConvertedValue(QuadroDataIndexes.FLOW) / 10f; // Flow
_voltages[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_1) / 100f; // Fan 1 voltage
_voltages[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_2) / 100f; // Fan 2 voltage
_voltages[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_3) / 100f; // Fan 3 voltage
_voltages[4].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_4) / 100f; // Fan 4 voltage
_currents[0].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_1) / 1000f; // Fan 1 current
_currents[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_2) / 1000f; // Fan 2 current
_currents[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_3) / 1000f; // Fan 3 current
_currents[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_4) / 1000f; // Fan 4 current
_powers[0].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_1) / 100f; // Fan 1 power
_powers[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_2) / 100f; // Fan 2 power
_powers[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_3) / 100f; // Fan 3 power
_powers[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_4) / 100f; // Fan 4 power
_rpmSensors[0].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_1); // Fan 1 speed
_rpmSensors[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_2); // Fan 2 speed
_rpmSensors[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_3); // Fan 3 speed
_rpmSensors[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_4); // Fan 4 speed
}
private sealed class QuadroDataIndexes
{
public const int FIRMWARE_VERSION = 13;
public const int TEMP_1 = 52;
public const int TEMP_2 = 54;
public const int TEMP_3 = 56;
public const int TEMP_4 = 58;
public const int VOLTAGE = 108;
public const int FLOW = 110;
public const int FAN_VOLTAGE_1 = 114;
public const int FAN_VOLTAGE_2 = 127;
public const int FAN_VOLTAGE_3 = 140;
public const int FAN_VOLTAGE_4 = 153;
public const int FAN_CURRENT_1 = 116;
public const int FAN_CURRENT_2 = 129;
public const int FAN_CURRENT_3 = 142;
public const int FAN_CURRENT_4 = 155;
public const int FAN_POWER_1 = 118;
public const int FAN_POWER_2 = 131;
public const int FAN_POWER_3 = 144;
public const int FAN_POWER_4 = 157;
public const int FAN_SPEED_1 = 120;
public const int FAN_SPEED_2 = 133;
public const int FAN_SPEED_3 = 146;
public const int FAN_SPEED_4 = 159;
}
private ushort? GetConvertedValue(int index)
{
if (_rawData[index] == sbyte.MaxValue)
return null;
return Convert.ToUInt16(_rawData[index + 1] | (_rawData[index] << 8));
}
}
// 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) LibreHardwareMonitor and Contributors.
// All Rights Reserved.
using System;
using HidSharp;
namespace LibreHardwareMonitor.Hardware.Controller.AquaComputer;
internal sealed class Quadro : Hardware
{
private readonly byte[] _rawData = new byte[210];
private readonly HidStream _stream;
private readonly Sensor[] _rpmSensors = new Sensor[4];
private readonly Sensor[] _temperatures = new Sensor[4];
private readonly Sensor[] _voltages = new Sensor[5];
private readonly Sensor[] _currents = new Sensor[4];
private readonly Sensor[] _powers = new Sensor[4];
private readonly Sensor[] _flows = new Sensor[1];
public Quadro(HidDevice dev, ISettings settings) : base("Quadro", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
//Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
Name = "QUADRO";
FirmwareVersion = GetConvertedValue(QuadroDataIndexes.FIRMWARE_VERSION).GetValueOrDefault(0);
// Initialize the 4 temperature sensors
for (int i = 0; i < 4; i++)
{
_temperatures[i] = new Sensor($"Temperature {i + 1}", i, SensorType.Temperature, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_temperatures[i]);
}
// Initialize the input voltage sensor
_voltages[0] = new Sensor("Input", 0, SensorType.Voltage, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_voltages[0]);
// Initialize the flow sensor
_flows[0] = new Sensor("Flow", 0, SensorType.Flow, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_flows[0]);
// Initialize the 4 fan voltage sensors
for (int i = 1; i < 5; i++)
{
_voltages[i] = new Sensor($"Fan {i}", i, SensorType.Voltage, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_voltages[i]);
}
// Initialize the 4 fan current sensors
for (int i = 0; i < 4; i++)
{
_currents[i] = new Sensor($"Fan {i + 1}", i, SensorType.Current, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_currents[i]);
}
// Initialize the 4 fan power sensors
for (int i = 0; i < 4; i++)
{
_powers[i] = new Sensor($"Fan {i + 1}", i, SensorType.Power, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_powers[i]);
}
// Initialize the 4 fan speed sensors
for (int i = 0; i < 4; i++)
{
_rpmSensors[i] = new Sensor($"Fan {i + 1}", i, SensorType.Fan, this, Array.Empty<ParameterDescription>(), settings);
ActivateSensor(_rpmSensors[i]);
}
}
}
public ushort FirmwareVersion { get; }
public override HardwareType HardwareType
{
get { return HardwareType.Cooler; }
}
public override void Close()
{
_stream.Close();
base.Close();
}
public override void Update()
{
//Reading output report instead of feature report, as the measurements are in the output report
_stream.Read(_rawData);
_temperatures[0].Value = GetConvertedValue(QuadroDataIndexes.TEMP_1) / 100f; // Temp 1
_temperatures[1].Value = GetConvertedValue(QuadroDataIndexes.TEMP_2) / 100f; // Temp 2
_temperatures[2].Value = GetConvertedValue(QuadroDataIndexes.TEMP_3) / 100f; // Temp 3
_temperatures[3].Value = GetConvertedValue(QuadroDataIndexes.TEMP_4) / 100f; // Temp 4
_voltages[0].Value = GetConvertedValue(QuadroDataIndexes.VOLTAGE) / 100f; // Input voltage
_flows[0].Value = GetConvertedValue(QuadroDataIndexes.FLOW) / 10f; // Flow
_voltages[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_1) / 100f; // Fan 1 voltage
_voltages[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_2) / 100f; // Fan 2 voltage
_voltages[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_3) / 100f; // Fan 3 voltage
_voltages[4].Value = GetConvertedValue(QuadroDataIndexes.FAN_VOLTAGE_4) / 100f; // Fan 4 voltage
_currents[0].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_1) / 1000f; // Fan 1 current
_currents[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_2) / 1000f; // Fan 2 current
_currents[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_3) / 1000f; // Fan 3 current
_currents[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_CURRENT_4) / 1000f; // Fan 4 current
_powers[0].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_1) / 100f; // Fan 1 power
_powers[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_2) / 100f; // Fan 2 power
_powers[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_3) / 100f; // Fan 3 power
_powers[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_POWER_4) / 100f; // Fan 4 power
_rpmSensors[0].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_1); // Fan 1 speed
_rpmSensors[1].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_2); // Fan 2 speed
_rpmSensors[2].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_3); // Fan 3 speed
_rpmSensors[3].Value = GetConvertedValue(QuadroDataIndexes.FAN_SPEED_4); // Fan 4 speed
}
private sealed class QuadroDataIndexes
{
public const int FIRMWARE_VERSION = 13;
public const int TEMP_1 = 52;
public const int TEMP_2 = 54;
public const int TEMP_3 = 56;
public const int TEMP_4 = 58;
public const int VOLTAGE = 108;
public const int FLOW = 110;
public const int FAN_VOLTAGE_1 = 114;
public const int FAN_VOLTAGE_2 = 127;
public const int FAN_VOLTAGE_3 = 140;
public const int FAN_VOLTAGE_4 = 153;
public const int FAN_CURRENT_1 = 116;
public const int FAN_CURRENT_2 = 129;
public const int FAN_CURRENT_3 = 142;
public const int FAN_CURRENT_4 = 155;
public const int FAN_POWER_1 = 118;
public const int FAN_POWER_2 = 131;
public const int FAN_POWER_3 = 144;
public const int FAN_POWER_4 = 157;
public const int FAN_SPEED_1 = 120;
public const int FAN_SPEED_2 = 133;
public const int FAN_SPEED_3 = 146;
public const int FAN_SPEED_4 = 159;
}
private ushort? GetConvertedValue(int index)
{
if (_rawData[index] == sbyte.MaxValue)
return null;
return Convert.ToUInt16(_rawData[index + 1] | (_rawData[index] << 8));
}
}
@@ -33,7 +33,7 @@ internal sealed class GridV3 : Hardware
private readonly HidStream _stream;
private readonly Sensor[] _voltages = new Sensor[FANS_COUNT];
public GridV3(HidDevice dev, ISettings settings) : base("NZXT GRID+ V3", new Identifier(dev.DevicePath), settings)
public GridV3(HidDevice dev, ISettings settings) : base("NZXT GRID+ V3", new Identifier(dev), settings)
{
if (dev.TryOpen(out _stream))
{
@@ -25,7 +25,7 @@ internal sealed class KrakenV2 : Hardware
private DateTime _lastUpdate = DateTime.MinValue;
public KrakenV2(HidDevice dev, ISettings settings) : base("Nzxt Kraken X", new Identifier(dev.DevicePath), settings)
public KrakenV2(HidDevice dev, ISettings settings) : base("Nzxt Kraken X", new Identifier(dev), settings)
{
_device = dev;
@@ -25,7 +25,7 @@ internal sealed class KrakenV3 : Hardware
private volatile bool _controllingFans;
private volatile bool _controllingPump;
public KrakenV3(HidDevice dev, ISettings settings) : base("Nzxt Kraken Z", new Identifier(dev.DevicePath), settings)
public KrakenV3(HidDevice dev, ISettings settings) : base("Nzxt Kraken Z", new Identifier(dev), settings)
{
switch (dev.ProductID)
{
@@ -29,7 +29,7 @@ internal sealed class RazerFanController : Hardware
private readonly Sensor[] _pwmControls = new Sensor[CHANNEL_COUNT];
private readonly Sensor[] _rpmSensors = new Sensor[CHANNEL_COUNT];
public RazerFanController(HidDevice dev, ISettings settings) : base("Razer PWM PC Fan Controller", new Identifier(dev.DevicePath), settings)
public RazerFanController(HidDevice dev, ISettings settings) : base("Razer PWM PC Fan Controller", new Identifier(dev), settings)
{
_device = dev;
@@ -220,13 +220,18 @@ internal sealed class IntelCpu : GenericCpu
case 0xA7: // Intel Core i5, i6, i7 11xxx (14nm) (Rocket Lake)
_microArchitecture = MicroArchitecture.RocketLake;
tjMax = GetTjMaxFromMsr();
break;
break;
case 0xC6: // Intel Core Ultra 7 200 Series ArrowLake
_microArchitecture = MicroArchitecture.ArrowLake;
tjMax = GetTjMaxFromMsr();
break;
break;
case 0xBD: // Intel Core Ultra 5/7 200 Series LunarLake
_microArchitecture = MicroArchitecture.LunarLake;
tjMax = GetTjMaxFromMsr();
break;
default:
_microArchitecture = MicroArchitecture.Unknown;
tjMax = Floats(100);
@@ -272,7 +277,7 @@ internal sealed class IntelCpu : GenericCpu
break;
case MicroArchitecture.Airmont:
case MicroArchitecture.AlderLake:
case MicroArchitecture.AlderLake:
case MicroArchitecture.ArrowLake:
case MicroArchitecture.Broadwell:
case MicroArchitecture.CannonLake:
@@ -284,6 +289,7 @@ internal sealed class IntelCpu : GenericCpu
case MicroArchitecture.IvyBridge:
case MicroArchitecture.JasperLake:
case MicroArchitecture.KabyLake:
case MicroArchitecture.LunarLake:
case MicroArchitecture.Nehalem:
case MicroArchitecture.MeteorLake:
case MicroArchitecture.RaptorLake:
@@ -304,6 +310,24 @@ internal sealed class IntelCpu : GenericCpu
int coreSensorId = 0;
//core temp avg and max value
//is only available when the cpu has more than 1 core
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown && _coreCount > 1)
{
_coreMax = new Sensor("Core Max", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_coreMax);
coreSensorId++;
_coreAvg = new Sensor("Core Average", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_coreAvg);
coreSensorId++;
}
else
{
_coreMax = null;
_coreAvg = null;
}
// check if processor supports a digital thermal sensor at core level
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown)
{
@@ -360,23 +384,6 @@ internal sealed class IntelCpu : GenericCpu
else
_distToTjMaxTemperatures = Array.Empty<Sensor>();
//core temp avg and max value
//is only available when the cpu has more than 1 core
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown && _coreCount > 1)
{
_coreMax = new Sensor("Core Max", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_coreMax);
coreSensorId++;
_coreAvg = new Sensor("Core Average", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_coreAvg);
}
else
{
_coreMax = null;
_coreAvg = null;
}
_busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
_coreClocks = new Sensor[_coreCount];
for (int i = 0; i < _coreClocks.Length; i++)
@@ -387,7 +394,7 @@ internal sealed class IntelCpu : GenericCpu
}
if (_microArchitecture is MicroArchitecture.Airmont or
MicroArchitecture.AlderLake or
MicroArchitecture.AlderLake or
MicroArchitecture.ArrowLake or
MicroArchitecture.Broadwell or
MicroArchitecture.CannonLake or
@@ -399,6 +406,7 @@ internal sealed class IntelCpu : GenericCpu
MicroArchitecture.IvyBridge or
MicroArchitecture.JasperLake or
MicroArchitecture.KabyLake or
MicroArchitecture.LunarLake or
MicroArchitecture.MeteorLake or
MicroArchitecture.RaptorLake or
MicroArchitecture.RocketLake or
@@ -602,6 +610,7 @@ internal sealed class IntelCpu : GenericCpu
case MicroArchitecture.IvyBridge:
case MicroArchitecture.JasperLake:
case MicroArchitecture.KabyLake:
case MicroArchitecture.LunarLake:
case MicroArchitecture.MeteorLake:
case MicroArchitecture.RaptorLake:
case MicroArchitecture.RocketLake:
@@ -609,7 +618,7 @@ internal sealed class IntelCpu : GenericCpu
case MicroArchitecture.Silvermont:
case MicroArchitecture.Skylake:
case MicroArchitecture.TigerLake:
case MicroArchitecture.Tremont:
case MicroArchitecture.Tremont:
_coreClocks[i].Value = (float)(((eax >> 8) & 0xff) * newBusClock);
break;
default:
@@ -690,6 +699,7 @@ internal sealed class IntelCpu : GenericCpu
IvyBridge,
JasperLake,
KabyLake,
LunarLake,
Nehalem,
NetBurst,
MeteorLake,
@@ -391,13 +391,14 @@ internal sealed class NvidiaGpu : GenericGpu
if (isMatch && D3DDisplayDevice.GetDeviceInfoByIdentifier(deviceId, out D3DDisplayDevice.D3DDeviceInfo deviceInfo))
{
int nodeSensorIndex = (_loads?.Length ?? 0) + (_powers?.Length ?? 0);
int memorySensorIndex = 4; // There are 4 normal GPU memory sensors.
int sensorCount = (_loads?.Length ?? 0) + (_powers?.Length ?? 0);
int loadSensorIndex = sensorCount > 0 ? sensorCount + 1 : 0;
int smallDataSensorIndex = 3; // There are three normal GPU memory sensors.
_d3dDeviceId = deviceId;
_gpuDedicatedMemoryUsage = new Sensor("D3D Dedicated Memory Used", memorySensorIndex++, SensorType.SmallData, this, settings);
_gpuSharedMemoryUsage = new Sensor("D3D Shared Memory Used", memorySensorIndex, SensorType.SmallData, this, settings);
_gpuDedicatedMemoryUsage = new Sensor("D3D Dedicated Memory Used", smallDataSensorIndex++, SensorType.SmallData, this, settings);
_gpuSharedMemoryUsage = new Sensor("D3D Shared Memory Used", smallDataSensorIndex, SensorType.SmallData, this, settings);
_gpuNodeUsage = new Sensor[deviceInfo.Nodes.Length];
_gpuNodeUsagePrevValue = new long[deviceInfo.Nodes.Length];
@@ -405,7 +406,7 @@ internal sealed class NvidiaGpu : GenericGpu
foreach (D3DDisplayDevice.D3DDeviceNodeInfo node in deviceInfo.Nodes.OrderBy(x => x.Name))
{
_gpuNodeUsage[node.Id] = new Sensor(node.Name, nodeSensorIndex++, SensorType.Load, this, settings);
_gpuNodeUsage[node.Id] = new Sensor(node.Name, loadSensorIndex++, SensorType.Load, this, settings);
_gpuNodeUsagePrevValue[node.Id] = node.RunningTime;
_gpuNodeUsagePrevTick[node.Id] = node.QueryTime;
}
+32 -3
View File
@@ -6,6 +6,7 @@
using System;
using System.Text;
using HidSharp;
namespace LibreHardwareMonitor.Hardware;
@@ -49,6 +50,35 @@ public class Identifier : IComparable<Identifier>
_identifier = s.ToString();
}
/// <summary>
/// Creates a new identifier instance based on the supplied <see cref="HidDevice" />.
/// If available the identifier will consist of the vendor-id, product-id and serial number of the HidDevice.
/// Alternatively a platform dependent identifier based on the usb device-path is generated.
/// </summary>
/// <param name="dev">The <see cref="HidDevice" /> this identifier will be created for.</param>
public Identifier(HidDevice dev)
{
string[] identifiers;
try
{
identifiers = ["usbhid", dev.VendorID.ToString("X4"), dev.ProductID.ToString("X4"), dev.GetSerialNumber()];
}
catch
{
identifiers = ["usbhid", dev.DevicePath];
}
CoerceIdentifiers(identifiers);
StringBuilder s = new();
for (int i = 0; i < identifiers.Length; i++)
{
s.Append(Separator);
s.Append(identifiers[i]);
}
_identifier = s.ToString();
}
/// <inheritdoc />
public int CompareTo(Identifier other)
{
@@ -65,8 +95,7 @@ public class Identifier : IComparable<Identifier>
for (int i = 0; i < identifiers.Length; i++)
{
string s = identifiers[i];
if (s.IndexOf(' ') >= 0)
identifiers[i] = s.Replace(' ', '-');
identifiers[i] = Uri.EscapeDataString(identifiers[i]);
}
}
@@ -123,4 +152,4 @@ public class Identifier : IComparable<Identifier>
return id1.CompareTo(id2) > 0;
}
}
}
@@ -581,6 +581,8 @@ internal class Identification
case var _ when name.Equals("B650M-CX", StringComparison.OrdinalIgnoreCase):
case var _ when name.Equals("B650M-CWX", StringComparison.OrdinalIgnoreCase):
return Model.B650M_C;
case var _ when name.Equals("B650M GAMING PLUS WIFI (MS-7E24)", StringComparison.OrdinalIgnoreCase):
return Model.B650M_Gaming_Plus_Wifi;
case var _ when name.Equals("B660 DS3H DDR4-Y1",StringComparison.OrdinalIgnoreCase):
case var _ when name.Equals("B660 DS3H DDR4",StringComparison.OrdinalIgnoreCase):
return Model.B660_DS3H_DDR4;
@@ -597,10 +599,16 @@ internal class Identification
return Model.X570_Gaming_Plus;
case var _ when name.Equals("ROG MAXIMUS Z790 FORMULA", StringComparison.OrdinalIgnoreCase):
return Model.ROG_MAXIMUS_Z790_FORMULA;
case var _ when name.Equals("Z790 Nova WiFi", StringComparison.OrdinalIgnoreCase):
return Model.Z790_Nova_WiFi;
case var _ when name.Equals("ROG MAXIMUS XII HERO (WI-FI)", StringComparison.OrdinalIgnoreCase):
return Model.ROG_MAXIMUS_XII_HERO_WIFI;
case var _ when name.Equals("X870E AORUS PRO", StringComparison.OrdinalIgnoreCase):
return Model.X870E_AORUS_PRO;
case var _ when name.Equals("X870E AORUS PRO ICE", StringComparison.OrdinalIgnoreCase):
return Model.X870E_AORUS_PRO_ICE;
case var _ when name.Equals("PROART B760-CREATOR D4", StringComparison.OrdinalIgnoreCase):
return Model.PROART_B760_CREATOR_D4;
return Model.PROART_B760_CREATOR_D4;
case var _ when name.Equals("Base Board Product Name", StringComparison.OrdinalIgnoreCase):
case var _ when name.Equals("To be filled by O.E.M.", StringComparison.OrdinalIgnoreCase):
return Model.Unknown;
+2
View File
@@ -37,6 +37,7 @@ internal enum Chip : ushort
IT8686E = 0x8686,
IT8688E = 0x8688,
IT8689E = 0x8689,
IT8696E = 0x8696,
IT8705F = 0x8705,
IT8712F = 0x8712,
IT8716F = 0x8716,
@@ -109,6 +110,7 @@ internal class ChipName
case Chip.IT8686E: return "ITE IT8686E";
case Chip.IT8688E: return "ITE IT8688E";
case Chip.IT8689E: return "ITE IT8689E";
case Chip.IT8696E: return "ITE IT8696E";
case Chip.IT8705F: return "ITE IT8705F";
case Chip.IT8712F: return "ITE IT8712F";
case Chip.IT8716F: return "ITE IT8716F";
@@ -228,10 +228,12 @@ public abstract class EmbeddedController : Hardware
ECSensor.FanWaterFlow),
new(Model.ROG_MAXIMUS_Z790_HERO,
BoardFamily.Intel700,
ECSensor.TempVrm,
ECSensor.TempTSensor,
ECSensor.TempWaterIn,
ECSensor.TempWaterOut,
ECSensor.FanWaterFlow),
ECSensor.FanWaterFlow,
ECSensor.FanCPUOpt),
new(Model.ROG_MAXIMUS_Z790_DARK_HERO,
BoardFamily.Intel700,
ECSensor.TempVrm,
+11 -3
View File
@@ -98,7 +98,8 @@ internal class IT87XX : ISuperIO
Chip.IT8613E or
Chip.IT8792E or
Chip.IT8655E or
Chip.IT8631E;
Chip.IT8631E or
Chip.IT8696E;
switch (chip)
{
@@ -158,8 +159,15 @@ internal class IT87XX : ISuperIO
Controls = new float?[6];
break;
case Chip.IT8696E:
Voltages = new float?[10];
Temperatures = new float?[6];
Fans = new float?[6];
Controls = new float?[6];
break;
case Chip.IT87952E:
Voltages = new float?[6];
Voltages = new float?[10];
Temperatures = new float?[3];
Fans = new float?[3];
Controls = new float?[3];
@@ -208,7 +216,7 @@ internal class IT87XX : ISuperIO
// Conflicting reports on IT8792E: either 0.0109 in linux drivers or 0.011 comparing with Gigabyte board & SIV SW.
_voltageGain = chip switch
{
Chip.IT8613E or Chip.IT8620E or Chip.IT8628E or Chip.IT8631E or Chip.IT8721F or Chip.IT8728F or Chip.IT8771E or Chip.IT8772E or Chip.IT8686E or Chip.IT8688E or Chip.IT8689E => 0.012f,
Chip.IT8613E or Chip.IT8620E or Chip.IT8628E or Chip.IT8631E or Chip.IT8721F or Chip.IT8728F or Chip.IT8771E or Chip.IT8772E or Chip.IT8686E or Chip.IT8688E or Chip.IT8689E or Chip.IT8696E => 0.012f,
Chip.IT8625E or Chip.IT8792E or Chip.IT87952E => 0.011f,
Chip.IT8655E or Chip.IT8665E => 0.0109f,
_ => 0.016f
@@ -45,14 +45,71 @@ internal class IsaBridgeGigabyteController : IGigabyteController
/// <returns>true on success</returns>
public bool Enable(bool enabled)
{
// TODO: Intel
return _vendor switch
{
Vendor.Intel => IntelEnable(enabled),
Vendor.AMD => AmdEnable(enabled),
_ => false
};
}
private bool IntelEnable(bool enabled)
{
if (!Mutexes.WaitPciBus(10))
return false;
bool result = false;
uint intelIsaBridgeAddress = Ring0.GetPciAddress(0x0, 0x1F, 0x0);
const uint ioOrMemoryPortDecodeEnableRegister = 0xD8;
const uint romAddressRange2Register = 0x98;
uint controllerFanControlAddress = _controllerBaseAddress + ControllerFanControlArea;
Ring0.ReadPciConfig(intelIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, out uint originalDecodeEnableRegister);
Ring0.ReadPciConfig(intelIsaBridgeAddress, romAddressRange2Register, out uint originalRomAddressRegister);
bool originalMmIoEnabled = false;
if (!enabled)
{
originalMmIoEnabled = ((int)originalDecodeEnableRegister & 1) == 0 || ((int)originalRomAddressRegister & 1) == 1;
}
else
{
originalMmIoEnabled = ((int)originalDecodeEnableRegister & 1) == 0 && ((int)originalRomAddressRegister & 1) == 1;
}
if (enabled == originalMmIoEnabled)
{
result = Enable(enabled, new IntPtr(controllerFanControlAddress));
Mutexes.ReleasePciBus();
return result;
}
uint lpcBiosDecodeEnable;
uint lpcMemoryRange;
if (enabled)
{
lpcBiosDecodeEnable = ioOrMemoryPortDecodeEnableRegister & ~(uint)(1 << 0);
lpcMemoryRange = romAddressRange2Register | (uint)(1 << 0);
}
else
{
lpcBiosDecodeEnable = Convert.ToUInt32(ioOrMemoryPortDecodeEnableRegister | (uint)(1 << 0));
lpcMemoryRange = Convert.ToUInt32(romAddressRange2Register & ~(uint)(1 << 0));
}
Ring0.WritePciConfig(intelIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, lpcBiosDecodeEnable);
Ring0.WritePciConfig(intelIsaBridgeAddress, romAddressRange2Register, lpcMemoryRange);
result = Enable(enabled, new IntPtr(controllerFanControlAddress));
Mutexes.ReleasePciBus();
return result;
}
private bool AmdEnable(bool enabled)
{
if (!Mutexes.WaitPciBus(10))
@@ -557,6 +557,7 @@ internal class LpcIO
0x8686 => Chip.IT8686E,
0x8688 => Chip.IT8688E,
0x8689 => Chip.IT8689E,
0x8696 => Chip.IT8696E,
0x8705 => Chip.IT8705F,
0x8712 => Chip.IT8712F,
0x8716 => Chip.IT8716F,
+4
View File
@@ -39,6 +39,7 @@ public enum Model
Z790_Pro_RS,
X570_Phantom_Gaming_4,
Z790_Taichi,
Z790_Nova_WiFi,
B650M_C,
H61M_DGS,
@@ -127,6 +128,7 @@ public enum Model
B360M_PRO_VDH,
B450A_PRO,
B550A_PRO,
B650M_Gaming_Plus_Wifi,
Z270_PC_MATE,
Z77_MS7751,
Z68_MS7672,
@@ -249,6 +251,8 @@ public enum Model
B650M_AORUS_PRO_AX,
B650M_AORUS_ELITE,
B650M_AORUS_ELITE_AX,
X870E_AORUS_PRO,
X870E_AORUS_PRO_ICE,
// Shuttle
FH67,
+175 -8
View File
@@ -36,6 +36,7 @@ internal sealed class SuperIOHardware : Hardware
GetBoardSpecificConfiguration(superIO,
manufacturer,
model,
index,
out IList<Voltage> v,
out IList<Temperature> t,
out IList<Fan> f,
@@ -181,6 +182,7 @@ internal sealed class SuperIOHardware : Hardware
ISuperIO superIO,
Manufacturer manufacturer,
Model model,
int superIOIndex,
out IList<Voltage> v,
out IList<Temperature> t,
out IList<Fan> f,
@@ -226,6 +228,7 @@ internal sealed class SuperIOHardware : Hardware
case Chip.IT8686E:
case Chip.IT8688E:
case Chip.IT8689E:
case Chip.IT8696E:
case Chip.IT8721F:
case Chip.IT8728F:
case Chip.IT8771E:
@@ -352,7 +355,7 @@ internal sealed class SuperIOHardware : Hardware
case Chip.NCT6798D:
case Chip.NCT6799D:
case Chip.NCT6683D:
GetNuvotonConfigurationD(superIO, manufacturer, model, v, t, f, c);
GetNuvotonConfigurationD(superIO, manufacturer, model, superIOIndex, v, t, f, c);
break;
case Chip.NCT6686D:
@@ -418,6 +421,39 @@ internal sealed class SuperIOHardware : Hardware
c.Add(new Control("System Fan #6", 7));
break;
case Manufacturer.MSI when model == Model.B650M_Gaming_Plus_Wifi: // NCT6687D
v.Add(new Voltage("+12V", 0));
v.Add(new Voltage("+5V", 1));
v.Add(new Voltage("CPU Northbridge/SoC", 2));
v.Add(new Voltage("CPU VDDIO", 3, 1, 1, 0));
v.Add(new Voltage("Vcore", 4, -1, 2, 0));
v.Add(new Voltage("+3.3V", 8));
v.Add(new Voltage("+3V Standby", 11));
v.Add(new Voltage("AVSB", 12));
v.Add(new Voltage("CPU Termination", 9));
v.Add(new Voltage("CMOS Battery", 13));
t.Add(new Temperature("CPU", 0));
t.Add(new Temperature("System", 1));
t.Add(new Temperature("VRM MOS", 2));
t.Add(new Temperature("Chipset", 3));
t.Add(new Temperature("CPU Socket", 4));
f.Add(new Fan("CPU Fan", 0));
f.Add(new Fan("CPU Pump Fan", 1));
f.Add(new Fan("System Fan #1", 2));
f.Add(new Fan("System Fan #2", 3));
f.Add(new Fan("System Fan #3", 4));
c.Add(new Control("CPU Fan", 0));
c.Add(new Control("CPU Pump Fan", 1));
c.Add(new Control("System Fan #1", 2));
c.Add(new Control("System Fan #2", 3));
c.Add(new Control("System Fan #3", 4));
break;
default:
v.Add(new Voltage("+12V", 0));
v.Add(new Voltage("+5V", 1));
@@ -1790,8 +1826,6 @@ internal sealed class SuperIOHardware : Hardware
case Model.Z790_UD: // ITE IT8689E
case Model.Z790_UD_AC: // ITE IT8689E
case Model.Z790_GAMING_X: // ITE IT8689E
case Model.Z790_GAMING_X_AX: // ITE IT8689E
v.Add(new Voltage("Vcore", 0));
v.Add(new Voltage("+3.3V", 1, 6.49f, 10));
v.Add(new Voltage("+12V", 2, 5f, 1));
@@ -1820,6 +1854,38 @@ internal sealed class SuperIOHardware : Hardware
c.Add(new Control("CPU Optional Fan", 4));
break;
case Model.Z790_GAMING_X: // ITE IT8689E
case Model.Z790_GAMING_X_AX: // ITE IT8689E
v.Add(new Voltage("Vcore", 0));
v.Add(new Voltage("+3.3V", 1, 6.49f, 10));
v.Add(new Voltage("+12V", 2, 5f, 1));
v.Add(new Voltage("+5V", 3, 1.5f, 1));
v.Add(new Voltage("iGPU", 4));
v.Add(new Voltage("CPU Input Auxiliary", 5));
v.Add(new Voltage("Dual DDR5 5V", 6, 1.5f, 1));
v.Add(new Voltage("+3V Standby", 7, 1, 1));
v.Add(new Voltage("CMOS Battery", 8, 1, 1));
v.Add(new Voltage("AVCC3", 9, true));
t.Add(new Temperature("System #1", 0));
t.Add(new Temperature("Chipset", 1));
t.Add(new Temperature("CPU", 2));
t.Add(new Temperature("PCIe x16", 3));
t.Add(new Temperature("VRM MOS", 4));
t.Add(new Temperature("System #2", 5));
f.Add(new Fan("CPU Fan", 0));
f.Add(new Fan("System Fan #1", 1));
f.Add(new Fan("System Fan #2", 2));
f.Add(new Fan("System Fan #3", 3));
f.Add(new Fan("System Fan #4 / Pump", 4));
f.Add(new Fan("CPU Optional Fan", 5));
c.Add(new Control("CPU Fan", 0));
c.Add(new Control("System Fan #1", 1));
c.Add(new Control("System Fan #2", 2));
c.Add(new Control("System Fan #3", 3));
c.Add(new Control("System Fan #4 / Pump", 4));
c.Add(new Control("CPU Optional Fan", 5));
break;
case Model.Z790_AORUS_PRO_X: // ITE IT8689E
case Model.Z690_AORUS_PRO:
case Model.Z690_AORUS_ULTRA: // ITE IT8689E
@@ -2106,6 +2172,36 @@ internal sealed class SuperIOHardware : Hardware
break;
case Model.X870E_AORUS_PRO: // ITE IT8696E
case Model.X870E_AORUS_PRO_ICE: // ITE IT8696E
v.Add(new Voltage("Vcore", 0, 0, 1));
v.Add(new Voltage("+3.3V", 1, 6.49F, 10));
v.Add(new Voltage("+12V", 2, 5, 1));
v.Add(new Voltage("+5V", 3, 1.5F, 1));
v.Add(new Voltage("Vcore SoC", 4, 0, 1));
v.Add(new Voltage("Vcore Misc", 5, 0, 1));
v.Add(new Voltage("CPU VDDIO Memory", 6, 0, 1));
v.Add(new Voltage("+3V Standby", 7, 10, 10));
v.Add(new Voltage("CMOS Battery", 8, 10, 10));
t.Add(new Temperature("System #1", 0));
t.Add(new Temperature("PCH", 1));
t.Add(new Temperature("CPU", 2));
t.Add(new Temperature("PCIe x16", 3));
t.Add(new Temperature("VRM MOS", 4));
t.Add(new Temperature("External #1", 5));
f.Add(new Fan("CPU Fan", 0));
f.Add(new Fan("System Fan #1", 1));
f.Add(new Fan("System Fan #2", 2));
f.Add(new Fan("System Fan #3", 3));
f.Add(new Fan("CPU Optional Fan", 4));
c.Add(new Control("CPU Fan", 0));
c.Add(new Control("System Fan #1", 1));
c.Add(new Control("System Fan #2", 2));
c.Add(new Control("System Fan #3", 3));
c.Add(new Control("CPU Optional Fan", 4));
break;
default:
v.Add(new Voltage("Voltage #1", 0, true));
v.Add(new Voltage("Voltage #2", 1, true));
@@ -2379,6 +2475,28 @@ internal sealed class SuperIOHardware : Hardware
c.Add(new Control("System Fan #4", 2));
break;
case Model.X870E_AORUS_PRO:
case Model.X870E_AORUS_PRO_ICE: // ITE IT87952E
v.Add(new Voltage("VIN0", 0));
v.Add(new Voltage("Voltage #2", 1, true));
v.Add(new Voltage("PM_VCC18", 2));
v.Add(new Voltage("VIN3", 3));
v.Add(new Voltage("CPU VDD18", 4));
v.Add(new Voltage("PM_VDD1V", 5));
v.Add(new Voltage("VIN6", 6));
v.Add(new Voltage("+3V Standby", 7, 1, 1));
v.Add(new Voltage("CMOS Battery", 8, 1, 1));
t.Add(new Temperature("PCIe x4", 0));
t.Add(new Temperature("External #2", 1));
t.Add(new Temperature("System #2", 2));
f.Add(new Fan("System Fan #5 / Pump", 0));
f.Add(new Fan("System Fan #6 / Pump", 1));
f.Add(new Fan("System Fan #4 ", 2));
c.Add(new Control("System Fan #5 / Pump", 0));
c.Add(new Control("System Fan #6 / Pump", 1));
c.Add(new Control("System Fan #4", 2));
break;
default:
v.Add(new Voltage("Voltage #1", 0, true));
v.Add(new Voltage("Voltage #2", 1, true));
@@ -2816,7 +2934,7 @@ internal sealed class SuperIOHardware : Hardware
}
}
private static void GetNuvotonConfigurationD(ISuperIO superIO, Manufacturer manufacturer, Model model, IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Control> c)
private static void GetNuvotonConfigurationD(ISuperIO superIO, Manufacturer manufacturer, Model model, int index, IList<Voltage> v, IList<Temperature> t, IList<Fan> f, IList<Control> c)
{
switch (manufacturer)
{
@@ -3196,6 +3314,55 @@ internal sealed class SuperIOHardware : Hardware
c.Add(new Control("Chassis Fan #3", 6));
break;
case Model.Z790_Nova_WiFi:
if (index != 0)
{
// second SIO
v.Add(new Voltage("1.05V CPU", 0));
v.Add(new Voltage("CPU I/O", 1));
v.Add(new Voltage("0.82V Chipset", 4));
v.Add(new Voltage("1.05V Chipset", 12, 5, 100));
f.Add(new Fan("VRM", 0));
f.Add(new Fan("MOS", 1));
c.Add(new Control("VRM", 0));
c.Add(new Control("MOS", 1));
}
else
{
v.Add(new Voltage("Vcore", 0));
v.Add(new Voltage("+5V", 1, 20, 10));
v.Add(new Voltage("+3.3V", 3, 34, 34));
v.Add(new Voltage("+12V", 4, 110, 10));
v.Add(new Voltage("CPU Input Auxiliary", 5, 1, 1));
v.Add(new Voltage("CPU System Agent", 13, 1, 1));
v.Add(new Voltage("+5V Standby", 14, 235, 100));
f.Add(new Fan("Chassis #3", 0));
f.Add(new Fan("CPU #1", 1));
f.Add(new Fan("CPU #2", 2));
f.Add(new Fan("Chassis #1", 3));
f.Add(new Fan("Chassis #2", 4));
f.Add(new Fan("Chassis #4", 5));
f.Add(new Fan("Chassis #5", 6));
c.Add(new Control("Chassis #3", 0));
c.Add(new Control("CPU #1", 1));
c.Add(new Control("CPU #2", 2));
c.Add(new Control("Chassis #1", 3));
c.Add(new Control("Chassis #2", 4));
c.Add(new Control("Chassis #4", 5));
c.Add(new Control("Chassis #5", 6));
t.Add(new Temperature("CPU Core", 0));
t.Add(new Temperature("Motherboard", 2));
t.Add(new Temperature("External #1", 3));
t.Add(new Temperature("External #2", 4));
t.Add(new Temperature("External #3", 5));
}
break;
case Model.B650M_C: // NCT6799D
v.Add(new Voltage("Vcore", 0));
v.Add(new Voltage("+12V", 1, 56, 10));
@@ -3789,7 +3956,7 @@ internal sealed class SuperIOHardware : Hardware
case Model.ROG_MAXIMUS_Z790_HERO: //NCT6798D
t.Add(new Temperature("CPU Package", 0));
t.Add(new Temperature("VRM", 1));
t.Add(new Temperature("CPU", 1));
t.Add(new Temperature("Motherboard", 2));
//t.Add(new Temperature("Temperature #3", 3));
//t.Add(new Temperature("Temperature #4", 4));
@@ -3800,8 +3967,8 @@ internal sealed class SuperIOHardware : Hardware
t.Add(new Temperature("Temperature #9", 9));
t.Add(new Temperature("Temperature #10", 10));
t.Add(new Temperature("Temperature #11", 11));
t.Add(new Temperature("Chipset", 12));
t.Add(new Temperature("Temperature #13", 13));
t.Add(new Temperature("Temperature #12", 12));
t.Add(new Temperature("Chipset", 13));
t.Add(new Temperature("Temperature #14", 14));
t.Add(new Temperature("Temperature #15", 15));
t.Add(new Temperature("Temperature #16", 16));
@@ -3809,7 +3976,7 @@ internal sealed class SuperIOHardware : Hardware
t.Add(new Temperature("Temperature #18", 18));
t.Add(new Temperature("Temperature #19", 19));
t.Add(new Temperature("Temperature #20", 20));
t.Add(new Temperature("CPU", 21));
t.Add(new Temperature("Temperature #21", 21));
for (int i = 0; i < superIO.Fans.Length; i++)
f.Add(new Fan("Fan #" + (i + 1), i));
@@ -18,7 +18,11 @@ public class Kernel32
public const int ERROR_SERVICE_EXISTS = unchecked((int)0x80070431);
internal const uint BATTERY_UNKNOWN_CAPACITY = 0xFFFFFFFF;
internal const uint BATTERY_UNKNOWN_VOLTAGE = 0xFFFFFFFF;
internal const int BATTERY_UNKNOWN_RATE = unchecked((int)0x80000000);
internal const uint BATTERY_UNKNOWN_TIME = 0xFFFFFFFF;
internal const string IntelNVMeMiniPortSignature1 = "NvmeMini";
internal const string IntelNVMeMiniPortSignature2 = "IntelNvm";
@@ -35,13 +35,13 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net472'">
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
<PackageReference Include="System.IO.Ports" Version="9.0.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="HidSharp" Version="2.1.0" />
<PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="System.Management" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\packageicon.png" PackagePath="">