Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for battery monitoring #612

Merged
merged 20 commits into from
Feb 7, 2022
Merged

Add support for battery monitoring #612

merged 20 commits into from
Feb 7, 2022

Conversation

EMN-CSharp
Copy link
Contributor

This PR adds support for monitoring values like voltage, current, charge level, charge/discharge rate, degradation level and capacities. Resolves #599

Before:
LHMBefore

After:
LHMAfter

@PhyxionNL
Copy link
Collaborator

Thanks, when possible, I'd like to avoid WMI. It's possible to request this information through Win32 API as well::
https://docs.microsoft.com/en-us/windows/win32/power/battery-information

@EMN-CSharp
Copy link
Contributor Author

I've tried to get battery information through Win32 before, but it doesn't work. Used this code as a reference: https://docs.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices.

@PhyxionNL
Copy link
Collaborator

I've tried to get battery information through Win32 before, but it doesn't work. Used this code as a reference: https://docs.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices.

It should definitely be possible to use this to get the battery information. There are some (C#) projects on GitHub that use it and return the correct battery information.

@pomianowski
Copy link
Contributor

@EMN-CSharp
Copy link
Contributor Author

I already discovered the bug in my code that was preventing me from getting battery info through Win32, it was hard to find. In a moment I will send the commit that replaces WMI with Win32.

@EMN-CSharp
Copy link
Contributor Author

Hi. Is there something I should fix before merging?

Copy link
Collaborator

@PhyxionNL PhyxionNL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few small things :)

@@ -31,6 +31,10 @@ public TypeNode(SensorType sensorType, Identifier parentId, PersistentSettings s
Image = Utilities.EmbeddedResources.GetImage("voltage.png");
Text = "Currents";
break;
case SensorType.Energy:
Image = Utilities.EmbeddedResources.GetImage("voltage.png");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be battery.png?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Changed

private readonly Sensor _remainingCapacity;
private readonly Sensor _chargeDischargeRate;
private readonly Sensor _degradationPercentage;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format this bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

using System.IO;
namespace LibreHardwareMonitor.Hardware.Battery
{
internal class BatteryGroup : IGroup
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format document / sort fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

battery.Close();
}
}
public string GetReport() => null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we fill this in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course

Comment on lines 11 to 17
internal struct BatteryReportInfo
{
public string Name { get; set; }
public uint Tag { get; set; }
public SafeFileHandle BatteryHandle { get; set; }
public Kernel32.BATTERY_INFORMATION MoreInformation { get; set; }
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, instead of this, can we perhaps abstract some of the stuff in ctor and call that also in GetReport?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We could also move those properties into the Battery class and call them from GetReport(). It will be necessary to add more battery properties. Properties would be updated in the Battery constructor and in the Update() method.

Comment on lines 62 to 63
// Limit battery search to 100 batteries
for (uint idev = 0; idev < 100; idev++)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I seriously doubt there would be more than 100 batteries, this should just loop until ERROR_NO_MORE_ITEMS is the last error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. That's from the C++ code I've used as a reference. It's fixed now.

IntPtr.Zero);
if (Marshal.GetLastWin32Error() == SetupApi.ERROR_INSUFFICIENT_BUFFER)
{
IntPtr pdidd = Kernel32.LocalAlloc(Kernel32.LPTR, cbRequired);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marshal.AllocHGlobal and below Marshal.FreeHGlobal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Because it IS necessary (in this case) to pass the LPTR (0x0000 | 0x0040) flag in LocalAlloc(). Marshal.AllocHGlobal() calls LocalAlloc(), but it passes a LMEM_FIXED (0x0000) flag. If I use the Marshal.AllocHGlobal() method, LHM crashes inmediately.

if (Marshal.GetLastWin32Error() == SetupApi.ERROR_INSUFFICIENT_BUFFER)
{
IntPtr pdidd = Kernel32.LocalAlloc(Kernel32.LPTR, cbRequired);
SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA didd = SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA.Default;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't seem to be doing anything with SP_DEVICE_INTERFACE_DETAIL_DATA, might as well remove this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also force SetupDiGetDeviceInterfaceDetail to unicode variant so you can remove CharSet.Auto stuff.

Copy link
Contributor Author

@EMN-CSharp EMN-CSharp Feb 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't seem to be doing anything with SP_DEVICE_INTERFACE_DETAIL_DATA, might as well remove this.

I've removed the "didd" variable. SP_DEVICE_INTERFACE_DETAIL_DATA is necessary to do the conversion to a pointer.

Also force SetupDiGetDeviceInterfaceDetail to unicode variant so you can remove CharSet.Auto stuff.

Done

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @EMN-CSharp, I have reformatted it a bit, can you check if everything is still working? Worked OK here but one more is always good, then I'll merge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything worked OK here:
LHMNow

@zeule
Copy link
Contributor

zeule commented Feb 7, 2022

I'd suggest to merge the "Power supplies" and "Batteries" hardware categories. "Power sources", maybe?

@PhyxionNL
Copy link
Collaborator

I'd suggest to merge the "Power supplies" and "Batteries" hardware categories. "Power sources", maybe?

Wouldn't be as clear maybe when you have both and just see a type number. Feel free to open an issue for it and discuss this 😁

@PhyxionNL PhyxionNL merged commit 5152b43 into LibreHardwareMonitor:master Feb 7, 2022
@EMN-CSharp
Copy link
Contributor Author

Thank you @PhyxionNL !!!

@PhyxionNL
Copy link
Collaborator

Thank you @PhyxionNL !!!

Thank you for your contribution, it's appreciated 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Monitor laptop battery
4 participants