psvanstrom / esphome-p1reader

ESPHome custom component for reading P1 data from electricity meters.
MIT License
267 stars 116 forks source link

Missing data #24

Closed johanvh83 closed 2 years ago

johanvh83 commented 2 years ago

Thanks for your nice 'project'. I've build your esphome p1 reader and it seems it works because I receive data in the logs:

[12:45:52][I][crc:276]: Telegram read. CRC: 5895 = 5895. PASS = YES [12:45:52][D][sensor:113]: 'Cumulative Active Import': Sending state 0.00000 kWh with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Cumulative Active Export': Sending state 0.00000 kWh with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Cumulative Reactive Import': Sending state 0.00000 kvarh with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Cumulative Reactive Export': Sending state 0.00000 kvarh with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Active Import': Sending state 0.43500 kW with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Active Export': Sending state 0.00000 kW with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Reactive Import': Sending state 0.00000 kvar with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Reactive Export': Sending state 0.00000 kvar with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Active Import Phase 1': Sending state 0.43500 kW with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Active Export Phase 1': Sending state 0.00000 kW with 3 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Reactive Import Phase 1': Sending state 0.00000 kvar with 3 decimals of accuracy [12:45:52][D][sensor:113]: 'Momentary Reactive Export Phase 1': Sending state 0.00000 kvar with 3 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: 'Voltage Phase 1': Sending state 232.80000 V with 3 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy [12:45:52][D][sensor:113]: 'Current Phase 1': Sending state 3.66000 A with 3 decimals of accuracy [12:45:52][D][sensor:113]: '': Sending state 0.00000 with 0 decimals of accuracy

As you see most entries contain the value 0.00000 except Momentary Active Import, Voltage Phase 1 and Current Phase 1. Any idea why the other information does not appear. My smart meter is type Sagemcom S211 (same as T211 but for 1 single phase)

I live in Belgium and based what I found on https://jensd.be/1205/linux/data-lezen-van-de-belgische-digitale-meter-met-de-p1-poort the data on the P1 ports seems different:

0-0:96.1.4(xxxxx) 0-0:96.1.1(xxxxxxxxxxxxxxxxxxxxxxxxxxxx) 0-0:1.0.0(210204163628W) 1-0:1.8.1(000439.094kWh) 1-0:1.8.2(000435.292kWh) 1-0:2.8.1(000035.805kWh) 1-0:2.8.2(000012.156kWh) 0-0:96.14.0(0001) 1-0:1.7.0(00.233kW) 1-0:2.7.0(00.000kW) 1-0:21.7.0(00.233kW) 1-0:22.7.0(00.000kW) 1-0:32.7.0(236.2V) 1-0:31.7.0(002.04A) 0-0:96.3.10(1) 0-0:17.0.0(999.9kW) 1-0:31.4.0(999A) 0-0:96.13.0() 0-1:24.1.0(003) 0-1:96.1.1(xxxxxxxxxxxxxxxxxxxxxxxxxxxx) 0-1:24.4.0(1) 0-1:24.2.3(210204163500W)(00343.925*m3) !1374 /FLU5\253xxxxxx_A

The obiscodes are corresponding with: "0-0:1.0.0": "Timestamp", "0-0:96.3.10": "Switch electricity", "0-1:24.4.0": "Switch gas", "0-0:96.1.1": "Meter serial electricity", "0-1:96.1.1": "Meter serial gas", "0-0:96.14.0": "Current rate (1=day,2=night)", "1-0:1.8.1": "Rate 1 (day) - total consumption", "1-0:1.8.2": "Rate 2 (night) - total consumption", "1-0:2.8.1": "Rate 1 (day) - total production", "1-0:2.8.2": "Rate 2 (night) - total production", "1-0:21.7.0": "L1 consumption", "1-0:41.7.0": "L2 consumption", "1-0:61.7.0": "L3 consumption", "1-0:1.7.0": "All phases consumption", "1-0:22.7.0": "L1 production", "1-0:42.7.0": "L2 production", "1-0:62.7.0": "L3 production", "1-0:2.7.0": "All phases production", "1-0:32.7.0": "L1 voltage", "1-0:52.7.0": "L2 voltage", "1-0:72.7.0": "L3 voltage", "1-0:31.7.0": "L1 current", "1-0:51.7.0": "L2 current", "1-0:71.7.0": "L3 current", "0-1:24.2.3": "Gas consumption"

psvanstrom commented 2 years ago

Interesting, could be a parse problem. I will take a look 👍

psvanstrom commented 2 years ago

Ok, so checking the obis codes, this looks like a simple fix by just updating the code that parses the codes.

For example, you have two cumulative import / export values, one pair for rate 1 (1.8.1 / 2.8.1) and one for rate 2 (1.8.2 / 2.8.2) while the Swedish specification only have one rate (1.8.0 / 2.8.0).

The empty values such as '': Sending state 0.00000 with 0 decimals of accuracy are for the second and third phases that your meter doesn't have.

So what you can do is to define a couple of new sensors for rate 1 / rate 2 like this to the ParsedMessage class:

class ParsedMessage {
  public:
    double cumulativeActiveImportRate1;
    double cumulativeActiveImportRate2;
    double cumulativeActiveExportRate1;
    double cumulativeActiveExportRate2;
    ...

and to the P1Reader class:

  public:
    Sensor *cumulativeActiveImportRate1 = new Sensor();
    Sensor *cumulativeActiveImportRate2 = new Sensor();
    Sensor *cumulativeActiveExportRate1 = new Sensor();
    Sensor *cumulativeActiveExportRate2 = new Sensor();

update the parse logic:

void parseRow(ParsedMessage* parsed, char* obisCode, char* value) {
      if (strncmp(obisCode, "1.8.1", 5) == 0) {
        parsed->cumulativeActiveImportRate1 = atof(value);

      } else if (strncmp(obisCode, "1.8.2", 5) == 0) {
        parsed->cumulativeActiveImportRate2 = atof(value);

      } else if (strncmp(obisCode, "2.8.1", 5) == 0) {
        parsed->cumulativeActiveExportRate1 = atof(value);

      } else if (strncmp(obisCode, "2.8.2", 5) == 0) {
        parsed->cumulativeActiveExportRate2 = atof(value);
      ....

and finally add them to the yaml so that they are exposed as sensors:

sensor:
- platform: custom
  lambda: |-
    auto meter_sensor = new P1Reader(id(uart_bus));
    App.register_component(meter_sensor);
    return {
      meter_sensor->cumulativeActiveImportRate1,
      meter_sensor->cumulativeActiveExportRate2,
      meter_sensor->cumulativeActiveImportRate1,
      meter_sensor->cumulativeActiveExportRate2,
      ...

You could also remove all sensors and parse logic for the 2nd and 3rd phases as you don't have those: momentaryActiveImportL2, momentaryActiveImportL3 etc.