diff --git a/Directory.Build.props b/Directory.Build.props
index f8f9949..8257db3 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,6 +1,6 @@
- 0.9.3
+ 0.9.4
LibreHardwareMonitor
diff --git a/LibreHardwareMonitor/LibreHardwareMonitor.csproj b/LibreHardwareMonitor/LibreHardwareMonitor.csproj
index 0b9fe08..158ea57 100644
--- a/LibreHardwareMonitor/LibreHardwareMonitor.csproj
+++ b/LibreHardwareMonitor/LibreHardwareMonitor.csproj
@@ -25,7 +25,7 @@
-
+
@@ -44,8 +44,8 @@
ParameterForm.cs
-
- PortForm.cs
+
+ InterfacePortForm.cs
@@ -61,8 +61,8 @@
ParameterForm.cs
-
- PortForm.cs
+
+ InterfacePortForm.cs
diff --git a/LibreHardwareMonitor/UI/PortForm.Designer.cs b/LibreHardwareMonitor/UI/InterfacePortForm.Designer.cs
similarity index 81%
rename from LibreHardwareMonitor/UI/PortForm.Designer.cs
rename to LibreHardwareMonitor/UI/InterfacePortForm.Designer.cs
index 5672d54..b791af2 100644
--- a/LibreHardwareMonitor/UI/PortForm.Designer.cs
+++ b/LibreHardwareMonitor/UI/InterfacePortForm.Designer.cs
@@ -6,7 +6,7 @@
namespace LibreHardwareMonitor.UI
{
- partial class PortForm
+ partial class InterfacePortForm
{
///
/// Required designer variable.
@@ -34,7 +34,7 @@ namespace LibreHardwareMonitor.UI
///
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;
}
}
diff --git a/LibreHardwareMonitor/UI/PortForm.cs b/LibreHardwareMonitor/UI/InterfacePortForm.cs
similarity index 57%
rename from LibreHardwareMonitor/UI/PortForm.cs
rename to LibreHardwareMonitor/UI/InterfacePortForm.cs
index e30d57b..c02d6c8 100644
--- a/LibreHardwareMonitor/UI/PortForm.cs
+++ b/LibreHardwareMonitor/UI/InterfacePortForm.cs
@@ -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);
}
-}
\ No newline at end of file
+
+ private void interfaceComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ _localIP = interfaceComboBox.SelectedItem as string;
+ PortNumericUpDn_ValueChanged(null, null);
+ }
+}
diff --git a/LibreHardwareMonitor/UI/PortForm.resx b/LibreHardwareMonitor/UI/InterfacePortForm.resx
similarity index 100%
rename from LibreHardwareMonitor/UI/PortForm.resx
rename to LibreHardwareMonitor/UI/InterfacePortForm.resx
diff --git a/LibreHardwareMonitor/UI/MainForm.Designer.cs b/LibreHardwareMonitor/UI/MainForm.Designer.cs
index 1291b25..e7785cd 100644
--- a/LibreHardwareMonitor/UI/MainForm.Designer.cs
+++ b/LibreHardwareMonitor/UI/MainForm.Designer.cs
@@ -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;
diff --git a/LibreHardwareMonitor/UI/MainForm.cs b/LibreHardwareMonitor/UI/MainForm.cs
index f1b9a13..45bacab 100644
--- a/LibreHardwareMonitor/UI/MainForm.cs
+++ b/LibreHardwareMonitor/UI/MainForm.cs
@@ -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)
diff --git a/LibreHardwareMonitor/Utilities/HttpServer.cs b/LibreHardwareMonitor/Utilities/HttpServer.cs
index 14d0d19..a975ffa 100644
--- a/LibreHardwareMonitor/Utilities/HttpServer.cs
+++ b/LibreHardwareMonitor/Utilities/HttpServer.cs
@@ -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 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();
}
diff --git a/LibreHardwareMonitorLib/Hardware/Battery/Battery.cs b/LibreHardwareMonitorLib/Hardware/Battery/Battery.cs
index a5c363b..f54e9ec 100644
--- a/LibreHardwareMonitorLib/Hardware/Battery/Battery.cs
+++ b/LibreHardwareMonitorLib/Hardware/Battery/Battery.cs
@@ -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(),
+ 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()
diff --git a/LibreHardwareMonitorLib/Hardware/Battery/BatteryGroup.cs b/LibreHardwareMonitorLib/Hardware/Battery/BatteryGroup.cs
index 4cdc35c..fc22616 100644
--- a/LibreHardwareMonitorLib/Hardware/Battery/BatteryGroup.cs
+++ b/LibreHardwareMonitorLib/Hardware/Battery/BatteryGroup.cs
@@ -17,6 +17,35 @@ internal class BatteryGroup : IGroup
{
private readonly List _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++;
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs b/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs
index 2be3f88..28e63ad 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AeroCool/P7-H1.cs
@@ -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];
}
}
-}
\ No newline at end of file
+}
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamUltimate.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamUltimate.cs
index 5e2da3b..26c380a 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamUltimate.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamUltimate.cs
@@ -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(), settings);
ActivateSensor(_temperatures[0]);
-
+
_temperatures[1] = new Sensor("External Sensor", 1, SensorType.Temperature, this, Array.Empty(), 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));
- }
+ }
}
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs
index 9e3b820..a04e240 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/AquastreamXT.cs
@@ -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;
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/D5Next.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/D5Next.cs
index f429563..e6092e0 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/D5Next.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/D5Next.cs
@@ -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))
{
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Farbwerk.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Farbwerk.cs
index 3aaf087..dfef6bd 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Farbwerk.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Farbwerk.cs
@@ -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))
{
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/HighFlowNext.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/HighFlowNext.cs
index 8e0e389..f25872c 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/HighFlowNext.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/HighFlowNext.cs
@@ -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
{
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs
index ea39fad..4db7054 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/MPS.cs
@@ -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))
{
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Octo.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Octo.cs
index 5acc104..0eac4b8 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Octo.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Octo.cs
@@ -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(), settings);
+ _temperatures[i] = new Sensor($"Temperature {i + 1}", i, SensorType.Temperature, this, Array.Empty(), 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(), settings);
+ _rpmSensors[i] = new Sensor($"Fan {i + 1}", i, SensorType.Fan, this, Array.Empty(), settings);
ActivateSensor(_rpmSensors[i]);
}
-
+
// Initialize the input voltage sensor
_voltages[0] = new Sensor("Input", 0, SensorType.Voltage, this, Array.Empty(), 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(), 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(), settings);
+ _currents[i] = new Sensor($"Fan {i + 1}", i, SensorType.Current, this, Array.Empty(), 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(), settings);
+ _powers[i] = new Sensor($"Fan {i + 1}", i, SensorType.Power, this, Array.Empty(), 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));
}
-}
\ No newline at end of file
+}
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Quadro.cs b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Quadro.cs
index e3216d2..13f37e4 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Quadro.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/AquaComputer/Quadro.cs
@@ -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(), settings);
- ActivateSensor(_temperatures[i]);
- }
-
- // Initialize the input voltage sensor
- _voltages[0] = new Sensor("Input", 0, SensorType.Voltage, this, Array.Empty(), settings);
- ActivateSensor(_voltages[0]);
-
- // Initialize the flow sensor
- _flows[0] = new Sensor("Flow", 0, SensorType.Flow, this, Array.Empty(), 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(), 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(), 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(), 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(), 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(), settings);
+ ActivateSensor(_temperatures[i]);
+ }
+
+ // Initialize the input voltage sensor
+ _voltages[0] = new Sensor("Input", 0, SensorType.Voltage, this, Array.Empty(), settings);
+ ActivateSensor(_voltages[0]);
+
+ // Initialize the flow sensor
+ _flows[0] = new Sensor("Flow", 0, SensorType.Flow, this, Array.Empty(), 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(), 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(), 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(), 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(), 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));
+ }
+}
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/GridV3.cs b/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/GridV3.cs
index 5eceb0e..018f68e 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/GridV3.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/GridV3.cs
@@ -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))
{
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV2.cs b/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV2.cs
index ed81da0..4905527 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV2.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV2.cs
@@ -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;
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV3.cs b/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV3.cs
index d2b0293..e476144 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV3.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/Nzxt/KrakenV3.cs
@@ -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)
{
diff --git a/LibreHardwareMonitorLib/Hardware/Controller/Razer/RazerFanController.cs b/LibreHardwareMonitorLib/Hardware/Controller/Razer/RazerFanController.cs
index 01d3302..2828a2a 100644
--- a/LibreHardwareMonitorLib/Hardware/Controller/Razer/RazerFanController.cs
+++ b/LibreHardwareMonitorLib/Hardware/Controller/Razer/RazerFanController.cs
@@ -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;
diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs
index f8766d8..fb1a40a 100644
--- a/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs
+++ b/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs
@@ -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();
- //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,
diff --git a/LibreHardwareMonitorLib/Hardware/Gpu/NvidiaGpu.cs b/LibreHardwareMonitorLib/Hardware/Gpu/NvidiaGpu.cs
index aed6da9..93cb32b 100644
--- a/LibreHardwareMonitorLib/Hardware/Gpu/NvidiaGpu.cs
+++ b/LibreHardwareMonitorLib/Hardware/Gpu/NvidiaGpu.cs
@@ -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;
}
diff --git a/LibreHardwareMonitorLib/Hardware/Identifier.cs b/LibreHardwareMonitorLib/Hardware/Identifier.cs
index 9d0eaa5..ab54b36 100644
--- a/LibreHardwareMonitorLib/Hardware/Identifier.cs
+++ b/LibreHardwareMonitorLib/Hardware/Identifier.cs
@@ -6,6 +6,7 @@
using System;
using System.Text;
+using HidSharp;
namespace LibreHardwareMonitor.Hardware;
@@ -49,6 +50,35 @@ public class Identifier : IComparable
_identifier = s.ToString();
}
+ ///
+ /// Creates a new identifier instance based on the supplied .
+ /// 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.
+ ///
+ /// The this identifier will be created for.
+ 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();
+ }
+
///
public int CompareTo(Identifier other)
{
@@ -65,8 +95,7 @@ public class Identifier : IComparable
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
return id1.CompareTo(id2) > 0;
}
-}
\ No newline at end of file
+}
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs
index 1bafc53..4cbdbdf 100644
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs
@@ -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;
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs
old mode 100644
new mode 100755
index 7a8c336..40307d3
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs
@@ -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";
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs
index 44bad72..47e893e 100644
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs
@@ -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,
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs
old mode 100644
new mode 100755
index b1e4dda..223a5d8
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs
@@ -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
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs
index 82394e4..ab21846 100644
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs
@@ -45,14 +45,71 @@ internal class IsaBridgeGigabyteController : IGigabyteController
/// true on success
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))
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs
index 8ecdbce..0313a7e 100644
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs
@@ -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,
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs
old mode 100644
new mode 100755
index 50c9e2d..bb9ec0a
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs
@@ -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,
diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs
old mode 100644
new mode 100755
index 0f503a0..858c463
--- a/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs
+++ b/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs
@@ -36,6 +36,7 @@ internal sealed class SuperIOHardware : Hardware
GetBoardSpecificConfiguration(superIO,
manufacturer,
model,
+ index,
out IList v,
out IList t,
out IList f,
@@ -181,6 +182,7 @@ internal sealed class SuperIOHardware : Hardware
ISuperIO superIO,
Manufacturer manufacturer,
Model model,
+ int superIOIndex,
out IList v,
out IList t,
out IList 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 v, IList t, IList f, IList c)
+ private static void GetNuvotonConfigurationD(ISuperIO superIO, Manufacturer manufacturer, Model model, int index, IList v, IList t, IList f, IList 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));
diff --git a/LibreHardwareMonitorLib/Interop/Kernel32.cs b/LibreHardwareMonitorLib/Interop/Kernel32.cs
index 7ace0c7..6f5003f 100644
--- a/LibreHardwareMonitorLib/Interop/Kernel32.cs
+++ b/LibreHardwareMonitorLib/Interop/Kernel32.cs
@@ -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";
diff --git a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj
index 8c10176..3be0b6d 100644
--- a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj
+++ b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj
@@ -35,13 +35,13 @@
-
+
-
+