Edl21 platform crashes

Hi there,
in Home Assistant 2021.2.3 there is a bug with the edl21 platform.
I use the Weidmann Electronics USB IR Reader.
If I set the following in configuration.yaml:

sensor:
  - platform: edl21
    serial_port: /dev/ttyUSB0

I got the following error in corelog:

2021-02-23 21:25:25 ERROR (MainThread) [homeassistant] Error doing job: Exception in callback SerialTransport._read_ready()
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/local/lib/python3.8/site-packages/serial_asyncio/__init__.py", line 119, in _read_ready
    self._protocol.data_received(data)
  File "/usr/local/lib/python3.8/site-packages/sml/asyncio.py", line 61, in data_received
    res = self.parse_frame(self._buf)
  File "/usr/local/lib/python3.8/site-packages/sml/__init__.py", line 415, in parse_frame
    obj = SmlFrame(SmlBase.__unescape(frame[8:-8-padding]))
  File "/usr/local/lib/python3.8/site-packages/sml/__init__.py", line 377, in __init__
    self.append(SmlMessage(self.bits))
  File "/usr/local/lib/python3.8/site-packages/sml/__init__.py", line 316, in __init__
    raise SmlParserError('CRC16 mismatch')
sml.SmlParserError: CRC16 mismatch

The Devicedata was read only once before crashing.
Any hints to get rid of this?

thanks,
Torben

I have the same problem, the reason might be a faulty implementation of the checksum on the sending side (that should be the smart meter).
Some hints I found (sorry german):


or also

Hi rheinlaender,

thanks for your reply!
German is no problem.
I´m a native german :wink:
(Du bist dem Namen nach auch deutsch?)
Unfortunately the linked posts could not help. The update to Core 2021.3.2 did not bring any improvement either. There is no other choice than to hope that someone will fix the problems in the EDL21 code.

Ja ich bin Deutscher :wink:
But to continue in english: I have a feeling - based on what I read in the links - there might be a problem with the meter itself not sending the right checksum. Are you using an ISKRA MT175 or MT176?

I have the ISKRA MT631.
With older versions of HA it worked like a charm.
I try to find a solution without these crc checks an post it here if it workes :wink:

Ah, interesting that it worked before. I dont have a setup which easily allows me to change the code (and dont have much time at the moment). One idea would be that older versions didnt check the CRC)

I have traced it down to a problem with pysml. The pysml lib does assume the CRC 16 is always 16 bit long. But for values < 256 the serialization of the ISK does - correctly I guess - store it with a 1 byte serialization only.
I have set up a unit test for that with the faulty package and the patch I have done does not show the error anymore.
Not sure how I can test it within hassio but I will inform the pysml lib owner about it.

1 Like

This is the pysml patch which should work:

diff --git a/sml/__init__.py b/sml/__init__.py
index 3c26e01..d25c8a8 100644
--- a/sml/__init__.py
+++ b/sml/__init__.py
@@ -303,7 +303,9 @@ class SmlMessage(dict):
         if tag != 7 or length != 6 or tlsize != 1:
             raise SmlParserError('Message does not start with 0x76')
 
-        values = self._read_list(length)
+        values,lastLength = self._read_list(length)
+        # the last key is the crc, but it may consume different number of bytes (if the CRC is smaller than 256 it is serialised in 1 byte only)
+        crcLength=lastLength
         for key, val in zip(self.__FIELDS, values):
             self[key] = val
 
@@ -312,7 +314,7 @@ class SmlMessage(dict):
 
         end = self._bits.pos
         msg_bytes = self._bits[start:end].bytes
-        if Crc.crc16(msg_bytes[:-4]) != self['crc16']:
+        if Crc.crc16(msg_bytes[:-(crcLength+1)]) != self['crc16']:
             raise SmlParserError('CRC16 mismatch')
 
         self['messageBody'] = SmlChoice.create(self.__CHOICES,
@@ -340,6 +342,7 @@ class SmlMessage(dict):
 
     def _read_list(self, count: int, nesting: int = 0) -> list:
         res = []
+        lastLength=0
         logger.debug("%s[*] List of %d items", nesting * ' ', count)
 
         for i in range(count):
@@ -347,7 +350,7 @@ class SmlMessage(dict):
 
             tag, length, tlsize = self._read_tag_length()
             logger.debug("%s[+] Tag: %#x, Len: %d", nesting * ' ', tag, length)
-
+            if length > 0: lastLength = length
             if tag == 0 and length == 0:
                 value = None
             elif tag == 0 and length >= tlsize:
@@ -357,7 +360,7 @@ class SmlMessage(dict):
             elif tag == 6 and length > tlsize:
                 value = self._bits.read('uintbe:%d' % ((length - tlsize) * 8))
             elif tag == 7 and length > 0:
-                value = self._read_list(length, nesting + 1)
+                value,length = self._read_list(length, nesting + 1)
             else:
                 raise SmlParserError('Unknown TL field')
 
@@ -365,7 +368,7 @@ class SmlMessage(dict):
             res.append(value)
 
         assert len(res) == count
-        return res
+        return res,lastLength
 
 
 class SmlFrame(list):
@@ -411,10 +414,12 @@ class SmlBase:
 
             frame = match.group(0)
             padding = frame[-3]
-            if padding < 4 and Crc.verify_fcs(frame):
-                obj = SmlFrame(SmlBase.__unescape(frame[8:-8-padding]))
-                return [match.end(), obj]
-
+            try:
+                if padding < 4 and Crc.verify_fcs(frame):
+                    obj = SmlFrame(SmlBase.__unescape(frame[8:-8-padding]))
+                    return [match.end(), obj]
+            except:
+                return [match.end()]
             start = match.start()
             assert match.end() > end
             end = match.end()

Hallo, wo füge ich den Patch ein? MFG

I’m really new to Home Assistant and also wanted to ask how I can implement the patch. And did you already ask the pysml lib owner to fix the issue?

Me too, also looking for the patch for this, my EDL21 setup worked find until recently, can only assume its the same error

Should be fixed in the 2021.5 core release according to the ChangeLog (" Bump pysml to 0.0.5 (@mtdcr - #49014) ([edl21 docs]

Unfortunally its not fixed yet.
Today i made the core update to 2021.5.
The Issue still exists.
But I found a dirty way to fix it anymore with the patch above in this thread.

I dont know how to apply this patch because the binary “patch” isnt present inside the core.
But I made the changes manually and it seems to work.

I continue to watch it and write my findings here.

Interesting. It is definately fixed for me. Ran since I last posted and not one CRC16 entry in the log, the data also looks fine. Before I had thousands of exceptions.

I am also having the ISKRA MT631 + Weidmann Elektronik Schreib-/Lesekopf USB and
HA is: Container Version 2021.9.4.
All I get is one relevant sensor (positive_active_energy_total), but not the current usage or so. 2 more sensors are created but not relevant (metering_point_id_1 and negative_active_energy_total).
The pin is entered and the normal display is showing what it should.
Have you done any initialization steps from command line or anyelse but configuring it like that:

sensor:
  - platform: edl21
    serial_port: /dev/ttyUSB0

I am not getting any errors, but have expected more informations out of the integration.

In addition I have changed the debug level to “sml: debug”. But not sure what to do with these informations now.

Regards
Lukas

Hi,
it is not sufficient to disable the PIN to get the full data set. I think i do have the same model and at the first try i also received only the (rounded) total energy.

In the smart meters menu there is another option labeled “Inf” (“Info”) which has to be switched to ON to receive the full data.

Hope this works for you as well,
Michael

To give you more reassurance: I have basically the same config.
And I also think the solution is in the config of your meter, maybe this can help you (also points to the manual of the meter)
https://wiki.volkszaehler.org/hardware/channels/meters/power/edl-ehz/iskraemeco_mt631