ИБП Энергия Smart.2 в Home Assistant: два одинаковых с виду ИБП и два разных протокола

от автора

Всем привет! Примерно с лета 2025 у меня работает ИБП Энергия Smart.2 1000W с внешней LiFePO4-батареей, и всё это время он был подключен к Home Assistant — я видел напряжение сети, заряд батареи, нагрузку и всё остальное прямо в дашборде. Написать об этом статью мне тогда в голову не пришло, т.к. всё завелось довольно быстро и казалось, что ничего интересного тут нет. Исправляюсь.

А поводом всё-таки сесть и написать стало то, что недавно я купил второй ИБП — Энергия Smart.2 600W под роутеры. Логика была простая: модель та же, конфиг уже готов, скопировал — работает. По факту же скопированный конфиг не заработал вообще, все сенсоры повисли в unavailable, и в процессе разбирательств выяснилось, что под одним и тем же названием «Smart.2» продаются два ИБП на совершенно разных платформах с разными протоколами. Об этом и расскажу: как подключить оба варианта, чем они отличаются и на какие грабли я наступил.

Кстати, в марте на Хабре выходила статья про подключение Энергии Smart к NUT — там 1000-ваттник подключали через dummy-ups и самописный Python-скрипт. Способ рабочий, но у меня к тому моменту уже давно всё работало более простым путём — через нативную интеграцию Modbus в Home Assistant, без NUT и без скриптов. Его и покажу первым.

Коротко о главном

Если не хочется читать всё:

Smart.2 1000W (монохромный дисплей)

Smart.2 600W (цветной дисплей)

Платформа

клон MUST EP2000

Mega System Technologies

Родное ПО

Smart PowerMonitor

UPSilon 2000

Протокол

Modbus RTU

Megatec (Q1)

Параметры порта

9600 8N1, slave 10

2400 8N1

Подключение к HA

modbus напрямую

через NUT

Данные

20 параметров, включая токи и мощности

базовый набор, без токов и мощностей

Дисплей тут не просто дизайн — по нему можно определить платформу. Монохромный — Modbus, цветной — Megatec.

Часть 1. Монохромный 1000W — Modbus напрямую в Home Assistant

Монохромные Smart.2 — это по сути инвертор MUST EP2000 с другим шильдиком. А MUST общается по Modbus RTU: скорость 9600, адрес устройства 10, данные лежат в регистрах начиная с 30000.

В Home Assistant есть штатная интеграция modbus, которая умеет работать с serial-портом напрямую, поэтому никакие промежуточные программы не нужны — ИБП втыкается по USB в сервер с HA, в configuration.yaml добавляется конфиг, и всё:

configuration.yaml
modbus:  - name: "must_inverter"    type: "serial"    port: "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0"    baudrate: 9600 # Согласно документации    bytesize: 8 # 8 data bits    method: "rtu"    parity: "N" # NONE - без четности    stopbits: 1 # 1 stop bit    delay: 3    sensors:      - name: "Тип устройства"        unique_id: "ups_machine_type"        slave: 10        address: 30000        scale: 1        device_class: "enum"        scan_interval: 15      - name: "Версия ПО"        unique_id: "ups_software_version"        slave: 10        address: 30001        scale: 1        device_class: "enum"        scan_interval: 15      - name: "Режим работы"        unique_id: "ups_work_state"        slave: 10        address: 30002        scale: 1        device_class: "enum"        scan_interval: 15      - name: "Класс батареи"        unique_id: "ups_battery_class"        slave: 10        address: 30003        scale: 1        device_class: voltage        unit_of_measurement: "V"        scan_interval: 15      - name: "Номинальная мощность"        unique_id: "ups_rated_power"        slave: 10        address: 30004        scale: 1        unit_of_measurement: "W"        scan_interval: 15      - name: "Напряжение на входе"        unique_id: "ups_input_ac_volt"        slave: 10        address: 30005        data_type: int16        scale: 0.1        precision: 1        device_class: voltage        unit_of_measurement: "V"        state_class: measurement        scan_interval: 15      - name: "Частота на входе"        unique_id: "ups_input_ac_freq"        slave: 10        address: 30006        data_type: int16        scale: 0.1        precision: 1        device_class: frequency        unit_of_measurement: "Hz"        state_class: measurement        scan_interval: 15      - name: "Напряжение на выходе"        unique_id: "ups_output_ac_volt"        slave: 10        address: 30007        data_type: int16        scale: 0.1        precision: 1        device_class: voltage        unit_of_measurement: "V"        scan_interval: 15      - name: "Частота на выходе"        unique_id: "ups_output_ac_freq"        slave: 10        address: 30008        data_type: int16        scale: 0.1        precision: 1        device_class: frequency        unit_of_measurement: "Hz"        scan_interval: 15      - name: "Ток на выходе"        unique_id: "ups_output_current"        slave: 10        address: 30009        data_type: int16        scale: 0.1        precision: 1        device_class: current        unit_of_measurement: "A"        scan_interval: 15      - name: "Активная мощность на выходе"        unique_id: "ups_output_active_power"        slave: 10        address: 30010        scale: 1        unit_of_measurement: "W"        scan_interval: 15      - name: "Полная мощность на выходе"        unique_id: "ups_output_apparent_power"        slave: 10        address: 30011        scale: 1        unit_of_measurement: "VA"        scan_interval: 15      - name: "Загрузка в процентах"        unique_id: "ups_load_percent"        slave: 10        address: 30012        scale: 1        unit_of_measurement: "%"        scan_interval: 15      - name: "Напряжение батареи"        unique_id: "ups_battery_voltage"        slave: 10        address: 30014        data_type: int16        scale: 0.1        precision: 1        device_class: voltage        unit_of_measurement: "V"        scan_interval: 15      - name: "Ток батареи"        unique_id: "ups_battery_current"        slave: 10        address: 30015        data_type: int16        scale: 0.1        precision: 1        device_class: current        unit_of_measurement: "A"        scan_interval: 15      - name: "Температура батареи"        unique_id: "ups_battery_temp"        slave: 10        address: 30016        scale: 1        device_class: temperature        unit_of_measurement: "°C"        scan_interval: 15      - name: "Заряд батареи"        unique_id: "ups_battery_soc"        slave: 10        address: 30017        scale: 1        unit_of_measurement: "%"        scan_interval: 15      - name: "Температура радиатора"        unique_id: "ups_radiator_temp"        slave: 10        address: 30018        scale: 1        device_class: temperature        unit_of_measurement: "°C"        scan_interval: 15      - name: "Заряд от сети"        unique_id: "ups_grid_charge_flag"        slave: 10        address: 30024        scan_interval: 15        device_class: enum      - name: "Состояние сети"        unique_id: "ups_grid_state"        slave: 10        address: 30025        scan_interval: 15        device_class: enum

Регистр «Режим работы» возвращает число, поэтому для человекочитаемого вида я добавил template-сенсор:

configuration.yaml
template:  - sensor:      - name: "UPS Work State Human"        unique_id: "ups_work_state_human"        state: >          {% set state = states('sensor.ups_work_state') | int(0) %}          {% set map = {0:'Самопроверка', 1:'Режим BACKUP', 2:'От сети (LINE)', 3:'Стоп', 4:'Отладка', 5:'Мягкий старт', 6:'Выключен', 7:'Ожидание'} %}          {{ map.get(state, 'Неизвестно') }}

После перезапуска HA появляется два десятка сенсоров: напряжения и частоты на входе и выходе, ток нагрузки, ток батареи, активная и полная мощность, загрузка в процентах, заряд, две температуры (батареи и радиатора), состояние сети и флаг заряда. То есть по сути всё, что ИБП вообще о себе знает.

Сенсоры и их отображение
Список объектов

Список объектов
Пример отображения на дашборде

Пример отображения на дашборде

Единственное ограничение такого способа — USB-кабель должен идти в ту же машину, где крутится Home Assistant. У меня сервер стоит рядом с бесперебойником, так что проблемы не было. Если HA далеко, порт можно прокинуть по сети через mbusd или ser2net (в конфиге тогда меняется type: serial на type: tcp с адресом моста), но сам я так не делал, не было нужды.

Часть 2. Цветной 600W — а вот тут Modbus не работает

Теперь про новый 600W. Внешне подключение то же самое: USB Type-B на корпусе, внутри тот же переходник CH340 (lsusb показывает 1a86:7523), порт в системе называется точно так же. Я скопировал конфиг, поменял имя — и получил ряд unavailable. Попробовал опросить вручную через mbpoll, перебрал разные slave id и скорости — на всё Connection timed out. Modbus молчал полностью.

Подсказка нашлась на сайте производителя в разделе загрузок. Там три программы:

  • Smart PowerMonitor и SolarPowerMonitor — для обычных Smart2

  • и отдельной строкой: «ПО для новых Smart2 (с цветным дисплеем) — UPSilon2000»

У 1000W дисплей монохромный, у 600W — цветной. И вот это «ПО для новых Smart2» — ключевой момент, т.к. UPSilon 2000 — это программа фирмы Mega System Technologies, и работает она не по Modbus, а по текстовому протоколу Megatec (в дистрибутиве даже в бинарниках виден копирайт Mega System Technologies, 2008 год). То есть у цветных моделей внутри вообще другая платформа.

Проверить это просто: Megatec работает на скорости 2400 и отвечает на текстовые команды. Кидаем в порт команду Q1:

$ python3 -c "import serial,time; s=serial.Serial('/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0',2400,timeout=1); s.write(b'Q1\r'); time.sleep(0.4); print(s.read(120))"b'(227.0 000.0 226.0 000 49.6 13.4 38.0 00001000\r'

И ИБП отвечает. В этой строке по порядку: входное напряжение, напряжение сбоя, выходное напряжение, нагрузка в процентах, частота, напряжение батареи, температура и байт статусных флагов.

Сразу про неприятное: ни тока, ни мощности в этом ответе нет, и это не лечится — в протоколе Megatec таких полей просто не существует. Есть расширенный диалект Voltronic с командой QPIGS, который токи и ватты отдаёт, но наш ИБП его не понимает — я пробовал, драйвер в режиме voltronic вообще не стартует. Родная программа UPSilon 2000, кстати, тоже показывает только напряжения, проценты и температуру — так что походу это ограничение железа, а не софта.

Часть 3. Подключаем 600W через NUT

Раз протокол Megatec — логично использовать NUT (Network UPS Tools), у него есть готовый драйвер nutdrv_qx под это семейство. Заодно решается вопрос расстояния: у меня 600W стоит не рядом с сервером, поэтому я повесил его на Raspberry Pi Zero, а Home Assistant забирает данные по сети.

На Raspberry ставим NUT (apt install nut) и заполняем четыре конфига.

/etc/nut/ups.conf:

[energia]    driver = nutdrv_qx    protocol = megatec    port = /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0    desc = "Energia Smart.2 600W"    default.battery.voltage.high = 13.5    default.battery.voltage.low  = 10.4    default.battery.voltage.nominal = 12

Строки default.battery.voltage.* — это пороги, по которым NUT считает процент заряда (у Megatec своего датчика заряда нет). Я взял их из настроек самого ИБП: 13.5 В — напряжение поддерживающего заряда, 10.4 В — напряжение отключения.

/etc/nut/nut.conf:

MODE=netserver

/etc/nut/upsd.conf — слушать не только localhost, чтобы HA мог подключиться:

LISTEN 0.0.0.0 3493

/etc/nut/upsd.users:

[user]    password = password    upsmon slave

Дальше по идее systemctl restart nut-server и всё должно работать, но у меня с первого раза не заработало, поэтому опишу две проблемы, на которые я потратил время.

Первая — права на порт. Мой пакет NUT собран так, что драйвер работает от пользователя ups (не nut, как можно подумать), и этого пользователя нет в группе dialout — соответственно драйвер просто не может открыть serial-порт и upsc отвечает «Driver not connected». Лечится так:

sudo usermod -aG dialout ups

Вторая — после правки ups.conf сервис nut-driver@energia падал с ошибкой «FATAL: Could not find a NUT device for service». Оказалось, в новых версиях NUT юниты драйверов генерирует отдельный сервис-энумератор, и после изменения конфига его надо дёрнуть:

sudo systemctl restart nut-driver-enumerator.servicesudo systemctl restart nut-driver.target nut-server

После этого всё поднялось:

$ upsc energia@localhostbattery.charge: 100battery.voltage: 13.5input.voltage: 231.0output.voltage: 230.0ups.load: 0ups.status: OLups.temperature: 38.0...

В Home Assistant дальше всё делается в WebUI: Настройки → Устройства и службы → Добавить интеграцию → NUT, вводим IP малинки, порт 3493, логин и пароль из upsd.users. Сенсоры создаются сами, никакого YAML.

Сенсоры и их отображение у «новой» энергии
Все объекты

Все объекты
Дашборд, похожий на первоначальный, мощность считается шаблоном

Дашборд, похожий на первоначальный, мощность считается шаблоном

Часть 4. Что в итоге доступно на каждой платформе

Сравнение того, что реально отдают оба ИБП:

Параметр

1000W (Modbus)

600W (Megatec/NUT)

Напряжение на входе

да

да

Напряжение на выходе

да

да

Частота

вход и выход

только вход

Нагрузка, %

да

да

Напряжение батареи

да

да

Заряд батареи, %

да, родной

оценка по напряжению

Температура

батарея и радиатор

одна

Состояние сети

да

да (OL/OB/LB)

Ток батареи

да

нет

Ток на выходе

да

нет

Активная мощность, Вт

да

нет

Полная мощность, ВА

да

нет

Разница заметная. Если мониторинг для вас важен, при выборе модели это стоит учитывать — по цветному дисплею в магазине сразу понятно, что токов и мощностей не будет.

Для 600W я мощность и ток в итоге сделал расчётными из процента нагрузки. Точность условная (это оценка от паспортных 600 Вт, а не измерение), но для графика хватает:

template:  - sensor:      - name: "ИБП выходная мощность"        unit_of_measurement: "W"        device_class: power        state: >          {{ (states('sensor.energia_load') | float(0) / 100 * 600) | round(0) }}

Часть 5. Modbus напрямую или NUT — плюсы и минусы

Так как у меня теперь работают оба варианта, могу сравнить.

Modbus напрямую (монохромные модели):

  • максимум данных — реальные токи, мощности, две температуры

  • никаких промежуточных программ, один блок в configuration.yaml

  • опрос можно делать хоть каждые 2-3 секунды, просто уменьшив scan_interval (у NUT интервал опроса по умолчанию больше, и в интеграции HA его вроде так просто не подкрутишь)

  • но USB должен идти в машину с HA, и всю логику реакции на отключение света (уведомления, выключение серверов) надо писать самому автоматизациями

NUT (цветные модели, и монохромные при желании тоже можно):

  • работает по сети — ИБП может стоять где угодно, рядом достаточно любой малинки

  • интеграция HA настраивается мышкой, сенсоры создаются сами

  • есть готовая инфраструктура для корректного выключения машин при разряде (upsmon)

  • но на платформе Megatec набор данных заметно беднее, и нужен промежуточный хост с конфигами

По итогу: на 1000W я оставил прямой Modbus, а на 600W выбора особо и нет — NUT.

Итоги

  • Энергия Smart.2 — это две разные платформы под одним названием. Монохромный дисплей — Modbus RTU (клон MUST), цветной — Megatec (Mega System Technologies).

  • Монохромные модели подключаются к Home Assistant напрямую через штатную интеграцию modbus — без NUT, без скриптов, и с полным набором данных, включая токи и мощности.

  • Цветные подключаются через NUT с драйвером nutdrv_qx (protocol = megatec, скорость 2400). Данных меньше: токов и мощностей нет и не будет, это ограничение протокола.

  • Если соберётесь повторять NUT-часть — проверьте, что пользователь ups состоит в группе dialout, и не забудьте перезапустить nut-driver-enumerator после правки ups.conf.

Буду рад комментариям и дополнениям — особенно интересно, что по протоколам у остальных моделей линейки (300W, 800W и старших), если у кого-то есть возможность проверить. Спасибо за внимание)

ссылка на оригинал статьи https://habr.com/ru/articles/1060646/