- Цена: US $32.58
Недорогой счетчик электроэнергии на DIN рейку с esp8266 и возможностью передавать данные через MQTT
Наконец у меня дошли руки и до моего электрощита. В проекте автоматы и узо от одной французской фирмы, но их счетчик на дин рейку имеет только импульсный выход.
Как альтернатива — использовать PZEM-004t, я уже писал о нем ранее, когда еще пользовался Domoticz. Но в таком случае нужно придумывать способ размещения в щитке. Самый простой способ — найти готовый модуль, с нормальной стоимостью и возможностью какой-либо интеграции в любой сервер автоматизаций.
Сейчас устройства с модулем ESP8266 становятся все доступнее и производители включают его во все более разношерстные устройства. Как итог — ZMAi-90. Модуль учета электроэнергии и сопутствующих ее характеристик с возможностью установки на стандартные din рейки и еспшкой внутри. Да еще и позволяющий управлять нагрузкой, так как в нем установлено реле.
Поставляется ZMAi-90 в белой коробке без каких-либо надписей.
В комплекте заглушки для контактов и фиксатор
На лицевой панели расположен экран, импульсный светодиод, кнопка и дополнительный светодиод, показывающий что реле выключено.
Характеристики ниже:
Контакты расположены стандартно для устройств подобного типа — вверху вход, внизу выход
Работает счетчик с приложением Tuya. Но останавливаться на сопряжении со стандартным приложением я не буду, на эту тему я уже неоднократно писал. Поэтому сразу решил его разобрать и перепрошить на альтернативную прошивку — Tasmota.
Разборка
Разбирается модуль довольно просто — откручиваем с обратной стороны два шурупа и разъединяем две половинки корпуса.
За WiFi отвечает TYWE3S
Внутри ZMAi-90 расположены 2 платы. Одна, вверху, с экраном, esp8266 и с обратной стороны с MCU. На нижней плате, с реле, находится электрическая часть с импульсным источником питания для электроники. Соединены коннекторами, один из которых припаян.
В ZMAi-90 за управление нагрузкой отвечает довольно массивного размера бистабильное реле с маркировкой ZM888N на 80А. Судя по расположению медных пластин, сделанное, видимо, специально для данного устройства.
Чтобы добраться до mcu придется отпаять припаянную часть соединения двух плат
Расположенный на данной плате MCU имеет маркировкуV9821 HKW562.11617
Перепрошивка ZMAi-90
Вот тут мы дошли до самого интересного. Прошить TYWE3S проще простого, а вот считывать показания с MCU V9821 было бы проблематично без колоссального труда по реверс инжинирингу данного модуля от автора блога creationfactory.co
Все его труды по ZMAi-90 расположены по следующим ссылкам:
Attempting to reverse engineer a home automation oriented smart-meter — Part 1
Reverse engineering the ZMAi-90 DIN rail meter/switch and integrating with Hass.io using Tasmota — Part 2
ZMAi-90 (or SMTONOFF WDS688) DIN rail meter/switch — more details on GPIOs and configuration
Ghost switching can be a bitch if your switch is your main circuit breaker
Там очень много интересной информации по ZMAi-90, почитайте. Поэтому пойдем по его пути, чтобы интегрировать ZMAi-90 в Home Assistant, прошив Тасмотой и научив ее читать и отправлять данные по MQTT.
Прошивается TYWE3S стандартным способом.
Подключаемся USB-UART адаптером к контактам TX RX GND VCC подав GPIO0 на землю.
Но при подаче питания через uart адаптер запустится и MCU. Чтобы этого избежать нужно RST пин MCU так же подать на GND. Удобное место отмечено на фото ниже:
Что я и сделал.
Дальше можно смело подключать uart адаптер к ПК и прошивать любимым способом. Я предварительно сделал бэкап родной прошивки.
Пару слов о Тасмоте. На версии v8.2.0 Elliot есть косяк с публикацией прочтенных данных по uart. Поэтому я залил версию v8.1.0, файл tasmota.bin
Настройка отправки данных в Home Assistant
После подаем питание на ZMAi-90, подключаемся к новой открытой точке доступа tasmota_xxxx и настраиваем wifi с mqtt брокером
Далее в Configuration > Configure Module ставим Module type Generic (0). Тасмота перезагрузится.
После перезагрузки возвращаемся туда же и настраиваем все как на скриншоте:
Тасмота опять перезагрузится.
После переходим в консоль тасмоты и вводим поочередно две команды, устанавливающие верные настройки uart:
Baudrate 9600
SerialConfig 8E1
После введем четыре команды, настраивающие верное поведение реле после включения устройства:
PowerOnState 3
SwitchRetain 0
ButtonRetain 0
PowerRetain 0
И введем правило, публикующее через mqtt считанные данные с mcu:
Rule1 on System#Boot do RuleTimer1 5 endon on Rules#Timer=1 do backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 5 endon
Правило взял из комментариев у автора creationfactory, которое решало определенные проблемы. Выполняется каждые 5 секунд, считывая и публикуя данные вида:
Теперь переходим к настройке на стороне Home Assistant. Добавляем переключатель реле в switches.yaml:
- platform: mqtt
name: zmai_90_general_switch
state_topic: 'stat/zmai_90/RESULT'
value_template: '{{ value_json["POWER"] }}'
command_topic: 'cmnd/zmai_90/POWER'
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_on: 'ON'
payload_off: 'OFF'
payload_available: 'Online'
payload_not_available: 'Offline'
retain: false
И добавляем датчики в sensors.yaml:
- platform: mqtt
name: "zmai_90_consumed_energy"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[6:14] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 100 }}
unit_of_measurement: 'kWh'
icon: mdi:circle-slice-3
- platform: mqtt
name: "zmai_90_voltage"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[14:22] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 10 }}
unit_of_measurement: 'V'
icon: mdi:flash-circle
- platform: mqtt
name: "zmai_90_current"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[22:30] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 10000 }}
unit_of_measurement: 'A'
icon: mdi:flash-auto
- platform: mqtt
name: "zmai_90_frequency"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[30:38] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 100 }}
unit_of_measurement: 'Hz'
icon: mdi:current-ac
- platform: mqtt
name: "zmai_90_active_power"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[38:46] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 100 }}
unit_of_measurement: 'W'
icon: mdi:flash-outline
- platform: mqtt
name: "zmai_90_reactive_power"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[46:54] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 100 }}
unit_of_measurement: 'W'
icon: mdi:flash-outline
- platform: mqtt
name: "zmai_90_apparent_power"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[54:62] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 100 }}
unit_of_measurement: 'W'
icon: mdi:flash-outline
- platform: mqtt
name: "zmai_90_power_factor"
state_topic: "tele/zmai_90/RESULT"
availability_topic: 'tele/zmai_90/LWT'
qos: 1
payload_available: 'Online'
payload_not_available: 'Offline'
value_template: >-
{% set message = value_json.SerialReceived %}
{% set payload = message[62:70] %}
{% set payload_len = (payload | length) %}
{% set result = namespace(value='') %}
{% for i in range(0, payload_len + 1) | reverse -%}
{%- if i is divisibleby 2 -%}
{%- set result.value = result.value + payload[i:i+2] -%}
{%- endif -%}
{%- endfor -%}
{{ (result.value|float) / 10 }}
unit_of_measurement: '%'
icon: mdi:percent-outline
Топик для публикации будет включать имя, которое вы дали модулю в настройках Тасмоты.
И после перезагрузки HA настраиваем карточку с датчиками:
Отличительные особенности альтернативной прошивки — возможность настроить отображение большего количества информации, чем в родной прошивке Tuya. Так же возможность настроить кнопку на корпусе, чтобы она отвечала за реле. На родной прошивке она выполняет только функцию сопряжения.
Небольшое видео, демонстрирующее обновление информации на встроенном дисплее:
Заключение
За умеренную сумму можно поставить себе в щиток универсальный прибор, который отображает данные на встроенном экране и отправляет их в ваш сервер «умного дома». Возможность управление нагрузкой я так же считаю очень полезной функцией. Реле с очень большим запасом по мощности, так как 80А в частном доме/квартире явно не будет. Даже если грубо разделить на 2, то это 40, при том, что вводные автоматы сотрудники наших электросетей рекомендуют ставить на 25А. Итого по реле запас больше чем в три раза. Как поведет себя данный модуль покажет только время, пока что я им полностью доволен.