Binary file not shown.
|
After Width: | Height: | Size: 648 B |
@@ -57,6 +57,9 @@ namespace LibreHardwareMonitor.UI
|
||||
case HardwareType.Psu:
|
||||
image = Utilities.EmbeddedResources.GetImage("power-supply.png");
|
||||
break;
|
||||
case HardwareType.Battery:
|
||||
image = Utilities.EmbeddedResources.GetImage("battery.png");
|
||||
break;
|
||||
default:
|
||||
image = new Bitmap(1, 1);
|
||||
break;
|
||||
|
||||
+32
-22
@@ -1,7 +1,7 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
||||
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// Copyright (C) LibreHardwareMonitor and Contributors.
|
||||
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
|
||||
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
|
||||
// All Rights Reserved.
|
||||
|
||||
namespace LibreHardwareMonitor.UI
|
||||
@@ -59,6 +59,7 @@ namespace LibreHardwareMonitor.UI
|
||||
this.fanControllerMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.hddMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.nicMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.psuMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuItem6 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.exitMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.viewMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -125,6 +126,7 @@ namespace LibreHardwareMonitor.UI
|
||||
this.timer = new System.Windows.Forms.Timer(this.components);
|
||||
this.splitContainer = new LibreHardwareMonitor.UI.SplitContainerAdv();
|
||||
this.treeView = new Aga.Controls.Tree.TreeViewAdv();
|
||||
this.batteryMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.psuMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.backgroundUpdater = new System.ComponentModel.BackgroundWorker();
|
||||
this.mainMenu.SuspendLayout();
|
||||
@@ -240,19 +242,19 @@ namespace LibreHardwareMonitor.UI
|
||||
// saveReportMenuItem
|
||||
//
|
||||
this.saveReportMenuItem.Name = "saveReportMenuItem";
|
||||
this.saveReportMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.saveReportMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.saveReportMenuItem.Text = "Save Report...";
|
||||
this.saveReportMenuItem.Click += new System.EventHandler(this.SaveReportMenuItem_Click);
|
||||
//
|
||||
// MenuItem2
|
||||
//
|
||||
this.MenuItem2.Name = "MenuItem2";
|
||||
this.MenuItem2.Size = new System.Drawing.Size(142, 6);
|
||||
this.MenuItem2.Size = new System.Drawing.Size(177, 6);
|
||||
//
|
||||
// resetMenuItem
|
||||
//
|
||||
this.resetMenuItem.Name = "resetMenuItem";
|
||||
this.resetMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.resetMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.resetMenuItem.Text = "Reset";
|
||||
this.resetMenuItem.Click += new System.EventHandler(this.ResetClick);
|
||||
//
|
||||
@@ -266,62 +268,69 @@ namespace LibreHardwareMonitor.UI
|
||||
this.fanControllerMenuItem,
|
||||
this.hddMenuItem,
|
||||
this.nicMenuItem,
|
||||
this.psuMenuItem});
|
||||
this.psuMenuItem,
|
||||
this.batteryMenuItem});
|
||||
this.menuItem5.Name = "menuItem5";
|
||||
this.menuItem5.Size = new System.Drawing.Size(145, 22);
|
||||
this.menuItem5.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuItem5.Text = "Hardware";
|
||||
//
|
||||
// mainboardMenuItem
|
||||
//
|
||||
this.mainboardMenuItem.Name = "mainboardMenuItem";
|
||||
this.mainboardMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.mainboardMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.mainboardMenuItem.Text = "Motherboard";
|
||||
//
|
||||
// cpuMenuItem
|
||||
//
|
||||
this.cpuMenuItem.Name = "cpuMenuItem";
|
||||
this.cpuMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.cpuMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.cpuMenuItem.Text = "CPU";
|
||||
//
|
||||
// ramMenuItem
|
||||
//
|
||||
this.ramMenuItem.Name = "ramMenuItem";
|
||||
this.ramMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.ramMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.ramMenuItem.Text = "RAM";
|
||||
//
|
||||
// gpuMenuItem
|
||||
//
|
||||
this.gpuMenuItem.Name = "gpuMenuItem";
|
||||
this.gpuMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.gpuMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.gpuMenuItem.Text = "GPU";
|
||||
//
|
||||
// fanControllerMenuItem
|
||||
//
|
||||
this.fanControllerMenuItem.Name = "fanControllerMenuItem";
|
||||
this.fanControllerMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.fanControllerMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.fanControllerMenuItem.Text = "Fan Controllers";
|
||||
//
|
||||
// hddMenuItem
|
||||
//
|
||||
this.hddMenuItem.Name = "hddMenuItem";
|
||||
this.hddMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.hddMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.hddMenuItem.Text = "Hard Disk Drives";
|
||||
//
|
||||
// nicMenuItem
|
||||
//
|
||||
this.nicMenuItem.Name = "nicMenuItem";
|
||||
this.nicMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.nicMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.nicMenuItem.Text = "Network";
|
||||
//
|
||||
// psuMenuItem
|
||||
//
|
||||
this.psuMenuItem.Name = "psuMenuItem";
|
||||
this.psuMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.psuMenuItem.Text = "Power supplies";
|
||||
//
|
||||
// menuItem6
|
||||
//
|
||||
this.menuItem6.Name = "menuItem6";
|
||||
this.menuItem6.Size = new System.Drawing.Size(142, 6);
|
||||
this.menuItem6.Size = new System.Drawing.Size(177, 6);
|
||||
//
|
||||
// exitMenuItem
|
||||
//
|
||||
this.exitMenuItem.Name = "exitMenuItem";
|
||||
this.exitMenuItem.Size = new System.Drawing.Size(145, 22);
|
||||
this.exitMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.exitMenuItem.Text = "Exit";
|
||||
this.exitMenuItem.Click += new System.EventHandler(this.ExitClick);
|
||||
//
|
||||
@@ -387,19 +396,19 @@ namespace LibreHardwareMonitor.UI
|
||||
// valueMenuItem
|
||||
//
|
||||
this.valueMenuItem.Name = "valueMenuItem";
|
||||
this.valueMenuItem.Size = new System.Drawing.Size(102, 22);
|
||||
this.valueMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.valueMenuItem.Text = "Value";
|
||||
//
|
||||
// minMenuItem
|
||||
//
|
||||
this.minMenuItem.Name = "minMenuItem";
|
||||
this.minMenuItem.Size = new System.Drawing.Size(102, 22);
|
||||
this.minMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.minMenuItem.Text = "Min";
|
||||
//
|
||||
// maxMenuItem
|
||||
//
|
||||
this.maxMenuItem.Name = "maxMenuItem";
|
||||
this.maxMenuItem.Size = new System.Drawing.Size(102, 22);
|
||||
this.maxMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.maxMenuItem.Text = "Max";
|
||||
//
|
||||
// optionsMenuItem
|
||||
@@ -847,11 +856,11 @@ namespace LibreHardwareMonitor.UI
|
||||
this.treeView.MouseMove += new System.Windows.Forms.MouseEventHandler(this.TreeView_MouseMove);
|
||||
this.treeView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.TreeView_MouseUp);
|
||||
//
|
||||
// psuMenuItem
|
||||
// batteryMenuItem
|
||||
//
|
||||
this.psuMenuItem.Name = "psuMenuItem";
|
||||
this.psuMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.psuMenuItem.Text = "Power supplies";
|
||||
this.batteryMenuItem.Name = "batteryMenuItem";
|
||||
this.batteryMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.batteryMenuItem.Text = "Batteries";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
@@ -970,6 +979,7 @@ namespace LibreHardwareMonitor.UI
|
||||
private ToolStripRadioButtonMenuItem timeWindow24hMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem authWebServerMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem psuMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem batteryMenuItem;
|
||||
private System.ComponentModel.BackgroundWorker backgroundUpdater;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace LibreHardwareMonitor.UI
|
||||
private readonly UserOption _readHddSensors;
|
||||
private readonly UserOption _readNicSensors;
|
||||
private readonly UserOption _readPsuSensors;
|
||||
private readonly UserOption _readBatterySensors;
|
||||
|
||||
private readonly UserOption _showGadget;
|
||||
private UserRadioGroup _plotLocation;
|
||||
@@ -262,6 +263,12 @@ namespace LibreHardwareMonitor.UI
|
||||
_computer.IsPsuEnabled = _readPsuSensors.Value;
|
||||
};
|
||||
|
||||
_readBatterySensors = new UserOption("batteryMenuItem", true, batteryMenuItem, _settings);
|
||||
_readBatterySensors.Changed += delegate
|
||||
{
|
||||
_computer.IsBatteryEnabled = _readBatterySensors.Value;
|
||||
};
|
||||
|
||||
_showGadget = new UserOption("gadgetMenuItem", false, gadgetMenuItem, _settings);
|
||||
_showGadget.Changed += delegate
|
||||
{
|
||||
|
||||
@@ -171,7 +171,8 @@ namespace LibreHardwareMonitor.UI
|
||||
{ SensorType.Factor, "1" },
|
||||
{ SensorType.Power, "W" },
|
||||
{ SensorType.Data, "GB" },
|
||||
{ SensorType.Frequency, "Hz" }
|
||||
{ SensorType.Frequency, "Hz" },
|
||||
{ SensorType.Energy, "mWh" }
|
||||
};
|
||||
|
||||
foreach (SensorType type in Enum.GetValues(typeof(SensorType)))
|
||||
|
||||
@@ -643,6 +643,9 @@ namespace LibreHardwareMonitor.UI
|
||||
case SensorType.TimeSpan:
|
||||
format = "{0:g}";
|
||||
break;
|
||||
case SensorType.Energy:
|
||||
format = "{0:F0} mWh";
|
||||
break;
|
||||
}
|
||||
|
||||
if (sensor.SensorType == SensorType.Temperature && _unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
|
||||
|
||||
@@ -76,6 +76,9 @@ namespace LibreHardwareMonitor.UI
|
||||
case SensorType.TimeSpan:
|
||||
Format = "{0:g}";
|
||||
break;
|
||||
case SensorType.Energy:
|
||||
Format = "{0:F0} mWh";
|
||||
break;
|
||||
}
|
||||
|
||||
bool hidden = settings.GetValue(new Identifier(sensor.Identifier, "hidden").ToString(), sensor.IsDefaultHidden);
|
||||
|
||||
@@ -181,6 +181,7 @@ namespace LibreHardwareMonitor.UI
|
||||
case SensorType.Power:
|
||||
case SensorType.Data:
|
||||
case SensorType.Load:
|
||||
case SensorType.Energy:
|
||||
return $"{Sensor.Value:F0}";
|
||||
default:
|
||||
return "-";
|
||||
@@ -255,6 +256,7 @@ namespace LibreHardwareMonitor.UI
|
||||
case SensorType.Power: format = "\n{0}: {1:F0} W"; break;
|
||||
case SensorType.Data: format = "\n{0}: {1:F0} GB"; break;
|
||||
case SensorType.Factor: format = "\n{0}: {1:F3} GB"; break;
|
||||
case SensorType.Energy: format = "\n{0}: {0:F0} mWh"; break;
|
||||
}
|
||||
string formattedValue = string.Format(format, Sensor.Name, Sensor.Value);
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ namespace LibreHardwareMonitor.UI
|
||||
Image = Utilities.EmbeddedResources.GetImage("voltage.png");
|
||||
Text = "Currents";
|
||||
break;
|
||||
case SensorType.Energy:
|
||||
Image = Utilities.EmbeddedResources.GetImage("battery.png");
|
||||
Text = "Capacities";
|
||||
break;
|
||||
case SensorType.Clock:
|
||||
Image = Utilities.EmbeddedResources.GetImage("clock.png");
|
||||
Text = "Clocks";
|
||||
|
||||
@@ -643,6 +643,8 @@ namespace LibreHardwareMonitor.Utilities
|
||||
return "nic.png";
|
||||
case HardwareType.Psu:
|
||||
return "power-supply.png";
|
||||
case HardwareType.Battery:
|
||||
return "battery.png";
|
||||
default:
|
||||
return "cpu.png";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
// 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 System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibreHardwareMonitor.Interop;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Battery
|
||||
{
|
||||
internal sealed class Battery : Hardware
|
||||
{
|
||||
private readonly SafeFileHandle _batteryHandle;
|
||||
private readonly Kernel32.BATTERY_INFORMATION _batteryInformation;
|
||||
private readonly uint _batteryTag;
|
||||
private readonly Sensor _chargeDischargeCurrent;
|
||||
private readonly Sensor _chargeDischargeRate;
|
||||
private readonly Sensor _chargeLevel;
|
||||
private readonly Sensor _degradationPercentage;
|
||||
private readonly Sensor _designedCapacity;
|
||||
private readonly Sensor _fullChargedCapacity;
|
||||
private readonly Sensor _remainingCapacity;
|
||||
private readonly Sensor _voltage;
|
||||
|
||||
public Battery
|
||||
(
|
||||
string name,
|
||||
string manufacturer,
|
||||
SafeFileHandle batteryHandle,
|
||||
Kernel32.BATTERY_INFORMATION batteryInfo,
|
||||
uint batteryTag,
|
||||
ISettings settings) :
|
||||
base(name, new Identifier("battery"), settings)
|
||||
{
|
||||
Name = name;
|
||||
Manufacturer = manufacturer;
|
||||
|
||||
_batteryTag = batteryTag;
|
||||
_batteryHandle = batteryHandle;
|
||||
_batteryInformation = batteryInfo;
|
||||
|
||||
if (batteryInfo.Chemistry.SequenceEqual(new[] { 'P', 'b', 'A', 'c' }))
|
||||
{
|
||||
Chemistry = BatteryChemistry.LeadAcid;
|
||||
}
|
||||
else if (batteryInfo.Chemistry.SequenceEqual(new[] { 'L', 'I', 'O', 'N' }) || batteryInfo.Chemistry.SequenceEqual(new[] { 'L', 'i', '-', 'I' }))
|
||||
{
|
||||
Chemistry = BatteryChemistry.LithiumIon;
|
||||
}
|
||||
else if (batteryInfo.Chemistry.SequenceEqual(new[] { 'N', 'i', 'C', 'd' }))
|
||||
{
|
||||
Chemistry = BatteryChemistry.NickelCadmium;
|
||||
}
|
||||
else if (batteryInfo.Chemistry.SequenceEqual(new[] { 'N', 'i', 'M', 'H' }))
|
||||
{
|
||||
Chemistry = BatteryChemistry.NickelMetalHydride;
|
||||
}
|
||||
else if (batteryInfo.Chemistry.SequenceEqual(new[] { 'N', 'i', 'Z', 'n' }))
|
||||
{
|
||||
Chemistry = BatteryChemistry.NickelZinc;
|
||||
}
|
||||
else if (batteryInfo.Chemistry.SequenceEqual(new[] { 'R', 'A', 'M', '\x00' }))
|
||||
{
|
||||
Chemistry = BatteryChemistry.AlkalineManganese;
|
||||
}
|
||||
else
|
||||
{
|
||||
Chemistry = BatteryChemistry.Unknown;
|
||||
}
|
||||
|
||||
DegradationLevel = 100f - (batteryInfo.FullChargedCapacity * 100f / batteryInfo.DesignedCapacity);
|
||||
DesignedCapacity = batteryInfo.DesignedCapacity;
|
||||
FullChargedCapacity = batteryInfo.FullChargedCapacity;
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
public float ChargeDischargeCurrent { get; private set; }
|
||||
|
||||
public float ChargeDischargeRate { get; private set; }
|
||||
|
||||
public float ChargeLevel { get; private set; }
|
||||
|
||||
public BatteryChemistry Chemistry { get; }
|
||||
|
||||
public float DegradationLevel { get; }
|
||||
|
||||
public float DesignedCapacity { get; }
|
||||
|
||||
public float FullChargedCapacity { get; }
|
||||
|
||||
public override HardwareType HardwareType => HardwareType.Battery;
|
||||
|
||||
public string Manufacturer { get; }
|
||||
|
||||
public float RemainingCapacity { get; private set; }
|
||||
|
||||
public float Voltage { get; private set; }
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
Kernel32.BATTERY_WAIT_STATUS bws = default;
|
||||
bws.BatteryTag = _batteryTag;
|
||||
Kernel32.BATTERY_STATUS batteryStatus = default;
|
||||
if (Kernel32.DeviceIoControl(_batteryHandle,
|
||||
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_STATUS,
|
||||
ref bws,
|
||||
Marshal.SizeOf(bws),
|
||||
ref batteryStatus,
|
||||
Marshal.SizeOf(batteryStatus),
|
||||
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;
|
||||
|
||||
_chargeLevel.Value = _remainingCapacity.Value * 100f / _fullChargedCapacity.Value;
|
||||
ChargeLevel = (_remainingCapacity.Value * 100f / _fullChargedCapacity.Value).GetValueOrDefault();
|
||||
|
||||
ChargeDischargeRate = batteryStatus.Rate / 1000f;
|
||||
|
||||
switch (batteryStatus.Rate)
|
||||
{
|
||||
case > 0:
|
||||
_chargeDischargeRate.Name = "Charge Rate";
|
||||
_chargeDischargeRate.Value = batteryStatus.Rate / 1000f;
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
_degradationPercentage.Value = 100f - (_fullChargedCapacity.Value * 100f / _designedCapacity.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
_batteryHandle.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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.
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Battery;
|
||||
|
||||
internal enum BatteryChemistry
|
||||
{
|
||||
Unknown,
|
||||
LeadAcid,
|
||||
NickelCadmium,
|
||||
NickelMetalHydride,
|
||||
LithiumIon,
|
||||
NickelZinc,
|
||||
AlkalineManganese
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using LibreHardwareMonitor.Interop;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware.Battery
|
||||
{
|
||||
internal class BatteryGroup : IGroup
|
||||
{
|
||||
private readonly List<Battery> _hardware = new();
|
||||
|
||||
public unsafe BatteryGroup(ISettings settings)
|
||||
{
|
||||
// No implementation for battery information on Unix systems
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
return;
|
||||
|
||||
IntPtr hdev = SetupApi.SetupDiGetClassDevs(ref SetupApi.GUID_DEVICE_BATTERY, IntPtr.Zero, IntPtr.Zero, SetupApi.DIGCF_PRESENT | SetupApi.DIGCF_DEVICEINTERFACE);
|
||||
if (hdev != SetupApi.INVALID_HANDLE_VALUE)
|
||||
{
|
||||
for (uint i = 0;; i++)
|
||||
{
|
||||
SetupApi.SP_DEVICE_INTERFACE_DATA did = default;
|
||||
did.cbSize = (uint)Marshal.SizeOf(typeof(SetupApi.SP_DEVICE_INTERFACE_DATA));
|
||||
|
||||
if (!SetupApi.SetupDiEnumDeviceInterfaces(hdev,
|
||||
IntPtr.Zero,
|
||||
ref SetupApi.GUID_DEVICE_BATTERY,
|
||||
i,
|
||||
ref did))
|
||||
{
|
||||
if (Marshal.GetLastWin32Error() == SetupApi.ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupApi.SetupDiGetDeviceInterfaceDetail(hdev,
|
||||
did,
|
||||
IntPtr.Zero,
|
||||
0,
|
||||
out uint cbRequired,
|
||||
IntPtr.Zero);
|
||||
|
||||
if (Marshal.GetLastWin32Error() == SetupApi.ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
IntPtr pdidd = Kernel32.LocalAlloc(Kernel32.LPTR, cbRequired);
|
||||
Marshal.WriteInt32(pdidd, Environment.Is64BitOperatingSystem ? 8 : 4); // cbSize.
|
||||
|
||||
if (SetupApi.SetupDiGetDeviceInterfaceDetail(hdev,
|
||||
did,
|
||||
pdidd,
|
||||
cbRequired,
|
||||
out _,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
string devicePath = new((char*)(pdidd + 4));
|
||||
|
||||
SafeFileHandle battery = Kernel32.CreateFile(devicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
|
||||
if (!battery.IsInvalid)
|
||||
{
|
||||
Kernel32.BATTERY_QUERY_INFORMATION bqi = default;
|
||||
|
||||
uint dwWait = 0;
|
||||
if (Kernel32.DeviceIoControl(battery,
|
||||
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_TAG,
|
||||
ref dwWait,
|
||||
Marshal.SizeOf(dwWait),
|
||||
ref bqi.BatteryTag,
|
||||
Marshal.SizeOf(bqi.BatteryTag),
|
||||
out _,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
Kernel32.BATTERY_INFORMATION bi = default;
|
||||
bqi.InformationLevel = Kernel32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryInformation;
|
||||
|
||||
if (Kernel32.DeviceIoControl(battery,
|
||||
Kernel32.IOCTL.IOCTL_BATTERY_QUERY_INFORMATION,
|
||||
ref bqi,
|
||||
Marshal.SizeOf(bqi),
|
||||
ref bi,
|
||||
Marshal.SizeOf(bi),
|
||||
out _,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
// Only batteries count.
|
||||
if (bi.Capabilities == Kernel32.BatteryCapabilities.BATTERY_SYSTEM_BATTERY)
|
||||
{
|
||||
const int maxLoadString = 100;
|
||||
|
||||
IntPtr ptrDevName = Marshal.AllocCoTaskMem(maxLoadString);
|
||||
bqi.InformationLevel = Kernel32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryDeviceName;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kernel32.LocalFree(pdidd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetupApi.SetupDiDestroyDeviceInfoList(hdev);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<IHardware> Hardware => _hardware;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Close()
|
||||
{
|
||||
foreach (Battery battery in _hardware)
|
||||
battery.Close();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetReport()
|
||||
{
|
||||
StringBuilder reportBuilder = new();
|
||||
|
||||
uint count = 1;
|
||||
|
||||
foreach (Battery bat in _hardware)
|
||||
{
|
||||
string chemistry = "Unknown";
|
||||
|
||||
switch (bat.Chemistry)
|
||||
{
|
||||
case BatteryChemistry.LeadAcid:
|
||||
chemistry = "Lead Acid";
|
||||
break;
|
||||
case BatteryChemistry.NickelCadmium:
|
||||
chemistry = "Nickel-Cadmium";
|
||||
break;
|
||||
case BatteryChemistry.NickelMetalHydride:
|
||||
chemistry = "Nickel-Metal Hydride";
|
||||
break;
|
||||
case BatteryChemistry.LithiumIon:
|
||||
chemistry = "Lithium Ion";
|
||||
break;
|
||||
case BatteryChemistry.NickelZinc:
|
||||
chemistry = "Nickel-Zinc";
|
||||
break;
|
||||
case BatteryChemistry.AlkalineManganese:
|
||||
chemistry = "Rechargeable Alkaline-Manganese";
|
||||
break;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
reportBuilder.AppendLine();
|
||||
count++;
|
||||
}
|
||||
|
||||
return reportBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security.Permissions;
|
||||
using LibreHardwareMonitor.Hardware.Battery;
|
||||
using LibreHardwareMonitor.Hardware.Controller.AeroCool;
|
||||
using LibreHardwareMonitor.Hardware.Controller.AquaComputer;
|
||||
using LibreHardwareMonitor.Hardware.Controller.Heatmaster;
|
||||
@@ -28,16 +28,11 @@ namespace LibreHardwareMonitor.Hardware
|
||||
/// </summary>
|
||||
public class Computer : IComputer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public event HardwareEventHandler HardwareAdded;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event HardwareEventHandler HardwareRemoved;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private readonly List<IGroup> _groups = new List<IGroup>();
|
||||
private readonly List<IGroup> _groups = new();
|
||||
private readonly object _lock = new();
|
||||
private readonly ISettings _settings;
|
||||
|
||||
|
||||
private bool _batteryEnabled;
|
||||
private bool _controllerEnabled;
|
||||
private bool _cpuEnabled;
|
||||
private bool _gpuEnabled;
|
||||
@@ -45,13 +40,12 @@ namespace LibreHardwareMonitor.Hardware
|
||||
private bool _motherboardEnabled;
|
||||
private bool _networkEnabled;
|
||||
private bool _open;
|
||||
private bool _storageEnabled;
|
||||
private bool _psuEnabled;
|
||||
|
||||
private SMBios _smbios;
|
||||
private bool _storageEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="IComputer"/> instance with basic initial <see cref="Settings"/>.
|
||||
/// Creates a new <see cref="IComputer" /> instance with basic initial <see cref="Settings" />.
|
||||
/// </summary>
|
||||
public Computer()
|
||||
{
|
||||
@@ -59,14 +53,20 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="IComputer"/> instance with additional <see cref="ISettings"/>.
|
||||
/// Creates a new <see cref="IComputer" /> instance with additional <see cref="ISettings" />.
|
||||
/// </summary>
|
||||
/// <param name="settings">Computer settings that will be transferred to each <see cref="IHardware"/>.</param>
|
||||
/// <param name="settings">Computer settings that will be transferred to each <see cref="IHardware" />.</param>
|
||||
public Computer(ISettings settings)
|
||||
{
|
||||
_settings = settings ?? new Settings();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event HardwareEventHandler HardwareAdded;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event HardwareEventHandler HardwareRemoved;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<IHardware> Hardware
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
List<IHardware> list = new List<IHardware>();
|
||||
List<IHardware> list = new();
|
||||
|
||||
foreach (IGroup group in _groups)
|
||||
list.AddRange(group.Hardware);
|
||||
@@ -84,35 +84,25 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains computer information table read in accordance with <see href="https://www.dmtf.org/standards/smbios">System Management BIOS (SMBIOS) Reference Specification</see>.
|
||||
/// </summary>
|
||||
public SMBios SMBios
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_open)
|
||||
throw new InvalidOperationException("SMBIOS cannot be accessed before opening.");
|
||||
|
||||
return _smbios;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsCpuEnabled
|
||||
public bool IsBatteryEnabled
|
||||
{
|
||||
get { return _cpuEnabled; }
|
||||
get { return _batteryEnabled; }
|
||||
set
|
||||
{
|
||||
if (_open && value != _cpuEnabled)
|
||||
if (_open && value != _batteryEnabled)
|
||||
{
|
||||
if (value)
|
||||
Add(new CPU.CpuGroup(_settings));
|
||||
{
|
||||
Add(new BatteryGroup(_settings));
|
||||
}
|
||||
else
|
||||
RemoveType<CPU.CpuGroup>();
|
||||
{
|
||||
RemoveType<BatteryGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
_cpuEnabled = value;
|
||||
_batteryEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +136,24 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsCpuEnabled
|
||||
{
|
||||
get { return _cpuEnabled; }
|
||||
set
|
||||
{
|
||||
if (_open && value != _cpuEnabled)
|
||||
{
|
||||
if (value)
|
||||
Add(new CPU.CpuGroup(_settings));
|
||||
else
|
||||
RemoveType<CPU.CpuGroup>();
|
||||
}
|
||||
|
||||
_cpuEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsGpuEnabled
|
||||
{
|
||||
@@ -224,6 +232,28 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPsuEnabled
|
||||
{
|
||||
get { return _psuEnabled; }
|
||||
set
|
||||
{
|
||||
if (_open && value != _psuEnabled)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Add(new CorsairPsuGroup(_settings));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveType<CorsairPsuGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
_psuEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsStorageEnabled
|
||||
{
|
||||
@@ -242,24 +272,17 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPsuEnabled
|
||||
/// <summary>
|
||||
/// Contains computer information table read in accordance with <see href="https://www.dmtf.org/standards/smbios">System Management BIOS (SMBIOS) Reference Specification</see>.
|
||||
/// </summary>
|
||||
public SMBios SMBios
|
||||
{
|
||||
get { return _psuEnabled; }
|
||||
set
|
||||
get
|
||||
{
|
||||
if (_open && value != _psuEnabled)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Add(new CorsairPsuGroup(_settings));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveType<CorsairPsuGroup>();
|
||||
}
|
||||
}
|
||||
_psuEnabled = value;
|
||||
if (!_open)
|
||||
throw new InvalidOperationException("SMBIOS cannot be accessed before opening.");
|
||||
|
||||
return _smbios;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +291,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
using StringWriter w = new StringWriter(CultureInfo.InvariantCulture);
|
||||
using StringWriter w = new(CultureInfo.InvariantCulture);
|
||||
|
||||
w.WriteLine();
|
||||
w.WriteLine(nameof(LibreHardwareMonitor) + " Report");
|
||||
@@ -341,7 +364,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the <see cref="IVisitor.VisitComputer"/> method for the given observer.
|
||||
/// Triggers the <see cref="IVisitor.VisitComputer" /> method for the given observer.
|
||||
/// </summary>
|
||||
/// <param name="visitor">Observer who call to devices.</param>
|
||||
public void Accept(IVisitor visitor)
|
||||
@@ -349,12 +372,11 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (visitor == null)
|
||||
throw new ArgumentNullException(nameof(visitor));
|
||||
|
||||
|
||||
visitor.VisitComputer(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the <see cref="IElement.Accept"/> method with the given visitor for each device in each group.
|
||||
/// Triggers the <see cref="IElement.Accept" /> method with the given visitor for each device in each group.
|
||||
/// </summary>
|
||||
/// <param name="visitor">Observer who call to devices.</param>
|
||||
public void Traverse(IVisitor visitor)
|
||||
@@ -387,13 +409,11 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (group == null)
|
||||
return;
|
||||
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_groups.Contains(group))
|
||||
return;
|
||||
|
||||
|
||||
_groups.Add(group);
|
||||
|
||||
if (group is IHardwareChanged hardwareChanged)
|
||||
@@ -417,7 +437,6 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (!_groups.Contains(group))
|
||||
return;
|
||||
|
||||
|
||||
_groups.Remove(group);
|
||||
|
||||
if (group is IHardwareChanged hardwareChanged)
|
||||
@@ -438,7 +457,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
private void RemoveType<T>() where T : IGroup
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
List<T> list = new();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
@@ -454,14 +473,14 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If hasn't been opened before, opens <see cref="SMBios"/>, <see cref="Ring0"/>, <see cref="OpCode"/> and triggers the private <see cref="AddGroups"/> method depending on which categories are enabled.
|
||||
/// If hasn't been opened before, opens <see cref="SMBios" />, <see cref="Ring0" />, <see cref="OpCode" /> and triggers the private <see cref="AddGroups" /> method depending on which categories are
|
||||
/// enabled.
|
||||
/// </summary>
|
||||
public void Open()
|
||||
{
|
||||
if (_open)
|
||||
return;
|
||||
|
||||
|
||||
_smbios = new SMBios();
|
||||
|
||||
Ring0.Open();
|
||||
@@ -506,6 +525,9 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
if (_psuEnabled)
|
||||
Add(new CorsairPsuGroup(_settings));
|
||||
|
||||
if (_batteryEnabled)
|
||||
Add(new BatteryGroup(_settings));
|
||||
}
|
||||
|
||||
private static void NewSection(TextWriter writer)
|
||||
@@ -523,7 +545,6 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (c == 0)
|
||||
return a.Index.CompareTo(b.Index);
|
||||
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -584,14 +605,13 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If opened before, removes all <see cref="IGroup"/> and triggers <see cref="OpCode.Close"/>, <see cref="InpOut.Close"/> and <see cref="Ring0.Close"/>.
|
||||
/// If opened before, removes all <see cref="IGroup" /> and triggers <see cref="OpCode.Close" />, <see cref="InpOut.Close" /> and <see cref="Ring0.Close" />.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (!_open)
|
||||
return;
|
||||
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
while (_groups.Count > 0)
|
||||
@@ -610,14 +630,13 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If opened before, removes all <see cref="IGroup"/> and recreates it.
|
||||
/// If opened before, removes all <see cref="IGroup" /> and recreates it.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
if (!_open)
|
||||
return;
|
||||
|
||||
|
||||
RemoveGroups();
|
||||
AddGroups();
|
||||
}
|
||||
@@ -635,7 +654,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Computer"/> specific additional settings passed to its <see cref="IHardware"/>.
|
||||
/// <see cref="Computer" /> specific additional settings passed to its <see cref="IHardware" />.
|
||||
/// </summary>
|
||||
private class Settings : ISettings
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
Network,
|
||||
Cooler,
|
||||
EmbeddedController,
|
||||
Psu
|
||||
Psu,
|
||||
Battery
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,77 +20,93 @@ namespace LibreHardwareMonitor.Hardware
|
||||
public interface IComputer : IElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Cpu"/> devices should be enabled and updated.
|
||||
/// Triggered when a new <see cref="IHardware" /> is registered.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsCpuEnabled { get; }
|
||||
event HardwareEventHandler HardwareAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about:
|
||||
/// <list>
|
||||
/// <item><see cref="LibreHardwareMonitor.Hardware.Controller.TBalancer.TBalancerGroup"/></item>
|
||||
/// <item><see cref="LibreHardwareMonitor.Hardware.Controller.Heatmaster.HeatmasterGroup"/></item>
|
||||
/// <item><see cref="LibreHardwareMonitor.Hardware.Controller.AquaComputer.AquaComputerGroup"/></item>
|
||||
/// <item><see cref="LibreHardwareMonitor.Hardware.Controller.AeroCool.AeroCoolGroup"/></item>
|
||||
/// <item><see cref="LibreHardwareMonitor.Hardware.Controller.Nzxt.NzxtGroup"/></item>
|
||||
/// </list>
|
||||
/// devices should be enabled and updated.
|
||||
/// Triggered when a <see cref="IHardware" /> is removed.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsControllerEnabled { get; }
|
||||
event HardwareEventHandler HardwareRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.GpuAmd"/> or <see cref="HardwareType.GpuNvidia"/> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsGpuEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Storage"/> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsStorageEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Motherboard"/> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsMotherboardEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Network"/> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsNetworkEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Memory"/> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsMemoryEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Psu"/> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if a given category of devices is already enabled.</returns>
|
||||
bool IsPsuEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all known <see cref="IHardware"/>.
|
||||
/// <para>Can be updated by <see cref="IVisitor"/>.</para>
|
||||
/// Gets a list of all known <see cref="IHardware" />.
|
||||
/// <para>Can be updated by <see cref="IVisitor" />.</para>
|
||||
/// </summary>
|
||||
/// <returns>List of all enabled devices.</returns>
|
||||
IList<IHardware> Hardware { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a new <see cref="IHardware"/> is registered.
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Battery" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
event HardwareEventHandler HardwareAdded;
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsBatteryEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a <see cref="IHardware"/> is removed.
|
||||
/// Gets or sets a value indicating whether collecting information about:
|
||||
/// <list>
|
||||
/// <item>
|
||||
/// <see cref="Controller.TBalancer.TBalancerGroup" />
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <see cref="Controller.Heatmaster.HeatmasterGroup" />
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <see cref="Controller.AquaComputer.AquaComputerGroup" />
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <see cref="Controller.AeroCool.AeroCoolGroup" />
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <see cref="Controller.Nzxt.NzxtGroup" />
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// devices should be enabled and updated.
|
||||
/// </summary>
|
||||
event HardwareEventHandler HardwareRemoved;
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsControllerEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Cpu" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsCpuEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.GpuAmd" /> or <see cref="HardwareType.GpuNvidia" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsGpuEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Memory" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsMemoryEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Motherboard" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsMotherboardEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Network" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsNetworkEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Psu" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsPsuEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether collecting information about <see cref="HardwareType.Storage" /> devices should be enabled and updated.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true" /> if a given category of devices is already enabled.</returns>
|
||||
bool IsStorageEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Generates full LibreHardwareMonitor report for devices that have been enabled.
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
SmallData, // MB = 2^20 Bytes
|
||||
Throughput, // B/s
|
||||
TimeSpan, // Seconds
|
||||
Energy // milliwatt-hour (mWh)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace LibreHardwareMonitor.Interop
|
||||
internal const byte SMART_LBA_MID = 0x4F;
|
||||
internal const byte SMART_LBA_HI_EXCEEDED = 0x2C;
|
||||
internal const byte SMART_LBA_MID_EXCEEDED = 0xF4;
|
||||
|
||||
internal const uint LPTR = 0x0000 | 0x0040;
|
||||
|
||||
private const string DllName = "kernel32.dll";
|
||||
|
||||
[Flags]
|
||||
@@ -203,6 +206,64 @@ namespace LibreHardwareMonitor.Interop
|
||||
out uint lpBytesReturned,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DeviceIoControl
|
||||
(
|
||||
SafeFileHandle hDevice,
|
||||
IOCTL dwIoControlCode,
|
||||
ref BATTERY_QUERY_INFORMATION lpInBuffer,
|
||||
int nInBufferSize,
|
||||
ref BATTERY_INFORMATION lpOutBuffer,
|
||||
int nOutBufferSize,
|
||||
out uint lpBytesReturned,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DeviceIoControl
|
||||
(
|
||||
SafeFileHandle hDevice,
|
||||
IOCTL dwIoControlCode,
|
||||
ref uint lpInBuffer,
|
||||
int nInBufferSize,
|
||||
ref uint lpOutBuffer,
|
||||
int nOutBufferSize,
|
||||
out uint lpBytesReturned,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DeviceIoControl
|
||||
(
|
||||
SafeFileHandle hDevice,
|
||||
IOCTL dwIoControlCode,
|
||||
ref BATTERY_WAIT_STATUS lpInBuffer,
|
||||
int nInBufferSize,
|
||||
ref BATTERY_STATUS lpOutBuffer,
|
||||
int nOutBufferSize,
|
||||
out uint lpBytesReturned,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DeviceIoControl
|
||||
(
|
||||
SafeFileHandle hDevice,
|
||||
IOCTL dwIoControlCode,
|
||||
ref BATTERY_QUERY_INFORMATION lpInBuffer,
|
||||
int nInBufferSize,
|
||||
IntPtr lpOutBuffer,
|
||||
int nOutBufferSize,
|
||||
out uint lpBytesReturned,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr LocalAlloc(uint uFlags, ulong uBytes);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr LocalFree(IntPtr hMem);
|
||||
|
||||
[DllImport(DllName, SetLastError = true)]
|
||||
internal static extern void RtlZeroMemory(IntPtr Destination, int Length);
|
||||
|
||||
@@ -291,7 +352,80 @@ namespace LibreHardwareMonitor.Interop
|
||||
IOCTL_SCSI_MINIPORT = 0x04d008,
|
||||
IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x04d014,
|
||||
IOCTL_SCSI_GET_ADDRESS = 0x41018,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400
|
||||
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400,
|
||||
IOCTL_BATTERY_QUERY_TAG = 0x294040,
|
||||
IOCTL_BATTERY_QUERY_INFORMATION = 0x294044,
|
||||
IOCTL_BATTERY_QUERY_STATUS = 0x29404C
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum BatteryCapabilities : uint
|
||||
{
|
||||
BATTERY_CAPACITY_RELATIVE = 0x40000000,
|
||||
BATTERY_IS_SHORT_TERM = 0x20000000,
|
||||
BATTERY_SET_CHARGE_SUPPORTED = 0x00000001,
|
||||
BATTERY_SET_DISCHARGE_SUPPORTED = 0x00000002,
|
||||
BATTERY_SYSTEM_BATTERY = 0x80000000
|
||||
}
|
||||
|
||||
internal enum BATTERY_QUERY_INFORMATION_LEVEL
|
||||
{
|
||||
BatteryInformation,
|
||||
BatteryGranularityInformation,
|
||||
BatteryTemperature,
|
||||
BatteryEstimatedTime,
|
||||
BatteryDeviceName,
|
||||
BatteryManufactureDate,
|
||||
BatteryManufactureName,
|
||||
BatteryUniqueID,
|
||||
BatterySerialNumber
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct BATTERY_QUERY_INFORMATION
|
||||
{
|
||||
public uint BatteryTag;
|
||||
public BATTERY_QUERY_INFORMATION_LEVEL InformationLevel;
|
||||
public uint AtRate;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct BATTERY_INFORMATION
|
||||
{
|
||||
public BatteryCapabilities Capabilities;
|
||||
public byte Technology;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] Reserved;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public char[] Chemistry;
|
||||
|
||||
public uint DesignedCapacity;
|
||||
public uint FullChargedCapacity;
|
||||
public uint DefaultAlert1;
|
||||
public uint DefaultAlert2;
|
||||
public uint CriticalBias;
|
||||
public uint CycleCount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct BATTERY_WAIT_STATUS
|
||||
{
|
||||
public uint BatteryTag;
|
||||
public uint Timeout;
|
||||
public uint PowerState;
|
||||
public uint LowCapacity;
|
||||
public uint HighCapacity;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct BATTERY_STATUS
|
||||
{
|
||||
public uint PowerState;
|
||||
public uint Capacity;
|
||||
public uint Voltage;
|
||||
public int Rate;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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 System.Runtime.InteropServices;
|
||||
|
||||
namespace LibreHardwareMonitor.Interop
|
||||
{
|
||||
internal class SetupApi
|
||||
{
|
||||
internal const int ERROR_INSUFFICIENT_BUFFER = 122;
|
||||
internal const int ERROR_NO_MORE_ITEMS = 259;
|
||||
internal const int DIGCF_PRESENT = 0x00000002;
|
||||
internal const int DIGCF_DEVICEINTERFACE = 0x00000010;
|
||||
internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
|
||||
internal static Guid GUID_DEVICE_BATTERY = new Guid(0x72631e54, 0x78A4, 0x11d0, 0xbc, 0xf7, 0x00, 0xaa, 0x00, 0xb7, 0xb3, 0x2a);
|
||||
private const string DllName = "SetupAPI.dll";
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SP_DEVICE_INTERFACE_DATA
|
||||
{
|
||||
public uint cbSize;
|
||||
public Guid InterfaceClassGuid;
|
||||
public uint Flags;
|
||||
public IntPtr Reserved;
|
||||
}
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
internal static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, uint Flags);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
|
||||
|
||||
[DllImport(DllName, SetLastError = true, EntryPoint = "SetupDiGetDeviceInterfaceDetailW", CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet,
|
||||
in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
|
||||
[Out, Optional] IntPtr DeviceInterfaceDetailData,
|
||||
uint DeviceInterfaceDetailDataSize,
|
||||
out uint RequiredSize,
|
||||
IntPtr DeviceInfoData = default);
|
||||
|
||||
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user