↩️ Назад

Универсальный диспетчер email-уведомлений для IoT на Python

15.01.2026 | Статья из категории: IOT умный дом

Как отправлять алерты по датчикам IOT через MySQL с помощью Python

Обновлено. сделал на питоне и внешнем смтп

Небольшой скрипт, который раз в несколько минут проверяет базу данных и отправляет все сообщения из служебного MQTT-топика zigbee2mqtt/_alerts/email на email. Идеально подходит для домашнего сервера на Raspberry Pi.

Как это работает

  • Скрипт запускается по cron (например, каждые 2 минуты).
  • Читает все записи с топиком zigbee2mqtt/_alerts/email.
  • Сразу удаляет их из БД — чтобы не отправлять повторно.
  • Отправляет письма через внешний SMTP (Mail.ru, Gmail и др.).

Требования к таблице

Таблица sensor_data должна содержать автоинкрементное поле id:

CREATE TABLE sensor_data (
    id INT AUTO_INCREMENT PRIMARY KEY,
    topic VARCHAR(255) NOT NULL,
    value TEXT,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);

Формат уведомлений

Поддерживаются два варианта:

  1. Простой текст: "Протечка в ванной!" → тема письма: «Уведомление из IoT».
  2. JSON — позволяет задать тему, тело и получателя:
    {
      "subject": "🚨 Авария!",
      "body": "Датчик воды сработал в 03:14",
      "to": "admin@example.com"
    }

Полный код скрипта

Сохраните как alert_dispatcher.py и сделайте исполняемым (chmod +x).

#!/home/mazzick/venv/bin/python3
"""
Универсальный диспетчер уведомлений.
Читает сообщения из MySQL и отправляет их на email.
Требуется таблица sensor_data с колонками: id (INT AI), topic (VARCHAR), value (TEXT).
"""

import pymysql
import smtplib
import json
import sys
from email.message import EmailMessage

# === НАСТРОЙКИ ===
DB_CONFIG = {
    'host': 'localhost',
    'user': 'iot_user',
    'password': 'your_db_password',      # ← замените!
    'database': 'iot_db',
    'charset': 'utf8mb4'
}

ALERT_TOPIC = 'zigbee2mqtt/_alerts/email'
EMAIL_TO_DEFAULT = "9447333@gmail.com"  # ← ваш email по умолчанию

def fetch_and_delete_alerts():
    """Получает и удаляет все уведомления из БД."""
    conn = pymysql.connect(**DB_CONFIG)
    try:
        with conn.cursor() as cursor:
            cursor.execute("""
                SELECT id, value FROM sensor_data
                WHERE topic = %s
                ORDER BY id ASC
            """, (ALERT_TOPIC,))
            rows = cursor.fetchall()
            if not rows:
                return []
            ids = [row[0] for row in rows]
            format_strings = ','.join(['%s'] * len(ids))
            cursor.execute(f"DELETE FROM sensor_data WHERE id IN ({format_strings})", ids)
            conn.commit()
            print(f"📨 Обработаны уведомления с ID: {ids}", file=sys.stderr)
            return [row[1] for row in rows]
    finally:
        conn.close()

def send_email(subject, body, to=None):
    """Отправка через smtp.mail.ru (пример для Mail.ru)."""
    msg = EmailMessage()
    msg.set_content(body)
    msg["Subject"] = subject
    msg["From"] = "9447333@mail.ru"          # ← ваш email
    msg["To"] = to or EMAIL_TO_DEFAULT

    try:
        with smtplib.SMTP("smtp.mail.ru", 587) as s:
            s.starttls()
            s.login("9447333@mail.ru", "ваш_16_значный_пароль")  # ← пароль приложения
            s.send_message(msg)
        print(f"✅ Email отправлен: {subject}")
    except Exception as e:
        print(f"❌ Ошибка SMTP: {e}", file=sys.stderr)

def main():
    alerts = fetch_and_delete_alerts()
    if not alerts:
        print("📭 Нет новых уведомлений")
        return

    for payload in alerts:
        try:
            data = json.loads(payload)
            subject = data.get("subject", "Уведомление IoT")
            body = data.get("body", payload)
            to = data.get("to")
        except (json.JSONDecodeError, TypeError):
            subject = "🚨 Уведомление из IoT"
            body = str(payload)
            to = None

        send_email(subject, body, to)

if __name__ == "__main__":
    main()

Запуск по расписанию

Добавьте в crontab:

*/2 * * * * /home/mazzick/venv/bin/python3 /home/mazzick/bash_scripts/alert_dispatcher.py >> /var/log/iot_alerts.log 2>&1

Советы

  • Для Mail.ru/Gmail используйте пароли для внешних приложений (16-значные).
  • Если нужна история уведомлений — замените DELETE на UPDATE ... SET processed=1.
  • Скрипт идемпотентен: можно запускать часто — дублей не будет.

Готово! Теперь любое устройство в вашей IoT-сети может отправить email, просто опубликовав сообщение в MQTT-топик zigbee2mqtt/_alerts/email.




Категории:

Категории

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку статей

Посетителей сегодня: 0
о блоге | карта блога

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA