logo elektroda
logo elektroda
X
logo elektroda

TOSA1 TONGOU Tuya WiFi Energy Meter teardown: CB2S BK7231N, BL0942, STC 8H3K64S2

_geku_ 849 9
ADVERTISEMENT
  • #1 21872909
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    TONGOU Tuya Smart WiFi Energy Meter - Teardown

    Promo graphic of TONGOU Tuya Smart WiFi Energy Meter with app screen and clip-on module on a cableAd for TONGOU WiFi smart energy meter with blue current coil and 99.5% accuracy claimsWhite WiFi energy meter 100–240V with pass-through hole and blue and brown wires with metal tips

    Bought this tiny-shiny power metering module on Aliexpress. What we have inside:

    Module: CB2S (BK7231N) - WiFi
    TuyaMCU: STC 8H3K64S2
    Sensor: BL0942 - power metering

    Communication between all parts done using 2 UARTs.

    Assembly contains 2 boards and current metering coil bulit into the plastic case. Smaller board is WiFi + TuyaMCU, bigger - power metering sensor with ac/dc converter:

    Close-up of a green PCB with a round CT hole, capacitors, and a brown and blue wire soldered to itClose-up of a green PCB with a circular hole and brown wire, showing a BL0942 chip, held between fingersGreen circuit board with a shielded module labeled “Model: CB2S” on a light fabric backgroundClose-up of a PCB with an STC chip and a push button, held between fingers.Small green PCB with an IC chip, a push button, and a blue module on the left on a white surfaceClose-up of an opened white plastic device casing with wires and a small circuit board

    Pinout is classic for "WiFi - TuyaMCU - Sensor" architecture:

    Front and back of a green PCB with a CB2S module, red pin labels, and pinout/diagram drawings below
    Futher invstigation shed light on used bandwidth in stock firmware:

    1. UART Module -> TuyaMCU: 115200
    2. UART TuyaMCU -> Sensor: 38400

    When you disconnect two boards, and power on WiFi + TuyaMCU stock firmware sometimes pauses for a while and after reset via EN0 loops itself, here is sample of UART communication:

    Module:

    
    55 AA 00 00 00 00 FF  - Heartbeat (HB)
    55 AA 00 00 00 00 FF  - HB
    55 AA 00 00 00 00 FF  - HB
    55 AA 00 00 00 00 FF  - HB (MCU responded)
    55 AA 00 01 00 00 00  - ask product info
    55 AA 00 02 00 00 01  - ask working mode 
    55 AA 00 03 00 01 02 05 - notify Net status "The module searches for network"
    55 AA 00 03 00 01 03 06 - notify Net status "The module is registered with the network but not connected to the network" 
    55 AA 00 08 00 00 07 - ask sensor info (statuses from dpIds)
    55 AA 00 03 00 01 04 07  - notify Net status "   The module is connected to the network and gets an IP address"
    55 AA 00 08 00 00 07 - ask sensor info (statuses from dpIds) 
    55 AA 00 00 00 00 FF - HB
    55 AA 00 00 00 00 FF - HB 
    55 AA 00 00 00 00 FF - HB
    55 AA 00 00 00 00 FF - HB
    


    MCU:

    
    00 - pause
    55 AA 03 00 00 01 00 03 - HB response
    55 AA 03 01 00 2A 7B 22 ......................................................................... 0F  - product info
    55 AA 03 02 00 00 04 - response working mode - module works with the MCU to process network events
    55 AA 03 07 00 05 6E 04 00 01 0A 8B - dpId 6E (110) status, type Enum, len 0001, value 0A (10) = Under_Voltage_Alarm
    55 AA 03 00 00 01 00 03 - HB response
    55 AA 03 01 00 2A 7B 22 ......................................................................... 0F  - product info
    55 AA 03 02 00 00 04 - response working mode
    55 AA 03 07 00 05 6E 04 00 01 0A 8B - dpId 6E (110) status
    55 AA 03 00 00 01 00 03 - HB reponse
    55 AA 03 01 00 2A 7B 22 ......................................................................... 0F  - product info
    55 AA 03 02 00 00 04 - response working mode
    55 AA 03 07 00 05 6E 04 00 01 0A 8B - dpId 6E (110) status
    55 AA 03 00 00 01 00 03 - HB response
    55 AA 03 01 00 2A 7B 22 ......................................................................... 0F  - product info
    55 AA 03 07 00 05 6E 04 00 01 0A 8B - dpId 6E (110) status
    55 AA 03 02 00 00 04  - response working mode
    55 AA 03 00 00 01 00 03 - HB response
    55 AA 03 01 00 2A 7B 22 ......................................................................... 0F  - product info
    55 AA 03 07 00 05 6E 04 00 01 0A 8B - dpId 6E (110) status
    55 AA 03 02 00 00 04  - response working mode
    ....... looping the same
    


    Also example of BL0942 UART communication:

    
    55 00 00 00 87 07 00 12 09 00 00 00 00 00 00 00 20 4E 00 02 03 00 36 
    55 00 00 00 87 07 00 DE 07 00 00 00 00 00 00 00 20 4E 00 02 03 00 6C 
    55 00 00 00 87 07 00 F7 07 00 00 00 00 00 00 00 20 4E 00 02 03 00 53 
    55 00 00 00 87 07 00 34 0A 00 00 00 00 00 00 00 20 4E 00 02 03 00 13 
    55 00 00 00 87 07 00 9F 09 00 00 00 00 00 00 00 20 4E 00 02 03 00 A9 
    55 00 00 00 2B 07 00 35 09 00 00 00 00 00 00 00 20 4E 00 02 03 00 6F 
    55 00 00 00 2B 07 00 B8 0B 00 00 00 00 00 00 00 20 4E 00 02 03 00 EA 
    55 00 00 00 2B 07 00 65 0A 00 00 00 00 00 00 00 20 4E 00 02 03 00 3E 
    55 00 00 00 2B 07 00 F8 03 00 00 00 00 00 00 00 20 4E 00 02 03 00 B2 
    55 00 00 00 2B 07 00 3E 05 00 00 00 00 00 00 00 20 4E 00 02 03 00 6A 
    55 00 00 00 2B 07 00 81 05 00 00 00 00 00 00 00 20 4E 00 02 03 00 27 
    55 00 00 00 2B 07 00 CE 03 00 00 00 00 00 00 00 20 4E 00 02 03 00 DC 
    55 00 00 00 2B 07 00 3C 05 00 00 00 00 00 00 00 20 4E 00 02 03 00 6C 
    55 00 00 00 2B 07 00 16 06 00 00 00 00 00 00 00 20 4E 00 02 03 00 91 
    55 00 00 00 2B 07 00 B2 06 00 00 00 00 00 00 00 20 4E 00 02 03 00 F5 
    55 00 00 00 2B 07 00 D4 0C 00 00 00 00 00 00 00 20 4E 00 02 03 00 CD
    


    Investigation on Tuya Dev portal gave me next list of dpIDs:

    
        "result": [
            { "dpId": 1, "dpName": "Total forward energy" },
            { "dpId": 131, "dpName": "CPU Real-time Temp" },
            { "dpId": 6, "dpName": "Phase A" },
            { "dpId": 11, "dpName": "Prepayment Switch" },
            { "dpId": 12, "dpName": "Clear Remaining Electricity" },
            { "dpId": 13, "dpName": "Remaining Electricity" },
            { "dpId": 14, "dpName": "Electricity Charge" },
            { "dpId": 32, "dpName": "Grid supply frequency" },
            { "dpId": 34, "dpName": "Factory Reset" },
            { "dpId": 101, "dpName": "Eletricity Shortage Setting" },
            { "dpId": 102, "dpName": "Over-voltage Setting" },
            { "dpId": 103, "dpName": "Under-voltage Setting" },
            { "dpId": 104, "dpName": "Over-current Setting" },
            { "dpId": 105, "dpName": "Over-power Setting" },
            { "dpId": 107, "dpName": "Temperature Setting" },
            { "dpId": 109, "dpName": "Online state" },
            { "dpId": 110, "dpName": "Event" },
            { "dpId": 113, "dpName": "Restore Default Switch" },
            { "dpId": 50, "dpName": "Overall Power Factor" },
            { "dpId": 114, "dpName": "Current Threshold" },
            { "dpId": 115, "dpName": "Over-voltage Threshold" },
            { "dpId": 116, "dpName": "Under-voltage Threshold" },
            { "dpId": 118, "dpName": "Temperature Threshold" },
            { "dpId": 119, "dpName": "Over-power Threshold" },
            { "dpId": 120, "dpName": "Electricity Shortage Threshold" },
            { "dpId": 125, "dpName": "Forward Electricity" }
        ]
    


    And I compiled it into autoexec.bat. It is work in progress, in terms of channel types. so expect few changes later if I came up with better typing:

    
    clearIO
    
    startDriver TuyaMCU
    tuyaMcu_setBaudRate 115200
    waitFor MQTTState 1
    setMqttAutoDiscovery 0
    
    setChannelLabel 0 "Online state"
    setChannelType 0 Toggle_Inv
    linkTuyaMCUOutputToChannel 109 enum 0
    
    setChannelType 1 Voltage_div10
    setChannelLabel 1 "Real-time Voltage, V"
    setChannelType 2 Current_div1000
    setChannelLabel 2 "Real-time Current, A"
    setChannelType 3 Power
    setChannelLabel 3 "Real-time Power, W"
    linkTuyaMCUOutputToChannel 6 RAW_TAC2121C_VCP
    
    setChannelLabel 5 "CPU °C"
    setChannelType 5 Temperature_div10
    linkTuyaMCUOutputToChannel 131 val 5
    
    setChannelLabel 4 "Total forward energy, kWh"
    setChannelType 4 EnergyTotal_kWh_div100
    linkTuyaMCUOutputToChannel 1 val 4
    
    setChannelLabel 6 "Forward Electricity, kWh"
    setChannelType 6 EnergyTotal_kWh_div100
    linkTuyaMCUOutputToChannel 125 val 6
    
    setChannelLabel 7 "Event"
    setChannelType 7 ReadOnly
    #setChannelType 7 ReadOnlyEnum
    #setChannelEnum 7 0:Normal 1:Over_Current_Trip 2:Over_Power_Trip 3:High_Temp_Trip 4:Over_Voltage_Trip 5:Under_Voltage_Trip 6:Over_Current_Alarm 7:Over_Power_Alarm 8:High_Temp_Alarm 9:Over_Voltage_Alarm 10:Under_Voltage_Alarm 11:Remote_ON 12:Remote_OFF 13:Manual_ON 14:Manual_OFF 15:Leakage_Trip 16:Leakage_Alarm 17:Restore_Default 18:Automatic_Closing 19:Electricity_Shortage 20:Electricity_Shortage_Alarm 21:Timing_switch_ON 22:Timing_switch_OFF 23:Electricity_Reset
    linkTuyaMCUOutputToChannel 110 enum 7
    
    ##############
    # Advanced
    
    setChannelLabel 8 "Restore Default"
    setChannelType 8 Toggle
    linkTuyaMCUOutputToChannel 113 bool 8
    
    setChannelLabel 9 "Frequency"
    setChannelType 9 Frequency_div100
    linkTuyaMCUOutputToChannel 32 val 9
    
    setChannelLabel 10 "Overall Power Factor"
    setChannelType 10 PowerFactor_div100
    linkTuyaMCUOutputToChannel 50 val 10
    
    setChannelLabel 11 "Factory Reset"
    setChannelType 11 Toggle
    linkTuyaMCUOutputToChannel 34 bool 11
    
    #################
    # Prepaid Power Recharge
    
    # Remaining Electricity
    setChannelLabel 12 "Current Remaining Electricity, kWh"
    setChannelType 12 EnergyTotal_kWh_div100
    linkTuyaMCUOutputToChannel 13 val 12
    
    setChannelLabel 13 "Prepayment Switch"
    setChannelType 13 Toggle
    linkTuyaMCUOutputToChannel 11 bool 13
    
    setChannelLabel 14 "Clear Remaining Electricity"
    setChannelType 14 Toggle
    linkTuyaMCUOutputToChannel 12 bool 14
    
    setChannelLabel 15 "Add Electricity Charge, kWh/100"
    setChannelType 15 TextField
    linkTuyaMCUOutputToChannel 14 val 15
    
    #################
    # Feature
    
    # Over-current Setting
    setChannelLabel 16 "Over-current alarm"
    setChannelType 16 Toggle
    linkTuyaMCUOutputToChannel 104 bool 16
    
    setChannelLabel 17 "Current Threshold, 1-50, A"
    setChannelType 17 TextField
    linkTuyaMCUOutputToChannel 114 val 17
    
    # Over-voltage Setting
    setChannelLabel 18 "Over-voltage alarm"
    setChannelType 18 Toggle
    linkTuyaMCUOutputToChannel 102 bool 18
    
    setChannelLabel 19 "Over-voltage Threshold, 100-280, V"
    setChannelType 19 TextField
    linkTuyaMCUOutputToChannel 115 val 19
    
    # Under-voltage Setting
    setChannelLabel 20 "Under-voltage alarm"
    setChannelType 20 Toggle
    linkTuyaMCUOutputToChannel 103 bool 20
    
    setChannelLabel 21 "Under-voltage Threshold, 100-280, V"
    setChannelType 21 TextField
    linkTuyaMCUOutputToChannel 116 val 21
    
    # Over-power Setting
    setChannelLabel 22 "Over-power alarm"
    setChannelType 22 Toggle
    linkTuyaMCUOutputToChannel 105 bool 22
    
    setChannelLabel 23 "Over-power Threshold, 5-12005, W"
    setChannelType 23 TextField
    linkTuyaMCUOutputToChannel 119 val 23
    
    # Temperature Setting
    setChannelLabel 24 "Temperature alarm"
    setChannelType 24 Toggle
    linkTuyaMCUOutputToChannel 107 bool 24
    
    setChannelLabel 25 "Temperature Threshold, -25 - +100, °C"
    setChannelType 25 TextField
    linkTuyaMCUOutputToChannel 118 val 25
    
    # Eletricity Shortage Setting
    setChannelLabel 26 "Balance alarm"
    setChannelType 26 Toggle
    linkTuyaMCUOutputToChannel 101 bool 26
    
    setChannelLabel 27 "Balance Threshold, 10-500, kW.h"
    setChannelType 27 TextField
    linkTuyaMCUOutputToChannel 120 val 27
    
    # WATCHDOG
    
    # Watchdog channel
    setChannelLabel 200 "MCU Watchdog"
    setChannelType 200 ReadOnly
    setChannelPrivate 200 1
    setChannel 200 1
    
    # Reset watchdog on incoming measurements dpIds 6, 32, 50, 131 (channels 1, 2, 3, 9, 10, 5)
    addEventHandler OnChannelChange 1 if $CH200==0 then "setChannel 200 1"
    addEventHandler OnChannelChange 9 if $CH200==0 then "setChannel 200 1"
    addEventHandler OnChannelChange 10 if $CH200==0 then "setChannel 200 1"
    addEventHandler OnChannelChange 5 if $CH200==0 then "setChannel 200 1"
    
    # Toggle online_state if no measurements are received for more than X seconds, to restart MCU reporting
    addRepeatingEvent 7 -1 if $CH200==1 then "setChannel 200 0" else "backlog setChannel 0 1; delay_s 1; setChannel 0 0"
    
    tuyaMcu_sendQueryState
    


    I have only set one flag - Flag 29 - [NETIF] Use short device name as a hostname instead of a long name.
    Also, cleaned Device Group name, to make sure DGR driver not loading.
    That gave me pretty stable setup.
    Measurements sent every 5 second, same as in stock firmware - got an idea to connect CB2S directly to BL0942, may be it will be faster.

    All experiments were done using firmware version 1.18.280 for BK7231N.
  • ADVERTISEMENT
  • #2 21873481
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    Updated original post with new autoexec.bat and flag configuration that gave me pretty stable results.
  • ADVERTISEMENT
  • #3 21873754
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    Seems like I still have stability issues:

    Line chart of voltage (V) over time, about 7:00–9:40, with fluctuations and step changes.

    Every 30 min it stops sending V/C/P readings from raw dpId 6 (Phase A - RAW_TAC2121C_VCP). What I see in logs... I spot 2 issues.

    1. Unsupported data point type 201-error. But it repeats every time when readings from dpId 6 are pushed by MCU, so it is probably not the stability issue:

    
    Info:TuyaMCU:Received: 55 AA 03 07 00 0C 06 00 00 08 08 A6 00 00 00 00 00 00 D1 
    Info:TuyaMCU:ProcessIncoming[v=3]: cmd 7 (State) len 19
    Info:TuyaMCU:ParseState: id 6 type 0-raw len 8
    Info:GEN:CHANNEL_Set channel 3 has changed to 2214 (flags 0)
    
    Info:TuyaMCU:OnChannelChanged: channel 3: unsupported data point type 201-error
    Info:MQTT:Channel has changed! Publishing 2214 to channel 3 
    Info:MQTT:Publishing val 2214 to home/power/meter/pm1/3/get retain=0
    Info:GEN:No change in channel 4 (still set to 0) - ignoring
    
    Info:GEN:No change in channel 5 (still set to 0) - ignoring
    


    UPDATE: fixed by replacing:
    linkTuyaMCUOutputToChannel 6 RAW_TAC2121C_VCP 3

    to
    linkTuyaMCUOutputToChannel 6 RAW_TAC2121C_VCP

    Original autoexec.bat updated.

    2. wifi_state_timer moves from 59 to 0 again, Will send SetWiFiState 4 appears - no new readings from V/C/P dpId 6
    
    ExtraDebug:TuyaMCU:TuyaMCU heartbeat_valid = 1, product_information_valid=1, self_processing_mode = 1, wifi_state_valid = 1, wifi_state_timer=58
    Info:MAIN:Time 1810, idle 170194/s, free 61560, MQTT 1(1), bWifi 1, secondsWithNoPing -1, socks 2/38 
    Info:GEN:dhcp=0 ip=xxx.xxx.xxx.xxx gate=xxx.xxx.xxx.xxx mask=xxx.xxx.xxx.xxx mac=xx:xx:xx:xx:xx:xx
    Info:GEN:sta: 1, softap: 0, b/g/n
    Info:GEN:sta:rssi=-35,ssid=xxxxxxxx,bssid=xx:xx:xx:xx:xx:xx,channel=1,cipher_type:CCMP
    ExtraDebug:TuyaMCU:TuyaMCU heartbeat_valid = 1, product_information_valid=1, self_processing_mode = 1, wifi_state_valid = 1, wifi_state_timer=59
    Info:MAIN:Time 1811, idle 169377/s, free 61560, MQTT 1(1), bWifi 1, secondsWithNoPing -1, socks 2/38 
    ExtraDebug:TuyaMCU:TuyaMCU heartbeat_valid = 1, product_information_valid=1, self_processing_mode = 1, wifi_state_valid = 1, wifi_state_timer=0
    ExtraDebug:TuyaMCU:Will send SetWiFiState 4.
    Info:MAIN:Time 1812, idle 175906/s, free 61560, MQTT 1(1), bWifi 1, secondsWithNoPing -1, socks 2/38 
    Info:TuyaMCU:Received: 55 AA 03 03 00 00 05 
    Info:TuyaMCU:ProcessIncoming[v=3]: cmd 3 (WiFiState) len 7
    ExtraDebug:TuyaMCU:TuyaMCU heartbeat_valid = 1, product_information_valid=1, self_processing_mode = 1, wifi_state_valid = 1, wifi_state_timer=2
    Info:MAIN:Time 1813, idle 168585/s, free 61560, MQTT 1(1), bWifi 1, secondsWithNoPing -1, socks 2/38 
    Info:TuyaMCU:Received: 55 AA 03 00 00 01 01 04 
    Info:TuyaMCU:ProcessIncoming[v=3]: cmd 0 (Hearbeat) len 8
    ExtraDebug:TuyaMCU:TuyaMCU heartbeat_valid = 1, product_information_valid=1, self_processing_mode = 1, wifi_state_valid = 1, wifi_state_timer=2
    Info:MAIN:Time 1814, idle 171955/s, free 61560, MQTT 1(1), bWifi 1, secondsWithNoPing -1, socks 2/38 
    


    Added after 8 [hours] 38 [minutes]:

    It is MCU itself. And this behaviour also exists with stock firmware. And even reset with stock firmware via SmartLife app didn't help.
    After 30 mins sensor continue to send data to MCU via UART as it was before.
    Heartbeats between MCU and Module also work as usually. But MCU does not send any measurements to module.
    One observation - it sends last updated status info, then after 30 sec it sand another one, and then freezes.
    Not sure what to do next.. App says MCU version 1.0.0, and there are no updates.
    May be I will just connect sensor directly to CB2S UART, and desolder MCU completely.

    Added after 11 [hours] 35 [minutes]:

    Alerts\Thresholds also does not work when MCU stuck, so seems like measurements routine or whatever it uses really stopped.
    I checked reset PIN on MCU, and seems like it is pulled high, so reset occures only with 10 Ohm resistor (300 Ohms proposed by spec does not work, even 47 and 22 ohm does not) - but it is shortcircuit, not proper reset.

    Added after 2 [hours] 19 [minutes]:

    Once in every hour it allows 1 reading:

    Line chart of voltage (V) over time with abrupt jumps and stepped flat segments
  • #4 21875077
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    Finally, I found the solution - need to toggle dpId 109 (online_state) back and fourth, and it starts sending measurements again.
    It all started from analysis of device spec I got from Tuya Dev Portal:
    
    [
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "forward_energy_total",
                    "codeDesc": "",
                    "codeName": "正向总有功电量",
                    "dpFormat": "{\"forward_energy_total\":\"$\"}",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "mainDP": "forward_energy_total",
                    "name": "Total forward energy",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":99999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "forward_energy_total",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "name": "Total forward energy",
                    "remark": "forward_energy_total",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":99999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "ro",
                    "code": "phase_a",
                    "codeDesc": "",
                    "codeName": "A相电压,电流及功率",
                    "dpFormat": "{\"phase_a\":\"$\"}",
                    "langDict": {
                        "unit": ""
                    },
                    "mainDP": "phase_a",
                    "name": "Phase A",
                    "remark": "",
                    "valueDesc": "{\"maxlen\":128}",
                    "valueType": "Raw"
                },
                "schema": {
                    "accessType": "ro",
                    "code": "phase_a",
                    "langDict": {},
                    "name": "Phase A",
                    "remark": "phase_a",
                    "valueDesc": "{\"maxlen\":128}",
                    "valueType": "Raw"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "prepayment_switch",
                    "codeDesc": "",
                    "codeName": "预付费开关",
                    "dpFormat": "{\"prepayment_switch\":\"$\"}",
                    "langDict": {
                        "false": "Off",
                        "true": "On"
                    },
                    "mainDP": "prepayment_switch",
                    "name": "Prepayment Switch",
                    "remark": "",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "prepayment_switch",
                    "langDict": {
                        "false": "Off",
                        "true": "On"
                    },
                    "name": "Prepayment Switch",
                    "remark": "prepayment_switch",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "clear_energy",
                    "codeDesc": "",
                    "codeName": "剩余可用电量清零",
                    "dpFormat": "{\"clear_energy\":\"$\"}",
                    "langDict": {
                        "false": "OFF",
                        "true": "ON"
                    },
                    "mainDP": "clear_energy",
                    "name": "Clear Remaining Electricity",
                    "remark": "",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "clear_energy",
                    "langDict": {
                        "false": "OFF",
                        "true": "ON"
                    },
                    "name": "Clear Remaining Electricity",
                    "remark": "clear_energy",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                }
            },
            {
                "functionSet": {
                    "accessType": "ro",
                    "code": "balance_energy",
                    "codeDesc": "",
                    "codeName": "剩余可用电量显示",
                    "dpFormat": "{\"balance_energy\":\"$\"}",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "mainDP": "balance_energy",
                    "name": "Remaining Electricity",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":99999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "ro",
                    "code": "balance_energy",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "name": "Remaining Electricity",
                    "remark": "balance_energy",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":99999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "energy_charge",
                    "codeDesc": "",
                    "codeName": "电量充值",
                    "dpFormat": "{\"energy_charge\":\"$\"}",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "mainDP": "energy_charge",
                    "name": "Electricity Charge",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "energy_charge",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "name": "Electricity Charge",
                    "remark": "energy_charge",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "ro",
                    "code": "supply_frequency",
                    "codeDesc": "",
                    "codeName": "电网供电频率",
                    "dpFormat": "{\"supply_frequency\":\"$\"}",
                    "langDict": {
                        "unit": "Hz"
                    },
                    "mainDP": "supply_frequency",
                    "name": "Grid supply frequency",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"Hz\",\"min\":0,\"max\":9999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "ro",
                    "code": "supply_frequency",
                    "langDict": {
                        "unit": "Hz"
                    },
                    "name": "Grid supply frequency",
                    "remark": "supply_frequency",
                    "valueDesc": "{\"unit\":\"Hz\",\"min\":0,\"max\":9999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "factory_reset",
                    "codeDesc": "",
                    "codeName": "恢复出厂设置",
                    "dpFormat": "{\"factory_reset\":\"$\"}",
                    "langDict": {
                        "false": "OFF",
                        "true": "ON"
                    },
                    "mainDP": "factory_reset",
                    "name": "Factory Reset",
                    "remark": "",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "factory_reset",
                    "langDict": {
                        "false": "OFF",
                        "true": "ON"
                    },
                    "name": "Factory Reset",
                    "remark": "factory_reset",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                }
            },
            {
                "functionSet": {
                    "accessType": "ro",
                    "code": "power_factor",
                    "codeDesc": "",
                    "codeName": "总功率因数",
                    "dpFormat": "{\"power_factor\":\"$\"}",
                    "langDict": {
                        "unit": ""
                    },
                    "mainDP": "power_factor",
                    "name": "Overall Power Factor",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"\",\"min\":-999,\"max\":999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "ro",
                    "code": "power_factor",
                    "langDict": {
                        "unit": ""
                    },
                    "name": "Overall Power Factor",
                    "remark": "power_factor",
                    "valueDesc": "{\"unit\":\"\",\"min\":-999,\"max\":999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "energy_shortage_set",
                    "codeDesc": "",
                    "codeName": "余额不足报警",
                    "dpFormat": "{\"energy_shortage_set\":\"$\"}",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "mainDP": "energy_shortage_set",
                    "name": "Eletricity Shortage Setting",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "energy_shortage_set",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "name": "Eletricity Shortage Setting",
                    "remark": "energy_shortage_set",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "ov_set",
                    "codeDesc": "",
                    "codeName": "过压设置",
                    "dpFormat": "{\"ov_set\":\"$\"}",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "mainDP": "ov_set",
                    "name": "Over-voltage Setting",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "ov_set",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "name": "Over-voltage Setting",
                    "remark": "ov_set",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "uv_set",
                    "codeDesc": "",
                    "codeName": "欠压设置",
                    "dpFormat": "{\"uv_set\":\"$\"}",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "mainDP": "uv_set",
                    "name": "Under-voltage Setting",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "uv_set",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "name": "Under-voltage Setting",
                    "remark": "uv_set",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "oc_set",
                    "codeDesc": "",
                    "codeName": "过电流设置",
                    "dpFormat": "{\"oc_set\":\"$\"}",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "mainDP": "oc_set",
                    "name": "Over-current Setting",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "oc_set",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "name": "Over-current Setting",
                    "remark": "oc_set",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "op_set",
                    "codeDesc": "",
                    "codeName": "过功率设置",
                    "dpFormat": "{\"op_set\":\"$\"}",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "mainDP": "op_set",
                    "name": "Over-power Setting",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "op_set",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "name": "Over-power Setting",
                    "remark": "op_set",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "temp_set",
                    "codeDesc": "",
                    "codeName": "温度设置",
                    "dpFormat": "{\"temp_set\":\"$\"}",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "mainDP": "temp_set",
                    "name": "Temperature Setting",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "temp_set",
                    "langDict": {
                        "Alarm": "",
                        "Closed": ""
                    },
                    "name": "Temperature Setting",
                    "remark": "temp_set",
                    "valueDesc": "{\"range\":[\"Closed\",\"Alarm\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "online_state",
                    "codeDesc": "",
                    "codeName": "在线状态",
                    "dpFormat": "{\"online_state\":\"$\"}",
                    "langDict": {
                        "offline": "Offline",
                        "online": "Online"
                    },
                    "mainDP": "online_state",
                    "name": "Online state",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"online\",\"offline\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "online_state",
                    "langDict": {
                        "offline": "Offline",
                        "online": "Online"
                    },
                    "name": "Online state",
                    "remark": "online_state",
                    "valueDesc": "{\"range\":[\"online\",\"offline\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "event",
                    "codeDesc": "",
                    "codeName": "实时事件",
                    "dpFormat": "{\"event\":\"$\"}",
                    "langDict": {
                        "Automatic_Closing": "",
                        "Electricity_Reset": "",
                        "Electricity_Shortage": "",
                        "Electricity_Shortage_Alarm": "",
                        "High_Temp_Alarm": "",
                        "High_Temp_Trip": "",
                        "Leakage_Alarm": "",
                        "Leakage_Trip": "",
                        "Manual_OFF": "",
                        "Manual_ON": "",
                        "Normal": "",
                        "Over_Current_Alarm": "",
                        "Over_Current_Trip": "",
                        "Over_Power_Alarm": "",
                        "Over_Power_Trip": "",
                        "Over_Voltage_Alarm": "",
                        "Over_Voltage_Trip": "",
                        "Remote_OFF": "",
                        "Remote_ON": "",
                        "Restore_Default": "",
                        "Timing_switch_OFF": "",
                        "Timing_switch_ON": "",
                        "Under_Voltage_Alarm": "",
                        "Under_Voltage_Trip": ""
                    },
                    "mainDP": "event",
                    "name": "Event",
                    "remark": "",
                    "valueDesc": "{\"range\":[\"Normal\",\"Over_Current_Trip\",\"Over_Power_Trip\",\"High_Temp_Trip\",\"Over_Voltage_Trip\",\"Under_Voltage_Trip\",\"Over_Current_Alarm\",\"Over_Power_Alarm\",\"High_Temp_Alarm\",\"Over_Voltage_Alarm\",\"Under_Voltage_Alarm\",\"Remote_ON\",\"Remote_OFF\",\"Manual_ON\",\"Manual_OFF\",\"Leakage_Trip\",\"Leakage_Alarm\",\"Restore_Default\",\"Automatic_Closing\",\"Electricity_Shortage\",\"Electricity_Shortage_Alarm\",\"Timing_switch_ON\",\"Timing_switch_OFF\",\"Electricity_Reset\"]}",
                    "valueType": "Enum"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "event",
                    "langDict": {
                        "Automatic_Closing": "",
                        "Electricity_Reset": "",
                        "Electricity_Shortage": "",
                        "Electricity_Shortage_Alarm": "",
                        "High_Temp_Alarm": "",
                        "High_Temp_Trip": "",
                        "Leakage_Alarm": "",
                        "Leakage_Trip": "",
                        "Manual_OFF": "",
                        "Manual_ON": "",
                        "Normal": "",
                        "Over_Current_Alarm": "",
                        "Over_Current_Trip": "",
                        "Over_Power_Alarm": "",
                        "Over_Power_Trip": "",
                        "Over_Voltage_Alarm": "",
                        "Over_Voltage_Trip": "",
                        "Remote_OFF": "",
                        "Remote_ON": "",
                        "Restore_Default": "",
                        "Timing_switch_OFF": "",
                        "Timing_switch_ON": "",
                        "Under_Voltage_Alarm": "",
                        "Under_Voltage_Trip": ""
                    },
                    "name": "Event",
                    "remark": "event",
                    "valueDesc": "{\"range\":[\"Normal\",\"Over_Current_Trip\",\"Over_Power_Trip\",\"High_Temp_Trip\",\"Over_Voltage_Trip\",\"Under_Voltage_Trip\",\"Over_Current_Alarm\",\"Over_Power_Alarm\",\"High_Temp_Alarm\",\"Over_Voltage_Alarm\",\"Under_Voltage_Alarm\",\"Remote_ON\",\"Remote_OFF\",\"Manual_ON\",\"Manual_OFF\",\"Leakage_Trip\",\"Leakage_Alarm\",\"Restore_Default\",\"Automatic_Closing\",\"Electricity_Shortage\",\"Electricity_Shortage_Alarm\",\"Timing_switch_ON\",\"Timing_switch_OFF\",\"Electricity_Reset\"]}",
                    "valueType": "Enum"
                }
            },
            {
                "functionSet": {
                    "accessType": "wr",
                    "code": "rd_set",
                    "codeDesc": "",
                    "codeDescEn": "",
                    "codeName": "恢复默认开关",
                    "dpFormat": "{\"rd_set\":\"$\"}",
                    "langDict": {
                        "false": "OFF",
                        "true": "ON"
                    },
                    "mainDP": "rd_set",
                    "name": "Restore Default Switch",
                    "remark": "",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                },
                "schema": {
                    "accessType": "wr",
                    "code": "rd_set",
                    "langDict": {
                        "false": "OFF",
                        "true": "ON"
                    },
                    "name": "Restore Default Switch",
                    "remark": "rd_set",
                    "valueDesc": "{}",
                    "valueType": "Boolean"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "c_thresh",
                    "codeDesc": "",
                    "codeName": "电流阈值",
                    "dpFormat": "{\"c_thresh\":\"$\"}",
                    "langDict": {
                        "unit": "A"
                    },
                    "mainDP": "c_thresh",
                    "name": "Current Threshold",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"A\",\"min\":1,\"max\":50,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "c_thresh",
                    "langDict": {
                        "unit": "A"
                    },
                    "name": "Current Threshold",
                    "remark": "c_thresh",
                    "valueDesc": "{\"unit\":\"A\",\"min\":1,\"max\":50,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "ov_thresh",
                    "codeDesc": "",
                    "codeName": "过压阈值",
                    "dpFormat": "{\"ov_thresh\":\"$\"}",
                    "langDict": {
                        "unit": "V"
                    },
                    "mainDP": "ov_thresh",
                    "name": "Over-voltage Threshold",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"V\",\"min\":100,\"max\":280,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "ov_thresh",
                    "langDict": {
                        "unit": "V"
                    },
                    "name": "Over-voltage Threshold",
                    "remark": "ov_thresh",
                    "valueDesc": "{\"unit\":\"V\",\"min\":100,\"max\":280,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "uv_thresh",
                    "codeDesc": "",
                    "codeName": "欠压阈值",
                    "dpFormat": "{\"uv_thresh\":\"$\"}",
                    "langDict": {
                        "unit": "V"
                    },
                    "mainDP": "uv_thresh",
                    "name": "Under-voltage Threshold",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"V\",\"min\":100,\"max\":280,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "uv_thresh",
                    "langDict": {
                        "unit": "V"
                    },
                    "name": "Under-voltage Threshold",
                    "remark": "uv_thresh",
                    "valueDesc": "{\"unit\":\"V\",\"min\":100,\"max\":280,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "temp_thresh",
                    "codeDesc": "",
                    "codeName": "温度阈值",
                    "dpFormat": "{\"temp_thresh\":\"$\"}",
                    "langDict": {
                        "unit": "℃"
                    },
                    "mainDP": "temp_thresh",
                    "name": "Temperature Threshold",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"℃\",\"min\":-250,\"max\":1000,\"scale\":1,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "temp_thresh",
                    "langDict": {
                        "unit": "℃"
                    },
                    "name": "Temperature Threshold",
                    "remark": "temp_thresh",
                    "valueDesc": "{\"unit\":\"℃\",\"min\":-250,\"max\":1000,\"scale\":1,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "op_thresh",
                    "codeDesc": "",
                    "codeName": "过功率阈值",
                    "dpFormat": "{\"op_thresh\":\"$\"}",
                    "langDict": {
                        "unit": "W"
                    },
                    "mainDP": "op_thresh",
                    "name": "Over-power Threshold",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"W\",\"min\":5,\"max\":12000,\"scale\":0,\"step\":10}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "op_thresh",
                    "langDict": {
                        "unit": "W"
                    },
                    "name": "Over-power Threshold",
                    "remark": "op_thresh",
                    "valueDesc": "{\"unit\":\"W\",\"min\":5,\"max\":12000,\"scale\":0,\"step\":10}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "rw",
                    "code": "energy_shortage",
                    "codeDesc": "",
                    "codeName": "余额报警阈值",
                    "dpFormat": "{\"energy_shortage\":\"$\"}",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "mainDP": "energy_shortage",
                    "name": "Electricity Shortage Threshold",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":10,\"max\":500,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "rw",
                    "code": "energy_shortage",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "name": "Electricity Shortage Threshold",
                    "remark": "energy_shortage",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":10,\"max\":500,\"scale\":0,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "ro",
                    "code": "fap_a",
                    "codeDesc": "",
                    "codeName": "正向总电量",
                    "dpFormat": "{\"fap_a\":\"$\"}",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "mainDP": "fap_a",
                    "name": "Forward Electricity",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":99999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "ro",
                    "code": "fap_a",
                    "langDict": {
                        "unit": "kW‧h"
                    },
                    "name": "Forward Electricity",
                    "remark": "fap_a",
                    "valueDesc": "{\"unit\":\"kW·h\",\"min\":0,\"max\":99999999,\"scale\":2,\"step\":1}",
                    "valueType": "Integer"
                }
            },
            {
                "functionSet": {
                    "accessType": "ro",
                    "code": "temp_a",
                    "codeDesc": "",
                    "codeName": "实时温度",
                    "dpFormat": "{\"temp_a\":\"$\"}",
                    "langDict": {
                        "unit": "℃"
                    },
                    "mainDP": "temp_a",
                    "name": "CPU Real-time Temp",
                    "remark": "",
                    "valueDesc": "{\"unit\":\"℃\",\"min\":-250,\"max\":1000,\"scale\":1,\"step\":1}",
                    "valueType": "Integer"
                },
                "schema": {
                    "accessType": "ro",
                    "code": "temp_a",
                    "langDict": {
                        "unit": "℃"
                    },
                    "name": "CPU Real-time Temp",
                    "remark": "temp_a",
                    "valueDesc": "{\"unit\":\"℃\",\"min\":-250,\"max\":1000,\"scale\":1,\"step\":1}",
                    "valueType": "Integer"
                }
            }
        ]
    


    I noticed there that online_state is rw, not ro. After changing channel type to Toggle_inv and turning it online -> offline -> online, it started working. So I ended up with updated autoexec.bat with watchdog timer. Idea is to listen for changes on dpIds 131, 6, 32, 50 and if there are no changes for more than 7 seconds - toggle online_state.

    Original autoexec.bat was updated.

    Added after 11 [hours] 19 [minutes]:

    Works pretty stable:
    Line chart of voltage over time (pm1 Real-time Voltage) from 11:00 to 19:00, about 214–226 V.
  • #5 21876453
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    And again autoexec.bat was updated - tuned watchdog part in the end of the file. Btw setChannel works better here than ToggleChannel.

    Added after 12 [minutes]:

    Original firmware:
    readResult...-12-21.bin (2 MB)You must be logged in to download this attachment.
  • ADVERTISEMENT
  • #6 21876543
    divadiow
    Level 38  
    Posts: 4880
    Help: 427
    Rate: 869
    interesting little device. Here's the boot log from dump

    Code: Text
    Log in, to see the code
  • #7 21876779
    ferbulous
    Level 18  
    Posts: 419
    Help: 8
    Rate: 56
    Thanks for your efforts, I’m getting this one instead to monitor my single phase. Do you still plan to connect the chip directly to BL942?
  • #8 21877764
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    >>21876779
    Hey, so far no, as I managed to make it working with TuyaMCU.
    Now working on adding it to my HA and also adjusting autoexec.bat in parts related to "prepayment" - as kWhWh seems need to be tweaked. Also dpId 110 - Enum - it is so big that seems like it was cut by the firmware, I tried even minimizing it to something like: 0:N 1:OCT 2:OPT ... but it was still cut. So ended up publishing it as a number, and then converting it to enum values on HA side.

    And from what I have seen, original 5 sec cadence works perfectly with my "control loop":
    1. Receive power measurement from TOSA1
    2. Update "Load power" in my EcoFlow Powerstream Microinverter - so that it does not overproduce (I have no ability to sell excessive power back to grid, and can end up paying for it)

    Not sure if direct wiring to the BL* will give me any noticeable benefits.

    But I purchased one more device, so if/when will have time, want to try next:
    1. Sniff TuyaMCU update via UART - don't know better approach, and it looks easier than setting up MITM proxy. Will have only 1 attempt to do it.
    2. Backup untouched original version of the WiFi module
  • ADVERTISEMENT
  • #9 21880958
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    Known issues so far:
    1. Balance Threshold/Alert and Over-Power Threshold/Alert - do not change Event value, maybe scaling problem, but so far was not able to make it working
  • #10 21884414
    _geku_
    Level 2  
    Posts: 9
    Rate: 2
    If anyone will find it useful, that is what I use in HomeAssistant (autodiscovery works as a basic step, but some UI parts better described manually + it has proper naming for enum values):

    
    mqtt:
      sensor:
        - name: "PM1 Real-time Voltage"
          unique_id: pm1_voltage
          state_topic: "home/power/meter/pm1/1/get"
          unit_of_measurement: "V"
          device_class: voltage
          state_class: measurement
          value_template: "{{ value | float(0) / 10 | round(1) }}"
          suggested_display_precision: 1
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Real-time Current"
          unique_id: pm1_current
          state_topic: "home/power/meter/pm1/2/get"
          unit_of_measurement: "A"
          device_class: current
          state_class: measurement
          value_template: "{{ value | float(0) / 1000 | round(4) }}"
          suggested_display_precision: 4
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Real-time Power"
          unique_id: pm1_power
          state_topic: "home/power/meter/pm1/3/get"
          unit_of_measurement: "W"
          device_class: power
          state_class: measurement
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Total Forward Energy"
          unique_id: pm1_total_forward_energy
          state_topic: "home/power/meter/pm1/4/get"
          unit_of_measurement: "kWh"
          device_class: energy
          state_class: total_increasing
          value_template: "{{ value | float(0) / 100 }}"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 CPU Temperature"
          unique_id: pm1_cpu_temperature
          state_topic: "home/power/meter/pm1/5/get"
          unit_of_measurement: "°C"
          device_class: temperature
          state_class: measurement
          value_template: "{{ value | float(0) / 10 }}"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Forward Electricity"
          unique_id: pm1_forward_electricity
          state_topic: "home/power/meter/pm1/6/get"
          unit_of_measurement: "kWh"
          device_class: energy
          state_class: total_increasing
          value_template: "{{ value | float(0) / 100 }}"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Event"
          unique_id: pm1_event_text
          state_topic: "home/power/meter/pm1/7/get"
          value_template: >-
            {% set v = value | int(-1) %}
            {% set map = {
              0: 'Normal',
              1: 'Over Current Trip',
              2: 'Over Power Trip',
              3: 'High Temp Trip',
              4: 'Over Voltage Trip',
              5: 'Under Voltage Trip',
              6: 'Over Current Alarm',
              7: 'Over Power Alarm',
              8: 'High Temp Alarm',
              9: 'Over Voltage Alarm',
              10: 'Under Voltage Alarm',
              11: 'Remote ON',
              12: 'Remote OFF',
              13: 'Manual ON',
              14: 'Manual OFF',
              15: 'Leakage Trip',
              16: 'Leakage Alarm',
              17: 'Restore Default',
              18: 'Automatic Closing',
              19: 'Electricity Shortage',
              20: 'Electricity Shortage Alarm',
              21: 'Timing Switch ON',
              22: 'Timing Switch OFF',
              23: 'Electricity Reset'
            } %}
            {{ map.get(v, 'Unknown (' ~ v ~ ')') }}
          icon: mdi:alert-outline
          device:
            identifiers:
              - "pm1"
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Event Raw"
          unique_id: pm1_event_raw
          state_topic: "home/power/meter/pm1/7/get"
          icon: mdi:alert-outline
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Frequency"
          unique_id: pm1_frequency
          state_topic: "home/power/meter/pm1/9/get"
          unit_of_measurement: "Hz"
          device_class: frequency
          state_class: measurement
          value_template: "{{ value | float(0) / 100 | round(2) }}"
          suggested_display_precision: 2
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Overall Power Factor"
          unique_id: pm1_power_factor
          state_topic: "home/power/meter/pm1/10/get"
          state_class: measurement
          icon: mdi:alpha-f-circle-outline
          value_template: "{{ value | float(0) / 100 | round(3) }}"
          suggested_display_precision: 3
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Current Remaining Electricity"
          unique_id: pm1_current_remaining_electricity
          state_topic: "home/power/meter/pm1/12/get"
          unit_of_measurement: "kWh"
          value_template: "{{ value | float(0) / 100 }}"
          device_class: energy
          state_class: total
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
      binary_sensor:
        - name: "PM1 Online State"
          unique_id: pm1_online_state
          state_topic: "home/power/meter/pm1/0/get"
          payload_on: "0"
          payload_off: "1"
          device_class: connectivity
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
      switch:
        - name: "PM1 Prepayment Switch"
          unique_id: pm1_prepayment_switch
          state_topic: "home/power/meter/pm1/13/get"
          command_topic: "home/power/meter/pm1/13/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Over-current Alarm"
          unique_id: pm1_overcurrent_alarm
          state_topic: "home/power/meter/pm1/16/get"
          command_topic: "home/power/meter/pm1/16/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Over-voltage Alarm"
          unique_id: pm1_overvoltage_alarm
          state_topic: "home/power/meter/pm1/18/get"
          command_topic: "home/power/meter/pm1/18/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Under-voltage Alarm"
          unique_id: pm1_undervoltage_alarm
          state_topic: "home/power/meter/pm1/20/get"
          command_topic: "home/power/meter/pm1/20/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Over-power Alarm"
          unique_id: pm1_overpower_alarm
          state_topic: "home/power/meter/pm1/22/get"
          command_topic: "home/power/meter/pm1/22/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Temperature Alarm"
          unique_id: pm1_temperature_alarm
          state_topic: "home/power/meter/pm1/24/get"
          command_topic: "home/power/meter/pm1/24/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Balance Alarm"
          unique_id: pm1_balance_alarm
          state_topic: "home/power/meter/pm1/26/get"
          command_topic: "home/power/meter/pm1/26/set"
          payload_on: "1"
          payload_off: "0"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
      button:
        - name: "PM1 Restore Default"
          unique_id: pm1_restore_default
          command_topic: "home/power/meter/pm1/8/set"
          payload_press: "1"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Factory Reset"
          unique_id: pm1_factory_reset
          command_topic: "home/power/meter/pm1/11/set"
          payload_press: "1"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Clear Remaining Electricity"
          unique_id: pm1_clear_remaining_electricity
          command_topic: "home/power/meter/pm1/14/set"
          payload_press: "1"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
      number:
        - name: "PM1 Electricity Charge"
          unique_id: pm1_electricity_charge
          state_topic: "home/power/meter/pm1/15/get"
          command_topic: "home/power/meter/pm1/15/set"
          min: 0
          max: 100000
          step: 0.01
          mode: box
          unit_of_measurement: "kWh"
          value_template: "{{ value | float(0) / 100 }}"
          command_template: "{{ (value | float(0) * 100) | int }}"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Current Threshold"
          unique_id: pm1_current_threshold
          state_topic: "home/power/meter/pm1/17/get"
          command_topic: "home/power/meter/pm1/17/set"
          min: 1
          max: 50
          step: 1
          mode: slider
          unit_of_measurement: "A"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Over-voltage Threshold"
          unique_id: pm1_overvoltage_threshold
          state_topic: "home/power/meter/pm1/19/get"
          command_topic: "home/power/meter/pm1/19/set"
          min: 100
          max: 280
          step: 1
          mode: slider
          unit_of_measurement: "V"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Under-voltage Threshold"
          unique_id: pm1_undervoltage_threshold
          state_topic: "home/power/meter/pm1/21/get"
          command_topic: "home/power/meter/pm1/21/set"
          min: 100
          max: 280
          step: 1
          mode: slider
          unit_of_measurement: "V"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Over-power Threshold"
          unique_id: pm1_overpower_threshold
          state_topic: "home/power/meter/pm1/23/get"
          command_topic: "home/power/meter/pm1/23/set"
          min: 5
          max: 12005
          step: 1
          mode: box
          unit_of_measurement: "W"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Temperature Threshold"
          unique_id: pm1_temperature_threshold
          state_topic: "home/power/meter/pm1/25/get"
          command_topic: "home/power/meter/pm1/25/set"
          min: -25
          max: 100
          value_template: "{{ value | float(0) / 10 | round(1) }}"
          step: 1
          mode: slider
          unit_of_measurement: "°C"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    
        - name: "PM1 Balance Threshold"
          unique_id: pm1_balance_threshold
          state_topic: "home/power/meter/pm1/27/get"
          command_topic: "home/power/meter/pm1/27/set"
          min: 10
          max: 500
          step: 1
          mode: slider
          unit_of_measurement: "kWh"
          device:
            identifiers: ["pm1"]
            name: "PM1 Power Meter"
            manufacturer: "Tuya/OpenBeken"
            model: "BK7231N"
    

Topic summary

✨ The TONGOU Tuya Smart WiFi Energy Meter teardown reveals a compact power metering module purchased from Aliexpress, consisting of two PCBs housed in a plastic case with an integrated current metering coil. The smaller board integrates the CB2S module based on the BK7231N WiFi SoC and a TuyaMCU STC 8H3K64S2 microcontroller, while the larger board contains the BL0942 power metering IC along with an AC/DC converter. Communication between the WiFi module, MCU, and power sensor is managed via two UART interfaces. The teardown includes detailed images of the assembly and internal components. An updated configuration involving an autoexec.bat script and flag settings was applied to achieve stable operation results.
Generated by the language model.
ADVERTISEMENT