Telegram бот для моніторингу електроенергії



Вступ

Масовані атаки росії на енергетичну інфраструктуру України, призводили до масштабних відключень електроенергії (блекаутів). Це створило побутові проблеми для пересічних цивільних громадян, а саме: навчання дітей ввечері без світла, пересування людей похилого віку в багатоповерхівках, приготування їжі за допомогою електроплит, зберігання продуктів в холодильнику, підігрів води бойлером, кондиціювання приміщень та інші проблеми пов’язані із відсутністю енергопостачання.

Нажаль і мене торкнулася така доля, через що я був вмотивований створити систему, яка б мене сповіщала про час та тривалість відсутності електроенергії, щоб мати змогу прогнозувати довготривалість наступного відключення. Це дало б змогу визначити який на перспективу можна купити генератор або зарядну станцію, щоб покрити мінімальні потреби під час відсутності централізованого електрозабезпечення.

Інфраструктура

Для реалізації мого задуму в мене була раніше створена інфраструктура, яка повністю задовольнила мої потреби, а саме:

  • Будь який пристрій який підключений до електромережі та локальної мережі через дротове з’єднання або через wi-fi.
  • Роутер, свіч та wi-fi точка доступу які підключені як до мережі так і до додаткового джерела живлення
  • Raspberry Pi яка також підключена до альтернативного джерела живлення

В моєму випадку, в ролі домашнього пристрою виступив wi-fi термостат для теплої підлоги. В ролі мережевих пристроїв виступили пристрої від Ubiquiti, а в ролі обробки даних виступила моя Raspberry Pi.

Принцип підключення та взаємодії я зобразив графічно

Тобто написаний на пайтоні скрипт постійно 24/7 надсилає пінг запити. Якщо електроенергія знакла, то звісно термостат не зможе відповісти, проте мережеве обладнання та Raspberry Pi продовжать працювати від альтернативного джерела енергії, і про відсутність електроенергії користувач дізнається через пуш сповіщення Телеграма. Коли електроенергія відновиться, термостат з’явиться в локальній мережі, і при успішній відповіді на пінг користувач буде проінформований про те, що електроенергія з’явилася, також буде прорахований час відсутності електроенергії.

Для реалізації цього алгоритму необхідно:

  • Створення Telegram-бота
  • Написання Python скрипта
  • Автоматизація запуску через сервіс

Ці пункти я опишу детально.

Створення Telegram-бота

В телеграмі є спеціальний бот, який створений спеціально для створення інших ботів. Цей бот має назву BotFather. Для створення свого власного боту необхідно виконати наступні дії:

  • У Telegram треба знайти бота під назвою BotFather
  • Для початку роботи треба написати /start
  • Для створення свого бота, треба ввести команду /newbot
  • Ввести ім’я та назву свого бота

Після створення бота, через головне меню можна налаштувати приватність та отримати АПІ токен. Також необхідно отримати Chat_ID для приватного використання бота, адже йому потрібно знати кому відправляти повідомлення. Для цього існує ще один бот @userinfobot, треба йому щось написати, наприклад /start і він у відповідь напише Chat_ID, який в майбутньому буде використаний.

Найголовніше, що ми отримали:

  • API token
  • Chat_ID

Переходимо до створення скрипту на пайтоні.

Написання Python скрипта

Для роботи скрипта необхідно встановити додаткові пакети та бібліотеки, створити та активувати віртуальне середовище.

Встановлення додаткових пакетів

sudo apt install python3-venv

Створення віртуального середовища в потрібній директорії, в моєму випадку /home/rpi/TG_BOT

cd /home/rpi/TG_BOT
python3 -m venv myenv

Активація віртуального середовища

source myenv/bin/activate

Коли віртуальне середовище активоване, треба встановити бібліотеки для роботи з API телеграма

pip install python-telegram-bot requests

Скрипт буде мати наступні функції:

  • format_time – для визначення часу
  • send_message – для відправки повідомлення
  • ping_address – для пінгування термостата
  • monitor_ip – для визначення статусу та формування повідомлення

Код надано в спойлері

electricity.py
import os
import time
import asyncio
from telegram import Bot

CHAT_ID = "<Your Chat ID>"
BOT_TOKEN = "<Your API tioken>"

bot = Bot(token=BOT_TOKEN)

def format_time(seconds):
    """Форматує секунди в години, хвилини і секунди."""
    hours, remainder = divmod(seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    return f"{hours} годин {minutes} хвилин {seconds} секунд"

async def send_message(message):
    await bot.send_message(chat_id=CHAT_ID, text=message)

def ping_address(ip, count=3):
    """
    Пінгує IP-адресу `count` разів.
    Повертає True, якщо хоча б один пінг успішний.
    """
    response = os.system(f"ping -c {count} -W 2 {ip} | ts")
    return response == 0

async def monitor_ip(ip):
    power_off_time = None
    power_on = True

    while True:
        if ping_address(ip):
            if not power_on:
                power_on = True
                time_power_on = time.time()
                outage_duration = int(time_power_on - power_off_time)
                formatted_duration = format_time(outage_duration)
                outage_message = f"Світло з'явилося. Відключення тривало {formatted_duration}."
                await send_message(outage_message)
        else:
            if power_on:
                power_on = False
                power_off_time = time.time()
                await send_message("Світло зникло.")

        await asyncio.sleep(30)  # Використовуйте asyncio.sleep для асинхронного затримки

if __name__ == "__main__":
    ip_address = "<Thermostat local IP>"  # Замініть на свою IP-адресу
    asyncio.run(monitor_ip(ip_address))

Зазвичай лог виконання команди записується в системній журнал, і там кожен запис має мітку дати та часу, проте я вирішив виділити логування в окремий файл засобами сервісу. Якщо логування відбувається не в системний журнал, то за замовчуванням час події не фіксується. Для того, щоб час пінгу фіксувався, я команду ping обробляю додатково командою ts, таким чином вивід запису:

ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=16.1 ms

перетворюється на:

ping -c 3 8.8.8.8 | ts
May 12 19:18:23 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
May 12 19:18:23 64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=15.7 ms

Для цього необхідно додатково встановити утиліту moreutils

Автоматизація запуску через сервіс

Для того, щоб скрипт виконувався навіть після перезавантаження Raspberry Pi, я створив сервіс, який буде запускатися автоматично. Зазвичай всі системні сервіси знаходяться в директорії /etc/systemd/system/, тому сервіс для скрипта я розміщу також там. Як я раніше зазначав, що логування буде відбуватися в окремий файл для зручності, за адресою /var/log/sun.log, то ця адреса буде прописана саме в параметрах сервісу.

Я вигадав таку назву для свого сервісу – FolletSun.service. Параметри сервісу будуть наступними:

[Unit]
Description=Script which check electricity and pass status to Telegram Bot.

[Service]
ExecStart=/home/rpi/TG_BOT/bin/python3 /home/rpi/TG_BOT/Sun.py
StandardOutput=file:/var/log/sun.log
StandardError=file:/var/log/sun.log
WorkingDirectory=/home/rpi/TG_BOT
Restart=always
User=rpi
Group=rpi

[Install]
WantedBy=multi-user.target

Для того, щоб ініціювати сервіс без перезавантаження системи необхідно виконати наступні команди:

sudo systemctl daemon-reexec
sudo systemctl daemon-reload

Також, щоб активувати сервіс, запустити його та перевірити його статус слід виконати наступні команди:

sudo systemctl enable FolletSun.service
sudo systemctl start FolletSun.service
sudo systemctl status FolletSun.service

Результат виконання команди статусу сервісу буде такий:

● FolletSun.service - Script which check electricity and pass status to Telegram Bot.
     Loaded: loaded (/etc/systemd/system/FolletSun.service; enabled; preset: enabled)
     Active: active (running) since Sun 2025-05-11 22:31:20 EEST; 21h ago
   Main PID: 1458494 (python3)
      Tasks: 1 (limit: 8735)
        CPU: 3min 40.583s
     CGroup: /system.slice/FolletSun.service
             └─1458494 /home/rpi/TG_BOT/bin/python3 /home/rpi/TG_BOT/Sun.py

Це свідчить про те, що в скрипті не виявлено жодних помилок та конфліктів.

Перевірка роботи боту

Для того щоб перевірити роботу бота, треба в додатку Telegram, знайти створеного бота та підписатися на нього. З цієї миті Бот повинен сповіщати про зміну статусу енергоживлення. Ось скріншот з мого смартфона:

Пінг відбувається кожні 30 секунд, і ви мабуть звернули увагу на повідомлення, де електроенергія зникла лише на 30 секунд – це хибне спрацювання через те, що термостат не відповів на пінг запит, або Raspberry Pi не отримала відповідь від термостата. Можливо це результат нестабільного підключення. Для того, щоб уникнути цього або мінімізувати, краще використовувати не менше 3х пінг запитів.

Висновки

У відповідь на актуальні загрози, пов’язані з енергетичною безпекою в умовах війни, було розроблено ефективну та недорогу систему моніторингу електропостачання. Вона базується на популярних технологіях з відкритим кодом — мікрокомп’ютері Raspberry Pi, Python-скрипті та Telegram-боті.

Система забезпечує безперервне відстеження наявності електроенергії у домі, фіксує час її зникнення та повернення, а також автоматично надсилає сповіщення користувачеві. Такий підхід дозволяє швидко реагувати на ситуацію, планувати використання резервних джерел живлення і приймати обґрунтовані рішення щодо купівлі генератора або зарядної станції.

Проект доводить, що завдяки вже наявній інфраструктурі та базовим знанням програмування можна самостійно створити корисний інструмент для підвищення комфорту і безпеки в критичних умовах. Запропоноване рішення є масштабованим, простим у підтримці й може бути адаптоване до будь-якого іншого домашнього пристрою або об’єкта, який підключений до мережі.