forked from rajbos/home-automation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcamera-check.ps1
167 lines (140 loc) · 5.48 KB
/
camera-check.ps1
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#Requires -RunAsAdministrator
. $PSScriptRoot/import-env.ps1
# Utils provides Write-Host to prepends the log message with a date
Write-Host "Current PSScriptRoot [$PSScriptRoot]"
. $PSScriptRoot/utils.ps1
$location = Get-Location
# Provide handle yourself, by downloading it from: https://learn.microsoft.com/en-us/sysinternals/downloads/handle
$handleExe = "$location\Handle\handle64.exe"
# Verify that the device is connected to the pre-defined network
function CheckNetworkName {
$connectedNetwork = (Get-NetConnectionProfile).Name
$predefinedNetworkName = $env:network_name
return ($connectedNetwork -like "*$predefinedNetworkName*")
}
# Function to check whether a specified camera device is in use
function Check-Device {
param(
[object] $device
)
# load Physical Device Object Name
$property = Get-PnpDeviceProperty -InstanceId $device.InstanceId -KeyName "DEVPKEY_Device_PDOName"
if ($property.Data.Length -eq 0) {
Write-Message "No PDON found for [$($device.FriendlyName)] so skipping it"
return
}
Write-Message "Checking handles in use for [$($device.FriendlyName)] and PDON [$($property.Data)]"
$handles = $(& $handleExe -NoBanner -a "$($property.Data)")
if ($handles -gt 0) {
# Check if any handles for this device are found
if ($handles -is [string] -and $handles.ToLower().StartsWith("no matching handles found")){
Write-Message " - No handles found for [$($device.FriendlyName)]"
}
else {
# Print all processes using the camera to the standard out
Write-Message " - Found [$($handles.Length)] handles on $($device.FriendlyName)"
$processes = @()
foreach ($handle in $handles) {
# remove all spaces
$nospaceshandle = $handle.Replace(" ", "")
if ($nospaceshandle.Length -gt 0) {
$splitted = $handle.Split(" ")
$process = $splitted[0]
if (!($processes.Contains($process))) {
$processes += $process
}
}
}
# Print the result of the handle check and return true if handles were found
if ($processes.Length -eq 0) {
Write-Message " - No handles found for [$($device.FriendlyName)]"
}
else {
foreach ($process in $processes) {
Write-Message " - Found process [$($process)] that has a handle on [$($device.FriendlyName)]"
Write-Host "$(Get-Date -Format "HH:mm:ss") " $process -ForegroundColor Green
return $true
}
}
}
}
return $false
}
# Find every camera device on the system and check whether it is in use
function Get-CameraActive {
$deviceFilter = $env:webcam_filter
Write-Message "Searching for camera devices..."
$devices = Get-PnpDevice -Class Camera
Write-Message "Found [$($devices.Count)] potential camera devices before wildcard filter"
foreach ($device in $devices) {
# If a filter for the name is specified, filter on it
if ($device.FriendlyName -notlike "*$deviceFilter*") {
continue
}
$result = Check-Device $device
if ($result) {
Write-Message "Found active camera device"
return $true
}
}
return $false
}
function LoopWithAction {
while ($true) {
# Main script
if (-Not (CheckNetworkName)) {
Write-Message "Device is connected not to the predefined network."
exit
}
$start = Get-Date
$logonui = Get-Process logonui -ErrorAction SilentlyContinue
if ($null -ne $logonui) {
# if logonui is running, the user is not logged in at all, so if the lights are already off, we can stop the execution
Write-Message "Found logonui process"
$state = getEntityState -entityId $entityId
Write-Message "Current entity state is [$($state.state)]"
if ($state.state -ne "on") {
Write-Message "The lights are off already and the user is not authenticated, skipping all checks"
}
}
$active = Get-CameraActive
Run-Action $active
# don't run again unless 30 seconds have passed
$end = Get-Date
$duration = $end - $start
$sleep = $env:sleep
$sleepTime = $sleep-$duration.TotalSeconds
if ($duration.TotalSeconds -lt $sleep) {
Write-Message "Sleeping for $(($sleepTime).ToString('#')) seconds"
Start-Sleep ($sleepTime)
}
}
}
function Run-Action {
param(
[bool] $active = $false
)
Write-Message "Running action to make the state [$active]"
. $PSScriptRoot/trigger-homeassistant.ps1
$state = getEntityState
Write-Message "Current entity state is [$($state.state)]"
if ($active) {
if ($state.state -eq "on") {
Write-Message "Already active, no need to do anything"
}
else {
Write-Message "Turning on"
setState -state $True
}
}
else {
if ($state.state -eq "off") {
Write-Message "Already off, no need to do anything"
}
else {
Write-Message "Turning off"
setState -state $False
}
}
}
LoopWithAction