olliiiver / sml_parser

Low memory C++ library to parse Smart Message Language (SML) data from smart meters.
GNU Lesser General Public License v2.1
34 stars 15 forks source link

reading ISKRA MT 681 fails #25

Closed xamfa closed 1 year ago

xamfa commented 1 year ago

First: great work on the parser! It's just what I was looking for.

I have an ISKRA MT681 and can't get the parser to produce meaningfull output. With my own device, I am struggeling to read in the data correctly since I get CRC errors - although the data does look ok and I managed to decode Wh value by hand and it checks out.

Now I startet to use sample data from here, see file below.

CRC checks out and message is parsed correctly but I get strange data back. For example for the manufacturer code I can see "ISK" in the data, but I get "c" as output.

As far as I understood your code and was able to debug it, there seems to be an offset in the list position when I call the handlers (smlOBISManufacturer) as per your examples.

Would you mind checking the sample data?

(I am new to github, so please give me a hint if the information given is not sufficient.)

edl21example.zip

I hestitated to upload the sample data of my device since I noticed the public key is masked in your sample data. However, if I would do that, I suspect it's hard to debug the CRC issue?

fbx71 commented 1 year ago

Hi @mentesix. If have an ISK meter, too. Your attached file works for me.

START
 LISTSTART on level 1 with 6 nodes
  Data 6 (length = 4, octet string): 04 71 A7 47
  Data 5 (length = 1, unsigned int): 00
  Data 4 (length = 1, unsigned int): 00
  LISTSTART on level 2 with 2 nodes
   Data 2 (length = 2, unsigned int): 01 01
   LISTSTART on level 3 with 6 nodes
    Data 6 (empty)
    Data 5 (empty)
    Data 4 (length = 4, octet string): 01 7B 37 C1
    Data 3 (length = 10, octet string): 09 01 49 53 4B 00 03 C2 A0 A0
    Data 2 (empty)
    Data 1 (empty)
   LISTEND
   back to previous list
  back to previous list
  Data 2 (length = 2, unsigned int): 39 20
 End of block at level 1
 back to previous list
 LISTSTART on level 1 with 6 nodes
  Data 6 (length = 4, octet string): 04 71 A7 48
  Data 5 (length = 1, unsigned int): 00
  Data 4 (length = 1, unsigned int): 00
  LISTSTART on level 2 with 2 nodes
   Data 2 (length = 2, unsigned int): 07 01
   LISTSTART on level 3 with 7 nodes
    Data 7 (empty)
    Data 6 (length = 10, octet string): 09 01 49 53 4B 00 03 C2 A0 A0
    Data 5 (length = 6, octet string): 01 00 62 0A FF FF
    LISTSTART on level 4 with 2 nodes
     Data 2 (length = 1, unsigned int): 01
     Data 1 (length = 4, unsigned int): 02 2B 94 67
    LISTEND on level 4
    back to previous list
    LISTSTART on level 4 with 10 nodes
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 81 81 C7 82 03 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (empty)
      Data 3 (empty)
      Data 2 (length = 3, octet string): 49 53 4B
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 00 00 09 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (empty)
      Data 3 (empty)
      Data 2 (length = 10, octet string): 09 01 49 53 4B 00 03 C2 A0 A0
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 01 08 00 FF
      Data 6 (length = 4, unsigned int): 00 00 01 82
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1E
      Data 3 (length = 1, signed int): FF
      Data 2 (length = 8, signed int): 00 00 00 00 05 7A EC 91
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 01 08 01 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1E
      Data 3 (length = 1, signed int): FF
      Data 2 (length = 8, signed int): 00 00 00 00 05 7A EC 91
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 01 08 02 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1E
      Data 3 (length = 1, signed int): FF
      Data 2 (length = 8, signed int): 00 00 00 00 00 00 00 00
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 10 07 00 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1B
      Data 3 (length = 1, signed int): 00
      Data 2 (length = 4, signed int): 00 00 00 ED
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 24 07 00 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1B
      Data 3 (length = 1, signed int): 00
      Data 2 (length = 4, signed int): 00 00 00 4F
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 38 07 00 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1B
      Data 3 (length = 1, signed int): 00
      Data 2 (length = 4, signed int): 00 00 00 89
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 01 00 4C 07 00 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (length = 1, unsigned int): 1B
      Data 3 (length = 1, signed int): 00
      Data 2 (length = 4, signed int): 00 00 00 15
      Data 1 (empty)
     LISTEND
     back to previous list
     LISTSTART on level 5 with 7 nodes
      Data 7 (length = 6, octet string): 81 81 C7 82 05 FF
      Data 6 (empty)
      Data 5 (empty)
      Data 4 (empty)
      Data 3 (empty)
      Data (length = 48): 63 40 B3 53 9D 70 E4 6A C9 4B 38 79 94 59 18 40 1C 8C 8B EE 99 8C D9 4C 24 65 C4 6E 12 B9 6E 66 04 84 2A D3 B0 20 82 0D E7 D7 AA 6B 97 3B B9 59
      Data 2 (empty)
      Data 1 (empty)
     LISTEND
     back to previous list
    back to previous list
    Data 2 (empty)
    Data 1 (length = 2, unsigned int): 96 C9
   LISTEND on level 3
   back to previous list
  back to previous list
 End of block at level 1
  LISTSTART on level 2 with 6 nodes
   Data 6 (length = 4, octet string): 04 71 A7 49
   Data 5 (length = 1, unsigned int): 00
   Data 4 (length = 1, unsigned int): 00
   LISTSTART on level 3 with 2 nodes
    Data 2 (length = 2, unsigned int): 02 01
    LISTSTART on level 4 with 1 nodes
     Data 1 (empty)
    LISTEND
    back to previous list
   back to previous list
   Data 2 (length = 2, unsigned int): F8 41
  End of block at level 2
  back to previous list
 back to previous list
Received checksum: 1671
Calculated checksum: 1671
>>> FINAL! Checksum OK
>>> Manufacturer.............: ISK
>>> Power T1    (1-0:1.8.1)..: 9194203.300 Wh
>>> Power T1+T2 (1-0:1.8.0)..: 9194203.300 Wh
>>> Watt        (1-0:15.7.0).: -2.000 W
xamfa commented 1 year ago

Hi @fbx71 , this is realy strange - my debug output looks exactly like yours but the handler returns garbage values. I used the handler code from the esp32_receiver example running on ESP32 in debug-mode. As far as I can tell void smlOBISManufacturer(unsigned char *str, int maxSize) seems to jump past the "ISK" in the listBuffer and I don't know why...

Can you share the code you used?

Nevermind, I found the bug in my code - at first I did not understand the logic behind the for-loop checking the handlers and I included the if-clause in the loop (subconcious):

if (currentState == SML_LISTEND)
    { 
      // check handlers on last received list
      for (iHandler = 0; OBISHandlers[iHandler].Handler != 0 && !(smlOBISCheck(OBISHandlers[iHandler].OBIS)); iHandler++)
      {
        if (OBISHandlers[iHandler].Handler != 0)
        {
          OBISHandlers[iHandler].Handler();
        }
      }
    }

instead it should be:

if (s == SML_LISTEND) {
      /* check handlers on last received list */
      for (iHandler = 0; OBISHandlers[iHandler].Handler != 0 &&
                         !(smlOBISCheck(OBISHandlers[iHandler].OBIS));
           iHandler++)
        ;
      if (OBISHandlers[iHandler].Handler != 0) {
        OBISHandlers[iHandler].Handler();
      }
    }

as all examples suggest...

Thank you for the help! - I did not spot this error despite some hours of comparing my code with example... talk about operation-blindness.