Tasmota: Power Meter Reading with Schneider EasyLogicâ„¢ PM2200 series

Created on 7 Aug 2019  Â·  7Comments  Â·  Source: arendst/Tasmota

Hi,
I try to create new Power Meter Sensor for Schneider EasyLogicâ„¢ PM2200
but it reboot after send
Any one investigate for me ?

http://www.schneider-electric.com/resources/sites/SCHNEIDER_ELECTRIC/content/live/FAQS/307000/FA307813/en_US/Public_PM2xxx_PMC%20Register%20List_v1001.xlsx

`
00:00:00 WIF: Connecting to AP2 4G-CPE-020331 in mode 11N as SONOFF_CB3D6F...
00:00:04 WIF: Connected
00:00:04 HTP: Web server active on SONOFF_CB3D6Fwith IP address 192.168.100.195
00:00:05 MQT: Attempting connection...
00:00:05 MQT: Connected
00:00:06 MQT: v1/devices/me/LWT = Online (retained)
00:00:06 MQT: v1/devices/me/cmnd/rpc/request/ =
00:00:06 MQT: v1/devices/me/attributes = {"Module":"WiFi-EZ001","Version":"6.5.0(sonoff)","FallbackTopic":"cmnd/DVES_CB3D6F_fb/","GroupTopic":"capteur"}
00:00:06 MQT: v1/devices/me/attributes = {"WebServerMode":"Admin","Hostname":"SONOFF_CB3D6F","IPAddress":"192.168.100.195"}
00:00:06 MQT: v1/devices/me/attributes = {"RestartReason":"Fatal exception:0 flag:2 (EXCEPTION) epc1:0x40204900 epc2:0x00000000 epc3:0x00000000 excvaddr:0x00000000 depc:0x00000000"}
11:06:09 MQT: v1/devices/me/attributes = {"Uptime":"0T00:00:14","SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"AP":2,"SSId":"4G-CPE-020331","BSSId":"00:03:7F:86:6B:40","Channel":7,"RSSI":98,"LinkCount":1,"Downtime":"0T00:00:04"}
11:06:09 MQT: v1/devices/me/telemetry = {"ts":1565150769000 ,"values":{"ANALOG_A0":9,"PM_Total":51.241,"PM_Frequency":50.01,"PM_Active_L1":0,"PM_Active_L2":0,"PM_Active_L3":0,"PM_ReActive_L1":-0,"PM_ReActive_L2":0,"PM_ReActive_L3":0,"PM_PF_L1":null,"PM_PF_L2":null,"PM_PF_L3":null,"PM_Volt_L1":119,"PM_Volt_L2":0,"PM_Volt_L3":120,"PM_Current_L1":0.000,"PM_Current_L2":0.000,"PM_Current_L3":0.000}}
11:06:10 MQT: Attempting connection...
11:06:10 MQT: Connected
11:06:10 MQT: v1/devices/me/LWT = Online (retained)
11:06:10 MQT: v1/devices/me/cmnd/rpc/request/ =

Exception (0):
epc1=0x40204900 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys
sp: 3ffffc30 end: 3fffffb0 offset: 01a0

stack>>>
3ffffdd0: 40107402 00dd9999 00000019 00000100
3ffffde0: c0036035 401003ca 00000001 00000000
3ffffdf0: 00000000 40100197 00000000 00000022
3ffffe00: 3fffc200 401073c8 3fffc258 4000050c
3ffffe10: 4000437d 00000030 00000018 ffffffff
3ffffe20: 60000200 00000008 00021700 80000000
3ffffe30: 20000000 3fff7bf8 80000000 200fc280
3ffffe40: 80000000 3fffc6fc 3ffeef74 3fff7bfc
3ffffe50: 00000074 000fc280 60000600 00000030
3ffffe60: ffffffff 0000000c 00000000 4020490f
3ffffe70: 4010746d 00080000 00000000 4010745c
3ffffe80: c0036035 00bdf6ba 00000000 4000050c
3ffffe90: 00000000 00000000 0000001f 40104301
3ffffea0: 4000050c 401073c8 3fffc258 4000050c
3ffffeb0: 40000f68 00000030 00000014 ffffffff
3ffffec0: 40000f58 00000000 00000020 00000000
3ffffed0: 00000000 4023a558 00000000 bfffffff
3ffffee0: ffffffff 3fffc6fc 3ffeef74 3fffdab0
3ffffef0: 00000000 3fffdcb0 3ffef030 00000030
3fffff00: 00000000 400042db 3ffead71 60000600
3fffff10: 40004b31 3fff797c 000002f4 000fc000
3fffff20: 40104866 3ffef020 3ffeeec0 401070c8
3fffff30: 4023a029 3ffeeec0 3ffef020 020649ff
3fffff40: 3fff797c 00001000 4023a4be 00000008
3fffff50: 3ffef020 3ffeef74 4023a56b 3ffeef74
3fffff60: 3ffef020 00a1ce43 4023a480 000000f2
3fffff70: 4023c791 3ffeef74 3ffef020 020623f8
3fffff80: 4023c7d6 3fffdab0 00000000 3fffdcb0
3fffff90: 3ffef038 00000000 40000f65 3fffdab0
3fffffa0: 40000f49 00003603 3fffdab0 40000f49
<<

ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v3fff3e48
~ld

00:00:00 Project capteur Capteur Version 6.5.0(sonoff)-2_3_0

ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v3fff3e48
~ld
`

here is my code which modify from xsns_25_sdm630.ino

`/*
xsns_25_pm2200.ino - Eastron pm2200-Modbus energy meter support for Sonoff-Tasmota

Copyright (C) 2019 Gennaro Tortone

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
*/

ifdef USE_PM2200

/*******************************\

define XSNS_91 91

include

TasmotaSerial *PM2200Serial;

uint8_t pm2200_type = 1;
//uint8_t pm2200_state = 0;

float pm2200_voltage[] = {0,0,0};
float pm2200_current[] = {0,0,0};
float pm2200_active_power[] = {0,0,0};
float pm2200_reactive_power[] = {0,0,0};
float pm2200_power_factor[] = {0,0,0};
float pm2200_energy_total = 0;
float pm2200_frequency = 0;

bool PM2200_ModbusReceiveReady(void)
{
return (PM2200Serial->available() > 1);
}

void PM2200_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count)
{
uint8_t frame[8];

frame[0] = 0x01; // default PM2200 Modbus address
frame[1] = function_code;

frame[2] = (uint8_t)(start_address >> 8);
frame[3] = (uint8_t)(start_address);
frame[4] = (uint8_t)(register_count >> 8);
frame[5] = (uint8_t)(register_count);

uint16_t crc = PM2200_calculateCRC(frame, 6); // calculate out crc only from first 6 bytes
frame[6] = lowByte(crc);
frame[7] = highByte(crc);

while (PM2200Serial->available() > 0) { // read serial if any old data is available
PM2200Serial->read();
}

PM2200Serial->flush();
PM2200Serial->write(frame, sizeof(frame));
}

uint8_t PM2200_ModbusReceive(float *value)
{
uint8_t buffer[9];

*value = NAN;
uint8_t len = 0;
while (PM2200Serial->available() > 0) {
buffer[len++] = (uint8_t)PM2200Serial->read();
}

if (len < 9)
return 3; // SDM_ERR_NOT_ENOUGHT_BYTES

if (len == 9) {

if (buffer[0] == 0x01 && buffer[1] == 0x03 && buffer[2] == 4) {   // check node number, op code and reply bytes count hjk347

  if((PM2200_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) {  //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8)

    ((uint8_t*)value)[3] = buffer[3];
    ((uint8_t*)value)[2] = buffer[4];
    ((uint8_t*)value)[1] = buffer[5];
    ((uint8_t*)value)[0] = buffer[6];

  } else return 1; // SDM_ERR_CRC_ERROR

} else return 2;  // SDM_ERR_WRONG_BYTES

}

return 0; // SDM_ERR_NO_ERROR
}

uint16_t PM2200_calculateCRC(uint8_t *frame, uint8_t num)
{
uint16_t crc, flag;
crc = 0xFFFF;
for (uint8_t i = 0; i < num; i++) {
crc ^= frame[i];
for (uint8_t j = 8; j; j--) {
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
} else { // Else LSB is not set
crc >>= 1; // Just shift right
}
}
}
return crc;
}

/*******************************/

const uint16_t pm2200_start_addresses[] {
0x0BCB, // L1 - Voltage A-B [V] 3020
0x0BCD, // L2 - Voltage B-C [V] 3022
0x0BCF, // L3 - Voltage C-A [V] 3024
0x0BB7, // L1 - Current A [A] 3000
0x0BB9, // L2 - Current B [A] 3002
0x0BBB, // L3 - Current C [A] 3004
0x0BED, // L1 - Active Power A [kW] 3054
0x0BEF, // L2 - Active Power B [kW] 3056
0x0BF1, // L3 - Active Power C [kW] 3058
0x0B5F, // L1 - Reactive Power A [kVAR] 3062
0x0BF5, // L2 - Reactive Power B [kVAR] 3064
0x0BF9, // L3 - Reactive Power C [kVAR] 3066
0x0C05, // L1 - Power Factor A 3078
0x0C07, // L2 - Power Factor B 3080
0x0C09, // L3 - Power Factor C 3082
0x0A8B, // Active Power Total 3000
0x0C25 // Frequency

};

uint8_t pm2200_read_state = 0;
uint8_t pm2200_send_retry = 0;

void PM2200250ms(void) // Every 250 mSec
{
// pm2200_state++;
// if (6 == pm2200_state) { // Every 300 mSec
// pm2200_state = 0;

float value = 0;
bool data_ready = PM2200_ModbusReceiveReady();

if (data_ready) {
  uint8_t error = PM2200_ModbusReceive(&value);
  if (error) {
    snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "PM2200 response error %d"), error);
    AddLog(LOG_LEVEL_DEBUG);
  } else {

    switch(pm2200_read_state) {
      case 0:
        pm2200_voltage[0] = value;
        break;

      case 1:
        pm2200_voltage[1] = value;
        break;

      case 2:
        pm2200_voltage[2] = value;
        break;

      case 3:
        pm2200_current[0] = value;
        break;

      case 4:
        pm2200_current[1] = value;
        break;

      case 5:
        pm2200_current[2] = value;
        break;

      case 6:
        pm2200_active_power[0] = value;
        break;

      case 7:
        pm2200_active_power[1] = value;
        break;

      case 8:
        pm2200_active_power[2] = value;
        break;

      case 9:
        pm2200_reactive_power[0] = value;
        break;

      case 10:
        pm2200_reactive_power[1] = value;
        break;

      case 11:
        pm2200_reactive_power[2] = value;
        break;

      case 12:
        pm2200_power_factor[0] = value;
        break;

      case 13:
        pm2200_power_factor[1] = value;
        break;

      case 14:
        pm2200_power_factor[2] = value;
        break;

      case 15:
        pm2200_energy_total = value;
        break;

      case 16:
        pm2200_frequency = value;
        break;
    } // end switch

    pm2200_read_state++;

    if (sizeof(pm2200_start_addresses)/2 == pm2200_read_state) {
      pm2200_read_state = 0;
    }
  }
} // end data ready

if (0 == pm2200_send_retry || data_ready) {
  pm2200_send_retry = 5;
   PM2200_ModbusSend(0x03, pm2200_start_addresses[pm2200_read_state], 2);
} else {
  pm2200_send_retry--;
}

// } // end 300 ms
}

void PM2200Init(void)
{
pm2200_type = 0;
if ((pin[GPIO_PM2200_RX] < 99) && (pin[GPIO_PM2200_TX] < 99)) {
PM2200Serial = new TasmotaSerial(pin[GPIO_PM2200_RX], pin[GPIO_PM2200_TX], 1);

ifdef PM2200_SPEED

if (PM2200Serial->begin(PM2200_SPEED)) {

else

if (PM2200Serial->begin(2400)) {

endif

  if (PM2200Serial->hardwareSerial()) { ClaimSerial(); }
  pm2200_type = 1;
}

}
}

ifdef USE_WEBSERVER

const char HTTP_SNS_PM2200_DATA[] PROGMEM = "%s"
"{s}PM2200 " D_VOLTAGE "{m}%s/%s/%s " D_UNIT_VOLT "{e}"
"{s}PM2200 " D_CURRENT "{m}%s/%s/%s " D_UNIT_AMPERE "{e}"
"{s}PM2200 " D_POWERUSAGE_ACTIVE "{m}%s/%s/%s k" D_UNIT_WATT "{e}"
"{s}PM2200 " D_POWERUSAGE_REACTIVE "{m}%s/%s/%s k" D_UNIT_VAR "{e}"
"{s}PM2200 " D_POWER_FACTOR "{m}%s/%s/%s{e}"
"{s}PM2200 " D_ENERGY_TOTAL "{m}%s k" D_UNIT_WATTHOUR "{e}"
"{s}PM2200 Frequency {m}%s Hz {e}";

endif // USE_WEBSERVER

void PM2200Show(bool json)
{
char voltage_l1[33];
dtostrfd(pm2200_voltage[0], Settings.flag2.voltage_resolution, voltage_l1);
char voltage_l2[33];
dtostrfd(pm2200_voltage[1], Settings.flag2.voltage_resolution, voltage_l2);
char voltage_l3[33];
dtostrfd(pm2200_voltage[2], Settings.flag2.voltage_resolution, voltage_l3);
char current_l1[33];
dtostrfd(pm2200_current[0], Settings.flag2.current_resolution, current_l1);
char current_l2[33];
dtostrfd(pm2200_current[1], Settings.flag2.current_resolution, current_l2);
char current_l3[33];
dtostrfd(pm2200_current[2], Settings.flag2.current_resolution, current_l3);
char active_power_l1[33];
dtostrfd(pm2200_active_power[0], Settings.flag2.wattage_resolution, active_power_l1);
char active_power_l2[33];
dtostrfd(pm2200_active_power[1], Settings.flag2.wattage_resolution, active_power_l2);
char active_power_l3[33];
dtostrfd(pm2200_active_power[2], Settings.flag2.wattage_resolution, active_power_l3);
char reactive_power_l1[33];
dtostrfd(pm2200_reactive_power[0], Settings.flag2.wattage_resolution, reactive_power_l1);
char reactive_power_l2[33];
dtostrfd(pm2200_reactive_power[1], Settings.flag2.wattage_resolution, reactive_power_l2);
char reactive_power_l3[33];
dtostrfd(pm2200_reactive_power[2], Settings.flag2.wattage_resolution, reactive_power_l3);
char power_factor_l1[33];
dtostrfd(pm2200_power_factor[0], 2, power_factor_l1);
char power_factor_l2[33];
dtostrfd(pm2200_power_factor[1], 2, power_factor_l2);
char power_factor_l3[33];
dtostrfd(pm2200_power_factor[2], 2, power_factor_l3);
char energy_total[33];
dtostrfd(pm2200_energy_total, Settings.flag2.energy_resolution, energy_total);
char energy_frequency[33];
dtostrfd(pm2200_frequency, 2, energy_frequency);

if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PM_Total\":%s,\"PM_Frequency\":%s,\"PM_Active_L1\":%s,\"PM_Active_L2\":%s,\"PM_Active_L3\":%s,\"PM_ReActive_L1\":%s,\"PM_ReActive_L2\":%s,\"PM_ReActive_L3\":%s,\"PM_PF_L1\":%s,\"PM_PF_L2\":%s,\"PM_PF_L3\":%s,\"PM_Volt_L1\":%s,\"PM_Volt_L2\":%s,\"PM_Volt_L3\":%s,\"PM_Current_L1\":%s,\"PM_Current_L2\":%s,\"PM_Current_L3\":%s"),
mqtt_data, energy_total,energy_frequency,
active_power_l1, active_power_l2, active_power_l3,
// "4000","5000","6000",
reactive_power_l1, reactive_power_l2, reactive_power_l3,
// "1000","2000","3000",
power_factor_l1, power_factor_l2, power_factor_l3,
// "1.1","1.2","1.3",
voltage_l1, voltage_l2, voltage_l3,
current_l1, current_l2, current_l3);

ifdef USE_WEBSERVER

} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PM2200_DATA, mqtt_data,
voltage_l1, voltage_l2, voltage_l3, current_l1, current_l2, current_l3,
active_power_l1, active_power_l2, active_power_l3,
reactive_power_l1, reactive_power_l2, reactive_power_l3,
power_factor_l1, power_factor_l2, power_factor_l3, energy_total,energy_frequency);

endif // USE_WEBSERVER

}
}

/*******************************\

  • Interface
    *******************************/

bool Xsns91(byte function)
{
bool result = false;

if (pm2200_type) {
switch (function) {
case FUNC_INIT:
PM2200Init();
break;
case FUNC_EVERY_250_MSECOND:
//case FUNC_EVERY_SECOND:
PM2200250ms();
break;
case FUNC_JSON_APPEND:
PM2200Show(1);
break;

ifdef USE_WEBSERVER

  case FUNC_WEB_APPEND:
    PM2200Show(0);
    break;

endif // USE_WEBSERVER

}

}
return result;
}

endif

`

enhancement

Most helpful comment

Thanks for this feature.

Maybe a hint about your crash, you are allocating a lot of data on the stack in PM2200Show(): 17x33 bytes, with 4 bytes alignment that makes at least 612 bytes on the stack. Please keep in mind the ESP8266 stack is 4k (actually it's a bit more as there is a continuation stack as well).

Can you please split the snprintf_P() and add each value one after the other reusing the same buffer.

Here is an example from xdrv_08_serial_bridge.ino:

      Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\""));
      for (uint32_t i = 0; i < serial_bridge_in_byte_counter; i++) {
        ResponseAppend_P(PSTR("%02x"), serial_bridge_buffer[i]);
      }
      ResponseAppend_P(PSTR("\"}"));

All 7 comments

Please, could you be so kind on completing the troubleshooting template in order to have more information so as to properly help you?

Also remember that it is available the Tasmota support chat for general questions.

Remember to read the Contributing Guideline and Policy. Thanks.


Support Information (Guide)

See Wiki for more information.
See FAQ for common questions/answers and links if none of your question is in the list.
See Chat for more user experience.
See Community for forum.
See Code of Conduct

If you are using core 2.3.0, you must use the tx and rx gpios of the esp8266 (hardware serial)

If you need to use software serial in other gpios, please upgrade your core to 2.5.2

Also, exception(0) sometimes is led to insuficient power to your device.

Besides this, you should update to latest Tasmota and with Tasmota's unmodified code, try to add this as a new driver. (as your logs said project capteur instead of project sonoff as default, give us the idea you have modified a lot of other things in your version)

Hope you can make this meter works and do a pull request with your changes.

I believe hardware serial is also supported on GPIO13/GPIO15 for some devices:

/* 6.3.0.3 20181105
 * Add optional hardware serial when GPIO13(Rx) and GPIO15(Tx) are selected removing hardware serial from GPIO01(Tx) and GPIO03(Rx) (#4288)

This was incorporated into the master branch as of 6.4.0.

Sorry for Template missing,

after I change to core 2.5.2

it has no reboot as in log, Thank you for your support.

if I want to contribute this as new feature of Tasmota. how I can do that ?

00:00:00 Project capteur Sonoff Version 6.5.0(sonoff)-2_5_0
00:00:00 WIF: Connecting to AP1 wsa in mode 11N as sonoff...
00:00:04 WIF: Connected
00:00:04 HTP: Web server active on sonoff with IP address 192.168.1.146
14:39:36 LOG: SerialLog 2, WebLog 2, SysLog 0, LogHost , LogPort 514, TelePeriod 15
14:39:36 RSL: tele/sonoff/attributes = {"Uptime":"0T00:00:29","SleepMode":"Dynamic","Sleep":50,"LoadAvg":24,"AP":1,"SSId":"wsa","BSSId":"78:44:76:E4:4E:90","Channel":11,"RSSI":88,"LinkCount":1,"Downtime":"0T00:00:04"}
14:39:36 RSL: tele/sonoff/telemetry = {"ts":1565185176000 ,"values":{"ANALOG_A1":10,"PM_Total":51.241,"PM_Frequency":50.02,"PM_Active_L1":0,"PM_Active_L2":0,"PM_Active_L3":0,"PM_ReActive_L1":-0,"PM_ReActive_L2":0,"PM_ReActive_L3":0,"PM_PF_L1":null,"PM_PF_L2":null,"PM_PF_L3":null,"PM_Volt_L1":118,"PM_Volt_L2":0,"PM_Volt_L3":118,"PM_Current_L1":0.000,"PM_Current_L2":0.000,"PM_Current_L3":0.000}}
14:39:51 RSL: tele/sonoff/attributes = {"Uptime":"0T00:00:44","SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"AP":1,"SSId":"wsa","BSSId":"78:44:76:E4:4E:90","Channel":11,"RSSI":94,"LinkCount":1,"Downtime":"0T00:00:04"}
14:39:51 RSL: tele/sonoff/telemetry = {"ts":1565185191000 ,"values":{"ANALOG_A1":3,"PM_Total":51.241,"PM_Frequency":50.01,"PM_Active_L1":0,"PM_Active_L2":0,"PM_Active_L3":0,"PM_ReActive_L1":-0,"PM_ReActive_L2":0,"PM_ReActive_L3":0,"PM_PF_L1":null,"PM_PF_L2":null,"PM_PF_L3":null,"PM_Volt_L1":118,"PM_Volt_L2":0,"PM_Volt_L3":118,"PM_Current_L1":0.000,"PM_Current_L2":0.000,"PM_Current_L3":0.000}}
14:40:06 RSL: tele/sonoff/attributes = {"Uptime":"0T00:00:59","SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"AP":1,"SSId":"wsa","BSSId":"78:44:76:E4:4E:90","Channel":11,"RSSI":98,"LinkCount":1,"Downtime":"0T00:00:04"}
14:40:06 RSL: tele/sonoff/telemetry = {"ts":1565185206000 ,"values":{"ANALOG_A1":8,"PM_Total":51.241,"PM_Frequency":50.01,"PM_Active_L1":0,"PM_Active_L2":0,"PM_Active_L3":0,"PM_ReActive_L1":-0,"PM_ReActive_L2":0,"PM_ReActive_L3":0,"PM_PF_L1":null,"PM_PF_L2":null,"PM_PF_L3":null,"PM_Volt_L1":118,"PM_Volt_L2":0,"PM_Volt_L3":119,"PM_Current_L1":0.000,"PM_Current_L2":0.000,"PM_Current_L3":0.000}}
14:40:21 RSL: tele/sonoff/attributes = {"Uptime":"0T00:01:14","SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"AP":1,"SSId":"wsa","BSSId":"78:44:76:E4:4E:90","Channel":11,"RSSI":94,"LinkCount":1,"Downtime":"0T00:00:04"}
14:40:21 RSL: tele/sonoff/telemetry = {"ts":1565185221000 ,"values":{"ANALOG_A1":3,"PM_Total":51.241,"PM_Frequency":50.04,"PM_Active_L1":0,"PM_Active_L2":0,"PM_Active_L3":0,"PM_ReActive_L1":-0,"PM_ReActive_L2":0,"PM_ReActive_L3":0,"PM_PF_L1":null,"PM_PF_L2":null,"PM_PF_L3":null,"PM_Volt_L1":118,"PM_Volt_L2":0,"PM_Volt_L3":118,"PM_Current_L1":0.000,"PM_Current_L2":0.000,"PM_Current_L3":0.000}}
14:40:36 RSL: tele/sonoff/attributes = {"Uptime":"0T00:01:29","SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"AP":1,"SSId":"wsa","BSSId":"78:44:76:E4:4E:90","Channel":11,"RSSI":94,"LinkCount":1,"Downtime":"0T00:00:04"}
14:40:36 RSL: tele/sonoff/telemetry = {"ts":1565185236000 ,"values":{"ANALOG_A1":3,"PM_Total":51.241,"PM_Frequency":50.04,"PM_Active_L1":0,"PM_Active_L2":0,"PM_Active_L3":0,"PM_ReActive_L1":-0,"PM_ReActive_L2":0,"PM_ReActive_L3":0,"PM_PF_L1":null,"PM_PF_L2":null,"PM_PF_L3":null,"PM_Volt_L1":118,"PM_Volt_L2":0,"PM_Volt_L3":118,"PM_Current_L1":0.000,"PM_Current_L2":0.000,"PM_Current_L3":0.000}}
14:40:51 RSL: tele/sonoff/attributes = {"Uptime":"0T00:01:44","SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"AP":1,"SSId":"wsa","BSSId":"78:44:76:E4:4E:90","Channel":11,"RSSI":92,"LinkCount":1,"Downtime":"0T00:00:04"}

if I want to contribute this as new feature of Tasmota. how I can do that ?

Please, do a pull request adding this as a new driver. Thanks

Thanks for this feature.

Maybe a hint about your crash, you are allocating a lot of data on the stack in PM2200Show(): 17x33 bytes, with 4 bytes alignment that makes at least 612 bytes on the stack. Please keep in mind the ESP8266 stack is 4k (actually it's a bit more as there is a continuation stack as well).

Can you please split the snprintf_P() and add each value one after the other reusing the same buffer.

Here is an example from xdrv_08_serial_bridge.ino:

      Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\""));
      for (uint32_t i = 0; i < serial_bridge_in_byte_counter; i++) {
        ResponseAppend_P(PSTR("%02x"), serial_bridge_buffer[i]);
      }
      ResponseAppend_P(PSTR("\"}"));

@sensorthai

Thanks for your interest on this. We would love to have that added to tasmota. If you need assistance on making a Pull Request, please just ask.

Was this page helpful?
0 / 5 - 0 ratings