Looking for help making a battery meter object

Hi all,

First, I would like to apologize; I realize this section is for posting tutorials but I figured that if someone replies to this question it will pretty much be a tutorial for others so here goes:

 

I'm using the graphical performance meters 2 plugin and I was wondering if anyone could help me with how to make a battery meter which ALSO tells the time remaining on battery life when the laptop is NOT plugged in.

I've tinkered around with it for a bit and found the section under the tab which says "data source" and I went down to battery status and selected the instance pointing to discharge rate and then linked that to a text- based object on the desktop but whenever I do that, the battery and the text object both just show 0.

Any Ideas?

Thanks

8,484 views 10 replies
Reply #1 Top

my suggestion try searching for something like WMI Battery Meter.

Reply #2 Top

that took 10 seconds:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")

Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")

For Each objItem in colItems
Wscript.Echo "Battery: " & objItem.InstanceName
Wscript.Echo "On AC Power: " & objItem.PowerOnline
Wscript.Echo "Battery is Discharging: " & objItem.Discharging
Wscript.Echo "Battery is Charging: " & objItem.Charging
Wscript.Echo "Remaining capacity: " & objItem.RemainingCapacity
Next

This could be modified to work in Vbscript on DX.. look at my WMI tutorial
https://www.wincustomize.com/articles.aspx?aid=149299


Reply #3 Top

Everyone knows i cant let things lie.... so:

Make a TEXT object, and add this code:

Code: vbscript
  1. Sub Object_OnScriptEnter
  2.     strComputer = "."
  3.     Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
  4.     Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")
  5.     For Each objItem In colItems
  6.     object.text =  "Battery: " & objItem.InstanceName & vbnewline
  7.     object.text = object.text & "On AC Power: " & objItem.PowerOnline& vbnewline
  8.     object.text = object.text & "Battery is Discharging: " & objItem.Discharging& vbnewline
  9.     object.text = object.text & "Battery is Charging: " & objItem.Charging& vbnewline
  10.     object.text = object.text & "Remaining capacity: " & objItem.RemainingCapacity
  11.     Next
  12. End Sub

 

I found this on the page i found that code:

InstanceName. Identifying information for the battery.
PowerOnline. The key to this entire script. If PowerOnline is True that means that the AC adapter is plugged in and the computer is not running off the battery. If PowerOnline is False that means that the computer is running off the battery.
Discharging. Indicates whether the battery is in use and therefore discharging.
Charging. Indicates whether the battery is currently charging.
RemainingCapacity. Lets you know the estimated battery life. We’re not 100% sure what this number means. We found some information that suggests the value is reported back as milliwatt-hours, but we don’t know that for sure; for that matter, we don’t even know what a millwatt-hour is. However, we do know this: on our test computer the Windows Power Meter would report an estimated battery life like 2 hours and 54 minutes (that is, 174 minutes). Meanwhile, the value of the RemainingCapacity property would come back as 43734. If we divided 43734 by 174 minutes, we got back a value of 252. For us 252 seemed to be the magic number: any time we divided RemainingCapacity by 252 we got back a value, in minutes, that matched up quite nicely with the estimated battery life reported back by the Power Meter. Again, we can’t guarantee that 252 is the magic number but, again, it gives you a place to start.

Reply #4 Top

There seems to be a lot of info hiding in that class... look over this code:

Code: vbscript
  1. Sub Object_OnScriptEnter
  2.     strComputer = "."
  3.     Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
  4.     Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")
  5.     For Each objItem In colItems
  6.         object.text = "Battery Info:" & vbnewline
  7.     object.text = object.text & "Active: " & objItem.Active & vbnewline
  8.     object.text = object.text & "Caption: " & objItem.Caption & vbnewline
  9.     object.text = object.text & "ChargeRate: " & objItem.ChargeRate & vbnewline
  10.     object.text = object.text & "Charging: " & objItem.Charging & vbnewline
  11.     object.text = object.text & "Critical: " & objItem.Critical & vbnewline
  12.     object.text = object.text & "Description: " & objItem.Description & vbnewline
  13.     object.text = object.text & "DischargeRate: " & objItem.DischargeRate & vbnewline
  14.     object.text = object.text & "Discharging: " & objItem.Discharging & vbnewline
  15.     object.text = object.text & "Frequency_Object: " & objItem.Frequency_Object & vbnewline
  16.     object.text = object.text & "Frequency_PerfTime: " & objItem.Frequency_PerfTime & vbnewline
  17.     object.text = object.text & "Frequency_Sys100NS: " & objItem.Frequency_Sys100NS & vbnewline
  18.     object.text = object.text & "InstanceName: " & objItem.InstanceName & vbnewline
  19.     object.text = object.text & "Name: " & objItem.Name & vbnewline
  20.     object.text = object.text & "PowerOnline: " & objItem.PowerOnline & vbnewline
  21.     object.text = object.text & "RemainingCapacity: " & objItem.RemainingCapacity & vbnewline
  22.     object.text = object.text & "Tag: " & objItem.Tag & vbnewline
  23.     object.text = object.text & "Timestamp_Object: " & objItem.Timestamp_Object & vbnewline
  24.     object.text = object.text & "Timestamp_PerfTime: " & objItem.Timestamp_PerfTime & vbnewline
  25.     object.text = object.text & "Timestamp_Sys100NS: " & objItem.Timestamp_Sys100NS & vbnewline
  26.     object.text = object.text & "Voltage: " & objItem.Voltage
  27.    
  28.     Next
  29. End Sub

Reply #5 Top

Awesome!

Thanks alot this is really helpfull ^_^

 

I haven't tried to attach a script to the object-- I just assumed that it was possible to do it with DX's built in plugin but that makes sense.

 

EDID: BTW, I figured out the formula to relate the values to time remaining; just add these lines to the code:

 

If objItem.PowerOnline = False Then
    object.text = object.text & "DischargeRate: " & objItem.DischargeRate & vbnewline
    object.text = object.text & "Time remaining: " & Left(objItem.RemainingCapacity/objItem.DischargeRate, 1) & ":" & Left(Mid(objItem.RemainingCapacity/objItem.DischargeRate, 2, 3)*60, 2)
End If

 

Its usually exactly on but It might be off by about a minute or two at the most.. rounding error :/

Reply #6 Top

LOL gotta love it when you cant put it down and have to tinker with it!! Roman how about a dx object that will calculate the meaning of life!! excellant posts by the way!

 

Reply #7 Top

lol sorry for the seemingly stupid question but, is there a way to get the code to automatically update AS SOON AS there's a change in the capacity and as soon as the discharge state turns to True WITHOUT using a timer to have it manually check everytime? Or is the only way to attach an update timer and to find a middleground time for the update?

I mean you can attach a timer to the battery to have it update all the statistics but if you make it quick, it will take up a lot of needless processing power and If you make it slow, it will be unreliable as far as its readings go.

I was thinking of using something like the Object_Onstatechange (state) function which waits for the event to occur before executing the commands...

Thanks again

Reply #8 Top

LOL gotta love it when you cant put it down and have to tinker with it!! Roman how about a dx object that will calculate the meaning of life!! excellant posts by the way!

YES:  42

ol sorry for the seemingly stupid question but, is there a way to get the code to automatically update AS SOON AS there's a change in the capacity and as soon as the discharge state turns to True WITHOUT using a timer to have it manually check everytime? Or is the only way to attach an update timer and to find a middleground time for the update?

I mean you can attach a timer to the battery to have it update all the statistics but if you make it quick, it will take up a lot of needless processing power and If you make it slow, it will be unreliable as far as its readings go.

I was thinking of using something like the Object_Onstatechange (state) function which waits for the event to occur before executing the commands...

Thanks again

Look at TIMER Tutorials, there are a few, or look in any weather app, or just about any of my apps, there is a timer call in there.  Just set it to 10 seconds or so or even 15 seconds.  ie: 10000 or 15000  Good Luck

Reply #9 Top

Okie Its done,

I attached a timer to it to check for update as per Roman's suggestion.

 

Here's the script in case anyone reading this wants to make one too ^_^

 

3 objects;

 1 main battery,

Sub Object_OnScriptenter
 Object.SetTimer 6000, 60000
End Sub
Sub Object_ontimer6000
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")
For Each objItem In colItems
If objItem.PowerOnline = True Then
 If objItem.Charging = True Then
     DesktopX.Object("Charge").State = "Charging"
    Else
    DesktopX.Object("Charge").State = "Show"
 End If
Else
    DesktopX.Object("Charge").State = "Hide"
End If
 If objItem.RemainingCapacity/47741 = 1 Then
         Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_full.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 <> 100 And  (objItem.RemainingCapacity/47741)*100 > 89  Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_7.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 < 89  And  (objItem.RemainingCapacity/47741)*100 > 79  Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_6.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 < 79 And  (objItem.RemainingCapacity/47741)*100 > 69  Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_5.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 < 69 And  (objItem.RemainingCapacity/47741)*100 > 45  Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_4.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 < 45 And  (objItem.RemainingCapacity/47741)*100 > 20  Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_3.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 < 20 And  (objItem.RemainingCapacity/47741)*100 > 1  Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_1.png"
 End If
 If (objItem.RemainingCapacity/47741)*100 < 1 Then
    Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_empty!.png"
 End If
Next
Object.SetTimer 6000, 60000
End Sub

1 statistics object

Sub Object_OnScriptEnter
Object.SetTimer 5000, 100
End Sub
Sub Object_ontimer5000
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
Set colItems = objWMIService.ExecQuery("Select * From BatteryStatus Where Voltage > 0")
For Each objItem In colItems
 object.text = FormatPerCent((objItem.RemainingCapacity/47741), 0) &vbnewline

If objItem.Charging = True Then
 If objItem.ChargeRate > 0 Then
    object.text = object.text & Left(((47741-objItem.RemainingCapacity)/objItem.ChargeRate)*60, 3)&vbnewline
 End If
End If

If objItem.PowerOnline = False Then
    If objItem.DischargeRate > 0 Then
    object.text = object.text & Left(objItem.RemainingCapacity/objItem.DischargeRate, 1) & ":" & Left(Mid(objItem.RemainingCapacity/objItem.DischargeRate, InStr(1, objItem.RemainingCapacity/objItem.DischargeRate, "."), 2)*60, 2) + 3 &vbnewline
    End If
End If
object.tooltiptext =  "Battery: " & objItem.InstanceName & vbnewline
object.tooltiptext = object.tooltiptext & "On AC Power: " & objItem.PowerOnline& vbnewline
object.tooltiptext = object.tooltiptext & "Battery is Charging: " & objItem.Charging& vbnewline
object.tooltiptext = object.tooltiptext & "Voltage: " & objItem.Voltage& vbnewline
object.tooltiptext = object.tooltiptext & "Discharge Rate: " & objItem.DischargeRate& vbnewline
object.tooltiptext = object.tooltiptext & "Charge Rate: " & objItem.chargeRate& vbnewline

Next
Object.SetTimer 5000, 5000
End Sub

1 charge status object

No script, Object MUST have three states, one Hide with no image attached, one Show, with the image, and one charging state that's got a colored image attached.

 

Notes: The number 47441 just happens to be my battery's remaining capacity at 100%. I expect this value to be different for other batteries.

Make sure you change all of the filepaths accordingly to lead to the battery icon images..

I didn't have the time nor did I care enough to clean up this code, as it is, it's pretty fast, gets the job done, and doesn't waste TOO many resources. I might go back and optimize the code later but I wouldn't mind if someone here wants to do it :P

Reply #10 Top

Code: vbscript
  1. If objItem.PowerOnline = True Then
  2. If objItem.Charging = True Then
  3. DesktopX.Object("Charge").State = "Charging"
  4. Else
  5. DesktopX.Object("Charge").State = "Show"
  6. End If
  7. Else
  8. DesktopX.Object("Charge").State = "Hide"
  9. End If
  10. If objItem.RemainingCapacity/47741 = 1 Then
  11. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_full.png"
  12. End If
  13. If (objItem.RemainingCapacity/47741)*100 &lt;&gt; 100 And (objItem.RemainingCapacity/47741)*100 &gt; 89 Then
  14. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_7.png"
  15. End If
  16. If (objItem.RemainingCapacity/47741)*100 &lt; 89 And (objItem.RemainingCapacity/47741)*100 &gt; 79 Then
  17. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_6.png"
  18. End If
  19. If (objItem.RemainingCapacity/47741)*100 &lt; 79 And (objItem.RemainingCapacity/47741)*100 &gt; 69 Then
  20. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_5.png"
  21. End If
  22. If (objItem.RemainingCapacity/47741)*100 &lt; 69 And (objItem.RemainingCapacity/47741)*100 &gt; 45 Then
  23. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_4.png"
  24. End If
  25. If (objItem.RemainingCapacity/47741)*100 &lt; 45 And (objItem.RemainingCapacity/47741)*100 &gt; 20 Then
  26. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_3.png"
  27. End If
  28. If (objItem.RemainingCapacity/47741)*100 &lt; 20 And (objItem.RemainingCapacity/47741)*100 &gt; 1 Then
  29. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_1.png"
  30. End If
  31. If (objItem.RemainingCapacity/47741)*100 &lt; 1 Then
  32. Object.Picture = "C:\Users\Homer\Pictures\IconS\battery_empty!.png"
  33. End If

 

I would suggest that you make more "States" for this object and just add these images into it.

You could call the states:

Full,7,6,5,4,3,2,1,empty

then just set the state to that so that no one has to point to the actual images.