Система умный дом — Как научить siri исполнять маты?
Как использовать яблочный homekit в связке с Raspberry pi в качестве сервера автоматизации всех имеющихся датчиков и управляемых устройств и при этом управлять любым копеешным электрческим говном всем, что у вас есть из айфона?
Начиная с IOS 10, Аpple выпустила замечательную вещь — homekit. Вы можете видеть это в телефоне как программу Дом. Айтишные «Робин Гуды» сразу пропатчили этот функционал в правильную сторону, чтобы работать можно было с чем угодно. Даже с самым дешманским датчиком за семь рублей пятьдесят копеек, а не только со сверх-супер-пупер-сертифицированной продукцией (обычные датчики/устройства, но продаваемые за бешеные деньги с одобрения Аpple).
Для любителей коротких обзоров и желающих убедиться воочию, что из этого выходит, мы подготовили небольшое видео:
А для желающих собрать нечто подобное самостоятельно — немного терпения и добро пожаловать 🙂
Подготовка системы
Делаем апдейт и апгрейд:
1
2
|
$ sudo apt-get update
$ sudo apt-get upgrade
|
ставим git и make, если не установлены
1
|
$ sudo apt-get install git make
|
Если у вас установлена RASPBIAN JESSIE, все в порядке. У вас уже установлен необходимый компилятор, но на всякий случай лучше проверить.
Версия должна быть такой, как показано ниже:
1
2
3
|
$ g++-4.9 -v
…
gcc version 4.9.2 (Raspbian 4.9.2-10)
|
Если же у вас другой дистрибутив или версия компилятора ниже, то придется поставить:
1
|
$ sudo apt-get install g++
|
Установка NodeJS
Начиная с 4.0.0 версии NodeJS стала поддерживать ARM платформы по умолчанию. Львиная доля одноплатников работает именно на чипе ARM. Raspberry pi — не исключение.
Для желающих поставить NodeJS вручную на вашу малину или произвольный arm-одноплатник, можно воспользоваться этой ссылкой:
Установка ручками NodeJS для всех версий Raspberry pi.
Установка ручками NodeJS для Raspberry pi3.
Но стоит учесть, что homebridge, если не ошибаюсь, начинает работать с версии Nodejs 5.10 , поэтому стоит несколько модифицировать инструкции в ссылках и выбрать Nodejs посвежее.
Лично я предпочитаю не усложнять себе ситуацию совместимостью версий и поставлю последнюю доступную:
1
2
|
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash —
$ sudo apt-get install -y nodejs
|
проверяем версию:
1
2
|
$ nodejs -v
v6.9.5
|
Установка Homebridge
Устанавливаем Avahi и другие зависимости. Это необходимо для пакета mdns из библиотеки HAP-NodeJS.
1
|
$ sudo apt-get install avahi-daemon avahi-discover libnss-mdns libavahi-compat-libdnssd-dev
|
Проверьте ваши пути! Если вы все-таки ставили пакет ручками, а не через apt-get install — пути должны быть /usr/local/lib вместо /usr/lib/
Теперь ставим сам Homebridge и зависимости:
1
2
3
4
5
|
$ sudo npm install -g —unsafe-perm homebridge hap-nodejs node-gyp
$ cd /usr/lib/node_modules/homebridge/
$ sudo npm install —unsafe-perm bignum
$ cd /usr/lib/node_modules/hap-nodejs/node_modules/mdns
$ sudo node-gyp BUILDTYPE=Release rebuild
|
Можем проверить тестовым запуском:
1
2
3
4
5
6
7
8
9
10
11
12
|
$ homebridge
...
[2017—02—10 14:43:01] ——
[2017—02—10 14:43:01] config.json (/home/pi/.homebridge/config.json) not found.
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:
┌────────────┐
│ 031—45—154 │
└────────────┘
[2017—02—10 14:43:01] Homebridge is running on port 44204
...
|
Если видите что-то похожее, значит, все функционирует.
Строка: config.json (/home/pi/.homebridge/config.json) not found говорит, что не существует конфига для пользователя из-под которого мы совершили запуск. Нужно определиться с тем, из под кого мы будем запускать службу, и создать все необходимые директории и этот конфиг для выбранного пользователя.
Из-под кого все запускать? Конечно, в целях безопасности лучше из-под отдельного специально созданного пользователя, но тогда получим кучу геморроя с модулями, которые будут дергать различные системные скрипты и сценарии, придется много дебажить по каждому плагину и сценарию. Рекомендую для проверки использовать пользователя root, а в дальнейшем перевести всю работу на специально созданного пользователя. Создаем директорию и конфиг:
1
2
3
|
$ sudo -i
# mkdir /root/.homebridge
# touch /root/.homebridge/config.json
|
Пример минимального рабочего конфига можно скопировать из
/usr/lib/node_modules/homebridge/config-sample.json:
1
|
# vim /root/.homebridge/config.json
|
1
2
3
4
5
6
7
8
|
{
«bridge»: {
«name»: «My bridge to RPI»,
«username»: «CC:22:3D:E3:CE:32»,
«port»: 51827,
«pin»: «031-45-155»
}
}
|
Проверим, все ли правильно:
1
|
$ homebridge
|
Должны увидеть, что строка с отсутствием конфигурационного файла пропала.
Теперь необходимо сделать homebridge демоном и добавить его в автозагрузку. Для этого нам потребуется создать небольшой init скрипт:
1
|
# vim /etc/init.d/homebridge
|
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
|
#!/bin/sh
### BEGIN INIT INFO
# Provides: homebridge
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
dir=«/root»
cmd=«DEBUG=* /usr/bin/homebridge»
user=«root»
name=`basename $0`
pid_file=«/var/run/$name.pid»
stdout_log=«/var/log/$name.log»
stderr_log=«/var/log/$name.err»
get_pid() {
cat «$pid_file»
}
is_running() {
[ —f «$pid_file» ] && ps `get_pid` > /dev/null 2>&1
}
case «$1» in
start)
if is_running; then
echo «Already started»
else
echo «Starting $name»
cd «$dir»
if [ —z «$user» ]; then
sudo $cmd >> «$stdout_log» 2>> «$stderr_log» &
else
sudo —u «$user» $cmd >> «$stdout_log» 2>> «$stderr_log» &
fi
echo $! > «$pid_file»
if ! is_running; then
echo «Unable to start, see $stdout_log and $stderr_log»
exit 1
fi
fi
;;
stop)
if is_running; then
echo —n «Stopping $name..»
kill `get_pid`
for i in {1..10}
do
if ! is_running; then
break
fi
echo —n «.»
sleep 1
done
echo
if is_running; then
echo «Not stopped; may still be shutting down or shutdown may have failed»
exit 1
else
echo «Stopped»
if [ —f «$pid_file» ]; then
rm «$pid_file»
fi
fi
else
echo «Not running»
fi
;;
restart)
$0 stop
if is_running; then
echo «Unable to stop, will not attempt to start»
exit 1
fi
$0 start
;;
status)
if is_running; then
echo «Running»
else
echo «Stopped»
exit 1
fi
;;
*)
echo «Usage: $0 {start|stop|restart|status}»
exit 1
;;
esac
exit 0
|
Делаем скрипт исполняемым и добавляем в стандартные уровни загрузки:
1
2
|
# chmod 755 /etc/init.d/homebridge
# update-rc.d homebridge enable
|
Теперь при загрузке homebridge будет стартовать автоматически.
Проверим запуск и останов в ручном режиме, все должно отрабатывать:
1
2
3
4
5
6
7
|
# /etc/init.d/homebridge start
Starting homebridge
# /etc/init.d/homebridge status
Running
# /etc/init.d/homebridge stop
Stopping homebridge..
Stopped
|
Последний штрих — добавление аксессуара «My bridge to RPI» в homekit вашего айфона.
Для этого в айфоне должен быть включен bluetooth и оба девайса должы находится в одной сети WiFi.
Останавливаем службу homebridge, если она запущена и запускаем из-под root homebridge в интерактивном режиме:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# service homebridge stop
Stopping homebridge..
Stopped
# homebridge
…
[2017-02-10 14:43:01] —
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:
┌────────────┐
│ 031-45-155 │
└────────────┘
[2017-02-10 14:43:01] Homebridge is running on port 54204
…
|
Заходим в приложение Дом на айфоне, создаем новый дом, и нажимаем ‘добавить аксессуар’. Включится поиск (bluetooth должен работать на всех девайсах) и вскоре будет обнаружен ваш мост «My bridge to RPI». Добавляем мост, вводим руками пароль из homebridge (пароль из рамочки), со всем соглашаемся, радуемся!
Готово. Можно проверить перезагрузкой малины ваш результат: после перезагрузки мост должен снова стать активен в вашем телефоне.
Установка плагинов homebridge
Переходим к вопросам насущным: ноду поставили, а как присобачить в нее наше имеющееся добро?
Потребуются плагины. Можно писать самим, если квалификация позволяет, можно воспользоваться готовыми.
Мы поставим несколько простых и в то же время очень мощных инструментов — это плагины включения, выключения и димирования ваших устройств. Для примера этого хватит. В дальнейшем рекомендую поискать в разделе плагинов что-то в духе термометра/влажности/объемника из файла или скрипта, чтобы окончательно перекрыть вопросы с имеющимися у вас датчиками и устройствами, не поддерживающими прямую коммуникацию с apple.
cmdswitch2
Простое включение/выключение устройств из скриптов. Ставим:
1
|
$ sudo npm install -g homebridge-cmdswitch2
|
homebridge-cmd_light_control
Включение/выключение/димирование света скриптами. Ставим:
1
|
$ sudo npm install -g homebridge-cmd_light_control
|
Теперь нам необходимо скорректировать конфигурационный файл homebridge и добавить в него ваши имеющиеся девайсы. Для примера будет лампа и вентилятор, подключенные через реле на 220 вольт.
1
|
# vim /root/.homebridge/config.json
|
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
|
{
«bridge»: {
«name»: «My bridge to RPI»,
«username»: «CC:22:3D:E3:CE:32»,
«port»: 51827,
«pin»: «031-45-155»
},
«accessories»: [
{
«accessory»: «CMD»,
«service»: «Light»,
«brightnessHandling»: «no»,
«name»: «лампа»,
«on_cmd»: «/home/pi/light_on.py»,
«off_cmd»: «/home/pi/light_off.py»,
«get_status_cmd»: «/home/pi/light_state.py»
}],
«platforms»: [{
«platform»: «cmdSwitch2»,
«switches»: [{
«name» : «вентилятор»,
«on_cmd»: «/home/pi/spin_on.py»,
«off_cmd»: «/home/pi/spin_off.py»,
«state_cmd»: «/home/pi/spin_state.py»
«manufacturer»: «рога и копыта»,
«model»: «допотопный вращатель»,
«serial»: «шта?»
}]
}]
}
|
Как видно из конфига, все управляется скриптами и обратная связь происходит тоже через скрипт. И это прекрасно! Ниже приведу простейшие примеры включения/выключения реле 220v и их обратного контроля, которые будут коммутировать фазу лампы и вентилятора. Кстати, кто не знает, как подключить такие реле и где нужно быть аккуратным — вам стоит прочитать подобную инструкцию. Рекомендую подойти ответственно и очень внимательно прочесть, если еще не сталкивались с управлением и коммутацией 220V.
1
2
3
4
5
6
7
|
#!/usr/bin/env python
import RPi.GPIO as GPIO
gpio_pin_number=20
GPIO.setmode(GPIO.BCM) # BCM pin numbering
GPIO.setwarnings(False)
GPIO.setup(gpio_pin_number, GPIO.OUT)
GPIO.output(gpio_pin_number, GPIO.HIGH)
|
1
2
3
4
5
6
7
|
#!/usr/bin/env python
import RPi.GPIO as GPIO
gpio_pin_number=20
GPIO.setmode(GPIO.BCM) # BCM pin numbering
GPIO.setwarnings(False)
GPIO.setup(gpio_pin_number, GPIO.OUT)
GPIO.output(gpio_pin_number, GPIO.LOW)
|
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
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
from subprocess import Popen, PIPE
pin_number=20
proc = Popen(
«echo %s > /sys/class/gpio/export» % pin_number,
shell=True,
stdout=PIPE, stderr=PIPE
)
proc.wait()
proc = Popen(
«cat /sys/class/gpio/gpio%s/value» % pin_number,
shell=True,
stdout=PIPE, stderr=PIPE
)
proc.wait()
res = proc.communicate() # get tuple(‘stdout’, ‘stderr’)
count = res[0].replace(«n»,«»)
count = int(count)
if count == 0:
id=0
else:
print(‘1’).replace(«n»,«»)
|
Для лампы скрипты полностью аналогичны, только смените pin, на который вы подключаете сигнальный провод реле лампы. Делаем все скрипты исполняемыми, при необходимости ставим питоновские библиотеки для корректного исполнения скриптов.
Перезапускаем homebridge:
1
|
# service homebridge restart
|
Заходим в айфон, в приложение дом — должны появиться 2 новых девайса.
Ура! Реле подключены как управляемые выключатель (switch) и лампа. Все, теперь мы владельцы сертифицированного и одобренного Apple вентилятора 89-го года выпуска и умнейшей диодной лампы за 32 рубля!
Шугар-он-топ
«Где же обещанные маты?» — спросите вы. Все просто:
снова идем в приложение Дом, нажимаем на плюсик, добавляем сценарий, выбираем пользовательский и именуем сценарий как хотим. Тоже самое касается девайсов. Их можно переименовывать как угодно. Стоит учесть регистр — иногда он влияет на результат распознания. В процессе распознания Siri пишет с заглавной только первое слово, а при именовании сценария — заглавная буква вылезает после каждого пробела.
Также хочу привести пример возможных команд по управлению устройствами для Siri. Хоть пример и на английском, но думаю, вам не составит труда перевести эти незамысловатые фразы:
“Turn on the lights” or “Turn off the lights.”
“Dim the lights” or “Set the brightness to 50%.”
“Set the temperature to 68 degrees.”
“Turn on the coffee maker.”
“Turn on the upstairs lights.”
“Turn off Chloe’s light.”
“Turn down the kitchen lights”
“Dim the lights in the dining room to 50%.”
“Make the living room lights the brightest.”
“Set the Tahoe house to 72 degrees.”
“Set the thermostat downstairs to 70.”
“Turn on the printer in the office.”
“Set up for a party, Siri.”
“Set the dinner scene.”
“Set my bedtime scene.”
Последние 3 фразы относятся к сценариям.
Ложка дегтя в бочке меда
Увы, сейчас нет возможности (может, мы об этом не знаем) нормально работать с Siri через SiriProxy.
С точки зрения мата, да и вообще произвольных речевых конструкций, SiriProxy — полная свобода действий. В ней можно было закладывать в свои программы различные фразы, проксируя распознанные запросы. Это было шикарно 🙂
Но, увы, протокол и логику Siri несколько переписали и с 7 версии IOS и выше SiriProxy работает в холостую. Согласитесь, жить на IOS6 сейчас будет несколько проблемно. Но мы не расстраиваемся и ждем очередной дыры подарков от Apple в использовании функционала на свое усмотрение!
алиса умный дом