А АThursday, 11 January 2018

Как управлять Wanscam камерой с помощью Powershell?

Всем привет.

Как управлять Wanscam камерой с помощью Powershell?

Автор идеи купил китайскую wanscam вебкамеру с wifi, инфракрасной подсветкой, микрофоном, динамиком, поворотным механизмом и web-интерфейсом. И решил автор сделать из этой web-камеры что-то вроде домашней видео-охраны.

Как он пишет идея была следующая: пингуем смартфоны или ноутбуки дома, если пингуются - значит кто-то есть дома, если не пингуются - значит дома, скорее всего, никого нет, или они просто забыты. Когда дома никого нет - камера поворачивается в сторону, например, двери и включается в режим "motion alarm", то есть оповещает нас если что-либо в кадре начинает двигаться. Если же дома кто-то есть - отключаем "motion alarm" и поворачиваем камеру в стенку.

Что делать с любимой кошкой?) Ограничить область сканирования уровнем выше полуметра от пола. Или ничего не делать, ибо кошки не так активны днем как нам кажется.


А вот его Powershell скрипт с помощью которого это все было реализовано:


#Общие параметры
$hour = (Get-Date).Hour #текущее время
$date = Get-Date -format dd-MM-yyyy
$file_temp = "C:\Temp\WebCam\camera.txt"
$file_log =  "C:\Temp\WebCam\Camera_log-" + $date + ".txt"
$ping = new-object System.Net.NetworkInformation.Ping


#Сетевые параметры
#увы, но пароль к камере здесь в открытом виде
$camera_user_pass = "user=CameraUser&pwd=CameraPassword"
$camera_ip = "192.168.2.30"
$camera_ip_port = "http://"+$camera_ip+":8888/"
$mail_username = "MyHouse"
$mail_from = $mail_username+"@gmail.com"
$mail_to = "HugMe@gmail.com"
#пароль к gmail тоже в открытом виде
$mail_pass = "mail_password"
$wifi_ip = "192.168.2.10"  #телефон автора
$wifi_ip2 = "192.168.2.11" #резервный
$wifi_ip3 = "192.168.2.12" #ноут


#А доступна ли web-камера по ping?
$i = 0;$time = 'timeout'
While (($i -lt 3) -and ($time -eq 'timeout')) {
 $i++
 $reply = $ping.send($camera_ip) #пинг в адрес камеры
 $time = $reply.RoundtripTime
#Упс, а наша камера недоступна. Надо об этом срочно сообщить мне!
 if (($reply.status -ne "Success") -and ($i -eq 3)){
  write-host "send mail"
#заголовки сообщения
  $SMTPServer = "smtp.gmail.com"
  $SMTPPort = "587"
  $subject = "Camera Timeout"
  $body = "Camera Timeout"
#текст в формате HTML
  $message = New-Object System.Net.Mail.MailMessage $mail_from, $mail_to
  $message.Subject = $subject
  $message.IsBodyHTML = $true
  $message.Body = $body
  $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort)
  $smtp.EnableSSL = $true
  $smtp.Credentials = New-Object System.Net.NetworkCredential($mail_username, $mail_pass)
отправляем сообщение
  $smtp.Send($message)
 }
}

#Ищем наши гаджеты дома
$time = 'timeout'
Write-host "Start Ping"
$IPArray = "$wifi_ip", "$wifi_ip2", "$wifi_ip3"
$logtime = "{0:dd-MM-yyyy HH:mm:ss}" -f (get-date)
ForEach ($Adr in $IPArray) {
$reply = $ping.send($Adr)
  if ($reply.status -eq "Success"){
   $time = $reply.RoundtripTime
   $string = "$logtime $Adr : $time"
   $string | Out-File -Append $file_log -Encoding UTF8
  }
 Write-host "Ping $i : $time"
}


#Получаем статус камеры согласно "IP Camera CGI Manual".
#get_params.cgi
#Description: Gain device parameters set
#Grammer: /get_params.cgi[?user=&pwd=]
$webclient = New-Object System.Net.WebClient
$url = $camera_ip_port+"get_params.cgi?"+$camera_user_pass
$webclient.DownloadFile($url,$file_temp)
#$Error[0].Exception.InnerException.ToString() #детальный вывод ошибки
#читаем содержимое файла в масив построчно и берем из 149-й строки статус согласно "IP Camera CGI Manual".
$file = Get-Content $file_temp
$motion_status = $file[149]


# Mode 1: слежение установлено, хост доступен, не время сна. Oтключаем слежение и поворачиваем камеру в стену.
if (($motion_status -eq "var alarm_motion_armed=1;")-and(($time -ne "timeout")-and($hour -gt 7))) {
 write-host "отключаем слежение"
#set_alarm.cgi
 $url = $camera_ip_port+"set_alarm.cgi?motion_armed=0&"+$camera_user_pass #отключаем слежение
 $webclient.DownloadFile($url,$file_temp)
 $motion_status = "var alarm_motion_armed=0;"
#decoder_control.cgi
 $url = $camera_ip_port+"decoder_control.cgi?command=37&"+$camera_user_pass #поворачиваем в стену
 $webclient.DownloadFile($url,$file_temp)
}


# Mode 2: слежение не установлено, хост не доступен или время сна. Включаем слежение и поворачиваем на правильный фокус.
if (($motion_status -eq "var alarm_motion_armed=0;")-and(($time -eq "timeout")-or($hour -le 7))) {
 write-host "Включаем слежение"
 $url = $camera_ip_port+"set_alarm.cgi?motion_armed=1&"+$camera_user_pass #включаем слежение
 $webclient.DownloadFile($url,$file_temp)
 $motion_status = "var alarm_motion_armed=1;"
 $url = $camera_ip_port+"decoder_control.cgi?command=31&"+$camera_user_pass #фокус
 $webclient.DownloadFile($url,$file_temp)
}
#Записываем в журнал время и статус слежения
$string = "$logtime $motion_status"
$string | Out-File -Append $file_log -Encoding UTF8

В данном примере автор пинговал только свой телефон, телефон жены и ноут, но можно добавить в условия и другие ip-адреса (IPArray).  URL-команды можно почерпнуть из документации к камере "IP Camera CGI Manual". Как видите скрипт сравнительно не сложен. Я его малость поправил для наглядности. Кстати надо бы исключить из работы лишний код для выполнения в случае если камера не пингуется. Это вам для домашней разминки. Осталось лишь создать задачу (например, на включенном ноутбуке) в планировщике заданий, которая бы выполняла этот скрипт с некоторой периодичностью.

И еще один важный момент: сamera_ip - это внутренний IP-адрес вашей домашней подсети. Его надо вывести в Интернет, чтобы вы могли до него достучаться извне.

Для этого у нас есть два варианта:
1) можно поднять дома openvpn сервер и подключаться к нему. В результате будет доступ ко всем внутренним ресурсам по шифрованному каналу.
То есть дома у вас будет поднят VPN-сервер, а на вашем смартфоне VPN-клиент.
vpn — https://elims.org.ua/blog/openvpn-server-na-windows-kak-nastroit/
2) можно пробросить порт.

Powershell рулит однозначно. Пробуйте.



No comments:

Post a Comment

А что вы думаете по этому поводу?

Версия на печать

Популярное