Ad

Saturday, December 7, 2019

Reverse engineering the ZMAi-90 DIN rail meter/switch and integrating with Hass.io using Tasmota - Part 2

I finished the first post with  a tone of optimism, in spite of not being quite there yet. But this time I'm bringing the complete story, with something which hopefully can be a useful takeaway for most users.

Initial analysis of the MCU communication

After figuring out what kind of communication was going on between the ESP8266 and the Vangotech V9821 chip (the specialized MCU which does all the metering functions - and a bit more which I will go in detail afterwards), I got a bit puzzled with the output and its consistency. I first connected a known AC current source through the shunt mounted in the relay's output rail, and in the middle of a stream of garbage, some values seemed consistent with the current I was putting and  being shown in the device's display.


I still cracked my mind at trying to figure out a pattern (I felt as if I was trying to incarnate John Nash while looking for patterns in seemingly chaotic data), and trying to prove assumptions such as the last byte being a checksum. But nothing fruitful came out of that first iteration.



In this first attempt to eavesdrop and decode the communication between the two MCUs that composed this device, I was using the UART feature of a Pickit2, which supposedly had the advantage of not disrupting the impedance of the serial lines.

Pondering on the possibility that I was collecting the serial data incorrectly, I went for a different approach, and instead of using the Pickit, I tried using the regular UART of a standard USB to serial adaptor, and put a 4.7 kOhm resistor between its RX pin and the Vangotech chip TX pin.


With this, the result was certainly more consistent, with message lengths that were regular. This led me to assume that I was collecting the messages correctly, and the commands that the ESP was sending were probably the correct ones. All these captures were done at 9600 bps 8/N/1 settings. I found that at that speed, the 0xFE01 preamble would appear in the messages, and coincidentally or not, the serial protocol from another metering chip, the V9261F, would also have its messages start with the same header sequence:



As such, holding the confidence acquired from that observation, I decided to accept the risk, and use the tuya-convert tool (https://github.com/ct-Open-Source/tuya-convert) to  try to flash Tasmota via OTA (I knew that with the slave MCU always connected to the ESP8266, flashing Tasmota via the serial port would probably not work). The flashing worked, and I managed to retain a backup of the original firmware, through the same tool.

Switching from the original MCU firmware to Tasmota


Already in Tasmota, I setup the hardware serial port (Serial TX and Serial RX in GPIO1 and GPIO 3 pins respectively), and tried to send the same command message that the original firmware would send, but nothing happened. No response.

Rolling back...


I thought of several possibilities, including that some sort of authentication procedure could be happening between the ESP and the Vangotech chip, prior to the actual commands, or that some form of signalling via different GPIO pins could be happening.

That is when I took the backup of the original Tuya firmware and reverted to it. To do this however, I had to forcefully flash via the serial port. I first tried to just connect the pins to GPIO1 and 3 from the ESP chip, but soon figured out that the only immediate option was to remove the R1 and R14 resistors during the flashing, and at the end put these back in place:



Sucess was not immediate, however. The first time I flashed the original firmware, it would enter a boot loop. After some support from the tuya-convert community, it was found that the problem was in the flashing tool recognizing an incorrect flash size for this chip (2 MB instead of 1MB, which is the actual size of the flash). The selection of an incorrect flash size apparently affects the location where the firmware tries to find RF calibration data during the boot process:

https://github.com/ct-Open-Source/tuya-convert/issues/419

As such, flashed it again, by forcing the real size in esptool (1 MB):

esptool.py --port COM3 --baud 74880 --after no_reset write_flash --flash_size 1MB --flash_mode dio 0x00000 tuya_backup.bin --erase-all

And this time it worked like a charm.

Resuming communication analysis in a more proper way


With the Tuya firmware running, I picked up the oscilloscope and started analysing the signals from other GPIO pins. A brief 18 us pulse would indeed occur in the GPIO15 pin during bootup, but apart from that, nothing. With the exception of the GPIO2 which puzzled me initially, because it appeared to send a burst of data during bootup.

When I tried to capture the data, I could only capture garbage. But switching to the ESP8266 bootloader baudrate of 74880 bps, I could see that this was just the debug output from the firmware:

OS SDK ver: 2.0.0(e8c5810) compiled @ Jan 25 2019 14:26:04
ú[notice]wf_sdk_adpt.c:888 country code:CN,SC:1,NC:13
[notice]user_main.c:310 SDK version:2.0.0(e8c5810)
[notice]user_main.c:314 fireware info name:esp_v9801_1plug_zhimei version:1.0.2
[notice]user_main.c:317 tuya sdk compiled at Jul 25 2019 20:39:58
[notice]user_main.c:319 BV:5.46 PV:2.2 LPV:3.3
reset reason: 4
epc1=0x00000000, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000,depc=0x00000000
mode : null
[notice]gw_intf.c:405 Authorization success
mode : sta(bc:dd:c2:xx:xx:xx)
add if0
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
[notice]mqtt_client.c:576 gw wifi stat is:5
state: 3 -> 5 (10)
add 0
aid 6
pm open phy_2,type:2 0 0
cnt 

connected with xxxxx, channel 11
dhcp client start...
ip:192.168.1.42,mask:255.255.255.0,gw:192.168.1.1
[notice]mqtt_client.c:576 gw wifi stat is:5
[notice]mqtt_client.c:607 DNS START 11-27 00:11:05
[notice]mqtt_client.c:634 DNS END 11-27 00:11:05
[notice]mqtt_client.c:640 MQTT CONN START 11-27 00:11:05
[notice]mqtt_client.c:663 MQTT CONN END 11-27 00:11:05
[notice]mqtt_client.c:758 mqtt connect success
[notice]smart_wf_frame.c:3800 firmware self detect upgrade start...
[notice]smart_wf_frame.c:3810 get fw ug info op_ret:2

(As a matter of fact, this second UART is frequently used in the ESP8266 platform for debug logging, as it only features a TX pin)

That is when I had the "brilliant" idea of using the oscilloscope to compare the command as sent by the Tuya firmware, with the command sent by the computer (until this point I was always assuming I had the correct serial port parameters). These were clearly different waveforms, in spite of the minimum pulse length being the same in both cases. Played a bit with the settings on the computer side, until I found a setting which was "bang on" with what Tuya was sending: 9600 8/E/1:


This was like the eureka moment, because it fitted the puzzle and explained the inconsistencies I was having, and potentially why the device was not answering to the command.

With the 2 serial pin resistors still removed from the board, hooked the computer UART to the V9821 serial port, and sent the command originally captured from the ESP:

FE010F080000001C

As expected, the device would respond with a byte sequence that would now make much more sense:

FE010800000000000000000000000000000000000000000000000000000000001000001B

And the checksum documented by Vangotech, once applied in these messages, (i.e. performing the sum of all the bytes except the last, doing the bitwise NOT on the result, and finally adding 0x33), gave the same result.

Just before switching back to Tasmota, and after an accident with the C20 capacitor: I had a wire soldered there, for resetting the Vangotech chip, while doing some experiments. The wire detached taking the solder pad and the capacitor with it.  I noticed that with the Vangotech chip not running because of the reset pin, the relay would also not switch. This made me think that unlike the initial expectation, the Vangotech chip had to have a role in switching the relay. I first thought it was just a GPIO pin from the ESP chip, connected to some driver chip for the relay itself.

With some more investigation and following the traces, I found that there is indeed a driver chip, a Chipnorth CN8023, which receives signals from two pins from the Vangotech V9821. The later, on the other hand, receives a signal from GPIO12 on the ESP chip: when GPIO12 switches from high to low, the V9821 sends a pulse to relay1 pin of the CN8023 chip. This causes the relay to switch off. When the GPIO12 switches from low to high, the V9821 sends a pulse to relay2 pin of the CN8023. This causes the relay to switch on. This slightly complex approach allows the ESP firmware to send a signal as if it would be a regular relay, abstracting the nuances of controlling a bistable relay.

Rolling forward to Tasmota


While investigating on the Tasmota side, I found that (to make things harder :) ) it had no support for changing any serial port parameters other than the baudrate. Given this constraint, I talked with a few people related to the project, via the Discordapp, to get a pulse on what would be the status of this limitation, and if there would be some kind of relevant constraint for not supporting it longer ago.

Given that there was no previous feature request, or any pending Pull Request covering this feature, I decided to try to contribute myself, forking from the project and doing the changes myself.

There was (and is) indeed a challenge in adding a feature to change these settings in the software UART, due to the lack of available iRAM in the current implementation.

But regarding the hardware UART this is just a parameter that has to be set during the initialization of the device.

As such I did the change, tested on a NodeMCU, and after everything was tuned and working, flashed it to the ZMAi-90 meter. After some tests in all of the supported serial port modes, opened the Pull Request:


Theo Arends (the main developer of the Tasmota project) promptly responded to the contribution, making the changes in order to cover all of the 24 possible serial port settings (in my implementation I only covered four of those - I was being conservative to not use more bits from what was an apparently already full flash memory erase block). Theo obviously much more knowledgable of what to change, allocated a spare byte in this block of flash, and dedicated it for the serial configuration.

First success

With Tasmota now able to send data in the needed 9600 8/E/1 format, it was the moment of truth, of trying to send a command and obtaining the response from the V9821 chip.

Configured the port with my new command SerialConfig, for using 8/E/1:

00:01:59 CMD: SerialConfig
00:01:59 RSL: stat/tasmota/RESULT = {"SerialConfig":3}

And upon sending the command to the V9821, bang:

00:04:06 CMD: SerialSend5 fe010f080000001c
00:04:06 RSL: stat/tasmota/RESULT = {"SerialSend":"Done"}
00:04:07 RSL: tele/tasmota/RESULT = {"SerialReceived":"FE01081400000059230000478604000050000096381100000000004149110000100000F0"}

Full success! Communication between the MCUs was fully working.

In-depth protocol analysis

Now it was time to understand the protocol. It didn't take much time to figure out what the data was: I  first noticed that every pair of digits in the hex string represents actual digits from the values, in the correct order. This means we have BCD (binary coded decimal) encoded data. On the other hand, between pairs of digits, the order is inverted.

I found that each data field contains exactly 4 bytes. Splitting the message by each field, for the sample message we have:

FE0108 14000000 59230000 47860400 00500000 96381100 00000000 41491100 00100000 F0

There are always 8 data fields. According to the Vangotech specification (obtained from the datasheet of a simpler device, the V9261F), the number of fields that we expect to receive must be provided in the 4th byte of the request. In our command, indeed we have  the same value:

fe010f080000001c

I first determined, by comparing with the value shown in the LCD display, that the 2nd field was the voltage. By looking at it:

59230000 

If we invert the order of the bytes (pairs of digits) we obtain:

00002359

Interpreting the value as a number and dividing by 10, we obtain the voltage:

235.9 Volts

Using the same principle for the other fields, I could determine the following:

  • the 1st field corresponds to the consumed energy, in kWh after being divided by 100;
  • the 2nd field is the Voltage, as mentioned above. Needs to be divided by 10;
  • the 3rd field corresponds to the current in Amps. Needs to be divided by 10000;
  • with the 4th field I observed it would output 00500000 with the device powered by the mains supply, but stay at 00000000 if supplied directly by a DC supply. Reading the datasheet it was documented that the mains frequency is measured and placed on a register. Given that the mains frequency in my location is 50 Hz (and has to be a very stable value), there is a great likelihood that this field is actually the mains frequency. For the output in Hz, it needs to be divided by 100;
  • the 3 following fields would only output values on the presence of a load. Given that the values were closely related to the power measurement shown in the LCD, and because there is also indication in the datasheet, I started by assuming that the 5th field would corresponds to the Active Power, the 6th field the Reactive Power (in this example taken during the use of a heater attached to the meter), and the 7th field the Apparent Power. The reasoning was due to the observation that the active power field had a value slightly smaller than the apparent power, and that with some loads - such as a motor, the reactive power field would display a value, while with a mostly resistive load such as the heater, it would be zero. For these three values, to obtain the power in Watts, it needs to be divided by 100;
  • The 8th field I observed it would be 00100000 everytime there would be no load connected, or with a resistive load, but display a different value, such as 68070000 when a motor would be connected. The value would be consistent with the relation between active and apparent power, which corresponds to the power factor. So I got to the conclusion that dividing this value by 10 (after inverting the order of the bytes as previously explained) we obtain the power factor in %.

In sum we have:

FE0108 [E (KWh)] [V (Volts)] [I (Amps)] [f (Hz)] [Pactive (Watts)] [Preactive (Watts)] [Papparent (Watts)] [pf (%)] [Checksum]

where the header FE0108 is 3 bytes long, the [Checksum] is 1 byte long and is calculated as the sum of all of the previous bytes, which is the applied bitwise NOT, followed by the addition of value 0x33. Each of the data fields is 4 bytes long and corresponds to the BCD encoded digits of the measurements. The order of the bytes needs to be reversed prior to parsing.

As you may have noticed by now (especially if you have this device and used the Tuya firmware and app), there are more quantities being measured than the original app actually exposes! For example it is particularly useful to obtain the measure of reactive power, as we can characterize the types of loads and their proportion in the appliances consuming energy in the house. Or by monitoring the frequency, we can setup an alarm, notify the user or take some other relevant action if for some reason this value changes (the frequency is critical for some loads).

With the message format resolved, it was now time to go to the fun part, and integrate with Hass.io. Given that I had not written any driver on the Tasmota side, to parse these message and expose the data as sensors, this work had to be done on Hass.io side.

Before that, one important step would be required: configure Tasmota itself. The sections that follow are potentially useful for the user to replicate, and as such I will describe with the clarity that a tutorial/script requires.

Guide for setting up Tasmota and Hass.io with the ZMAi-90

Setup your device

The first thing you will need to setup is your ZMAi-90 device. In order to flash it, you will need to use either tuya-convert or directly via the serial cable.

1. Using tuya-convert:
  • follow the instructions as described in the tuya-convert project: https://github.com/ct-Open-Source/tuya-convert
  • make sure your tasmota binary is greater or equal to version 7.1.2.2 (where the SerialConfig command was introduced). Replace with the correct binary, in the tuya-convert/files directory;
2. Using the serial cable:
  • temporarily solder a wire betwen the RSTn pin (the point between R30 and C20, as shown in the image below) and GND. This will keep the V9821 MCU from booting up and interfere with the communication on the ESP UART;
  • temporarily solder a wire betwen the TYWE3S module (where the ESP8266 chip is) GPIO0 pin and GND. This will put the ESP chip in programming mode;
  • connect TX, RX and GND to your USB-serial bridge. Make sure it is set for 3.3 Volts (5 Volts TTL will fry the chip);
  • provide 5 Volts and GND to the pins in the "J-V" connector, as shown in the picture:

  • using esptool or similar, flash the chip, making sure the flash size is forced to 1MB:
$ esptool.py --port COM3 --baud 74880 --after no_reset write_flash --flash_size 1MB --flash_mode dio 0x00000 tasmota.bin --erase-all

  • remove the shunt between GPIO0 and GND;
  • remove the shunt between RSTn and GND;
  • mount the components together and power the device.

Configure Tasmota

Besides the common Tasmota aspects which I will not detail here (setup WiFi, MQTT, etc), you will need to:
  • configure the module:
    • in the Tasmota web UI, go to Configuration > Configure Module and select Generic (0) as the module type; click "Save". The module will restart afterwards;
    • go back to the same configuration screen, and cofigure the I/O pins like the following screen. Click "Save" and the module will restart once again:
  • configure the serial port to the correct speed: 
    • in the Tasmota console type: Baudrate 9600
  • configure the serial port to the correct mode: 
    • in the Tasmota console type: SerialConfig 8E1
  • you will need to create a rule to periodically send a command to the V9821, to obtain the measurements:
    • in the Tasmota console type:
      Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog SerialSend5 fe010f080000001c; RuleTimer1 10 endon
    • next, enable the rule by typing:
      Rule1 1
With this done, Tasmota will publish every 10 seconds the output from the V9821, into the MQTT topic tele/general-meter-switch/RESULT. For example:

02:59:15 MQT: tele/general-meter-switch/RESULT = {"SerialReceived":"FE01083002000076230000808404000050000028431100000000007253110000100000A6"}

We will need this on Hass.io side.


Configure Hass.io

On Hass.io (Home Assistant) you will need to define the two new types of entities, namely a sensor for each of the 8 measurements, and a switch for the relay. This boils down to adding the following configuration, which covers the parsing (through jinja2) of the BCD encoded data, and the conversion of the values as explained above.

1. Edit the /config/configuration.yaml file, and add the following entries to the "sensor:" section:

  - platform: mqtt
    name: "Mains Consumed Energy"
    state_topic: "tele/general-meter-switch/RESULT"
    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'    
  - platform: mqtt
    name: "Mains Voltage"
    state_topic: "tele/general-meter-switch/RESULT"
    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: 'Volts'
  - platform: mqtt
    name: "Mains Current"
    state_topic: "tele/general-meter-switch/RESULT"
    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: 'Amps'
  - platform: mqtt
    name: "Mains Frequency"
    state_topic: "tele/general-meter-switch/RESULT"
    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'
  - platform: mqtt
    name: "Mains Active Power"
    state_topic: "tele/general-meter-switch/RESULT"
    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: 'Watts'    
  - platform: mqtt
    name: "Mains Reactive Power"
    state_topic: "tele/general-meter-switch/RESULT"
    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: 'Watts'      
  - platform: mqtt
    name: "Mains Apparent Power"
    state_topic: "tele/general-meter-switch/RESULT"
    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: 'Watts'
  - platform: mqtt
    name: "Mains Power Factor"
    state_topic: "tele/general-meter-switch/RESULT"
    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: '%'

You may rename the topic name and the entity name as appropriate for your setup.

2. Edit the "switch:" section, by adding:

  - platform: mqtt
    name: general-meter-switch
    state_topic: 'stat/general-meter-switch/RESULT'
    value_template: '{{ value_json["POWER"] }}'
    command_topic: 'cmnd/general-meter-switch/POWER'
    availability_topic: 'tele/general-meter-switch/LWT'
    qos: 1
    payload_on: 'ON'
    payload_off: 'OFF'
    payload_available: 'Online'
    payload_not_available: 'Offline'
    retain: true 

Again, rename the topic name and the entity name as appropriate for your setup.

3. Restart Hass.io, and you should be done! In the web UI, the new badges should become visible:


Obviously like the sensors in general, the history of values is retained:


And the relay will appear just like any other switch:


Final considerations

This work was quite a bit of a journey, with all the learning that it carried, but also for how pleasing it was with the results that it brought after all of the challenges, and moreover, the satisfaction of sharings results with the community which may prove useful to other users.

There are still potential steps of improvement which I intend to pursue, such as developing the driver on the Tasmota side, or discovering other metering MCU commands such as how to reset the energy counter.

I thank the community, especially the people from the Tasmota and tuya-convert projects, who have provided helpful feedback when needed.

148 comments:

Jarek said...

What’s your guess?
Will it work with who’s meter:

https://a.aliexpress.com/_dtjs2

Creation Factory said...

Hi,

I've looked into this meter before. Given the fact that this is a 3-phase device (the v9821 that is in the ZMAI-90 is a single phase metering chip) and because of the RS-485 bus capability and the type of protocol that is detailed in the product page, it is likely a very different device. It is of course also an interesting target for reverse engineering just as done with the ZMAI-90..

Cheers

Unknown said...

great work!! Thank, I hope you find the way to reset the energy counter!! that would be the cherry on top of the cake. Your blog gave me the missing push to get a Zmai90. flashed and setup following your instruction, the only thing I had to change was the "tele/general-meter-switch/RESULT" part of the mass setup into "general-meter-switch/tele/RESULT"

again MANY THANKS!!!

Rogerio said...


Hello friend, congratulations for the post. I recently purchased a Zmai-90 and it is not registering energy consumption in the Tuya application. It does not register and does not record. I would like to leave it in original firmware, but it would work. My Zmai90 has current firmware 1.0.2 and I found that updated firmware would be 1.0.6. Would the current firmware update (1.0.6) flash? Would you have this file to provide me? You said you backed up yours. I thank you for your attention.

Creation Factory said...

Hello Rogerio, thanks! I'm sorry, I don't have the original firmware v1.0.6. I converted my own test device to Tasmota before any original firmware update could take place (it was in version 1.0.2). Nevertheless (not sure if is true or not), I read that Tuya firmwares can contain device specific data, preventing a firmware image extracted from one device, to work in another device.

Cheers

Rogerio said...

Thanks for the reply friend. Could you give me a hint as to why my device does not register or record energy consumption in the application?

I bought 2 devices and both are having the same problem.

Creation Factory said...

Hello Rogerio, it is difficult to troubleshoot just based on the behaviors you describe. It is possible that you are not provisioning it with the correct Wifi password? Can it be the case that you Wifi access point uses older encryption standards such as WEP? It can be the case that open or unsafe encryption is unsupported by these Tuya firmwares..honestly my experience with stock firmware was short and not incredibly satisfying. Sorry for not being able to help further..

L02R said...

Thanks for all your hard work, and thanks for sharing it for free! Cheers :)

Mark said...

Hello, me again :)

I've noticed in Home Assistant that the switch is very rarely "on" even though it is. I cannot post a picture, but is it either unavailable or mainly OFF. I was off for 24 hours, till I logged into the web console and it changed to ON. Also I am trying to change the friendly name and when I do it resets. Not sure what I have done wrong, but I followed the above to the letter.. :D

00:00:00 CFG: Loaded from flash at F9, Count 35
00:00:00 Project tasmota Tasmota Version 8.1.0(tasmota)-2_6_1
00:00:00 WIF: Connecting to AP1 xxxxx in mode 11N as StudioPower-5893...
00:00:00 RSL: tele/StudioPower/RESULT = {"SerialReceived":"F0"}
00:00:06 WIF: Connected
00:00:06 HTP: Web server active on StudioPower-5893 with IP address 192.168.0.27
10:04:52 MQT: Attempting connection...
10:04:52 MQT: Connected
10:04:52 MQT: tele/StudioPower/LWT = Online (retained)
10:04:52 MQT: cmnd/StudioPower/POWER =
10:04:52 MQT: tele/StudioPower/INFO1 = {"Module":"Generic","Version":"8.1.0(tasmota)","FallbackTopic":"cmnd/DVES_593705_fb/","GroupTopic":"cmnd/tasmotas/"}
10:04:52 MQT: tele/StudioPower/INFO2 = {"WebServerMode":"Admin","Hostname":"StudioPower-5893","IPAddress":"192.168.0.27"}
10:04:52 MQT: tele/StudioPower/INFO3 = {"RestartReason":"Hardware Watchdog"}
10:04:52 MQT: stat/StudioPower/RESULT = {"POWER":"ON"}
10:04:52 MQT: stat/StudioPower/POWER = ON

Creation Factory said...

Hello Mark,

Can you try increasing the log level so that we can have more details? Go to Configuration > Configure Logging > Web log level > 4 More debug.

Could you share the output of the State command? Do you have a solid wifi connection with the device?

You may also want to share this behavior as an issue in the Tasmota project (https://github.com/arendst/Tasmota/issues)

Thank you

Cheers

Mark said...

Hello

I upgraded to 8.2 and the problem went away. Then I realised HA was calculating the formula. After checking the console, I noticed it was reporting the right value but it was missing the quotes... so I downgraded back to 8.1 and everything is fine now and I could change the name.. very odd..

16:25:47 MQT: tele/StudioPower/RESULT = {"SerialReceived":FE01083233000050230000402211000050000004392600521300008241260000100000CF}

notice no quotes on 8.2 and 8.1 below

17:04:20 MQT: tele/StudioPower/RESULT = {"SerialReceived":"FE01085234000094230000871906000050000068831400283100003386140000100000C3"}

Angelo said...

Hi , thank's to your post i was able to do what you wrote but instead of using home assistant, i'm using openhab...could you help me please to find a way to analyze and convert the string from the MQTT message into some ussefull items? thank you very much

Angelo said...

Hi,
how to implement this in openhab instead of home assitant?
Thank you very much

ViktorSWA said...

Sorry for my English. I use Google translate.
Changed the electric meter WDS688.
Version Tasmota 8.2.0.
I need your help.
Here is what Tasmota displays in the console:
11:30:57 MQT: stat / tasmota_C557E6 / RESULT = {"SerialSend": "Done"}
11:30:58 MQT: stat / tasmota_C557E6 / RESULT = {"T1": 10, "T2": 0, "T3": 0, "T4": 0, "T5": 0, "T6": 0, "T7": 0, "T8": 0}
What could be the problem?

Creation Factory said...

Hello Angelo,

I don't use OpenHAB so I can't readily help you with your question. Take a look at the part of my post where I detail the meaning of each field in the hex string and how to parse these. The jinja code may also be useful as a starting point for your setup.

I cannot promise when but I have the ambition of implementing logic on Tasmota side for doing the parsing, and exposing the calculated values as sensors, making the integration simpler and similar to other sensors/meters.

Cheers

Creation Factory said...

Hello Unknown,

Could you send more of your log output?

I would expect to see something like this, if the meter chip is responding:

14:43:23 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
14:43:23 MQT: stat/general-meter-switch/RESULT = {"SerialSend":"Done"}
14:43:23 MQT: stat/general-meter-switch/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
14:43:23 MQT: tele/general-meter-switch/RESULT = {"SerialReceived":"FE01080927090053230000236401000050000088120300364900000487030000080000F2"}

Have you set the serial parameters correctly? I.e.:

Baudrate 9600
SerialConfig 8E1

Cheers

Angelo said...

I included the baudrate command inside the system boot rule, because I have the same issue, when you restart the tasmota, it loses the configuration of the baudrate

Angelo said...

I did it by myself, I created a similar rule inside openhab to split the data and parse them. Thank you

ViktorSWA said...

Hello.
Thanks for the answer.
You write: Could you send more of your log output?
Unfortunately in the logs only what I indicated.
There aren't records of the form:
{"SerialReceived":"FE01080927090053230000236401000050000088120300364900000487030000080000F2"}

As for setting up the serial port: I did everything according to your instructions.
How can I check if the serial port settings have been applied?

ViktorSWA said...

Hello.
Thanks for the answer.
You write: Could you send more of your log output?
Unfortunately in the logs only what I indicated.
There aren't records of the form:
{"SerialReceived":"FE01080927090053230000236401000050000088120300364900000487030000080000F2"}

As for setting up the serial port: I did everything according to your instructions.
How can I check if the serial port settings have been applied?

Creation Factory said...

Hi ViktorSWA,

You can check by issuing the commands in the console:

Baudrate
SerialConfig

Cheers

ViktorSWA said...

Hi Creation Factory,

log from the console:

07:19:40 CMD: Baudrate
07:19:40 MQT: stat/tasmota_C557E6/RESULT = {"Baudrate":9600}
07:19:42 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
07:19:43 MQT: stat/tasmota_C557E6/RESULT = {"SerialSend":"Done"}
07:19:43 MQT: stat/tasmota_C557E6/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
07:19:53 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
07:19:53 MQT: stat/tasmota_C557E6/RESULT = {"SerialSend":"Done"}
07:19:54 MQT: stat/tasmota_C557E6/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
07:20:04 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
07:20:04 MQT: stat/tasmota_C557E6/RESULT = {"SerialSend":"Done"}
07:20:05 MQT: stat/tasmota_C557E6/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
07:20:14 CMD: SerialConfig
07:20:14 MQT: stat/tasmota_C557E6/RESULT = {"SerialConfig":"8E1"}
07:20:15 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
07:20:15 MQT: stat/tasmota_C557E6/RESULT = {"SerialSend":"Done"}
07:20:16 MQT: stat/tasmota_C557E6/RESULT = {"T1":9,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}

As you can see, the serial port settings are correct.
But there is no answer in the form: E1:
{"SerialReceived":"FE01080927090053230000236401000050000088120300364900000487030000080000F2"}
Please help me

Creation Factory said...

Hi ViktorSWA,

It is possible that you have different hardware in your device. Is there a chance you can open your device and share photos of the boards?

It would be particularly relevant to know if you have the same metering chip.

Thank you

Cheers

Creation Factory said...

Regarding the change in format of the SerialReceived JSON output, this was the motivation:

https://github.com/arendst/Tasmota/issues/7506

Cheers

ViktorSWA said...

Hi Creation Factory,
Yes, there is such an opportunity. Tomorrow I will take a photo

And one more question ... the state of the switch is not updated after rebooting the home assistant ... only after changing the state of the switch, the home assistant will receive information about this. How to make sure that the state of the switch is sent to the MKTT topic not only when it changes, but with a certain frequency ...

Creation Factory said...

Fyi regarding the format of the SerialReceived, the regression was fixed:

https://github.com/arendst/Tasmota/commit/caff54da7ccadf437a1d5e4bc72599cdc0f530dc

If you can, please build from development branch and give it a try (currently I cannot take my ZMAi-90 out of service for testing :) ).

Thank you.

Cheers

ViktorSWA said...

Hi Creation Factory,

You write:
"Fyi regarding the format of the SerialReceived, the regression was fixed:
https://github.com/arendst/Tasmota/commit/caff54da7ccadf437a1d5e4bc72599cdc0f530dc"

unfortunately, for me it is incomprehensible and difficult.Can you explain more clearly (I am not very good at it)?

Now I also do not have access to the device (quarantine), but the task of reengineering the electric meter is very interesting, and I hope to defeat it :)

Francis said...

I have the same problem as VictorSWA

16:35:15 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
16:35:15 MQT: stat/electricity1/RESULT = {"SerialSend":"Done"}
16:35:16 MQT: stat/electricity1/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
16:35:26 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
16:35:26 MQT: stat/electricity1/RESULT = {"SerialSend":"Done"}
16:35:27 MQT: stat/electricity1/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
16:35:28 CMD: Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog SerialSend5 fe010f080000001c; RuleTimer1 10 endon
16:35:28 MQT: stat/electricity1/RESULT = {"Rule1":"ON","Once":"OFF","StopOnError":"OFF","Free":396,"Rules":"on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog SerialSend5 fe010f080000001c; RuleTimer1 10 endon"}
16:35:32 MQT: tele/electricity1/STATE = {"Time":"2020-04-04T16:35:32","Uptime":"0T01:15:12","UptimeSec":4512,"Heap":29,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":1,"POWER":"ON","Wifi":{"AP":1,"SSId":"SNOW","BSSId":"10:FE:ED:AF:44:7A","Channel":10,"RSSI":80,"Signal":-60,"LinkCount":1,"Downtime":"0T00:00:06"}}
16:35:37 RUL: RULES#TIMER=1 performs "backlog SerialSend5 fe010f080000001c; RuleTimer1 10"
16:35:37 MQT: stat/electricity1/RESULT = {"SerialSend":"Done"}
16:35:38 MQT: stat/electricity1/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}

but nothing received on tele/electricity1/RESULT

ViktorSWA said...

Hi, Francis.

I still have not solved my problem. Unfortunately, I am quarantined by the coronovirus.
I hope in the near future I will be able to access my device. I will take a photo of the processor.
Let's hope that dear Creation Factory will help us.

ViktorSWA said...

Hi Creation Factory.

Please see the photo of the chip from my electric meter. (link below).
https://www.dropbox.com/s/h6zu6dqw5og0dq1/2020-04-13%2018.18.03.jpg?dl=0

If there are suggestions what could be the cause of my problem, I will be very happy to receive help from you.

Thanks!

Creation Factory said...

Hi ViktorSWA, thanks. It pretty much the same board and chip as in the ZMAi-90. Have you ever used your the device with the original firmware? Did it work?

If so, by any chance you have a copy of the original firmware? That could be helpful in understanding if the command set is the same of if the manufacturer changed the commands (technically, the V9821 chip is also programmable and quite versatile just like an ordinary microcontroller).

Cheers.

ViktorSWA said...

Hi Creation Factory.

Yes, I tested the device with original firmware. It worked. Unfortunately, the original firmware was not preserved.
I think my V9821 chip has a different firmware and command system. My device has a different name - WDS-688. I have a digital oscilloscope, but, I'm afraid, without the original firmware, this will not help.
Do you have any further suggestions?

Unknown said...

Hi Creation Factory,

Firstly, thanks for an in-depth analysis of the ZMAi-90. It helped get my meter integrated with HA (or hass, hassio, home assistant core or what ever it is called this week).

Just a few issues,
1) I think something has changed in Tasmota 8.2, and is referred to above about the serial received format.
I noticed that I was not getting what I expected via MQTT;
expecting "SerialReceived":"FE0108000000009123000000000000005000000000000000000000000000000010000017"
getting "SerialReceived":FE0108000000009123000000000000005000000000000000000000000000000010000017
Notice the second set of quotes around the data have gone missing.

To solve this I modified your sensor.yaml example
I decided to simplify by removing the JSON decode which is now broken, and go for direct string slicing on the full received data. The changes are simply using 'value' instead of 'value_json.SerialReceived', and a change to the index of characters picked up. I also fixed 'payload_len' at 8 as I couldn't see why we should calculate it every time.

#Example fo picking up voltage reading
- platform: mqtt
   name: "Server Room Mains Voltage"
    state_topic: "tele/unit1/Serverroom-EM/RESULT"
    value_template: >-
        {% set payload = value[32:40] %}
        {% set payload_len = 8 %}
        {% 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: 'Volts'




2) Another poster has also said above, that the command BaudRate 9600 does not seem to be 'sticky'. I.e. on a reboot, the data messages are not seen over MQTT. On typing Baudrate, you can see that 9600 is apparently set. However, typing Baudrate 9600 then makes the messages flow again.

I haven't been able to fix this yet.

I think all of these are issues in Tasmota 8.2

3) I wondered if I would have a black start issue... In my configuaration, the wireless access point is on the load side of the energy meter. On power cycle, the access point will be off, and no way to access the ZMAi-90 until that AP is powered. However, it appears that the relay is bistable and retains its last known state. I am sure I could engineer a black start problem, buy turning off the ZMAi-90 and then removing its supply. On start up it would still be off, with no live access point with which to control it. In practice this is unlikely. Short term 'ghost switching' can be tollerated as this is supplying a UPS anyway. Long term blackouts where the UPS will have shutdown too, might need some looking at.

Thanks again for a great analysis of the ZMAi-90.

Unknown said...

Just to clarify the fix given by Angelo, which has also now fixed my issue. I think it is also ViktorSWA's issue.

Change the command issued at the console to;
Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10 endon

Note that Baudrate 9600 is added to the sequence.

With Tasmota 8.2 (the only one I have tested with), the serial data does not flow until the Baudrate command is issued after boot (even though it is set to the same value).

My meter now properly communicates after a power cycle.

Thanks again.

Creation Factory said...

Hi all,

Responding in sequence of arrival of the questions:

@ViktorSWA: possibly there are differences in the command set, yes. Regarding it being a WDS688 and not a ZMAi-90, I don't think that is necessarily the cause because people have been reporting success with the conversion of either device.

You could potentially go brute force and vary the 3 header bytes to see if you obtain an answer:

fe010f080000001c

There is however some risk by doing this, as you may discover first some command that could be changing calibration data or something worse.

@Francis do you also have a WDS688? Do you have a backup of the original firmware?

btw, you are also setting the serial port to the correct parity settings? I.e.: {"SerialConfig":"8E1"}. Take into account the comment provided by @Unknown.


@Unknown, regarding the "SerialReceived" with the hex data not delimited by " ", there is a fix for that already in the Tasmota project (is currently in the development branch, should go in the next release).

Regarding the bitrate setting not being sticky I will check if I can reproduce the issue, and in that case if there was a fix already.

Cheers

kvvoff said...

Hello! You did a fantastic job of reverse engineering this device. I reflash it on tasmota 8.1 and it works great. But my question is: is it possible to make the relay remember its previous state? It is very inconvenient when the relay always turns off when power is applied. Regards

kvvoff said...

At the moment, I solved this problem by creating and restoring a scene in HA, but this is not an entirely elegant way.

#
- alias: 'zmai_90_revert_create'
description: '.'
trigger:
- platform: state
entity_id: switch.zmai_90_general_switch
to: 'unavailable'
condition: []
action:
service: scene.create
data:
scene_id: zmai_90_revert
snapshot_entities: 'switch.zmai_90_general_switch'

#
- alias: 'zmai_90_revert_on'
description: '.'
trigger:
- platform: state
entity_id: switch.zmai_90_general_switch
from: 'unavailable'
action:
- service: scene.turn_on
data:
entity_id: scene.zmai_90_revert

Best when the device is self-contained and autonomous

Creation Factory said...

Hi @kvvoff, thanks for your comment. Are you talking to the switch via MQTT?


I've created a post exactly about that topic some time ago:

https://www.creationfactory.co/2019/12/ghost-switching-can-be-bitch-if-your.html

Basically what I believe is happening with you, is not the switch itself that is not remembering the state (the relay inside it is bistable, it actually stays in whatever state you leave it in), but it is related to the mqtt broker and how these are published. The retain settings are tricky because these can cause the behavior you describe: once the device turns on, if it consumes a message that is persisting in the mqtt broker, telling it to turn off, it will turn off all the time.

Even after you disable and configure the retain settings properly as I described in my post, If you still have messages persisting in the MQTT broker, the behavior will happen again. I recommend also deleting the broker database file, for allowing it to start from a clean slate.

Cheers.

kvvoff said...

Thanks for your reply! Yes, I use mqtt. After your comment, I figured out the tasmota and zmai90 saves the state of the relay after a power outage.

Here is what I did:
In ha switch: retain: false
In tasmota console: PowerOnState 3, SwitchRetain 0, ButtonRetain 0, PowerRetain 0
In Tasmota Device Manager: Clear retained

And after that, everything works great, and most importantly - the relay does not click at startup, it remains in the previous state. Thank you very much for your help! I will write about you on my blog

Creation Factory said...

Ok, what's your blog by the way?

Cheers

ViktorSWA said...

Hi all,

Thanks, unknown! After I fulfilled your recommendation (Change the command issued at the console to; Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10 endon),
it all worked for me!
Of course, I had to change the sensor so that the data would be processed correctly.

Question to kvvoff:
You write:
"Here is what I did:
In ha switch: retain: false
In tasmota console: PowerOnState 3, SwitchRetain 0, ButtonRetain 0, PowerRetain 0
In Tasmota Device Manager: Clear retained"
1. Why do all this need to be done?
2. I did not find the following: In Tasmota Device Manager: Clear retained. Where is the device manager?

kvvoff said...

my blog kvvhost.ru (in russian)

@ViktorSWA, you ask:

"1. Why do all this need to be done?
2. I did not find the following: In Tasmota Device Manager: Clear retained. Where is the device manager?"

1. I did this so that the relay retains its status when power is restored.
2. Available here: https://github.com/jziolkowski/tdm/releases

In general, all this is painted by the author of this blog at this link: https://www.creationfactory.co/2019/12/ghost-switching-can-be-bitch-if-your.html

Thank you, @Creation Factory, for this information, friend!


Francis said...

Change the command issued at the console to; Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10 endon

Did it for me to !

Unknown said...

Hi this could be a noob issue im having so be gentle chaps, but i just can not seem toe get the serial working at all this is log off console so im kinda stuck at the mqtt phase and

great and helpful project BTW

I have two devices and both behave the same i hate to say

"10:33:53 RUL: RULES#TIMER=1 performs "backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10"
10:33:53 MQT: stat/tasmota_DF5240/RESULT = {"Baudrate":9600}
10:33:53 MQT: stat/tasmota_DF5240/RESULT = {"SerialSend":"Done"}
10:33:54 MQT: stat/tasmota_DF5240/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
10:33:54 CMD: SerialConfig 8E1
10:33:54 MQT: stat/tasmota_DF5240/RESULT = {"SerialConfig":"8E1"}
10:34:04 RUL: RULES#TIMER=1 performs "backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10"
10:34:04 MQT: stat/tasmota_DF5240/RESULT = {"Baudrate":9600}
10:34:04 MQT: stat/tasmota_DF5240/RESULT = {"SerialSend":"Done"}
10:34:05 MQT: stat/tasmota_DF5240/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
10:34:15 RUL: RULES#TIMER=1 performs "backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10"
10:34:15 MQT: stat/tasmota_DF5240/RESULT = {"Baudrate":9600}
10:34:15 MQT: stat/tasmota_DF5240/RESULT = {"SerialSend":"Done"}
10:34:16 MQT: stat/tasmota_DF5240/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
10:34:16 CMD: Baudrate
10:34:16 MQT: stat/tasmota_DF5240/RESULT = {"Baudrate":9600}
10:34:26 RUL: RULES#TIMER=1 performs "backlog Baudrate 9600; SerialSend5 fe010f080000001c; RuleTimer1 10"
10:34:26 MQT: stat/tasmota_DF5240/RESULT = {"Baudrate":9600}
10:34:26 MQT: stat/tasmota_DF5240/RESULT = {"SerialSend":"Done"}
10:34:27 MQT: stat/tasmota_DF5240/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
"
I just keep getting the {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0} and nothing else Sigh!
i have tried the diffrent options in this but alas nothing

Creation Factory said...

Hi @Unknown, what device model do you have? Also, do you happen to know which is the original firmware version of your device?

Thank you

Cheers

Unknown said...

Hi
the boot screen says OS SDK ver: 2.1.1 (317e50f) compiled @ Dec 10 2019 11:05:04 phy ver: 1058_13, pp

does that help ?

its also odd that i can not switch it via tasmoda also, it set ro relay1 btw

Andrew

Unknown said...

i posted the note, but have not had a comment can you shed any light on it ?

Creation Factory said...

Hi @Unknown, sorry I missed your comments were still pending moderation. Apparently you have a superior version of the firmware.

Do you also have any line similar to:

[notice]user_main.c:314 fireware info name:esp_v9801_1plug_zhimei version:1.0.2

It contains the actual firmware version.

Cheers

Unknown said...

Hi @Creation Factory
i have done some more work on this and i think im getting closer, when i boot all the devices i have (960081n) and spike the serial gpio from the esp i get a OS SDK 2.1.1 (317e50f) compiled @ dec 10 2019 and in addition if i sniff the ethernet traffic i get a https session not the MQTT that seems to be common for everyone else.
this all said im now thinking that they did a SW update, so i googled around and have found nothing at all except that the smart app reports this as 3.1.4 and mcu module as 1.0.0 and that no sw updates are available
so feeling a bit discouraged that google didn't know the answers either i decided to have a poke around with my scope and found to things that are quite different first is that the GPIO no longer seems to be controlling the Bi State and this is backed up by the data burst on the TX pin and the second is that the chatter your referred to on GPIO 15 is gone
so the plot thickens
i removed the board and have found different silk screen numbers that the one you show in your photo also

this all lead me the the assumption that they have done a HW and SW mod, and when i tasmod it, it just did nothing so that pretty much confirmed that i had something different going on

so just sitting on the serial port (960081e) I get a 0x55 0xaa 0x80 0x80 0x40 0x40 every 15 secs and a 55 aa 80 83 40 41 a0 20 05 05 c8 f8 to turn the relay on and a 55 aa 80 83 40 41 a0 20 05 10 a8 f8 to turn it off

because this data seems consistent im assuming that they are using 55 as preamble

my issue is (apart from not knowing how to config tasmoda to use this) is the 15sec burst im pretty sure is some sort of poling so i decided to sniff the other line and got 0x FE 00 80 0.. and then had a sad issue dropping my soldering iron on it and the smoke cam out

so im thinking that it maybe very similar your comments are very welcome

Creation Factory said...

Hi @Unknown, that "0x FE 00 80 0" preamble you got from the other line is similar to the Vangotech chip responses.. I am a bit confused regarding where you were obtaining the other data (e.g. 0x55 0xaa 0x80 0x80 0x40 0x40). Can you share in which pins of the ESP chip (TYWES board) you were obtaining each data stream from?

Regarding the metering chip, is it the same (V9821)?

Thank you

Cheers.

lazysloth said...

Hi, I'm new in IOT and have no deep knowledge of Tasmota but I hope my humble experience will help someone who also is researching this field and/or wants investigate it more deeply than I am.
I've recently got an updated version of this device.
Due to 'New PSK issue', (https://github.com/ct-Open-Source/tuya-convert/issues/483) Tuya convert didn't work but thanks to the labor of this blog's author I've been able to successfully flash the device with only difference from the described procedure - I didn't supply 5V to the J-V connector(BTW why is it necessary to supply 5V since we are already powering the ESP chip with 3V?).
What came next was at first a disappointment. The relay was off and I was unable to turn it on via GPIO. MCU also did not respond to serial command. Also device performed self resets from time to time. Then I thought that I've somehow broken the device during flashing but further research proved me wrong.
It appears that both PCB layout and internal communication architecture have been changed in new version of device. Some GPIOs became disconnected from the PCB as long as Button/Led/Relay controls - now everything is connected to V8921 chip and all control from ESP is performed now via TuyaMCU (https://tasmota.github.io/docs/TuyaMCU). ESP chip sends serial commands to MCU and MCU responds: turns on and off the relay, report measured power metrics and probably turns on/off the LEDs. I guess that earlier self resets could have been caused by serial tx on GPIO 13 which was interpreted as 40-second button pressing. When GPIO 13 setting has been changed from button no more self resets was observed. Finally module type/GPIO assignment has been set up as at screenshot(I'm not sure if double set of tx/rx communication lines need to be configured. Also since it appeared to be working with all GPIOs set to none probably some settings are already embedded into TuyaMCU tasmota module and therefore GPIO assignment is not needed.)

It appears that there is only 4 metrics now(full list of metrics is exposed with 'SerialSend5 55aa0001000000' command as described in Tasmota TuyaMCU documentation article). The metrics are following:
"DpType2Id17":20 Cumulative W/h during device life time
"DpType2Id18":130 Current = 0,13A
"DpType2Id19":295 Power = 29,5W
"DpType2Id20":2264 Voltage = 226,4V

The measurements were taken while the only connected load was an 28W old fashioned filament lamp. For better understanding please see a log excerpt in next comment.

lazysloth said...

--Part2 of 2--

20:53:50 CMD: SerialSend5 55aa0001000000
20:53:50 CMD: Group 0, Index 5, Command "SERIALSEND", Data "55aa0001000000"
20:53:50 MQT: stat/tasmota_DF58C4/RESULT = {"SerialSend":"Done"}
20:53:50 {"TuyaReceived":{"Data":"55AA0301002A7B2270223A226136646A61627A6D7062627036326777222C2276223A22312E302E30222C226D223A307DE8","Cmnd":1,"CmndData":"7B2270223A226136646A61627A6D7062627036326777222C2276223A22312E302E30222C226D223A307D"}}
20:53:50 TYA: MCU Product ID: {"p":"a6djabzmpbbp62gw","v":"1.0.0","m":0}
20:53:50 TYA: Send "55aa0002000001"
20:53:50 {"TuyaReceived":{"Data":"55AA0302000004","Cmnd":2}}
20:53:50 TYA: RX MCU configuration Mode=0
20:53:50 TYA: Read MCU state
20:53:50 TYA: Send "55aa0008000007"
20:53:50 {"TuyaReceived":{"Data":"55AA03070005010100010112","Cmnd":7,"CmndData":"0101000101","DpType1Id1":1,"1":{"DpId":1,"DpIdType":1,"DpIdData":"01"}}}
20:53:50 TYA: fnId=11 is set for dpId=1
20:53:50 TYA: RX Relay-1 --> MCU State: On Current State:On
20:53:50 {"TuyaReceived":{"Data":"55AA0307000811020004000000143C","Cmnd":7,"CmndData":"1102000400000014","DpType2Id17":20,"17":{"DpId":17,"DpIdType":2,"DpIdData":"00000014"}}}
20:53:50 TYA: fnId=0 is set for dpId=17
20:53:50 {"TuyaReceived":{"Data":"55AA030700081202000400000082AB","Cmnd":7,"CmndData":"1202000400000082","DpType2Id18":130,"18":{"DpId":18,"DpIdType":2,"DpIdData":"00000082"}}}
20:53:50 TYA: fnId=32 is set for dpId=18
20:53:50 TYA: Rx ID=18 Current=130
20:53:50 {"TuyaReceived":{"Data":"55AA03070008130200040000012752","Cmnd":7,"CmndData":"1302000400000127","DpType2Id19":295,"19":{"DpId":19,"DpIdType":2,"DpIdData":"00000127"}}}
20:53:50 TYA: fnId=31 is set for dpId=19
20:53:50 TYA: Rx ID=19 Active_Power=295
20:53:50 {"TuyaReceived":{"Data":"55AA0307000814020004000008D80B","Cmnd":7,"CmndData":"14020004000008D8","DpType2Id20":2264,"20":{"DpId":20,"DpIdType":2,"DpIdData":"000008D8"}}}
20:53:50 TYA: fnId=33 is set for dpId=20
20:53:50 TYA: Rx ID=20 Voltage=2264

I'm not sure if TuyaMCU tasmota module poll the MCU itself or MCU by itself reports the status periodically but no further polling settings (like described Rule1 creation) need to be done manually. Probably if you need to poll more frequently you need to create a Rule with 'SerialSend5 55aa0001000000' command.
The only thing you need to do is to to enable 'SetOption66 1' in order to publish metric values received from MCU.

Images of updated device/Tasmota screenshot
https://ibb.co/4jY3pDX
https://ibb.co/FwP7fGs
https://ibb.co/9Gd6Cp1

lazysloth said...

One more thing. In order to integrate metrics into Tasmota and therefore into HomeAssistant the following commands need to be executed:
tuyamcu 31,19
tuyamcu 32,18
tuyamcu 33,20

According to my understanding Tasmota at the moment does not support integration for Total W/h metric (DpType2Id17). Tasmota's values for total Kw/h appears to be calculated from momentary Voltage/Current/Power measurements and since that can't be accurate. But because I'm planning to read Total W/h counter into Zabbix via mqtt it's not an issue for me.

Creation Factory said...

Hi @lazysloth,

I am very happy to know that you had success with the Tasmotization of your device. Your sharing will certainly be useful for the community, and it is interesting to see that apparently the manufacturer evolved the product towards an interface more consistent with other Tuya products.

If you don't mind, I can make reference to you and your findings in the Tasmota discord channel, as the community members more related to the TuyaMCU integration may have some ideas regarding additional commands that may potentially exist (given that the metering chip is the same, it wouldn't be surprising that the measurements exposed in the previous version are also available in this one too, via different commands).

Thanks for your sharing.

Kind regards.

Unknown said...

First of all Thank you @Creation Factory and @lazysloth for that great job!

I Have 3 ZMAi-90 devices, one old version and two upgraded versions,
No issues with old one, flashed, configured, but just a matter of parsing data somewhere as node red.
But upgraded versions dons want to send any data.
Have configured both with below steps:
1) Flashed Tasmota 8.4 by serial cable
2) Set module as Tuya MCU (54)
3) run:
a)Backlog SetOption66 1; TuyaMCU 32,17; TuyaMCU 31,19; TuyaMCU 33,20; SetOption59 1
b)Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog SerialSend5 55aa0001000000; RuleTimer1 10 endon
c)Rule1 1

Finaly able to switch relay, but don't get power data:
22:46:21 CMD: SerialSend5 55aa0001000000
22:46:21 SRC: WebConsole from 192.168.1.38
22:46:21 CMD: Group 0, Index 5, Command "SERIALSEND", Data "55aa0001000000"
22:46:21 RSL: stat/tasmota_DF55AE/RESULT = {"SerialSend":"Done"}
22:46:21 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA0301002A7B2270223A226136646A61627A6D7062627036326777222C2276223A22312E302E30222C226D223A307DE8","Cmnd":1,"CmndData":"7B2270223A226136646A61627A6D7062627036326777222C2276223A22312E302E30222C226D223A307D"}}
22:46:21 TYA: MCU Product ID: {"p":"a6djabzmpbbp62gw","v":"1.0.0","m":0}
22:46:21 TYA: Send "55aa0002000001"
22:46:21 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA0302000004","Cmnd":2}}
22:46:21 TYA: RX MCU configuration Mode=0
22:46:21 TYA: Read MCU state
22:46:21 TYA: Send "55aa0008000007"
22:46:21 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA03070005010100010011","Cmnd":7,"CmndData":"0101000100","DpType1Id1":0,"1":{"DpId":1,"DpIdType":1,"DpIdData":"00"}}}
22:46:21 TYA: fnId=11 is set for dpId=1
22:46:21 TYA: RX Relay-1 --> MCU State: Off Current State:Off
22:46:21 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA03070008110200040000000028","Cmnd":7,"CmndData":"1102000400000000","DpType2Id17":0,"17":{"DpId":17,"DpIdType":2,"DpIdData":"00000000"}}}
22:46:21 TYA: fnId=32 is set for dpId=17
22:46:21 TYA: Rx ID=17 Current=0
22:46:22 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA03070008120200040000000029","Cmnd":7,"CmndData":"1202000400000000","DpType2Id18":0,"18":{"DpId":18,"DpIdType":2,"DpIdData":"00000000"}}}
22:46:22 TYA: fnId=0 is set for dpId=18
22:46:22 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA0307000813020004000000002A","Cmnd":7,"CmndData":"1302000400000000","DpType2Id19":0,"19":{"DpId":19,"DpIdType":2,"DpIdData":"00000000"}}}
22:46:22 TYA: fnId=31 is set for dpId=19
22:46:22 TYA: Rx ID=19 Active_Power=0
22:46:22 RSL: tele/tasmota_DF55AE/RESULT = {"TuyaReceived":{"Data":"55AA0307000814020004000000002B","Cmnd":7,"CmndData":"1402000400000000","DpType2Id20":0,"20":{"DpId":20,"DpIdType":2,"DpIdData":"00000000"}}}
22:46:22 TYA: fnId=33 is set for dpId=20
22:46:22 TYA: Rx ID=20 Voltage=0

All time data looks like: "DpIdData":"00000000".
Have I frogot to configure somthing? or just broke them both?
Actulay I can see voltage on device screen, and some other figures, probable power.




Unknown said...

I have also recently flashed a ZMAi-90 with PCB version 2011 F20439. Unfortunately nothing works here. I cant toggle the relay, nor check the status of the reset pin. It seems like they are not even directly connected to the ESP8266 anymore but rather to the V9821.
GPIO4 is not even soldered. Has someone with the same PCB version made a backup of the orginial firmware maybe?

Unknown said...

Ok found the solution: Indeed all switches and LEDs are now connected to the V9821 and the V9821 runs now a standard Tuya protocol.
One can simply use the TuyaMCU(54) config and it works out of the box:
https://tasmota.github.io/docs/TuyaMCU/#power-monitoring-plug

I am currently adding it ESPHome as well. Fortunately EspHome also already has the basic protocol implemented (TuyaLight component) and I only need to a switch (already done and working) and 3 sensors... so should not be a big deal.

Creation Factory said...

HI @Unknown, that is awesome. It makes perfect sense that they are moving to using the same protocol as with other devices of the same family.

Great work

Cheers

Juampe said...

Thanks a lot for the excellent work
I have the new version of ZMAi-90 since a week.
Tested with tasmota-lite 8.4.0 with serial flashing.
It works with TuyaMCU(54) config.
I can pull sensor data using QMTT CMND Status 10, sensor data appears accurate.
I can switch on and off from MQTT commands.
I miss use peer button to manual switch on and off. Someone have the same issue?
Sensor does not work with this template https://templates.blakadder.com/ZMAi-90.html TuyaMCU commands only works with TuyaMCU(54) config.

Sani said...

Hi, I bougth one of this, and no problem with tuyamcu config. All is runing ok in tasmota and HA.

I have a question, i would like to put it in my home, but only for power meter, i want not to use as general power switch.

Is a posiblility to use it as as a power meter adding a coil??? I read that you mention an analoge imput..

Or there is another option? add a pzem to another gpio?

Creation Factory said...

Hello @Sani,

You may use it as is, to measure the voltage and the frequency of the power grid. Just provide power (phase and neutral) to the top two pins.

If you want to still measure current, power, etc and not use it as a power switch, you can skip the configuration of the switch in HA. Actually it is the way I have it setup. If I ever want to cut the power, I will either go to its UI or manually publish the MQTT message for controlling the switch.

Adding a current sense coil, I believe that could be complex and require some signal conditioning before passing it to the meter chip. The way the device senses current is through a current shunt (it senses the tiny voltage drop across two points in the copper rail through which the mains current passes). It is somewhat different from a sense coil, as it is a direct measurement, instead of through an inductively coupled device.

Cheers

Unknown said...
This comment has been removed by the author.
Unknown said...

Hi Sani

My wds688 can be on and off. i can only see the voltage and today power. how can i get it to work? i mean the amperage and the power?

Thank you in advance.

Unknown said...

My settings:
Backlog SetOption66 1; TuyaMCU 0,17; TuyaMCU 32,18; TuyaMCU 31,19; TuyaMCU 33,20; SetOption59 1

Rule1 on System#Boot do RuleTimer1 5 endon on Rules#Timer=1 do backlog SerialSend5 55aa0001000000; RuleTimer1 5 endon

It works with TuyaMCU(54) config

fernando said...

Hi, excuse me, how is the best way to open it? I mean, to open the case? Could you pulish some photos of the case to know "where" to push or pull ?

Thanks

Creation Factory said...

hi @fernando,

Opening the case is pretty straightforward. You have two screws in the back, the holes you can more or less see in this post:

https://www.creationfactory.co/2019/11/attempting-to-reverse-engineer-home.html

Upon removing these screws, just split the two halves of the case, and you have access to the inside. There are two boards connected to each other via header pins, and that is it. The lower board handles the mains voltage and contains a large bi-stable relay.

Hope I helped clarify the process.

Cheers

fernando said...

Hi, thanks a lot. I didn't see them ;)

I have a clone of these. it is eMylo. I will try first to use tuya-convert, may it works. Otherwise, if I use it without trying first it could connect to tuya server, update firmware, and then, I will have to open case.

I prefer to try first tuya-convert. it is better, isn't it? That way, i will have also the backup of the firmware.

Thanks a lot

Creation Factory said...

Yes, if you are successful with tuya-convert, then there is no need to use the soldering iron.

Cheers

Unknown said...

Hello everybody. I managed to flash the ZMAi-90, I can see the data but in the Tasmota panel but, not in Home Assistant. Could anyone help me?
Could you post all the innovative actions to the new ZMAi cards?
Thanks for the future help.

WildeRNS said...

Hello everybody, as I understand - in "new versions" of device, there is no way to use external button as switch, correct?

fernando said...

Hi, I have a clone version. eMylo.
As it is new version, I have finally use this version from "unknown":

After flashing Tasmota with Tasmotizer y configure it as TuyaMCU (54) and check settings with @lazysloth

My settings (console):
Backlog SetOption66 1; TuyaMCU 32,18; TuyaMCU 31,19; TuyaMCU 33,20; SetOption59 1

Rule1 on System#Boot do RuleTimer1 5 endon on Rules#Timer=1 do backlog SerialSend5 55aa0001000000; RuleTimer1 5 endon

It works with TuyaMCU(54) config


I have several questions:
1. With this config the physical button doesn't have any function. Could we need to configure something in "configure module" gpio's ?
2. With TUYAMCU and the config that I write, we can't get all stuff that old version gets: FE0108 [E (KWh)] [V (Volts)] [I (Amps)] [f (Hz)] [Pactive (Watts)] [Preactive (Watts)] [Papparent (Watts)] [pf (%)] [Checksum]. Is there any way to get all values: f, reactive, pf, ....
3. Something not very important, in captive web portal we have all energy values with 0, could we have these values filled?

Thanks a lot.




Terence's @rchive said...

I'm getting frequent tasmota restarts due to exception? Anyone encounter this? I'm running the latest tasmota version 8.5.1

I'm gonna try switching to esphome see if its helps with my restart issues.

Bluefox said...

@Creation Factory
Really thanks for the awsome article and sharing.
I got 1 upgraded version - moudule firmware 3.0.2 and 11 old version - moudule firmware 1.0.2 (Weird, old one bouhgt later). Fianlly able to get old version flash with Tuya-Convert and connect to HA.

Kind of bricked the upgraded version during testing. The meter is still working, but wifi completely dead. Not able to see wifi led light up.

Anyway, Thanks again for the hard work!!

Nooy said...

Hi fernando

I simply print state 8 to the serial line (that is sent to MQTT) and select only the necessary information with JSON.

It works with TuyaMCU(54) config (GPIO1 TuyaTX,GPIO3 TuyaRX) with your console settings and:

Rule2 on System#Boot do RuleTimer2 5 endon on Rules#Timer=2 do backlog status 8; RuleTimer2 5 endon
Rule2 1


you'll see this continuously after 5 seconds:
MQT: stat/power/STATUS8 = {"StatusSNS":{"Time":"2020-11-25T11:23:30","ENERGY":{"TotalStartTime":"2020-11-22T00:00:00","Total":57.68,"Yesterday":20.45,"Today":7.73,"Power":102,"ApparentPower":178,"ReactivePower":146,"Factor":0.57,"Voltage":227,"Current":0.784}}}

Unknown said...

Hello!
First, thanks for this project.
I am having some troubles with this.
I have been running tasmota 8.3.1 for some time now, it was flashed via tuya convert.
Today I decided to upgrade to tasmota 9.20. because every once in a while I had to re set the baudrate in order to receive correct data over mqtt.

The problem is, after upgrading, it seems the device will no longer send correct data, as it can't be decoded by the ha integration.

Any idea what could have gone wrong?
Thanks!

fernando said...

Hi Nooy, as I have the "new version", in which all stuff is made by the MCU (ESP8266/TY3WS only does wifi stuff) I get nothing from status 8, only ZEROS.

Thanks a lot, i think it can't be solved, can it?

And the other thing is about button, how we can use the button to power on or off the ZMAI's main switch? Is there anything to configure about tuyamcu?

Thanks.

fernando said...

HI, I have discovered a problem getting ZEROS or not real values from ZMAI-90 (in my case EMYLO EAI-90 clone).

Please, read this and comment if you suffer the same problem:

https://github.com/arendst/Tasmota/issues/10278

I can get data when I first configure my device in tasmota, but after a power down - up cycle of the device (not relay) I can't get real data until I send in console
Serialsend5 55aa0006000501010001010e

I hope all of us could get a solution.

Bye,

GlenW said...

Hi All,
I have 2 of these Power Meters. The first is labeled Sinotimer WDS688 and the second is ZMAi90, both use the later TuyaMCU circuitry.
I have flashed both with Tasmota one is on V8.4 and the second is V8.5, I haven't yet updated them as I had read some one have problems with V9.x.
They both work fine, the front display seems to be accurate and I can read the output via MQTT in Home Assistant (eventually, took me a while to figure it out).

I just wanted to check that everyone is seeing what I am seeing with Tasmota on these to units.

Both are configured as [Tuya MCU(54)] units and both show the same problem on the Tasmota Web page for the 2 devices, the problem is minor but annoying.
The Tasmota Web config page doesn't seem to display real power values!

=== Typical Output on Web configuration page ===
Tuya MCU Module
PwrMtrSino

Voltage 242 V
Current 0.219 A
Power 52 W
Apparent Power 53 VA
Reactive Power 12 VAr
Power Factor 0.97
Energy Today 0.002 kWh
Energy Yesterday 0.000 kWh
Energy Total 3416.190 kWh
===

Voltage ; Current and Power look OK and agree with what is shown on the meters display. Apparent Power & Power Factor look logical.
Reactive Power - Not really sure but might be is ok.

The last 3 lines are never correct.
Energy Today & Energy Yesterday & Energy Total values are just wrong.

I am not even sure why the first 2 are needed out of a meter, but since they are there it would be nice if they were correct.

Energy Total should display the same as the display on the meter but never does.
All three seem like a random values to me but since they do actually change it is like the incorrect multiplier is being applied to them.
=== End of part 1 ===

GlenW said...

=== Start of part 2 ===
Using the Tasmota console on the Web interface we see the strings don't match:-
---
13:45:11 MQT: tele/pwrmtr1/SENSOR = {"Time":"2020-12-28T13:45:11","ENERGY":{"TotalStartTime":"2020-08-09T18:04:55","Total":3416.192,"Yesterday":0.000,"Today":0.003,"Period":0,"Power":0,"ApparentPower":0,"ReactivePower":0,"Factor":0.00,"Voltage":242,"Current":0.000}}
13:45:14 RUL: RULES#TIMER=1 performs "backlog SerialSend5 55aa0001000000; RuleTimer1 10"
13:45:14 MQT: stat/pwrmtr1/RESULT = {"SerialSend":"Done"}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA0301002A7B2270223A226136646A61627A6D7062627036326777222C2276223A22312E302E30222C226D223A307DE8","Cmnd":1,"CmndData":"7B2270223A226136646A61627A6D7062627036326777222C2276223A22312E302E30222C226D223A307D"}}
13:45:14 TYA: MCU Product ID: {"p":"a6djabzmpbbp62gw","v":"1.0.0","m":0}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA0302000004","Cmnd":2}}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA03070005010100010112","Cmnd":7,"CmndData":"0101000101","DpType1Id1":1,"1":{"DpId":1,"DpIdType":1,"DpIdData":"01"}}}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA03070008110200040000D6D8D6","Cmnd":7,"CmndData":"110200040000D6D8","DpType2Id17":55000,"17":{"DpId":17,"DpIdType":2,"DpIdData":"0000D6D8"}}}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA03070008120200040000000029","Cmnd":7,"CmndData":"1202000400000000","DpType2Id18":0,"18":{"DpId":18,"DpIdType":2,"DpIdData":"00000000"}}}
13:45:14 MQT: stat/pwrmtr1/RESULT = {"T1":10,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA0307000813020004000000002A","Cmnd":7,"CmndData":"1302000400000000","DpType2Id19":0,"19":{"DpId":19,"DpIdType":2,"DpIdData":"00000000"}}}
13:45:14 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA030700081402000400000974A8","Cmnd":7,"CmndData":"1402000400000974","DpType2Id20":2420,"20":{"DpId":20,"DpIdType":2,"DpIdData":"00000974"}}}
13:45:21 MQT: tele/pwrmtr1/RESULT = {"TuyaReceived":{"Data":"55AA030000010104","Cmnd":0,"CmndData":"01"}}
13:45:25 RUL: RULES#TIMER=1 performs "backlog SerialSend5 55aa0001000000; RuleTimer1 10"
13:45:25 MQT: stat/pwrmtr1/RESULT = {"SerialSend":"Done"}
=== End of part 2 ===

GlenW said...

=== Start of part 3 ===
The important things to know about those strings is that the ["Total":3416.192] value should be the same as the ["DpType2Id17":55000] except for the decimal point so it should display ["Total":55.000] kWh the same as the meters LCD display but it never does. The other values ("Yesterday" & "Today")aren't shown on the display but simple maths on yesterdays usage and todays usage shows these are always incorrect too. I have been using one of these meters for months with this problem by just ignoring the Web page and using the MQTT values for Volts; Current; Power & Total kWh in HA instead.

Please tell me if it just me as I have seen no-one mention this?
I am relatively new to Tasmota; MQTT and Home Assistant so am ready to concede that I might have done something wrong here but I have no idea what.

Unknown said...

@GlenW: see here: https://github.com/krikk/Hiking-DDS238-2-WIFI-Din-Rail-Energy-Meter-flashing-Tasmota

DybaMati said...

Hello

Do I have to flash the device to clean the data from the meter after UART, if I ask, my meter receives the answer:

000055aa00000000000000080000004b00000000332e33000000000000ea110000000134f2d61aca6eb4ea232964b449a1e92bf19858dce744093aa4aa82f77eca31c6994ad2deba36d87682acb93565853664407c20000000aa55

Creation Factory said...

Hello @DybaMati,

It is unlikely that reflashing the firmware of the meter will reset the counters. Unless you refer to the metering chip itself and not the ESP8266 (where the WiFi and interface with the device is implemented).

I believe there must be a serial command for resetting the counters, but I haven't done any digging in respect to that so far. Tapping the UART serial pins while running the factory firmware and performing a reset using the original app, should allow to figure out which serial command is being sent to the metering chip.

Cheers



DybaMati said...

I need to read kWh and Wats won't reset

Unknown said...

Good day. What do you think about the new version of the electricity meter. The tui module costs WB3S (not really!). Tasmoto is not stitched. I changed the module to esp-12 and tasmota 9.2 through the programmer.
Settings:
Thuja MCU (54)
1) Backlog SetOption66 1; TuyaMCU 0.17; TuyaMCU 32.18; TuyaMCU 31.19; TuyaMCU 33.20; SetOption59 1
2) Backlog Rule1 1; Rule1 in the system # Load execute RuleTimer1 5 execute according to the rules # Timer = 1 execute SerialSend5 delay 55aa0001000000; RuleTimer1 5 endon
And no tasmot muzzle pointers are all zeros like MQTT. The logs have an answer to polling the total power and voltage. any ideas?

Unknown said...

Good day. What do you think about the new version of the electricity meter. The tui module costs WB3S (not really!). Tasmoto is not stitched. I changed the module to esp-12 and tasmota 9.2 through the programmer.
Settings:
Thuja MCU (54)
1) Backlog SetOption66 1; TuyaMCU 0.17; TuyaMCU 32.18; TuyaMCU 31.19; TuyaMCU 33.20; SetOption59 1
2) Backlog Rule1 1; Rule1 in the system # Load execute RuleTimer1 5 execute according to the rules # Timer = 1 execute SerialSend5 delay 55aa0001000000; RuleTimer1 5 endon
And no tasmot muzzle pointers are all zeros like MQTT. The logs have an answer to polling the total power and voltage. any ideas?

StainBase said...
This comment has been removed by the author.
StainBase said...

I modified Tasmota to work with the clone Emylo EAI-90.
You can find it at https://github.com/shaap/Tasmota

StainBase said...

It uses a somewhat different protocol and has only more basic readings (total consumption, voltage, current and power). You can only utilize the relay (i think it was dpId 16) with the current development firmware of tasmota. I submitted a pull request for my changes, which make it possible to get the rest of the data.

Unknown said...

@StainBase, big thank you! your change perfectly works with new ZMAI-90 based on WB3S (after changing WB3S to esp 12).

For others, who got new ZMAI-90 with WB3S,
you need to:
1) Change WB3S to esp 12.
2) Compile latest tasmota from, (Tasmota 9.3.1 Kenneth, still doesn't support it), future version will be support.
3) Apply, choose module TuyaMCU(54)

And run in console:

Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1

Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog TuyaSend8; RuleTimer1 10 endon

Rule1 1

Marius said...

@Unknown, @StainBase,
The latest tasmota should be compiled, or can I use directly the Tasmota 9.3.1 that is already available ?
I have tried to flash Tasmota 9.3.1, and after adding the commands in console, I got the error below:
13:23:51.751 CMD: Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1
13:23:51.844 RSL: stat/tasmota_7A5264/RESULT = {"SetOption66":"ON"}
13:23:52.053 RSL: stat/tasmota_7A5264/RESULT = {"TuyaMCU":[{"fnId":11,"dpId":16}]}
13:23:52.301 TYA: TuyaMcu Invalid function id=36
13:23:52.305 RSL: stat/tasmota_7A5264/RESULT = {"TuyaMCU":[{"fnId":11,"dpId":16}]}
13:23:52.551 TYA: TuyaMcu Invalid function id=37
13:23:52.554 RSL: stat/tasmota_7A5264/RESULT = {"TuyaMCU":[{"fnId":11,"dpId":16}]}
13:23:52.806 RSL: stat/tasmota_7A5264/RESULT = {"SetOption59":"ON"}
13:23:53.053 RSL: stat/tasmota_7A5264/RESULT = {"SetOption72":"ON"}

Could you please guide me how can I solve this issue ?
I have a ZMAI-90 with WB3S controller, and was replaced by a ESP12F

Marius said...

Hello all,
@Unknown, @StainBase,
I have a ZMAI-90 with WB3S Wifi module. I replaced the module with an ESP12F and I have flashed on it a Tasmota 9.3.1. I have tried to run the above commands in console, but I get some errors. I guess this version is not supporting these features yet:

CMD: Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1
MQT: stat/zmai_90/RESULT = {"SetOption66":"ON"}
MQT: stat/zmai_90/RESULT = {"TuyaMCU":[{"fnId":11,"dpId":16}]}
TYA: TuyaMcu Invalid function id=36
MQT: stat/zmai_90/RESULT = {"TuyaMCU":[{"fnId":11,"dpId":16}]}
TYA: TuyaMcu Invalid function id=37
MQT: stat/zmai_90/RESULT = {"TuyaMCU":[{"fnId":11,"dpId":16}]}
MQT: stat/zmai_90/RESULT = {"SetOption59":"ON"}
MQT: stat/zmai_90/RESULT = {"SetOption72":"ON"}

Could you please guide me how should I compile the firmware, or can you please compile it and send me by e-mail ? ("mariuss_suciu@yahoo.com")

I just downloaded the archive from github, but there are many files and I don't really know how should I do that.
Thanks in advance for your help.

StainBase said...

I can mail it to you tomorrow.

Snake said...

Any changes in new tasmota releases? They approve your pull request?
Can I use official release for esp12?

Snake said...

Give an answer for myself :) Everything work from latest official developer release compiled with energy sensors and rules!
09:15:15.473 MQT: tele/zmai90/SENSOR = {"Time":"2021-04-30T09:15:15","ENERGY":{"TotalStartTime":"2021-04-30T04:53:51","Total":0.043,"Yesterday":0.000,"Today":0.003,"Period":1,"Power":30,"ApparentPower":34,"ReactivePower":16,"Factor":0.88,"Voltage":225,"Current":0.151}}

fernando said...

HI @Snake, could you please explain what is exactly for you "compiled with energy sensors and rules" ?? Thanks

grizlyadams said...
This comment has been removed by the author.
IntEx said...

Great!
The command in Tasmota console:

Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1

After replacing WB3S to ESP-12 is everything to get it work with Tasmota!

Now I would like to find the command for resetting the total power consumption counter and it is ready to go. :-)

I am waiting for another ZMAi-90 where I will try to find in original firmware/app, which serial command it is.
Did someone done any progress with that?

fernando said...

Hi, guys, do you get ApparentPower and ReactivePower? I have the "new version", not "original version" and, yes, it works with Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1, but I cant get Apparent Power, Reactive, Factor .....

IntEx said...

@fernando: I have not connected the device to the circuit yet, but I see some small readings of Aparent Power/Reactive Power when toggling the relay (power consumption of the relay itself).

Snake said...

@fernando: New version have WB3S Chip. It must be replaced with ESP-12.
After that I'm used tasmocompiler with latest developer sources, with enabled options 'energy sensors' and other as u wish!
After flashing with this firmware, do as described

Console:
Backlog SetOption66 1; TuyaMCU 11,16; TuyaMCU 36,6; TuyaMCU 37,1; SetOption59 1; SetOption72 1
Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog TuyaSend8; RuleTimer1 10 endon

and all works

JUF said...

Hi and thx for this good guide. Get my zmai-90 today and it have a wb3s chip. For replace can i use this
https://www.amazon.de/AZDelivery-ESP8266-ESP-12F-verbesserte-Version/dp/B01NASA1MV/ref=sr_1_4?__mk_de_DE=ÅMÅŽÕÑ&dchild=1&keywords=esp%2B12%2BTasmota&qid=1620306443&sr=8-4&th=1
Regards

Jens

JUF said...

Hi, thx for this good manual.
Today i get my mai-90 and it have a wb3s chip.
Can i use this one
https://www.amazon.de/AZDelivery-ESP8266-ESP-12F-verbesserte-Version/dp/B01NASA1MV/ref=sr_1_4?__mk_de_DE=ÅMÅŽÕÑ&dchild=1&keywords=esp%2B12%2BTasmota&qid=1620306443&sr=8-4&th=1
For replaced

Regards
Jens

Shari said...

@JUF yes, you can use the ESP12F you posted

JUF said...

@ Shari thx for feedback.
Have done the soldering job. ����
But I don’t get the summery from yesterday?
See the total sum and today but it will not appeared at yesterday.
Can you give me a hint?
And is it true that I don’t see the frequency?
Regards

JUF said...

@StainBase
Is it possible that I get the modified Tasmota.bin from you, pls?
I have no idea how to compile by my self.
Have run the 9.4.0
Or is your change in thi version already included?


Regards

tesna said...

So I have the new version and this is my TuyaMCU settings (same seting found on https://templates.blakadder.com/ZMAi-90.html)

Backlog SetOption66 1; TuyaMCU 0,17; TuyaMCU 32,18; TuyaMCU 31,19; TuyaMCU 33,20; SetOption59 1

I'm running official 9.4.0

tesna said...

So I have managed sucessfully to run the new version with the TuyaMCU mode in tasmota. However, the values of kwh readings somehow inconsistent. More often the value of total kwh is getting reset after a power cycle.

I saw the MQTT logs the correct value is displayed:

Message 77 received on stat/tasmota_936F2D/LOGGING at 8:57 PM:
14:57:03.635 MQT: tele/tasmota_936F2D/RESULT = {"TuyaReceived":{"Data":"55AA03070008110200040026D1EE0D","Cmnd":7,"CmndData":"110200040026D1EE","DpType2Id17":2544110,"17":{"DpId":17,"DpIdType":2,"DpIdData":"0026D1EE"}}}

the value is 2544.110 kwh

however the one displayed in HA is below:

Message 83 received on tele/tasmota_936F2D/SENSOR at 8:57 PM:
{
"Time": "2021-05-15T14:57:06",
"ENERGY": {
"TotalStartTime": "2021-05-14T12:50:32",
"Total": 45.959,
"Yesterday": 0,
"Today": 45.959,
"Period": 8,
"Power": 2492,
"ApparentPower": 2589,
"ReactivePower": 702,
"Factor": 0.96,
"Voltage": 217,
"Current": 11.914
}
}

So I think I can still display the correct value by manually entering mqtt config on yaml file. however I lack the skill to parse the text strings. Can anyone help me to parse 2544.110 to HA?

tesna said...

nevermind, found the way to do it

- platform: mqtt
name: smart_meter_kwh
state_topic: "tele/tasmota_936F2D/RESULT"
value_template: "{{ (value_json.TuyaReceived.DpType2Id17|float) / 1000 }}"
unit_of_measurement: 'kWh'

Regards,

Tesna

tesna said...

Found a minor bug, affecting the new version of the zmai-90 using tuyamcu protocols. the latest tasmota binaries (9.4.0) limited the power reports to around 6500W.

discussion:
https://github.com/arendst/Tasmota/discussions/12114?_pjax=%23js-repo-pjax-container

details:
https://github.com/arendst/Tasmota/pull/12115

the fix has been merged into official development branch

Stargazer said...

Good morning everyone! I wonder if anyone managed to find the command to reset the KWh counter

Ben V said...

Thanks for this work, most helpful.

Small update:

Currently working on a version with the new chip (WB3S) hence this had to be replaced (by ESP-12E). This went not well the first time (destroyed most of the PCB pads holding the WB3S ship). Technique used was absorbing solder with fluxed desolder braid. Unit is unrepairable.

next unit i will attempt quikchip removal, heard good things on this.

kind regards,

Ben

Ben V said...

Another update, second unit came in (also with WB3S chip). Now i used a desolder kit (from quik chip) to release the chip. Went like a breeze. definitely would recommend this method to change the WB3S chip to ESP-12E!

link to the kit used:

_meugen_ said...

Hi!
1. Is it possible WITHOUT reassembly and soldering to point ZMAI-90 to ip-address of my own web-server?
2. If yes, do you know data exchange protocol (to implement on my server)?

_meugen_ said...

Hi!
Maybe you know:
1. Is it possible in the ZMAI-90 (without reassembling and without soldering) to point to send data to ip-address of my own server (tcp|udp|http|mqtt|etc)?
2. If yes, maybe you know data exchange protocol (to implement on my server)?

IntEx said...

No.

Creation Factory said...

Hello _meugen_,

With the stock firmware it is unlikely that you are able to change the infrastructure to which the device tries to connect to.

If you have an ESP based device, you might be able to convert it (to Tasmota for example) via OTA with this process:

https://github.com/ct-Open-Source/tuya-convert

It is not guaranteed that it will work because the manufacturer might have added new protections meanwhile.

If you already have Tasmota, you simply have to configure your MQTT server in the Tasmota UI and you are ready to go.

"2. If yes, maybe you know data exchange protocol (to implement on my server)?"

Tuya uses a few relatively standard protocols such as secure MQTT (MQTTS) and REST APIs over HTTPS.

All of that goes encrypted so it is difficult without modifying the original firmware, to know exactly what is being exchanged between client (IoT device) and server (Tuya cloud infrastructure).

Tuya does however provide some information online for the developer community about their APIs, so it is possible that these IoT devices use similar APIs to the ones explained in these documents:

https://developer.tuya.com/en/docs/cloud/device-management?id=K9g6rfntdz78a

Best regards

Unknown said...

I got a new ZMAi-90 with a CBU chip: https://developer.tuya.com/en/docs/iot/cbu-module-datasheet?id=Ka07pykl5dk4u

With that pin layout, I guess there is no way to replace it with an ESP to be able to use Tasmota on it?

Andrew said...

I have module, like you. Did you succeed used Tasmota or it impossible? What you think?

Unknown said...

I haven't found a way. I will see if I can get an older device somewhere that still has an ESP-based chip or can be fitted with one.

Matt2_uk said...

If it's of any use, I've the ZMAi-90 CBU based unit and managed to pull all the info in to homeassistant from the stock firmware.

Creation Factory said...

Hey @Unknown,

"If it's of any use, I've the ZMAi-90 CBU based unit and managed to pull all the info in to homeassistant from the stock firmware."

That is great. Do you mind sharing how that was achieved?

Thanks

Matt2_uk said...

Disclaimer first - Probably a good idea to back your system up first just in case as I've developed this by trial and error so no doubt there's more graceful/proper ways of achieving it.... Any comments welcome!

Pre-requisite is that you've got LocalTuya installed and that you've added the ZMAi-90 as a device with config-flow.
If not, do that first and then see what Datapoints it gives you. Hopefully you get DP6. If not then set it up without it and I'll help you set them up but best not go any further until you've got them as you need their entity names for the configuration.yaml code below.

Next you need to create a python script to do the datapoint decoding. I had to make a directory 'python_scripts' in my .homeassistant directory.
In the directory create the script 'base64_int.py' with the following code:-

#!/usr/bin/env python3
import base64
import sys
import struct

data = sys.argv[1]
#if len(sys.argv) >= 3:
# length = int(sys.argv[2])
# data = data[:length]

# Python 2
value = base64.b64decode(data).encode('hex')
# Python 3
#value = base64.b64decode(data).hex()

print(value)


I for some reason have Python 2.7, so had to use the top conversion. Hash out in the code whatever you need to fit your install.

Now in config.yaml you need to add the following:-

sensor:
- platform: command_line
name: smartmeter_dp6
command: "python /home/homeassistant/.homeassistant/python_scripts/base64_int.py {{ states('sensor.smart_meter_06') }}"
- platform: template
sensors:
smartmeter_voltage:
value_template: "{{(states.sensor.smartmeter_dp6.state.split('.')[0][0:4])|int(base=16)*0.1}}"
friendly_name: 'Volts'
smartmeter_current:
value_template: "{{(states.sensor.smartmeter_dp6.state.split('.')[0][6:10])|int(base=16)*0.001}}"
friendly_name: 'Amps'
smartmeter_power:
value_template: "{{(states.sensor.smartmeter_dp6.state.split('.')[0][12:16])|int(base=16)}}"
friendly_name: 'Watts'


With the above you will need to modify the line that starts 'command:' so that it uses the correct path for the script and also that it points to the correct sensor.XXXX that you created with config flow.
Check your configuration to make sure it's ok, and if so restart your homeassistant.
You should then have all the entities available.

There's a similar config to deal with DP17 which reads in some settings, but I've had to omit that above as it's making this post too long.

Matt2_uk said...

Further info if you want to know how it works....
Raw data comes from the ZMAi-90 in two data points, DP6 for instantaneous values and DP17 for settings, these look a bit like CaEAFrIABYc= and AQAAPAMAAQUEAAC1CAAAFA== respectively
For configuration.yaml, these need to be converted from Base64 to Hex externally, so we use the command line function to pass the raw data to the python script which then returns the hex values, again looking something like 09a110016b2000587
& 0100003d03000105040000b508000014 respectively.

DP6 takes the format VVVV00CCCC00PPPP so to get:-
Volts we extract hex string digits 0 to 4 from the decoded value, convert to decimal and then multiply by 0.1
Current (Amps) we extract hex string digits 6 to 10 from the decoded value, convert to decimal and then multiply by 0.001
Power (Watts) extract hex string digits 12 to 16 from the decoded value, convert to decimal.
These values are put into the template sensors for us to pull out in the lovelace interface.

DP17 takes the format 0A0B0CCC0D0E0FFF0G0H0III0J0K0LLL, where:
# A = Value1 (?)
# B = Over Current Control Switch (1-on, 0=0ff)
# C = Over Current Control Value (In Amps)
# D = Value2 (?)
# E = Over Voltage Control Switch (1-on, 0=0ff)
# F = Over Voltage Control Value (in Volts)
# G = Value3 (?)
# H = Under Voltage Control Switch (1-on, 0=0ff)
# I = Under Voltage Control Value (in Volts)
# J = Value4 (?)
# K = Insufficient Balance Control Switch (1-on, 0=0ff)
# L = Insufficient Balance Control Val (in kWh)
# J?, K & L may not be implemented on some ZMAi-90 models.
# A, D, G & J are probably* some form of status signals that indicate the state of the trip/alarm
# B, E, H & K are the toggle bits to enable the alarm
# C, F, I & L are the respective values of the alarm
Similary to the above we can extract the respective hex string digits and convert them to decimal straight in to the template sensors.

Matt2_uk said...

This is the DP17 configuration.yaml code. It's probably not that useful but as it's possible to get it I did. It's settings that can be configured from the phone app so in theory I would expect that there's a way of writing them back out to the device but for a noob like me that's too much hassle. It's also a bit of a pain as from what I've seen the DP17 values won't populate unless written to by the phone App.

- platform: command_line
name: smartmeter_dp17
command: "python /home/homeassistant/.homeassistant/python_scripts/base64_int.py {{ states('sensor.smart_meter_17') }}"
- platform: template
sensors:
smartmeter_value1:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][1:2])|int(base=16) }}"
friendly_name: 'Smart_Meter_Value1'
smartmeter_over_current_control_switch:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][3:4])|int(base=16) }}"
friendly_name: 'Smart_Meter_Over_Current_Control_Switch'
smartmeter_over_current_control_value:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][5:8])|int(base=16) }}"
friendly_name: 'Smart_Meter_Over_Current_Control_Value'
smartmeter_value2:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][9:10])|int(base=16) }}"
friendly_name: 'Smart_Meter_Value2'
smartmeter_over_voltage_control_switch:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][11:12])|int(base=16) }}"
friendly_name: 'Smart_Meter_Over_Voltage_Control_Switch'
smartmeter_over_voltage_control_value:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][13:16])|int(base=16) }}"
friendly_name: 'Smart_Meter_Over_Voltage_Control_Value'
smartmeter_value3:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][17:18])|int(base=16) }}"
friendly_name: 'Smart_Meter_Value3'
smartmeter_under_voltage_control_switch:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][19:20])|int(base=16) }}"
friendly_name: 'Smart_Meter_Under_Voltage_Control_Switch'
smartmeter_under_voltage_control_value:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][21:24])|int(base=16) }}"
friendly_name: 'Smart_Meter_Under_Voltage_Control_Value'
smartmeter_value4:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][25:26])|int(base=16) }}"
friendly_name: 'Smart_Meter_Value4'
smartmeter_insufficient_balance_control_switch:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][27:28])|int(base=16) }}"
friendly_name: 'Smart_Meter_Insufficient_Balance_Control_Switch'
smartmeter_insufficient_balance_control_value:
value_template: "{{ (states.sensor.smartmeter_dp17.state.split('.')[0][29:32])|int(base=16) }}"
friendly_name: 'Smart_Meter_Insufficient_Balance_Control_Value'

Unknown said...

Hello! I got these DPs:

DPS [1] VALUE [20]
DPS [10] VALUE [0]
DPS [12] VALUE [False]
DPS [13] VALUE [0]
DPS [16] VALUE [True]

What should I do?

Unknown said...

Hello! I got these DPs:

DPS [1] VALUE [20]
DPS [10] VALUE [0]
DPS [12] VALUE [False]
DPS [13] VALUE [0]
DPS [16] VALUE [True]

What should I do?

Matt2_uk said...

ok, these are the ones you probably want, so looks like you've got most of them.
1 Energy Consumption Total
6 W/V/A Info String
10 I've not worked this one out yet?
12 kWh Prepayment Switch
13 Balance
15 Prepayment +Charge
16 Relay Switch
17 Settings Info String

What I found is that there's a file that stores all the config-flow setup information called core.config_entries, for me it was located in:
/home/homeassistant/.homeassistant/storage/
If you search through this for your device and you'll then be able to add the ones you want. If it was the last device you added, then start at the end of the file and look backwards.

It's best you stop your homeassistant before editing and don't copy my config directly (in the next post due to post length limitations) as it's got the key/id for my device so wouldn't work. Hopefully you can see from this what you need to end up with and make sure that you double check it once done so you don't have any issues when you start up homeasistant afterwards.

Hint... I'm not sure how you're modifying your files, but since I came across WinSCP it's been amazing as you can access and edit all your files on a Windows computer online from the pi and in a notepad like editor so no more sudo nano configuration.yaml.

Matt2_uk said...

Extract of my modified version of core.config_entries is as follows:-

{
"entry_id": "e955002ebb9a94dfdda0a8466f0e4060",
"version": 1,
"domain": "localtuya",
"title": "Smart Meter",
"data": {
"friendly_name": "Smart Meter",
"host": "192.168.2.168",
"local_key": "ac886b9659505bc3",
"protocol_version": "3.3",
"entities": [
{
"friendly_name": "Smart_Meter_01 kWh Total",
"id": 1,
"platform": "sensor"
},
{
"friendly_name": "Smart_Meter_06",
"id": 6,
"platform": "sensor"
},
{
"friendly_name": "Smart_Meter_10",
"id": 10,
"platform": "sensor"
},
{
"friendly_name": "Smart_Meter_12 kWh Prepayment Switch",
"id": 12,
"platform": "switch"
},
{
"friendly_name": "Smart_Meter_13 Wh Balance",
"id": 13,
"platform": "sensor"
},
{
"friendly_name": "Smart_Meter_15",
"id": 15,
"platform": "sensor"
},
{
"friendly_name": "Smart_Meter_16 Relay",
"id": 16,
"platform": "switch"
},
{
"friendly_name": "Smart_Meter_17",
"id": 17,
"platform": "sensor"
}
],
"device_id": "bf1aa15c46ab6af3b68tr9",
"dps_strings": [
"1 (value: 10)",
"6 (value: 15)",
"10 (value: 0)",
"12 (value: False)",
"13 (value: 0)",
"15 (value: 20)",
"16 (value: True)",
"17 (value: 17)"
],
"product_key": "nqbs1onwskmmmaac"
},

Matt2_uk said...

I've just been investigating further and uncovered a few states for DP10:-
1 - Unit tripped on over current
4 - Unit tripped on over voltage
8 - Unit tripped on under voltage
512 - Seems to come up with Under Balance, so would expect to be an under balance trip

suedtirolcamping said...

Hallo, erstmal Kompliment für Ihr gelungenes Tasmota-Flashen des ZMAi-90. Ich habe auch schon diverse Sonoff Produkte selbst geflasht aber beim ZMAi-90 glaube ich bin ich zu schwach. Wäre es möglich einen Tasmota geflashten ZMAi-9o von Ihnen zu erwerben? Konnten Sie schon eine Lösung zu Rückstellen des Zählers finden?
Liebe Grüße
Norbert

Creation Factory said...

Hi Norbert,

"Hello, first of all compliments for your successful Tasmota flashing of the ZMAi-90. I've flashed various Sonoff products myself, but I think I'm too weak with the ZMAi-90. Would it be possible to purchase a Tasmota flashed ZMAi-9o from you? Have you already found a solution to reset the counter?
Warm greetings
Norbert"

> Would it be possible to purchase a Tasmota flashed ZMAi-9o from you?

I currently don't have that streamlined as commercial service. Also there is the challenge that many ZMAi-90 are now shipped with a different IoT MCU (no longer ESP8266), which makes it more difficult to convert.

Unfortunately I haven't yet figured out how to reset the counter..

Cheers

Unknown said...

Hello.
I would like to provide you with very simple instructions. The method works and is proven. I did so a few devices.

https://www.eskaen.de/blog/zmai-90

Creation Factory said...

Hi @Unknown,

Thanks for the instructions. Nice to be aware of an approach via TuyaMCU.

Cheers

HF said...

Hi guys,
Today i upgraded my zmai-90 module from version 8.3.0.0 to 11.1.0.0. After the upgrade my module stop send the MQTT readings as before.
So i followed the new tip on https://templates.blakadder.com/ZMAi-90.html to use the template "Tuya MCU (54)" and after changing to this template on WebGui i lost power on my home.. was a bit stressing without light and even be at night, but reading online i followed the "Fast Power Cycle Device Recovery" and ufff finally i got power on home.
Starting the configuration i realized that the MQTT is still not working...
Anyone could help me please?
Thanks and Regards,

HF said...

Hi guys,
Today i upgraded my zmai-90 module from version 8.3.0.0 to 11.1.0.0. After the upgrade my module stop send the MQTT readings as before.
So i followed the new tip on https://templates.blakadder.com/ZMAi-90.html to use the template "Tuya MCU (54)" and after changing to this template on WebGui i lost power on my home.. was a bit stressing without light and even be at night, but reading online i followed the "Fast Power Cycle Device Recovery" and ufff finally i got power on home.
Starting the configuration i realized that the MQTT is still not working...
Anyone could help me please?
Thanks and Regards,

GlenW said...

I don't have the answer for you but you but it should be noted that you can only use the "Tuya MCU (54)" if your device has a Tuya MCU in it. Both of mine have this MCU fitted as do all newer units do, only the older ones don't. If it was working before with the serial Tx and Rx configured, then it needs to stay that way, the two models are completely different.

Unknown said...

I used that home assistant snippet for a long time, now I'm using NODE-RED for all my MQTT data, so i wrote some code to decode data from ZMAI, maybe someone want to reuse it, chech that:



var message = msg.payload.SerialReceived,
bcdDecode = function (coded) {
var output = 0;
for (var i = coded.length+1; i >=0; i--) {
if (i%2 ==0) {
output+=coded.substring(i,i+2);
}
}

return output;
}


var output = {
'consumed': {"units": "kWh", "value": parseFloat(bcdDecode(message.substring(6,14)))/100},
'voltage': { "units": "V", "value": parseFloat(bcdDecode(message.substring(14, 22))) / 10 },
'current': { "units": "A", "value": parseFloat(bcdDecode(message.substring(22, 30))) / 10000 },
'freq': { "units": "Hz", "value": parseFloat(bcdDecode(message.substring(30, 38))) / 100 },
'activePower': { "units": "W", "value": parseFloat(bcdDecode(message.substring(38, 46))) / 100 },
'reactivePower': { "units": "W", "value": parseFloat(bcdDecode(message.substring(46, 54))) / 100 },
'apparentPower': { "units": "W", "value": parseFloat(bcdDecode(message.substring(54, 62))) / 100 },
'powerFactor': { "units": "%", "value": parseFloat(bcdDecode(message.substring(62, 70))) / 10 },
};



return {"payload": output};

Unknown said...

I used that home assistant snippet for a long time, now I'm using NODE-RED for all my MQTT data, so i wrote some code to decode data from ZMAI, maybe someone want to reuse it, chech that:



var message = msg.payload.SerialReceived,
bcdDecode = function (coded) {
var output = 0;
for (var i = coded.length+1; i >=0; i--) {
if (i%2 ==0) {
output+=coded.substring(i,i+2);
}
}

return output;
}


var output = {
'consumed': {"units": "kWh", "value": parseFloat(bcdDecode(message.substring(6,14)))/100},
'voltage': { "units": "V", "value": parseFloat(bcdDecode(message.substring(14, 22))) / 10 },
'current': { "units": "A", "value": parseFloat(bcdDecode(message.substring(22, 30))) / 10000 },
'freq': { "units": "Hz", "value": parseFloat(bcdDecode(message.substring(30, 38))) / 100 },
'activePower': { "units": "W", "value": parseFloat(bcdDecode(message.substring(38, 46))) / 100 },
'reactivePower': { "units": "W", "value": parseFloat(bcdDecode(message.substring(46, 54))) / 100 },
'apparentPower': { "units": "W", "value": parseFloat(bcdDecode(message.substring(54, 62))) / 100 },
'powerFactor': { "units": "%", "value": parseFloat(bcdDecode(message.substring(62, 70))) / 10 },
};



return {"payload": output};

Neeraj said...

hi,

I have an energy meter from a different vendor but it contains v9821 IC. It is a multi-functional energy meter which can show energy, voltage, current, load and frequency on the LCD. I could find there are 4 pins exposed for connection. Later I realized those are nothing but pin 43 and pin 44 and other two are GND and +3v . I have few question regarding it as following:

1. Can I use those pins to read the metering data like voltage, current, energy etc.
2. Can I connect esp32 with those pins for serial communication
3. Will the protocol be same as V9261F for V9821 IC which I have
4. Will the send command be same as you showed in the presentation "FE010F080000001C"

Please help me with the above queries.
Thanks

Creation Factory said...

Hi @Unknown,

As your device is also based on the v9821 (just as the ZMAi-90), I believe that there is a good chance you can have success with the approach you describe. Try to connect the UART pins from your ESP32 to that chip, and look for what responses you obtain from the chip. Mind the baud rate, data bits and parity settings, which should be the same as I have described here.

If you have another chip connected to the v9821 you might consider keeping it powered off or cutting the TX/RX traces between the two, as it could upset the communication with your ESP32.

As far as I could understand there are some protocol differences between V9261F and V9821, even though some frames have a similar structure. These are not interchangeable devices.

Good luck.

Cheers

Neeraj said...

hi Creation Factory,

Thanks for your response. Please let me share the pictures of the PCB.

1. Front view of the PCB
FrontView
The description of J1 is as below:
J1-1 = V9821 Pin P2.4/RXD2
J1-2 = +3v
J1-3 = V9821 Pin P2.5/TXD2
J1-4 = GND

As it is clearly visible that J1 is nothing but extension of Pin 43 and Pin 44 with is described as UART communication pins. let's consider J1 and UART pins interchangeable terms.

2. Rear view of the PCB
RearView

3. Close look at the chip
CloseLook

4. Front Complete
FrontComplete

Looking at the schematic of the PCB I realized that a chip (ATHYC802) is connected with the V9821 IC with following pins:
(i) Pin 46 P2.0/RXD4/T2/OSC
(ii) Pin 45 P2.1/TXD4/T0

As it seems that the chip (ATHYC802) is connected with V9821 with different pins than the J1 connector pins, will it still interfere with the signals of J1 pins or UART pins?

Will the J1 connector work as UART2 as mentioned in the datasheet ?

please let me know if I could provide any other information.

Thanks

Creation Factory said...

Hello @Neeraj,

Apparently the ATHYC802 is a serial EEPROM connected to those 2 GPIO pins as you mentioned (these likely are not configured as UART in that case, but as I2C master, in order to communicate with the EEPROM).

In principle tapping the TXD2/RXD2 should not interfere with anything. You may want to follow its traces to see if there is anything else connected to those in the PCB, but possibly these are dedicated to communicate with an external device or for ISP programming. From the datasheet an IR port is one such scenario.

I don't think there is much risk in tapping to those pins, just beware of the serial adaptor you use, if it provides the same voltage levels as the V9821 (e.g. 3.3 or 5 Volts). Otherwise you may fry the UART or the chip.

If the chip also responds to metering commands in this port is another story..I guess that depends on what is programmed on the firmware in the chip. I remember checking that port on the ZMAI-90, but it didn't seem to respond to anything. Yours might be different though, as the V9821 is a very flexible architecture. Some manufacturers might include different customizations than others.

Does your meter also have a Wifi / IoT board/module? If that is the case, can you also share info and photos of it?

Thanks




Creation Factory said...

Btw, in the ZMAi-90 (as you can see in the PCB photo), the ESP8266 board connects to the pins you mention as having the serial EEPROM (TXD4, RXD4), so given this scenario is likely that your chip is programmed differently.

Nevertheless I believe it is still worth tapping into the various UARTs and see if for any you get a response.

Cheers

Neeraj said...

hi Creation Factory,

Thanks for your response.

If ATHYC802 is not using UART then there's a high chance that UART (J1) is free to use.

And yes as per the datasheet pins exposed via J1 connector are for IR communication. I was thinking of using that directly with the ESP32. There is no WiFi module on the meter right now. That's the project I'm working on. I want to connect ESP32 with this meter and make this meter smart. Which can share energy meter data in real time at a remote location. In this case, localhost only.

But if we think of using the UART pins there are high chances that the firmware could be different. But I strongly believe that the firmware would be same due to its origin (China).

Earlier I had tried sending some random data as I was not aware of any command before visiting your blog (which is very nice blog actually).
Although I had sent random string from ESP32 to V9821 but I did not receive any response from V9821. I was expecting some error response or something but there was no response at all.

I had tried different baud rate combinations well.

Later I came to know that I had missed sending the string in a particular format which is nothing but the command.

What would you suggest ?

Thanks

Creation Factory said...

Hi @Neeraj, are you making sure that the command you send via the serial line is the correct sequence of bytes? For example when we are sending the command "fe010f080000001c", it is not actually the text string, but the sequence of byte values that hex string represents, i.e.:

0xfe 0x01 0x0f 0x08 0x00 0x00 0x00 0x1c

Try using some terminal application such as RealTerm, so that you can input the hex values of each byte.

Cheers

Neeraj said...

Sure, please allow me some time. I think I need to write some kind of library to send the command.

Neeraj said...

hi CreationFactory,

I am able to send the command as described by you. The format is hex. mode of communication is 8E1. But I'm not able to get any response.

Thanks
Neeraj