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 @@ - + - +