Недорогой счетчик электроэнергии на DIN рейку с esp8266 и возможностью передавать данные через MQTT

Наконец у меня дошли руки и до моего электрощита. В проекте автоматы и узо от одной французской фирмы, но их счетчик на дин рейку имеет только импульсный выход. 

Как альтернатива — использовать PZEM-004t, я уже писал о нем ранее, когда еще пользовался Domoticz. Но в таком случае нужно придумывать способ размещения в щитке. Самый простой способ — найти готовый модуль, с нормальной стоимостью и возможностью какой-либо интеграции в любой сервер автоматизаций.

Сейчас устройства с модулем ESP8266 становятся все доступнее и производители включают его во все более разношерстные устройства. Как итог — ZMAi-90. Модуль учета электроэнергии и сопутствующих ее характеристик с возможностью установки на стандартные din рейки и еспшкой внутри. Да еще и позволяющий управлять нагрузкой, так как в нем установлено реле.


Ссылка на ZMAi-90: https://aliexpress.ru/item/4000630131830.html
Ссылка на магазин Zemismart: https://aliexpress.ru/store/1848374


Поставляется 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А. Итого по реле запас больше чем в три раза. Как поведет себя данный модуль покажет только время, пока что я им полностью доволен.

0 0 vote
Article Rating

Подписаться
Уведомление о
guest

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

8 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sem2000
Sem2000
1 месяц назад

Edit

ViktorSWA
ViktorSWA
1 месяц назад

Добрый день.
Спасибо за помощь в обсуждениях на сайте Creation Factory.
Все получилось.
У вас в карточке есть переключатель «Восстановление состояния». Я так понимаю, это какой-то скрипт для того чтобы НА считал состояние реле при перезагрузке сервера или при реконнекте девайса?

ViktorSWA
ViktorSWA
1 месяц назад
Reply to  kvv

Добрый день.
Состояние реле, при перезагрузке счетчика, запоминается. Т.е. все работает как надо.
Но есть одно «но». Если перегрузить сервер HA в тот момент, когда реле включено, то положение ползунка general-meter-switch находится в положении OFF. Его надо переключить «руками». Не очень как то… как это победить?

ViktorSWA
ViktorSWA
1 месяц назад
Reply to  kvv

Спасибо! Все работает как надо.
П.С. Это была моя первая автоматизация 🙂