-1

Writing a VB script to monitor battery percentage. If it is > 95, then unplug. If < 20, plug in charger or else hibernate and so on. When battery goes below 20%, there is a popup Plug-in charger… and though within 10 sec system is plugged, it goes to else part and hibernates. It does not enter "System won't hibernate" part.

hibernate.bat is a simple batch script to hibernate Windows7. The code is a never ending for loop, in which do while loop is used to replicate 'continue' in shell scripting. When battery reaches 20%, there is 10 sec time given to plugin charger. If charged, then it has to go to next for loop iteration. "If charged" loop is not being entered. Why?

Set oLocator = CreateObject("WbemScripting.SWbemLocator")
Set oServices = oLocator.ConnectServer(".","root\wmi")
Set oResults = oServices.ExecQuery("select * from batteryfullchargedcapacity")
For Each oResult In oResults
    iFull = oResult.FullChargedCapacity
Next

For i=1 To 10
    Do
        i=+2
        Set oResults = oServices.ExecQuery("select * from batterystatus")
        For Each oResult In oResults
            iRemaining = oResult.RemainingCapacity
            Charging = oResult.Charging
            Discharging = oResult.Discharging
        Next

        iPercent = ((iRemaining / iFull) * 100) Mod 100
        If Charging And (iPercent > 95) Then
            MsgBox "Unplug Charger. Battery is at " & iPercent & "%", vbInformation, "Battery monitor"
        ElseIf Discharging And (iPercent < 20) Then
            MsgBox "Plug-in Charger. Battery is at " & iPercent & "%", vbInformation, "Battery monitor"
            WScript.Sleep 10000 ' 10 sec
            If Charging Then
                CreateObject("WScript.Shell").Popup "System won't hibernate", 5, "Good News!!!"
                Exit Do
            Else
                Set shell = CreateObject("WScript.Shell")
                shell.CurrentDirectory = "C:\Users\abcd\Desktop"
                CreateObject("WScript.Shell").Popup "System will hibernate", 5, "Hmm..."
                shell.Run "hibernate.bat"
                Exit For
            End If
        End If
    Loop While False
Next
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
amit
  • 29
  • 5

1 Answers1

1

This is your problem:

ElseIf Discharging And (iPercent < 20) Then
    ...
    If Charging Then
        ...
    Else
        ...
    End If
End If

The Charging and Discharging state are the inverse of each other. If Discharging is true then Charging is false and vice versa. Because of this the value of Charging is always False when you enter the ElseIf branch. And since the value of the variable reflects the state at time of assignment it's still False even after you plug in a power cord. The variable doesn't automagically update itself when the battery state changes. You need to re-evaluate the battery state after the delay to make your code work as expected. For that I'd suggest refactoring the WMI lookup into two functions:

Function IsCharging
    For Each oResult In oServices.ExecQuery("SELECT * FROM BatteryStatus")
        IsCharging = oResult.Charging
    Next
End Function

Function GetRemainingCapacity
    For Each oResult In oServices.ExecQuery("SELECT * FROM BatteryStatus")
        GetRemainingCapacity = oResult.RemainingCapacity
    Next
End Function

and use them like this:

Do
    iPercent = ((GetRemainingCapacity / iFull) * 100) Mod 100
    If IsCharging And (iPercent > 95) Then
        ...
    ElseIf Not IsCharging And (iPercent < 20) Then
        ...
        If IsCharging Then
            ...
        Else
            ...
        End If
    End If
Loop While True
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328