DEV Community

Andrii Kondratiev
Andrii Kondratiev

Posted on

Автоматичні повідомлення в ТГ канал по наявності свтла

В Україні війна. Росія вкотре бомбить українську енергетичну інфраструктуру, через що ледь не кожен українець стикнувся з доволі неприємним фактом — припинення електропостачання. Або по-народному — вимкнення світла.

Часто потрібно в режимі реального часу знати — є світло в будівлі чи немає. Можна це робити в ручному режимі — приїхати та перевірити особисто, але для чого, якщо є сучасні технології?

Декілька тижнів тому я зробив службу, яка автоматично повідомляє про відключення та включення електропостачання для ЖК, в якому мешкаю, напряму в канал Telegram, і ось як він виглядає станом на сьогоді:

Image description

Отже, розберемось як працює сервіс з інформування відключення та підключення електропостачання. Є два варіанта — з роутером Mikrotik та без нього.

Крок 1 — сетап

Доступ в Інтернет

Головне — доступ до інтернету. Ідеально, якщо до квартири прокладена оптика (GPON), в такому випадку є велика вірогідність мати Інтернет навіть якщо будівля повністю обезточена.

Також буває, що й у випадку заведення мідного кабелю Ethernet провайдер може надавати доступ в мережу після відключення електрики. Це досягається шляхом встановлення ДБЖ на проміжному мережевому обладнанні зі сторони самого провайдера. Така ситуація буває далеко не завжди, і якщо мережеві комунікації було прокладено давно — скоріше за все працювати не буде.

Третій варіант — LTE модем. Теж доволі надійний варіант на випадок вимкнення електрики, але не всі роутери підтримують LTE-модеми для доступу до WAN. І також все залежить від самої мобільної мережі.

Ну і, власне, Старлінк.

Роутер

В нашому випадку ми використовуємо роутер Mikrotik hAP ac, але підійде практично будь-який Мікротік. І саме роутер цього виробника ми налаштовуємо.

Він має звичайне підключення по мідному дроту. Також, на випадок зникнення Інтернету, він вміє автоматично перемикатись на мобільний Інтернет. Налаштовував приблизно так: https://www.batna24.com/en/mikrotik-failover-connection-via-backup.

Автономне живлення роутера

Далі, цей роутер треба живити автономно. Це може бути як звичайний офісний ДБЖ, так і різного типу станції типу EcoFlow. Важливо, щоб роутер після відключення електропостачання продовжував працювати та мати доступ в Інтернет.

Пристрій-детектор наявності електрики

Далі, нам потрібен хост, який постійно підключений до локальної мережі роутера та автоматично запускається після вимкнення напруги. Це може бути смарт-телевізор, розумна розетка, компʼютер чи ноутбук без акумулятора, тощо. В моєму випадку це Raspberry Pi. Так, жирно, але нарешті він згодився.

Цей хост повинен бути доступним по мережі з роутера та підключений до звичайної розетки.

Загальна схема мого підключення виглядає ось так:
Image description
Як бачимо, сетап доволі примітивний, але потребує наявності певного обладнання, а саме джерела безперебійного живлення, роутера Mikrotik, хоста, який постійно повинен бути в мережі.

Крок два — налаштування бота та каналу.

Перше, створюємо канал в телеграмі, налаштовуємо його. Тут все дуже просто, а якщо ні — в інтернеті тонна інформації стосовно цього.

Друге — створюємо нового бота. Йдемо до офіційного бота @BotFather, та виконуємо /newbot. А далі — даємо назву та адресу, і коли все буде добре, нам дадуть ID бота та секретний ключ. Ось як це виглядає:
Image description
В результаті нам дали токен для керування ботом:
5863194005:AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc
Переходимо на нового бота за посиланням та даємо йому команду /start. Це його активує.

Далі йдемо до створеного каналу та додаємо туди нашого нового бота як адміна:
Image description
Гуд. Далі ми пишемо в цій групі просто якесь повідомлення. Байдуже яке. Наприклад, "Тест".

Далі йдемо до іншого бота — @RawDataBot та запускаємо його. Повертаємось до нашого каналу, і тестове повідомлення з нього пересилаємо до RawDataBot. У відповідь отримуємо ID нашого чату та купу іншої інформації низького рівня:
Image description
Тут ми маємо ID нашого каналу:
-1001825242471
Тепер треба щось в цей канал написати самим ботом. В Linux та macOS для цього є чудова консольна утиліта curl. Під Wndows теж має бути, шукайте.

В терміналі вводимо наступну команду, але підставляємо свій токен та свій ID чату:

curl --header 'Content-Type: application/json' \
     --request 'POST' 
     --data '{"chat_id":"-1001825242471","text":"Тестуємо бота"}' \
"https://api.telegram.org/bot5863194005:AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc/sendMessage"
Enter fullscreen mode Exit fullscreen mode

В результаті бачимо ось такий вивід:
Image description
Спрацювало. В телеграмі є повідомлення:
Image description
Успєх. Повідомлення доставлено, бот працює.

Крок 3 — Налаштовуємо Mikrotik

Тепер налаштовуємо роутер. Заходимо на роутер через веб адресу 192.168.88.1 або через програму winbox. В розділі Tools знаходимо підрозділ Netwatch:
Image description
Там робимо наступні налаштування:
Image description
На вкладці Host вписуємо ІР адресу нашого хоста, в нашому випадку 192.168.88.166, та встановлюємо інтервал опитування. В моєму випадку це 30 секунд, ви можете ставити яку хочете.

На вкладці Up прописуємо сценарій, який буде виконуватись коли хост зʼявляється у мережі:

/tool fetch url=https://api.telegram.org/bot5863194005:AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc/sendMessage\?chat_id=-1001825242471&text=Svitlo%e"
Enter fullscreen mode Exit fullscreen mode

На вкладці Down прописуємо сценарій, коли хост перестає бути доступним:

/tool fetch url=https://api.telegram.org/bot5863194005:AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc/sendMessage\?chat_id=-1001825242471&text=Svitla%nema"
Enter fullscreen mode Exit fullscreen mode

Зберігаємо. Готово. Тепер коли світло вимикають, хост теж вимикається та перестає бути доступним. Виконується сценарій Down та автоматично відправляється повідомлення в телеграм канал. Світло дають — хост запускається, отримує ІР адресу та стає знову доступний. Виконується сценарій з вкладки Up.

Кирилицю Mikrotik не підтримує, тому я захардкодив українські літери кодами Unicode. Ось як це пишеться:

Світло є:
\D0\A1\D0\B2\D1\96\D1\82\D0\BB\D0\BE\C2\A0\D1\94\1F\F0\9F\92\A1

Світла немає:
\D0\A1\D0\B2\D1\96\D1\82\D0\BB\D0\B0\C2\A0\D0\BD\D0\B5\D0\BC\D0\B0\D1\94\C2\A0\F0\9F\94\A6
Таким чином, щоб відправляти українські сповіщення в канал, трішки модифікуємо наші сценарії.

На вкладці Up:

/tool fetch url=https://api.telegram.org/bot5863194005:AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc/sendMessage\?chat_id=-1001825242471&text=\D0\A1\D0\B2\D1\96\D1\82\D0\BB\D0\BE\C2\A0\D1\94\1F\F0\9F\92\A1"
Enter fullscreen mode Exit fullscreen mode

На вкладці Down:

/tool fetch url=https://api.telegram.org/bot5863194005:AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc/sendMessage\?chat_id=-1001825242471&text=\D0\A1\D0\B2\D1\96\D1\82\D0\BB\D0\B0\C2\A0\D0\BD\D0\B5\D0\BC\D0\B0\D1\94\C2\A0\F0\9F\94\A6"
Enter fullscreen mode Exit fullscreen mode

На цьому налаштування роутера Mikrotik завершено. Все має працювати.

Варіант без роутера Mikrotik

Mikrotik це доволі специфічне обладнання, яке використовують люди, які точно знають що це таке і для чого він потрібен. Тому далеко не в усіх він є.

Щоб організувати подібний сценарій без нього, нам потрібне додаткове обладнання в локальній мережі у вигляді того самого Raspberry Pi чи компʼютера/ноутбука з Debian Linux. В такому випадку наш сетап виглядатиме наступним чином:
Image description
Додатковий сервер ми підключаємо до роутера, щоб хост був доступним, і по живленню — до ДБЖ. Додатково рекомендую на ньому налаштувати альтернативний доступ в мережу через LTE-модем, якщо це ще не налаштовано на самому роутері.

Заходимо на сервер і в домашній папці користувача створюємо файл netmonitor з таким вмістом:

#!/bin/sh

host="192.168.88.166"
statefile=$HOME/state
BotID="bot5863194005"
Secret="AAGg3mrQ5OUKwPbMOhDrZ2ndXQk8yOViTbc"
WanIP="8.8.8.8"

[ ! -f $statefile ] && touch $statefile
while true
  do
    ping -c1 $host 2>/dev/null 1>/dev/null
    PingHost=$?

    ping -c1 $WanIP 2>/dev/null 1>/dev/null
    PingGoogle=$?
    if [ $PingHost -eq 0 ]
      then
      echo "$host alive"
          curr_state="0"
    last_state=$(cat $statefile)
    if [ "$curr_state" != "$last_state" ]; then
     echo "Host goes online"
     curl --header 'Content-Type: application/json' \
     --fail \
     --request 'POST' \
     --data '{"chat_id":"-1001825242471","text":"Світло є!"}' \
   "https://api.telegram.org/$BotID:$Secret/sendMessage"
    fi
    echo "0" > $statefile
   else
    echo "$host dead"
    curr_state="1"
    last_state=$(cat $statefile)
    if [ $PingGoogle -eq 0 ]; then
     if [ "$curr_state" != "$last_state" ]; then
      echo "Host goes offline"
      curl --header 'Content-Type: application/json' \
      --fail \
      --request 'POST' \
      --data '{"chat_id":"-1001825242471","text":"Світла немає!"}' \
                "https://api.telegram.org/$BotID:$Secret/sendMessage"
     fi
    fi
    echo "1" > $statefile
 fi
 sleep 20
done
Enter fullscreen mode Exit fullscreen mode

Цей скрипт я написав за 10 хв, і він далеко не ідеальний з точки зору коду. Але працює.

В моєму випадку скрипт лежить за адресою /home/ak/netmonitor. Даємо йому права на виконання:

chmod +x /home/ak/netmonitor
Enter fullscreen mode Exit fullscreen mode

Для тестування у верхній частині скрипта я вказав ІР адресу свого телефона, запустив скрипт і дивився, як він відпрацьовує коли телефон підключаєш до WiFi і коли відключаєш. Якщо все працює корректно, то можна додати його в автозавантаження. Для цього створюємо новий файл /etc/systemd/system/netmonitor.service (потрібні права root) з наступним вмістом, попередньо замінивши в User= на свого користувача, в WorkingDirectory= та ExecStart= свої шляхи до скрипта:

[Unit]
Description=Light detector

[Service]
User=ak
WorkingDirectory=/home/ak
ExecStart=/home/ak/netmonitor
Restart=always

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Після того, як файл зберегли, активуємо сервіс командою:

systemctl daemon-reload
systemctl enable netmonitor.service
Enter fullscreen mode Exit fullscreen mode

та запускаємо сам сервіс:

systemctl start netmonitor.service
Enter fullscreen mode Exit fullscreen mode

Тепер після кожного перезавантаження наш скрипт буде запускатись автоматично та моніторити хост, повідомляючі про зміни.

Таким чином чи досягли того самого функціоналу, що і в Mikrotik, але без Mikrotik.

Top comments (0)