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

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

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

  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 можно использовать во многих сценариях умного дома, а также выдавать близким людям, чтобы приезжая в гости они могли самостоятельно открывать шлагбаум, не прося вас об этом.

На этом все!

Комментарии (44)


  1. dmitrybelsky
    29.04.2022 01:58

    А зачем RPi? Не проще бесплатный питонохостинг юзать для тех же целей?


    1. Lonsdaleite Автор
      29.04.2022 02:02
      +4

      RPI уже есть дома всегда включённый, а ресурсов тут много не надо. Да и к тому же с этими виртуалками сейчас не все ясно. Например моя «вечно бесплатная» виртуалка от Оракла на днях должна превратиться в тыкву. Админку уже отобрали.

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


      1. dmitrybelsky
        29.04.2022 02:05

        Использовать основной телеграм-эккаунт вообще не комильфо для таких целей с точки зрения ИБ, имхо. 

        Но, кажется, даже из вашего опыта, стабильность RPI тоже не идеальна. Но логика понятна, спасибо


      1. Drakosh
        29.04.2022 07:26

        Безопаснее будет положить ключи в переменные окружения и задать их на сервере в хранилище секретов. Heroku это вполне позволит


        1. dabrahabra
          29.04.2022 20:02

          Может вопрос не в ключах и их местоположении, а в раскрытии основного аккаунта?


          1. Drakosh
            29.04.2022 22:30
            +1

            Если обсуждать вопрос защищенности, то еще подумать надо. Домашний хоббийный Распберри (пароль по умолчанию сменен? Ssh не доступен кому попало на порту по умолчанию?) или облачный сервер, где безопасностью как-то занимаются. Я не эксперт по безопасности и руководствуюсь чутьем, но вижу что аккаунт в любом случае раскроется, вопрос лишь насколько.


      1. Lexemz
        29.04.2022 23:53

        Кстати, а откуда информация, что виртуалка оракла в тыкву превратится? В консоль уже почти 2 месяца не пускают, но сама «машина» работает.


        1. Lonsdaleite Автор
          29.04.2022 23:53

          Мне Оракал прислал письмо, чтобы я перенёс виртуалку до 7 мая.


          1. Lexemz
            30.04.2022 01:24

            Спасибо.

            Возможно, машина продолжит работать. Посмотрел почту, мне грозились 12го марта отключить, но до сих пор можно подключиться к машине :)


  1. DuD
    29.04.2022 02:25
    +2

    Сама затея, как процесс интересная, но кажется ковырнуть аппку и дергать API его бекенда напрямую было бы куда проще и оперативнее.)


    1. Lonsdaleite Автор
      29.04.2022 02:34

      Думал об этом. Но у меня нет опыта ковыряния бэка Android/iOS приложений, поэтому данный способ для меня был как раз таки проще :)


      1. berezuev
        29.04.2022 12:29
        +1

        1. Lonsdaleite Автор
          29.04.2022 16:49

          Гляну на досуге, спасибо)


    1. FilimoniC
      29.04.2022 08:49
      +1

      ... и не забывать при каждом обновлении приложения проверять, не поменялось ли чего, ага...


      1. vcKomm
        30.04.2022 07:35

        А кто мешает разработчику изменить команду для открытия в телеграм боте?

        Кроме того, сценарий "изменить команду" выглядит более реалистичным, потому что пользователю в телеграме все равно, на какие кнопочки нажимать. А переписать бэк и аппку несколько сложнее.


        1. FilimoniC
          30.04.2022 07:41

          А телегу дебажить проще, потребуется буквально минута с любого смарта


  1. aborouhin
    29.04.2022 02:45
    +8

    У меня в автомобиле есть Android магнитола, а на руле есть кнопка голосового поиска

    Ну вот, а я дочитал до конца исключительно в предвкушении узнать подробности про подключение к CAN или OBD2 для перехвата нажатий на кнопку... А у Вас всё так просто :)


    1. Lonsdaleite Автор
      29.04.2022 02:57

      На самом деле чуть сложнее :) магнитола у меня обычная, но я купил коробку на Андроиде, которая подключается к магнитоле через протокол CarPlay. Без нее бы не получилось, конечно.

      С перехватом кнопки через тот же OBD2, безусловно, было бы в разы интереснее, но и сложнее на порядок. Я с ходу вообще довольно смутно представляю, как к этому пришлось бы подступаться :)


      1. blind_oracle
        29.04.2022 11:06

        Большинство современных машин транслируют все эти нажатия через мультимедийную CAN шину, так что там скорее всего всё просто


    1. RTFM13
      29.04.2022 15:18
      +4

      Ну вот, а я дочитал до конца исключительно в предвкушении узнать подробности про подключение к CAN или OBD2 для перехвата нажатий на кнопку... А у Вас всё так просто :)

      У меня в машине есть штатные кнопки открывания ворот. Но они, разумеется, "не той системы". Я достал плату из машины, сдул феном с этой платы всё кроме стабилизатора питания. После взял плату брелка от ворот и припаял проводочками к кнопкам, светодиодам и питанию. И никаких дебильных облаков и глючного интернета. )

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


    1. SamXYZ
      01.05.2022 10:32

      Всё гениальное просто.


  1. onlooked
    29.04.2022 08:59
    +5

    А я сделал так:

    Дешёвая ардуинка 200р + модуль sim 200р + адаптер 12в-5в(из категории зарядка в прикуриватель, у каждого есть). Подключаем к кнопкам руля (к любым что не используете, у меня это корейский голосовой помощник). Нажал, пошёл звонок -> ворота открыты.


    1. Rudmz
      29.04.2022 10:38
      +2

      Самое простое и эффективное решение. Странно, что такой вариант для автора "не подходит для автоматизаций по очевидным причинам".


      1. Lonsdaleite Автор
        29.04.2022 16:42
        +1

        Для этого нужно отдельный номер регистрировать в системе шлагбаума, а у нас разрешено 2 на квартиру. Плюс другие автоматизации, вроде открытия шлагбаума голосом через Алису, передачи прав открытия друзьям и т.д. не получится реализовать.


    1. Abyss777
      30.04.2022 07:25

      Увидел ваш комментарий и вспомнил, что натыкался как люди делают для BMW.
      Не реклама, просто первая попавшаяся ссылка. https://www.drive2.ru/l/599230264798880470/
      Оказываются уже универсальные придумали.


  1. vdo2000
    29.04.2022 09:44

    А можно было продолжить автоматизацию и при повторном нажатии (если открыты ворота) - закрыть их


    1. Lonsdaleite Автор
      29.04.2022 09:45

      Простые городские шлагбаумы сами закрываются, когда автомобиль проехал через них :) там вообще нет управляемой функции закрытия


      1. dodge
        30.04.2022 10:18

        Там датчик движения? Если друг за другом будет заезжать много машин?


  1. Scratch
    29.04.2022 11:24
    +3

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


    1. Lonsdaleite Автор
      29.04.2022 16:46

      Если честно, я не эксперт в инфобезе. Подскажите, какие проблемы вы в этом видите? Route в адресе можно сделать произвольный, хоть 100 символов. Случайно или брутфорсом никто не постучится.


      1. Scratch
        30.04.2022 13:33

        При каждом открытии шлагбаумы вы на весь интернет светите открытым текстом адрес и URL своего сервиса. Без TLS статик токен больше для самоуспокоения, чем для безопасности. Проще всего поднять TLS, хотя бы с самоподписанным сертификатом и принудительной проверкой его отпечатка на клиенте. Тогда можно уже использовать хоть токен хоть basic auth.
        Иначе надо смотреть в сторону PAKE, но это уже сильно сложнее


    1. dabrahabra
      29.04.2022 20:10
      +1

      Вы пытаетесь подменить секрет, но при замене на статический токен защита не станет лучше - считайте, что URL сейчас и есть токен.


      1. Scratch
        30.04.2022 13:28

        Всё верно, но хотя бы тупым брутфорсом не подобрать без доступа к трафику


  1. Valien
    29.04.2022 11:56
    +3

    А можно было нажать на кнопку ассистента на руле и сказать: `позвони воротам`?


    1. RTFM13
      29.04.2022 15:24

      А как будет "позвони воротам" по корейски?


    1. Lonsdaleite Автор
      29.04.2022 16:44

      У меня Android магнитола через внешнюю коробку, она со своей симкой. И голосовой набор работает только с той симки, что воткнута в коробку. Сделать вызов со своего телефона, подключенного по BT, не получается.


      1. Gvizdon
        01.05.2022 10:33
        +1

        Специально зарегистрировался.

        1. Настроить переадресацию вызова на вашем телефоне, а магнитолу просить звонить вам.

        1. Настроить шлагбаум на номер симки из машины и для удобства переадресацию вызова на номер ворот.

        2. Положить дома отдельный телефон с симкой, зарегистрировать ее на ворота и переадресацию

        А чтоб не открывали ворота незнакомые номера, можно настроить телефон на то, чтобы принимал звонки только от списка контактов.


        1. Lonsdaleite Автор
          01.05.2022 10:38

          1 вариант норм, но годится только для открытия из машины, потому что когда двигатель заглушён, магнитола обесточена.

          Другие варианты требуют перерегистрировать симку, что не очень. Свой номер хочется оставить на крайний случай.

          Читая это, родился четвёртый вариант: отдельная симка и цепочка переадресаций: любой человек -> отдельная симка -> мой номер -> шлагбаум. На отдельной симке можно сделать вайтлист переадресаций.


  1. dmitryvolochaev
    29.04.2022 16:45

    А нельзя повесить на кнопку звонок по определенному номеру?


    1. Lonsdaleite Автор
      29.04.2022 16:48

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


  1. ilya73
    29.04.2022 17:33
    +2

    Схожая проблема: садоводство, шлагбаумы с открытием по звонку с "верифицированного" номера + ограничение по кол-ву возможных зарегистрированных тел. номеров + тягомотина с регистрацией и изменением списка "доверенных" тел. номеров + потребность организовать допуск произвольному кол-ву людей из своего списка.
    Решение: одноплатник + SIM800 + немного шаманства на Go и вуа-ля! Пользователь из "списка" звонит на зарегистрированный в СКУД тел. номер, "бот" принимает звонок и сверяется с собственным списком и даёт отбой, если пользователь из списка "своих", то перезванивает на тел. номер шлагбаума. В принципе уже работает!


  1. Dark_Purple
    30.04.2022 00:11

     Для его открытия существует три способа:

    И все дибильные, есть же кнопки на зеркале заднего вида, специально для этого предназначенные.


    1. Lonsdaleite Автор
      01.05.2022 10:40

      Только здесь в комментариях впервые услышал про подобные кнопки. Видимо, на разных автомобилях ездим.


  1. DMGarikk
    30.04.2022 16:09

    А никто не заморачивался homelink использовать? А то в авто оно есть но в РФ такого оборудования, да ещё со штатовскими частотами по-моему не встречается