logo elektroda
logo elektroda
X
logo elektroda

Zemismart SPM01-D2TW Energy Counter: Data Issues with Tuya MCU and ESP02S Swap

Pete0815 6096 38
Best answers

How can I decode the Zemismart SPM01-D2TW Tuya MCU data after swapping the CB2S module, and what is the correct way to do the two-step UART capture on a CB2S-powered board?

Put the original CB2S back in and capture the UART traffic from the MCU with the board powered safely from 5V into the input of the 3.3V regulator, not from mains; start the capture before applying power so you catch the early boot messages [#21072618] On your board, the 5V source should go to the LDO input and you should see 3.3V at the module output; if the board uses a step-down converter instead, feed that converter’s input in the same way [#21072162][#21072618] If the chip is already desoldered, a 2 MB backup is still useful, and you can also flash OpenBeken to the module and then solder it back [#21072162][#21080800] For TuyaMCU devices, some data only appears when the MCU believes Wi‑Fi/cloud is present, so use either a real MQTT connection or force WiFi state 0x04, then run `tuyaMcu_sendQueryState` or even `addRepeatingEvent 5 -1 tuyaMcu_sendQueryState` if needed [#21072162][#21080877][#21126038] In this meter, dpID 6 carries the raw voltage/current/power packet and dpID 1 is total energy; the thread eventually got stable reporting with either `waitFor MQTTState 1` + one-shot query or `tuyaMcu_defWiFiState 4` + repeating query [#21080877][#21126038]
Generated by the language model.
ADVERTISEMENT
  • #31 21099682
    Pete0815
    Level 7  
    Posts: 34
    Help: 1
    Rate: 3
    p.kaczmarek2 wrote:
    Wait @Pete0815, so what exactly helped?


    Mmmh, need some more testing. For a quick answer, I just changed the state query back to a one-shot from repeating every 5 sec and expecting this is it.
    BUT, the energy counter is still working fine after this.

    So very strange because of no function before. Will test more carefully to find out.

    Edit: Tested again and again but no result why.

    The autoexec.bat is now:
    // This script provides extra REST page for hosting in LittleFS
    // Please see: https://www.elektroda.com/rtvforum/topic4040354.html
    // Script taken from: https://www.elektroda.com/rtvforum/viewtopic.php?p=20990058#20990058
    // Download HTML there.
    
    // Clear all previous definitions
    clearIO
    
    // clear flags
    // flags 0
    
    // set flag 46
    SetFlag 46 1
    
    // start TuyaMCU driver
    startDriver TuyaMCU
    tuyaMcu_setBaudRate 9600
    
    // This one is better than tuyaMcu_defWiFiState 4;  MQTTState 1 = WiFiState 4
    // issuing of tuyaMcu_defWiFiState 4 continues the script,
    // but doesnt report to MQTT since there is still no connection.
    // if you didn't setup MQTT connection then issue tuyaMcu_defWiFiState 4
    // and comment waitFor MQTTState 1
    
    waitFor MQTTState 1
    //tuyaMcu_defWiFiState 4
    
    // Total energy - Dpid 1 "total_forward_energy" -> channel 4
    linkTuyaMCUOutputToChannel 1 val 4
    setChannelType 4 EnergyTotal_kWh_div100
    setChannelLabel 4 "Total Energy"
    
    // Measurements - Dpid 6 "phase_a" - channel RAW_TAC2121C_VCP -> 5,6,7
    // TAC2121C VoltageCurrentPower Packet
    // This will automatically set voltage, power and current
    linkTuyaMCUOutputToChannel 6 RAW_TAC2121C_VCP
    setChannelType 5 Voltage_div10
    setChannelLabel 5 "Voltage"
    setChannelType 6 Power
    setChannelLabel 6 "Power"
    setChannelType 7 Current_div1000
    setChannelLabel 7 "Current"
    
    
    // Fault - Dpid 9 "fault" -> channel 9
    linkTuyaMCUOutputToChannel 9 raw 9
    setChannelType 9 ReadOnly
    setChannelLabel 9 "Fault"
    
    // Prepayment on-off - Dpid 11 "switch_prepayment" -> channel 2
    linkTuyaMCUOutputToChannel 11 bool 2
    setChannelType 2 toggle
    setChannelLabel 2 "Prepayment"
    
    // Clear Energy Counters - Dpid 12 "clear_energy" -> channel 3
    linkTuyaMCUOutputToChannel 12 bool 3
    setChannelType 3 toggle
    setChannelLabel 3 "Clear Energy Counters"
    
    // Prepaid energy - Dpid 13 "balance_energy" -> channel 11
    linkTuyaMCUOutputToChannel 13 val 11
    setChannelType 11 EnergyTotal_kWh_div100
    setChannelLabel 11 "Total Prepaid Energy"
    
    // Charge Prepayment - Dpid 14 "charge_energy" - channel 12
    linkTuyaMCUOutputToChannel 14 val 12
    setChannelType 12 TextField
    setChannelLabel 12 "Purchased Energy [kWh*100], i.e. 1kWh = 100"
    
    // Settings 1 - Dpid 17 "alarm_set_1" - channel 13
    linkTuyaMCUOutputToChannel 17 val 13
    setChannelType 13 TextField
    setChannelLabel 13 "Leakage Current Protection Settings"
    
    // Settings 2 - Dpid 18 "alarm_set_2" -> channel 10
    linkTuyaMCUOutputToChannel 18 raw 10
    setChannelType 10 ReadOnly
    setChannelLabel 10 "UV, OV, Max. Current Protections Settings"
    
    // Breaker Id - Dpid 19 "breaker_id" -> channel 0
    linkTuyaMCUOutputToChannel 19 str 0
    setChannelType 0 ReadOnly
    setChannelLabel 0 "Breaker ID"
    
    // The above are read only channels. Except Settings 2 (mapped on channel 10), but since we cannot set it due to wrong parse of TuyaMCU driver - for now read only
    
    
    // NOTE: addRepeatingEvent [RepeatTime] [RepeatCount]
    // code below will forever Send query state command every 5 seconds
    //addRepeatingEvent 5 -1 tuyaMcu_sendQueryState 
    
    // AngelOfDeath - We don't need it forever, since TuyaMCU sends everything when necessary
    // we need it just first time to obtain initial status. Some dpIDs not reported without asking
     tuyaMcu_sendQueryState


    So beside Alarm Set 1 & 2 and Leakage Protection everything seems to be ok.
    Because OV, UV and Max current protection are read only I´m not sure how to set this alarm values.


    Edit2:
    Still a guess what has happened but identified a new problem/reason.

    Maybe during I struggeld getting some data my MQTT connecting was not connected/configured.
    So the autoexec.bat entry:
    waitFor MQTTState 1

    will be a problem.

    So for now, I deleted the MQTT configuration for testing and the current, power and energy counter values are missing/not send anymore.

    Then I activated
    tuyaMcu_defWiFiState 4
    in the autoexec.bat and the energy counter started to send a value but current and power still missing.

    After changing back the
    waitFor MQTTState 1
    in the autoexec.bat and configured a mqtt connection everything is fine again.

    So to achieve this status I need a working MQTT connection.
  • ADVERTISEMENT
  • #32 21100203
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14505
    Help: 651
    Rate: 12505
    do you have enabled TuyaMCU queue in device flags?
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #33 21100333
    Pete0815
    Level 7  
    Posts: 34
    Help: 1
    Rate: 3

    p.kaczmarek2 wrote:
    do you have enabled TuyaMCU queue in device flags?


    No it was disabled and now enabled and tested again .... very illogical results....

    After enabling TuyaMCU queue I disabled the MQTT configuration and switch from waitFor MQTTState 1 to tuyaMcu_defWiFiState 4

    Result: No reported values anymore

    Then switch from tuyaMcu_sendQueryState to addRepeatingEvent 5 -1 tuyaMcu_sendQueryState

    Result: everything fine again

    Then switch back from addRepeatingEvent 5 -1 tuyaMcu_sendQueryState to tuyaMcu_sendQueryState

    Result: everything still ok. This I do not understand.

    Edit:

    Ok, figured out that there is a difference in using the Button "Save, Reset SVM and rund file as script thread" + Restart instead of disconnecting the device from power.

    After the last test scenario, where everything seems to work (active: tuyaMcu_defWiFiState 4 & tuyaMcu_sendQueryState) I disconnected the device from power.

    Now after repowering the situation is faulty again and values like dpIx 6 (voltage, current, power) are missing / not received from MCU.

    Guess I really have to repower fully for every test scenario to get true results.
  • #34 21126038
    Pete0815
    Level 7  
    Posts: 34
    Help: 1
    Rate: 3
    Ok, took some time for some new motivation to test.

    I figured out 2 working configurations:

    A) Mqtt Connection + One shot query send by autoexec
    
    waitFor MQTTState 1
    tuyaMcu_sendQueryState
    


    B) Wifi state + repeating query send by autoexec
    
    tuyaMcu_defWiFiState 4
    addRepeatingEvent 5 -1 tuyaMcu_sendQueryState
    


    Because maybe I'm not using Mqtt in every configuration, I'm preferring configuration B at the moment because it should always work.

    Still have not found a way to set alarm1 and alarm2 and therefore of course also not how to activate or check if it's working.
  • ADVERTISEMENT
  • #35 21126060
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14505
    Help: 651
    Rate: 12505
    It seems you've found one of the causes - doing OBK reset does not reset the TuyaMCU. If you want to have a fresh start, you need to power off the whole setup, wait a moment, and power it again.

    It's not possible to reset TuyaMCU from software.
    Helpful post? Buy me a coffee.
  • #36 21126492
    vincenzoernst1
    Level 9  
    Posts: 94
    Help: 3
    Rate: 7
    what i do is: remove vcc jumper cable, start flashing and reconnect vcc. needs some timing but works in general.
  • ADVERTISEMENT
  • #38 21877235
    Pete0815
    Level 7  
    Posts: 34
    Help: 1
    Rate: 3
    I previously put this project on hold due to a lack of progress. While the basic metering in OpenBeken worked fine, I couldn't figure out how to modify the reading cycle.
    I’m not an experienced programmer, but after experimenting with Claude AI in a sandbox environment yesterday, I’ve decided to reopen the project. I'm excited to see if using AI can help me bridge the gap and finally get it working.
  • #39 21877299
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14505
    Help: 651
    Rate: 12505
    I don't think that AI can help here much. The device described in topic is TuyaMCU. If you want faster readings, then remove MCU and connect to BL0942 directly.
    Pinout diagram of BL0942 IC showing pins such as 3.3V, GND, TX/RX, SEL, and CF1
    You will need to route UART, probably you will need to use BPS to select baud, and you will need to disconnect SEL. SEL is:
    
     UART/SPI mode selection (0: UART 1: SPI), internal pull-down resistance,
    connected to GND is 0 level (UART), connected directly to VDD is high level (SPI
    

    SEL has internall pull-down, so it's 0 (UART) by default unless connected externally.
    Helpful post? Buy me a coffee.

Topic summary

✨ The discussion revolves around issues encountered while using the Zemismart SPM01-D2TW energy counter, specifically after replacing the Tuya CB2S chip with an ESP02S. The user reports receiving limited and inconsistent data points from the device, primarily only one data point changing despite attempts to modify the load. Various solutions are proposed, including using the TuyaMCU guide for setup and configuration, capturing communication data, and utilizing commands like `tuyaMcu_sendQueryState` to request data points. The conversation also touches on the importance of ensuring proper power supply and the need for a stable connection to retrieve accurate readings. Users share insights on configuring the autoexec.bat file for optimal performance and troubleshooting steps to resolve data reporting issues.
Generated by the language model.

FAQ

TL;DR: This FAQ is for Zemismart SPM01-D2TW owners replacing CB2S with ESP-02S or OpenBeken. The device exposed 9 dpIds, and one expert noted, "some devices may need" repeated queries or forced WiFi state to report everything reliably. It explains safe UART capture, dpId mapping, OpenBeken setup, and why energy data can look inconsistent after partial resets. [#21126038]

Why it matters: This thread shows that most "missing data" problems came from TuyaMCU behavior, WiFi-state emulation, and incomplete cold-boot testing rather than from bad hardware.

Option Reporting behavior Best use Main limitation
Tasmota + sendtuya0 Data often appears only on request Quick probing Mapping was harder in this case
OpenBeken + TuyaMCU mapping dpId 6 and energy features were decoded Best for Home Assistant-style channel mapping Some dpIds need forced state or polling
OpenBeken direct to BL0942 Potentially faster refresh When TuyaMCU is too slow Requires hardware rerouting and MCU bypass

Key insight: A true power-cycle matters more than a soft restart here. “Reset SVM and run” does not reset the TuyaMCU, so cold-boot behavior, dpId availability, and refresh timing can look inconsistent until you remove power from the whole board. [#21126060]

Quick Facts

  • The meter initially exposed 9 data points, but only 3 carried non-zero data before deeper mapping and query tuning. [#21071605]
  • The decoded raw measurement packet on dpId 6 is 8 bytes long and carries voltage, current, and active power for phase A. [#21074304]
  • Two working OpenBeken strategies were confirmed on 2024-06-20: A) waitFor MQTTState 1 + one-shot query, or B) tuyaMcu_defWiFiState 4 + repeating query every 5 s. [#21126038]
  • The board used an LP2178 mains step-down stage and a separate 3.3 V MicrOne LDO for the WiFi module, not the more common AMS1117-3.3V layout. [#21072199]
  • A successful firmware backup exposed dpIds including 1, 2, 6, 9, 14, 17, 18, and 19, with phase_a, fault, charge_energy, and breaker_id explicitly identified. [#21074304]

How do I capture TuyaMCU UART communication on a Zemismart SPM01-D2TW safely after putting the original CB2S module back on the board?

Yes—capture it with the original CB2S reinstalled, but power the board from USB-fed low voltage only. 1. Feed 5 V into the input of the board’s 3.3 V LDO so the WiFi section powers up without mains. 2. Start UART capture before power is applied. 3. Reapply 5 V and record traffic from boot, because early packets matter. The key safety rule was explicit: never power the device from mains while UART is connected; use isolation if mains is unavoidable. [#21072162]

Why does the Zemismart SPM01-D2TW only report dpId data after running tuyaMcu_sendQueryState instead of sending updates automatically?

Because this TuyaMCU implementation does not always push full state automatically. The thread showed repeated cases where the meter returned useful dpIds only after tuyaMcu_sendQueryState, and OpenBeken users solved it with polling every 5 or 10 seconds. The MCU also may withhold full reporting unless it believes WiFi is paired to the cloud. That is why forced WiFi state or MQTT-linked state made readings appear more consistently than passive listening alone. [#21072162]

What is TuyaMCU, and how does it affect data reporting when swapping a Tuya CB2S module for an ESP-02S or OpenBeken?

"TuyaMCU" is a microcontroller-based serial protocol layer that exchanges dpId packets with the WiFi module, using request/response behavior and cloud-state awareness. When CB2S is replaced with ESP-02S or OpenBeken, the meter logic stays in the MCU, so the new module must emulate expected WiFi status and decode dpIds correctly. That is why the hardware swap alone did not produce full automatic measurements, even though UART packets were visible immediately at 9600 baud. [#21080872]

What is dpId 6 RAW_TAC2121C_VCP on this Zemismart energy counter, and how do voltage, current, and power get decoded from it?

dpId 6 is the main live-measurement packet for phase A. The firmware backup described it as a raw 8-byte big-endian block containing voltage, current, and active power. The example 08 80 00 03 E8 00 27 10 was documented as 217.6 V, 1.000 A, and 10.000 kW. In OpenBeken, linking dpId 6 to RAW_TAC2121C_VCP automatically split it into voltage, power, and current channels without manual byte parsing. [#21074304]

Which dpIDs were identified for the Zemismart SPM01-D2TW firmware backup, and what do dpId 1, 2, 6, 9, 14, 17, 18, and 19 represent?

The backup identified the key dpIds clearly. dpId 1 is total_forward_energy, dpId 2 is cur_neutral, dpId 6 is phase_a, dpId 9 is fault, dpId 14 is charge_energy, dpId 17 is alarm_set_1, dpId 18 is alarm_set_2, and dpId 19 is breaker_id. The same extracted metadata also showed dpId 13 as balance_energy and dpId 11 as switch_prepayment, which helped later OpenBeken mapping work. [#21074304]

How do I configure OpenBeken autoexec.bat for the Zemismart SPM01-D2TW so total energy, prepaid energy, fault, and phase A measurements show up correctly?

Use OpenBeken’s TuyaMCU driver, then map the known dpIds to channels. 1. Start TuyaMCU, set 9600 baud, and provide either MQTT-based WiFi state or tuyaMcu_defWiFiState 4. 2. Map dpId 1 to EnergyTotal_kWh_div100, dpId 6 to RAW_TAC2121C_VCP, dpId 9 to a read-only fault channel, and dpIds 13/14 to prepaid energy channels. 3. Trigger one initial tuyaMcu_sendQueryState. This setup produced working voltage, current, power, total energy, prepaid energy, breaker ID, and fault display. [#21082232]

Why do dpId 1 energy values and the OpenBeken web UI kWh display differ by about one count or show unexpected scaling like 0.07 kWh for channel value 8?

Because the raw counter and the UI presentation used different scaling and rounding behavior. The thread showed channel value 8 while the web view displayed 0.07 kWh, and later the user observed a roughly constant ±1 count mismatch. MQTT still published the integer channel value directly, which confirmed the underlying dpId value. The practical takeaway is to trust the mapped channel and transport value first, then treat the web widget display as a presentation layer that may round or lag. [#21099598]

What is the correct way to force WiFi state 0x04 in OpenBeken, and when should I use tuyaMcu_defWiFiState 4 instead of waitFor MQTTState 1?

Use tuyaMcu_defWiFiState 4 when MQTT is absent or optional, and use waitFor MQTTState 1 when MQTT is working reliably. The thread confirmed two stable configurations: A) MQTT connected, then one-shot query; B) forced WiFi state 0x04 plus repeated queries every 5 s. The forced state matters because some TuyaMCU devices report more data only when they think they are cloud-paired. Without MQTT, waitFor MQTTState 1 can stall the logic you need. [#21126038]

How should I power a Tuya energy meter board from USB for UART sniffing when it uses an LP2178 mains step-down and a 3.3 V MicrOne LDO instead of an AMS1117?

Feed USB-derived 5 V into the input of the MicrOne 3.3 V LDO, not into mains sections. The board in this thread used an LP2178 mains step-down and a small SOT23-3 MicrOne regulator for the WiFi module, so the usual AMS1117 reference point was missing. The recommended approach was to verify the regulator pins with a multimeter, then use the 5 V input so the LDO outputs 3.3 V for CB2S while avoiding mains entirely during UART capture. [#21072618]

What causes endless 55AA032B00002D network status packets during capture, and how do I tell whether the USB-TTL adapter is underpowering the board?

Those packets indicate repeated Tuya network-status traffic, often seen when the board is not reaching normal operating state. In this case, the capture loop showed endless 55AA032B00002D, while the device never appeared in the Tuya app or on the WiFi access point. The user then suspected the USB-TTL adapter lacked enough current for the whole board, which fits the symptoms: UART stays alive, but WiFi and full device behavior do not. If pairing never starts under low-voltage power, suspect underpower before blaming dpId mapping. [#21072681]

OpenBeken vs Tasmota for TuyaMCU energy meters like the Zemismart SPM01-D2TW — which is easier for dpId mapping and Home Assistant integration?

OpenBeken was easier in this thread. Tasmota could query raw Tuya data with sendtuya0, but the user struggled to interpret and map the results. OpenBeken added direct TuyaMCU helpers, channel types, autoexec scripting, Tasmota-style JSON emulation, and a dedicated setup guide for Home Assistant-oriented dpId mapping. The thread author explicitly moved toward OpenBeken after limited progress with Tasmota, and the working meter configuration was reached there, not in Tasmota. [#21072162]

How do I make sure a full power-cycle resets both OpenBeken and the TuyaMCU, and why doesn’t 'Reset SVM and run' reproduce cold-boot behavior?

Remove power from the whole board, wait briefly, and then reapply power. OpenBeken’s soft reset does not reset the TuyaMCU, so “Reset SVM and run” can leave the MCU in an old state. That caused misleading tests here: scripts looked fixed after a soft run, but dpId 6 and other packets vanished again after real repowering. The maintainer later stated plainly that software cannot reset TuyaMCU on this device. [#21126060]

What is the TuyaMCU queue flag in OpenBeken, and how can it change reliability when polling or receiving dpId updates from the MCU?

It is an OpenBeken device flag that can improve how TuyaMCU commands and responses are sequenced. The user enabled the TuyaMCU queue flag and then tested combinations of forced WiFi state, one-shot queries, and repeating queries. Results were inconsistent until full power-cycles were used, but with the queue enabled the setup eventually worked using tuyaMcu_defWiFiState 4 and proper query timing. The important limit is that flag changes alone can look effective after soft restarts, yet fail after true cold boot. [#21100333]

How can I set or modify alarm_set_1 and alarm_set_2 on the SPM01-D2TW for leakage, over-voltage, under-voltage, and over-current protection?

You can identify those dpIds, but the thread did not produce a confirmed write method for them. The extracted firmware metadata showed alarm_set_1 and alarm_set_2 as raw, writable dpIds intended for leakage, over-voltage, under-voltage, and over-current thresholds. However, the working OpenBeken setup still treated dpId 18 as read-only because of parsing limits, and the user explicitly said alarm settings remained unresolved. So monitoring worked better than editing protection thresholds in this project stage. [#21099682]

If I need faster refresh than TuyaMCU provides, how do I bypass the MCU and connect OpenBeken directly to the BL0942, including UART routing, baud selection, and SEL pin handling?

Bypass the TuyaMCU and wire the WiFi module directly to the BL0942. "BL0942" is an energy-measurement IC that reports electrical values over UART or SPI, with a mode-select pin named SEL and configurable baud behavior. The maintainer advised routing UART directly, using BPS to select baud, and disconnecting SEL from any external forcing. SEL has an internal pull-down, so leaving it low keeps UART mode active; tying it high switches the chip to SPI. [#21877299]
Generated by the language model.
ADVERTISEMENT