У меня есть самописная IoT-система на Raspberry Pi: данные с датчиков летят через MQTT → сохраняются в MySQL → отображаются в красивой веб-панели на PHP. Всё работает, графики строятся, автоматизации срабатывают — но сегодня я добавил первое управляемое устройство: умную розетку Zigbee (модель TS011F, IEEE: 0xa4c1385d1ba39457).
Цель: чтобы розетка появилась в панели с кнопками ВКЛ/ВЫКЛ и отображала статус, а заодно — показывала напряжение, ток и потребление.
Вот как я это сделал — чтобы ты (и я через год) мог повторить без гугла.
Сначала убедился, что Zigbee2MQTT публикует сообщения от розетки:
mosquitto_sub -h localhost -t "zigbee2mqtt/0xa4c1385d1ba39457" -v
Увидел:
{"state":"ON","power":0,"voltage":217,"current":8,...}
Отлично — данные есть. Значит, проблема не в устройстве, а в том, что моя система их не отображает.
Моя панель берёт данные из таблицы sensor_data, но отображает только те топики, для которых есть запись в sensor_info (там хранятся имя, комната, группа, иконка).
Проверил:
SELECT * FROM sensor_info WHERE topic LIKE '%0xa4c1385d1ba39457%';
Пусто. Значит — нужно добавить.
Но сначала — нужно, чтобы в sensor_data появился топик с состоянием (ON/OFF), а не только voltage.
Мой парсер (mqtt_to_mysql.py) раньше сохранял только известные ключи: temperature, humidity и т.д. А state игнорировал.
Добавил в функцию on_message:
if 'state' in data:
status_topic = f"{topic}/status"
save_to_sensor_data(status_topic, data['state'])
Теперь приходит:
topic: zigbee2mqtt/0xa4c1385d1ba39457/status
value: ON
Также добавил сохранение power, current — для мониторинга.
Выполнил в MySQL:
INSERT INTO sensor_info (topic, name, room, group_name, icon)
VALUES (
'zigbee2mqtt/0xa4c1385d1ba39457/status',
'Розетка ТВ',
'Гостиная',
'Розетки',
'🔌'
);
⚠️ Возникла ошибка с emoji — исправил, установив кодировку таблицы в utf8mb4.
В панели устройства фильтруются по типу. Тип определяется как basename(topic). Для .../status — это status.
Добавил 'status' в список разрешённых типов:
if (!in_array($type, [..., 'status'])) { continue; }
И сделал маппинг: если тип status → считаем его valve (чтобы отображались кнопки):
if ($type === 'status') { $type = 'valve'; }
В карточке устройства добавил:
<button onclick="sendCommand('...', 'ON')">ВКЛ
<button onclick="sendCommand('...', 'OFF')">ВЫКЛ
Функция sendCommand() заменяет /status на /set и отправляет команду через send_mqtt.php.
⚠️ Была ошибка: топик URL-кодировался (%2F вместо /) — исправил через decodeURIComponent().
Добавил в sensor_info:
INSERT INTO sensor_info (topic, name, room, group_name, icon) VALUES
('zigbee2mqtt/0xa4c1385d1ba39457/power', 'Потребление', 'Гостиная', 'Энергия', '⚡'),
('zigbee2mqtt/0xa4c1385d1ba39457/voltage', 'Напряжение', 'Гостиная', 'Энергия', '🔌'),
('zigbee2mqtt/0xa4c1385d1ba39457/current', 'Ток', 'Гостиная', 'Энергия', '🔋');
Теперь в панели — отдельные карточки с графиками!
В админке плодились дубли вроде .../set/status — удалил их из sensor_data:
DELETE FROM sensor_data WHERE topic LIKE '%/set/%';
Теперь в интерфейсе — только нужные устройства.
Теперь я знаю, как подключать любое Zigbee-устройство с state — просто добавляю в sensor_info и, при необходимости, дорабатываю парсер.
Следующая цель — автоматическое обнаружение новых устройств. Но это — уже другая статья 😉
-- Проверить данные устройства
SELECT * FROM sensor_data WHERE topic LIKE '%0xa4c1385d1ba39457%';
-- Добавить устройство в sensor_info
INSERT INTO sensor_info (topic, name, room, group_name, icon) VALUES (...);
-- Почистить мусор
DELETE FROM sensor_data WHERE topic LIKE '%/set/%';
-- Проверить кодировку таблицы
SHOW CREATE TABLE sensor_info;
Удачи в автоматизации дома! 🚀
Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.
Комментарии
Пока нет комментариев. Будьте первым!