-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGet-MonitorStatus.ps1
More file actions
135 lines (122 loc) · 5.1 KB
/
Get-MonitorStatus.ps1
File metadata and controls
135 lines (122 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<#
.NOTES
Name: Get-MonitorStatus.ps1
Author: Danny de Vries
Requires: PowerShell v2 or higher
Version History: https://github.com/EBOOZ/Get-MonitorStatus/commits/main
.SYNOPSIS
Sets the status of an external monitor to Home Assistant.
.DESCRIPTION
This script is monitoring connected monitors, and it makes use of one sensor that
is created in Home Assistant up front. The use case for this script is to monitor
if my laptop is connected to the external monitor in my home office, and to mute
the radio automatically either in the home office or downstairs in the kitchen,
depending on where I'm working in the house.
Refer to https://edid.tv/manufacturer/ for the manufacturer ID of your monitor.
.PARAMETER RunOnce
Run the script with the RunOnce-switch to get the current connected monitors
directly from the commandline. Get the serial number of both your internal (when
you're using a laptop) and external home office monitors to configure Settings.ps1
.EXAMPLE
.\Get-MonitorStatus.ps1 -RunOnce
#>
# Configuring parameter for interactive run
param (
[switch]$RunOnce
)
# Import Settings PowerShell script
. ($PSScriptRoot + "\Settings.ps1")
# Properties like ManufacturerName, UserFriendlyName, and SerialNumberID are stored as byte arrays and need to be decoded to human-readable strings.
function Convert-MonitorProperty {
param (
[byte[]]$Property
)
# Filter out null bytes and convert to string
$chars = $Property | Where-Object { $_ -ne 0 } | ForEach-Object { [char]$_ }
-join $chars
}
# Run the script when a parameter is used and stop when done
If ($RunOnce) {
$monitors = Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID
Write-Output "Number of connected monitors: $($monitors.instanceName.Count)"
ForEach ($monitor in $monitors) {
$instanceName = $monitor.InstanceName
$manufacturer = Convert-MonitorProperty -Property $monitor.ManufacturerName
$productCode = Convert-MonitorProperty -Property $monitor.ProductCodeID
$serialNumber = Convert-MonitorProperty -Property $monitor.SerialNumberID
$friendlyName = Convert-MonitorProperty -Property $monitor.UserFriendlyName
# Display monitor information
Write-Output "-----------------------------"
Write-Output "Instance Name: $instanceName"
Write-Output "Manufacturer: $manufacturer"
Write-Output "Product Code: $productCode"
Write-Output "Serial Number: $serialNumber"
Write-Output "Friendly Name: $friendlyName"
# Check if the monitor is external
If ($serialNumber -eq $externalMonitor) {
Write-Output "-----------------------------"
Write-Output "Home office monitor detected: $friendlyName"
Write-Output ""
}
ElseIf ($serialNumber -notlike $builtInMonitor -and $serialNumber -ne $externalMonitor) {
Write-Output "-----------------------------"
Write-Output "External monitor detected: $friendlyName"
Write-Output ""
}
}
break
}
DO {
# Start monitoring connected monitors when no switch is used to run the script
$headers = @{"Authorization"="Bearer $HAToken";}
$Enable = 1
# Check if the configured external monitor of the home office is connected
$monitors = Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID
ForEach ($monitor in $monitors) {
$instanceName = $monitor.InstanceName
$manufacturer = Convert-MonitorProperty -Property $monitor.ManufacturerName
$productCode = Convert-MonitorProperty -Property $monitor.ProductCodeID
$serialNumber = Convert-MonitorProperty -Property $monitor.SerialNumberID
$friendlyName = Convert-MonitorProperty -Property $monitor.UserFriendlyName
# Check if the monitor is external
If ($serialNumber -eq $builtInMonitor) {
Write-Output "Internal monitor detected: $friendlyName"
$HomeOfficeMonitor = 0
}
ElseIf ($serialNumber -eq $externalMonitor) {
Write-Output "Home office monitor detected: $friendlyName"
$HomeOfficeMonitor = 1
}
ElseIf ($serialNumber -notlike $builtInMonitor) {
Write-Output "External monitor detected: $friendlyName"
$HomeOfficeMonitor = 0
}
}
# Configure the API call parameters based on the monitor status
If ($HomeOfficeMonitor -eq 1) {
$Monitor = "on"
$params = @{
"state"="on";
"attributes"= @{
"icon"="mdi:monitor";
"device_class"="connectivity";
}
}
}
Else {
$Monitor = "off"
$params = @{
"state"="off";
"attributes"= @{
"icon"="mdi:monitor-off";
"device_class"="connectivity";
}
}
}
# Calling the Home Assistant API to set the monitor status
Write-Output "Updating home office monitor status in Home Assistant to $Monitor"
$params = $params | ConvertTo-Json
Invoke-RestMethod -Uri "$HAUrl/api/states/$entityID" -Method POST -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($params)) -ContentType "application/json"
# Wait for the next interval to check the monitor status
Start-Sleep $Interval
} Until ($Enable -eq 0)