Привет, Хабр!
Я живу в Москве и у меня во дворе, как и у многих, установлен шлагбаум. Некоторое время назад я задался вопросом, как мне упростить процесс его открытия? Хотелось, чтобы можно было добавлять это действие в сценарии умного дома, открывать по кнопке в авто, давать друзьям возможность открывать его самостоятельно и т.д. Частично я решил проблему еще в прошлом году, но недавно всё "допилил" и решил поделиться.
Для начала уточню, что в моем дворе используется шлагбаум Интеллект-Парк. Для его открытия существует три способа:
Звонок по телефону с авторизованного номера.
Официальное приложение.
Телеграм бот.
Первый вариант не подходит для автоматизаций по очевидным причинам. Второй вариант я в итоге не рассматривал по причине того, что один номер телефона можно использовать в приложении только на одном устройстве. Таким образом, я пришел к третьему варианту.
Для открытия шлагбаума через Телеграм бота нужно авторизоваться в нем (в боте) с зарегистрированного номера, после чего написать боту ряд команд. Общий процесс открытия шлагбаума выглядит примерно так:
Как же автоматизировать общение с ботом? Разумеется, написать другого бота! К сожалению, боты не могут писать сообщения друг другу. Да и писать данному боту нужно с зарегистрированного номера телефона. Поэтому пришлось писать юзербота на Python с использованием библиотеки Telethon. Разумеется, юзер бот должен использовать номер телефона, зарегистрированный в системе Интеллект-Парк.
Мой юзербот при запуске пишет официальному боту Интеллект-Парка, после чего правильно отвечает на его сообщения и завершает работу. Также я сделал таймаут 10 секунд, чтобы в случае проблем бот не крутился бесконечно. Код привожу ниже:
from telethon import TelegramClient, events
import asyncio
api_id = # Тут api_id для бота
api_hash = # Тут api_hash для бота
bot_name = 'intelpark_bot'
result = "ERROR"
client = TelegramClient('barrier_opener', api_id, api_hash)
@client.on(events.NewMessage(chats=(bot_name)))
async def handler(event):
if event.message.message[:16] == "Вот, что я умею:":
await client.send_message(bot_name, '/open_gate')
elif event.message.message == "Какой шлагбаум нужно открыть?":
await client.send_message(bot_name, 'Тут должен быть адрес, #1')
elif event.message.message in ("Готово."):
global result
result = "OK"
await client.disconnect()
else:
await client.send_message(bot_name, '/start')
async def main():
await client.send_message(bot_name, '/start')
for i in range(10):
await asyncio.sleep(1)
if result == "OK":
break
print(result)
client.start()
with client:
client.loop.run_until_complete(main())
Супер. Теперь можно просто запустить команду python3 ./bot.py
и шлагбаум откроется!
Я поместил скрипт на свой домашний Raspberry Pi и довольно долгое время для всех автоматизаций использовал подключение по SSH и вызов скрипта. Но это было достаточно неудобно, плюс после недавнего обновления OS Raspbian у меня почему-то перестали проходить SSH соединения с некоторых устройств. Как я понял, это как-то связано со сменой используемых протоколов шифрования, но до конца я не разбирался. Поэтому я решил поднять простой REST сервис на той же малинке, чтобы можно было открывать шлагбаум просто по HTTP-запросу.
Для сервиса использовал библиотеку Flask. Там все совсем просто, код ниже:
from flask import Flask
import subprocess
app = Flask(__name__)
@app.route('/open_gate')
def open_barrier():
result = subprocess.check_output('cd /home/pi/gate_opener/; python3 gate_opener.py', shell=True)
return result
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7092)
Порт я выбрал произвольный не занятый и добавил конкретный route. На мой взгляд, этого достаточно, чтобы не настраивать дополнительную авторизацию, и чтобы при этом различные ботнеты не постучались ко мне случайно. Сам скрипт я поставил на автозапуск на крон, а на роутере сделал проброс портов. Теперь для открытия шлагбаума можно просто делать cURL на http://<мой_ip>:7092/open_gate, либо открыть этот же адрес в браузере.
Ну и, собственно, последний шаг. Использование данной автоматизации в автомобиле для открытия шлагбаума по кнопке. У меня в автомобиле есть Android магнитола, а на руле есть кнопка голосового поиска, которую я совсем не использую. Поэтому я повесил открытие шлагбаума на нее. Для этого можно использовать любое средство автоматизации Android, я лично предпочитаю Automagic Automation. В конкретно моем случае достаточно было установить Automagic Automation в качестве голосового ассистента по умолчанию, а далее сделать flow, который по нажатию кнопки дергал бы HTTP запрос. Кому интересно, ниже картинка получившегося потока:
Теперь я просто подъезжаю на машине к шлагбауму, нажимаю кнопку на руле, и шлагбаум открывается. Красота!
Имеющийся URL можно использовать во многих сценариях умного дома, а также выдавать близким людям, чтобы приезжая в гости они могли самостоятельно открывать шлагбаум, не прося вас об этом.
На этом все!