Skip to content

Instantly share code, notes, and snippets.

@inamesh
Created June 18, 2020 09:49
Show Gist options
  • Save inamesh/afe9866560c5ff481bd38805695f8d7d to your computer and use it in GitHub Desktop.
Save inamesh/afe9866560c5ff481bd38805695f8d7d to your computer and use it in GitHub Desktop.
Keep laptop battery charged between 50 to 80% (or other custom limits). At home/office it can turn off the smart plug that the charger is connected to, and while away it will popup a message when the specified limit is breached. Home/away is detected using the Wireless network name.
#
#
##************************************* INFO SECTION *******************************
#
#
# This script tests the current battery status and uses that information to :
# a) AT HOME: Turn the smart Plug on/off
# b) AWAY: Alert the user
# See all available battery info using Get-wmiobject win32_battery |Format-List *
# win32_battery documentation here: https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-battery
#
# inspiration: https://www.petri.com/building-battery-manager-powershell
#
#
##************************************* CONSTANTS SECTION **************************
# For settings and other initialisation constants
#
$homeNetworks =@("NETWORK NAME")
$expectedStatuses =@(1,2)
$expectedAvailabilities =@(2,3)
$chargingStatuses =@(2)
$chargingAvailabilities =@(2)
$homeBatteryFloor = 60
$homeBatteryCeiling = 70
$awayBatteryFloor = 52
$awayBatteryCeiling = 78
#URLs of the respective IFTTT Recipes
$offURL = "https://maker.ifttt.com/trigger/EVENT_NAME/with/key/xxxxxKEYxxxxx"
$onURL = "https://maker.ifttt.com/trigger/EVENT_NAME/with/key/xxxxxKEYxxxxx"
#Boolean for quickly disabling automated switch on/off, and using alerts only
$automationEnabled = $true
#All values initialised to the "not at home" environment
$atHome = $false
$isCharging = $false
$batteryFloor = $awayBatteryFloor
$batteryCeiling = $awayBatteryCeiling
# Availability on Surface pro 2017 is -
# "3 (Running - Full Power)" on battery and "2 (Unknown)" while charging
# This Hashtable helps translate the numbers if needed
$availabilityTranslator=@{
1 = "Other"
2 = "Unknown"
3 = "Running - Full Power"
4 = "Warning"
5 = "In Test"
6 = "Not Applicable"
7 = "Power Off"
8 = "Off Line"
9 = "Off Duty"
10 = "Degraded"
11 = "Not Installed"
12 = "Install Error"
13 = "Power Save - Unknown"
14 = "Power Save - Low Power Mode"
15 = "Power Save - Standby"
16 = "Power Cycle"
17 = "Power Save - Warning"
18 = "Paused"
19 = "Not Ready"
20 = "Not Configured"
21 = "Quiesced"
}
# Status is weird because it never shows charging on Surface Pro 2017.
# Currently observed values are -
# "1 (Other)" - on Battery, "2 (Unknown)" while charging
# This Hashtable helps translate the numbers if needed
$statusTranslator=@{
1 = "Other"
2 = "Unknown"
3 = "Fully Charged"
4 = "Low"
5 = "Critical"
6 = "Charging"
7 = "Charging High"
8 = "Charging Low"
9 = "Charging Critical"
10 = "Undefined"
11 = "Partially Charged"
}
#
#
##************************************* OPERATIONAL SECTION **************************
#
#
#Get Currently connected WiFi network to determine if "At Home" or not
$currconn = Get-NetConnectionProfile | ?{$_.InterfaceAlias -eq "WiFi"}| select -exp Name
If ($automationEnabled -and ($currconn.count -eq 1) -and ($currconn -in $homeNetworks))
{
$atHome = $true
$batteryFloor = $homeBatteryFloor
$batteryCeiling = $homeBatteryCeiling
#Write-Host "AT Home Bro!"
}
#No "else" needed here since the intialized values correspond to "Not At Home"
#Get just the required properties and convert them to int
$battStat = Get-wmiobject win32_battery |
select @{Name = "PercentCharged";Expression={$_.EstimatedChargeRemaining -As [int]}},
@{Name = "Availability"; Expression = {$_.Availability -as [int]}},
@{Name = "BatteryStatus"; Expression = {$_.BatteryStatus -as [int]}}
#If unexpected values are encountered, prompt and exit
If ( ($battStat.BatteryStatus -notin $expectedStatuses) -or ($battStat.Availability -notin $expectedAvailabilities))
{
$message = -join
(
"Unexpected value(s).`n",
"Availability = $($availabilityTranslator.Item($battStat.Availability))`n",
"Status = $($statusTranslator.Item($battStat.BatteryStatus))`n",
"What Do?"
)
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup($message,0,"Battery Limiter PROBLEM !?",0)
return
}
#2 and 2 are the observed values for Availability and Status when charging
if (($battStat.Availability -in $chargingAvailabilities) -and ($battStat.BatteryStatus -in $chargingStatuses))
{
$isCharging = $true
}
$breachedCeiling = $battStat.PercentCharged -ge $batteryCeiling
$breachedFloor = $battStat.PercentCharged -le $batteryFloor
If ($atHome -and $isCharging -and $breachedCeiling)
{
Invoke-RestMethod $offURL
}
# Else If at home, not charging and at or below floor level, start charging automatically
ElseIf ($athome -and -Not($isCharging) -and $breachedFloor)
{
Invoke-RestMethod $onURL
}
ElseIf (-Not($atHome) -and (($isCharging -and $breachedCeiling) -or (-Not($isCharging) -and $breachedFloor)))
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Battery is at $($battStat.PercentCharged)%. Do what needs to be done",0,"Battery Limit Reached",16)
}
Else
{
#$wshell = New-Object -ComObject Wscript.Shell
#$wshell.Popup("Battery is at $($battStat.PercentCharged)%. For your eyes only.",0,"Script Tester",64)
#Popup options - https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/x83z1d9f(v=vs.84)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment