Решил с нуля собрать IoT-хаб на Raspberry Pi. Раньше у меня уже был MQTT, но Zigbee не "закрутился", Node.js не работал. Решил всё пересобрать чисто — и вот что получилось.
В итоге: Zigbee2MQTT + Mosquitto + MariaDB (вместо MySQL) + Nginx + PHP + веб-интерфейс. Всё работает, датчики ловит, данные пишет, управлять можно.
Сделать универсальный хаб для Zigbee-датчиков, который:
Поставил Raspberry Pi OS (64-bit, Lite). Подключился по SSH.
sudo apt update && sudo apt upgrade -y
sudo systemctl enable ssh sudo apt install ufw -y sudo ufw allow OpenSSH sudo ufw allow 1883/tcp # MQTT sudo ufw allow 8080/tcp # Zigbee2MQTT Web UI sudo ufw allow 80/tcp # Веб-интерфейс sudo ufw enable
sudo apt install mosquitto mosquitto-clients -y sudo systemctl enable mosquitto # Создаём пользователя sudo mosquitto_passwd -c /etc/mosquitto/passwd iotuser # Пароль: 123456
Конфиг: /etc/mosquitto/conf.d/mqtt.conf
allow_anonymous false password_file /etc/mosquitto/passwd listener 1883
В Debian 12+ MySQL больше нет в репозиториях — ставим MariaDB (полная замена).
sudo apt install mariadb-server mariadb-client -y sudo mysql_secure_installation
Создаём БД и пользователя:
sudo mysql -u root -p CREATE DATABASE iot_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'iot_user'@'localhost' IDENTIFIED BY '123456'; GRANT ALL PRIVILEGES ON iot_db.* TO 'iot_user'@'localhost'; FLUSH PRIVILEGES; EXIT;
Zigbee2MQTT 2.6.1 требует Node.js 20+.
cd /tmp wget https://nodejs.org/dist/v20.19.0/node-v20.19.0-linux-arm64.tar.xz sudo tar -xf node-v20.19.0-linux-arm64.tar.xz -C /usr/local --strip-components=1 node --version # v20.19.0 npm --version # 10.8.3
cd ~ git clone https://github.com/Koenkk/zigbee2mqtt.git cd zigbee2mqtt # Устанавливаем pnpm (теперь обязателен) sudo npm install -g pnpm # Копируем конфиг cp data/configuration.yaml.example data/configuration.yaml nano data/configuration.yaml
data/configuration.yaml
homeassistant: false permit_join: true mqtt: base_topic: zigbee2mqtt server: 'mqtt://localhost' user: 'iotuser' password: '123456' serial: port: /dev/ttyUSB0 adapter: ezsp frontend: port: 8080 advanced: log_level: info channel: 11 network_key: GENERATE
npm start
Если видишь:
Zigbee2MQTT:info Coordinator firmware version: ... Zigbee2MQTT:info Zigbee2MQTT started!
— поздравляю, хаб заработал!
Открой в браузере:
http://:8080
Там можно:
Как в статье хомасистент на пхп.
sudo apt install nginx php-fpm php-mysql mariadb-client -y sudo systemctl enable nginx php-fpm
sudo mkdir -p /var/www/html/iot
Туда копируем:
index.php
admin/
api/
js/
, css/
, img/
sudo nano /etc/nginx/sites-available/iot
server { listen 80; root /var/www/html/iot; index index.php; server_name localhost; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.2-fpm.sock; } }
sudo ln -s /etc/nginx/sites-available/iot /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default sudo systemctl reload nginx
Важно создать структуру БД, как в статье.
sudo mysql -u root -p
USE iot_db; -- Таблица с данными датчиков CREATE TABLE IF NOT EXISTS sensor_data ( id INT AUTO_INCREMENT PRIMARY KEY, topic VARCHAR(255) NOT NULL, value VARCHAR(255), timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_topic (topic), INDEX idx_time (timestamp) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- Таблица с информацией о датчиках CREATE TABLE IF NOT EXISTS sensor_info ( id INT AUTO_INCREMENT PRIMARY KEY, topic VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255), room VARCHAR(255), group_name VARCHAR(255), icon VARCHAR(50), INDEX idx_topic (topic) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Из-за PEP 668 в новых системах нельзя ставить пакеты через pip3 install
— используем виртуальное окружение.
python3 -m venv ~/mqtt-env source ~/mqtt-env/bin/activate pip install PyMySQL
~/mqtt_to_mysql.py
import paho.mqtt.client as mqtt import pymysql.cursors import json # Подключение к MySQL через PyMySQL connection = pymysql.connect( host='localhost', user='iot_user', password='123456', database='iot_db', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor ) def on_connect(client, userdata, flags, rc): print("✅ MQTT: Подключено") client.subscribe("zigbee2mqtt/#") def on_message(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() # Пропускаем служебные топики if any(x in topic for x in ["availability", "set", "linkquality", "info", "log"]): return try: data = json.loads(payload) # Обработка списка или объекта if isinstance(data, list): for item in data: process_data(item, topic) elif isinstance(data, dict): process_data(data, topic) else: save_to_db(topic, data) except Exception as e: print("❌ Ошибка при обработке:", e) def process_data(data, base_topic): if not isinstance(data, dict): return for key, value in data.items(): if key in ['temperature', 'humidity', 'pressure', 'battery', 'voltage', 'co2', 'pm25', 'light', 'water_pressure']: full_topic = f"{base_topic}/{key}" save_to_db(full_topic, value) def save_to_db(topic, value): try: with connection.cursor() as cursor: sql = "INSERT INTO sensor_data (topic, value) VALUES (%s, %s)" cursor.execute(sql, (topic, str(value))) connection.commit() except Exception as e: print("❌ Ошибка записи в БД:", e) # Настройка MQTT client = mqtt.Client() client.username_pw_set("iotuser", "123456") client.on_connect = on_connect client.on_message = on_message client.connect("localhost", 1883, 60) print("📡 Ожидание данных с Zigbee...") client.loop_forever()
Чтобы всё работало после перезагрузки.
sudo nano /etc/systemd/system/zigbee2mqtt.service
[Unit] Description=Zigbee2MQTT After=network.target [Service] Type=simple User=mazzick WorkingDirectory=/home/user/zigbee2mqtt ExecStart=/usr/bin/npm start Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
sudo systemctl enable zigbee2mqtt
sudo nano /etc/systemd/system/mqtt-to-mysql.service
[Unit] Description=MQTT to MySQL Bridge After=network.target zigbee2mqtt.service [Service] Type=simple User=mazzick WorkingDirectory=/home/user ExecStart=/home/user/mqtt-env/bin/python /home/user/mqtt_to_mysql.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
sudo systemctl enable mqtt-to-mysql.service sudo systemctl start mqtt-to-mysql.service
:8080
) задай имя: bedroom_sensor
INSERT INTO sensor_info (topic, name, room, group_name, icon) VALUES ('zigbee2mqtt/bedroom_sensor/temperature', 'Температура', 'Спальня', 'Датчики', '🌡️'), ('zigbee2mqtt/bedroom_sensor/humidity', 'Влажность', 'Спальня', 'Датчики', '💧');
Открой:
http:///iot
Должны отображаться датчики, графики, кнопки управления.
Хаб готов. Всё работает. Датчики добавляются, данные идут в БД, интерфейс красивый.
Теперь можно масштабировать: дача, гараж, теплица — через WireGuard в единой сети.
Админка доступна по запросу — если хочешь повторить, пиши в комментарии!
Задумался я тут, а сколько жрет малинка с GUI. и решил немного оптимизировать ее. Т.к. GUI мне не нужны. Хотел конечно использовать ее как домашний комп. Но как увидел сколько всего к ней подключается, это какой-то ядерный реактор а не компьютер. Пусть лучше в ящике как сервер крутится. Так ну и самое интересное, сколько я сэкономлю энергии за год если переведу малинку в режим полноценного сервера.<.p>
Как сэкономить электроэнергию, отключив GUI и лишние службы. Реальные цифры и простые шаги.
Вы поставили Raspberry Pi OS с графическим интерфейсом, но теперь решили использовать малинку как сервер — для хранения, торрентов, веба или домашнего облака. Отлично! Но знаете ли вы, что простое отключение GUI может сэкономить до 0.25 Вт в режиме 24/7?
Даже небольшое энергопотребление складывается:
Это может показаться мало, но если вы используете несколько Pi или питаете от батареек / солнечных панелей — каждая миллиампер-час (мА·ч) имеет значение.
Графический интерфейс (GUI) удобен, но для сервера он — :
Когда вы отключаете GUI командой:
sudo systemctl set-default multi-user.target
Система загружается в текстовом режиме, но пакеты GUI всё ещё установлены. Они не запускаются, но:
dbus
, avahi-daemon
)Показатель | Только GUI отключён | GUI полностью удалён |
---|---|---|
Потребление энергии (примерно) | ~3.0 Вт | ~2.75 Вт |
Использование RAM при старте | ~200–250 МБ | ~60–100 МБ |
Занятое место на диске | ~4–6 ГБ | ~1.5–2 ГБ |
Фоновые службы | Много (X, LXDE, Bluetooth) | Только необходимые |
Годовое энергопотребление | ~26 кВт·ч | ~24 кВт·ч |
Выполните команды (в терминале через SSH):
sudo apt remove --purge --autoremove \\ raspberrypi-ui-mods lxpanel lxsession openbox \\ xserver-xorg xinit lightdm desktop-base \\ chromium-browser firefox-esr libreoffice* \\ scratch* sonic-pi penguinspuzzle claws-mail sudo apt autoremove -y sudo apt clean
После этого ваша система будет почти идентична Raspberry Pi OS Lite — чистая, быстрая и энергоэффективная.
Чтобы сэкономить ещё больше:
sudo systemctl disable bluetooth hciuart
— отключить Bluetoothsudo systemctl disable avahi-daemon
— отключить mDNS (если не нужен)echo 0 | sudo tee /sys/class/leds/led0/brightness
Превратить Raspberry Pi в сервер — легко. А сделать его по-настоящему эффективным — просто:
sudo systemctl set-default multi-user.target
Каждый ватт на счету — особенно когда ваш сервер работает круглосуточно.
Внимание: Cтатьи здесь сгенерированы нейросетью, пока не правил ошибки, только запустил его да и не до этого. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
НО!
Каждый кейс я реально делал минимум один раз. Серьёзно.
Сервера стоят, клиенты довольны, дата-центры не горят.
Это не просто копипаста — это опыт, выстраданный в бою, просто пересказанный через ИИ.
Если у вас есть вопросы, или Нашли неточность? пишите в коментах —
вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.
Комментарии
Пока нет комментариев. Будьте первым!