Открываем шлагбаум кнопкой на руле автомобиля

Привет, Хабр!

Я живу в Москве и у меня во дворе, как и у многих, установлен шлагбаум. Некоторое время назад я задался вопросом, как мне упростить процесс его открытия? Хотелось, чтобы можно было добавлять это действие в сценарии умного дома, открывать по кнопке в авто, давать друзьям возможность открывать его самостоятельно и т.д. Частично я решил проблему еще в прошлом году, но недавно всё «допилил» и решил поделиться.

Для начала уточню, что в моем дворе используется шлагбаум Интеллект-Парк. Для его открытия существует три способа:

  1. Звонок по телефону с авторизованного номера

  2. Официальное приложение

  3. Телеграм бот

Первый вариант не подходит для автоматизаций по очевидным причинам. Второй вариант я в итоге не рассматривал по причине того, что один номер телефона можно использовать в приложении только на одном устройстве. Таким образом, я пришел к третьему варианту.

Для открытия шлагбаума через Телеграм бота нужно авторизоваться в нем (в боте) с зарегистрированного номера, после чего написать боту ряд команд. Общий процесс открытия шлагбаума выглядит примерно так:

Да, команда не одна, их несколькоДа, команда не одна, их несколько

Как же автоматизировать общение с ботом? Разумеется, написать другого бота! К сожалению, боты не могут писать сообщения друг другу. Да и писать данному боту нужно с зарегистрированного номера телефона. Поэтому пришлось писать юзербота на 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 запрос. Кому интересно, ниже картинка получившегося потока:

Сам flowСам flow

Теперь я просто подъезжаю на машине к шлагбауму, нажимаю кнопку на руле, и шлагбаум открывается. Красота!

Имеющийся URL можно использовать во многих сценариях умного дома, а также выдавать близким людям, чтобы приезжая в гости они могли самостоятельно открывать шлагбаум, не прося вас об этом.

На этом все!

© Habrahabr.ru