[SOLVED] Logging DSMR sensor?

Can you send your daemon? If I can get it to work locally I can run home assistant with debugpy and see where it fails.

Very crude python telegram daemon
import threading
import time


def on_new_client(c):

    VERSION = 40
    sleep_time = 5
    telegram = r"/ISk5\2MT382-1000\r\n\r\n1-3:0.2.8({version:d})\r\n0-0:1.0.0(101209113020W)\r\n0-0:96.1.1(4B384547303034303436333935353037)\r\n1-0:1.8.1(123456.789*kWh)\r\n1-0:1.8.2(123456.789*kWh)\r\n1-0:2.8.1(123456.789*kWh)\r\n1-0:2.8.2(123456.789*kWh)\r\n0-0:96.14.0(0002)\r\n1-0:1.7.0(01.193*kW)\r\n1-0:2.7.0(00.000*kW)\r\n0-0:17.0.0(016.1*kW)\r\n0-0:96.3.10(1)\r\n0-0:96.7.21(00004)\m0-0:96.7.9(00002)\r\n1-0:99.97.0(2)(0-0:96.7.19)(101208152415W)(0000000240*s)(101208151004W)(00000000301*s)\r\n1-0:32.32.0(00002)\r\n1-0:52.32.0(00001)\r\n1-0:72.32.0(00000)\r\n1-0:32.36.0(00000)\r\n1-0:52.36.0(00003)\r\n1-0:72.36.0(00000)\r\n0-0:96.13.1(3031203631203831)\r\n0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F)\r\n0-1:24.1.0(03)\r\n0-1:96.1.0(3232323241424344313233343536373839)\r\n0-1:24.2.1(101209110000W)(12785.123*m3)\r\n0-1:24.4.0(1)\r\n!522B"

    while True:
        try:
            with c:
                i = 0
                while not c._closed:
                    i += 1
                    sent = c.sendall(
                        telegram.format(
                            version=VERSION
                        ).encode())
                    print(f"Sent telegram {i:d}, sleeping {sleep_time:d}s.")
                    time.sleep(sleep_time)
        except ConnectionError as ex:
            # Make sure to recover and serve again for a reconnect
            print(f"A connection error occurred: {ex}")
            pass


if __name__ == '__main__':

    HOST = socket.getfqdn()
    HOST = socket.gethostbyname(HOST)
    PORT = 6638

    while True:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            try:
                s.bind((HOST, PORT))
                s.listen()

                s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
                s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
                s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 3)
                s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)

                print(f"Serving at {HOST:s} at port {PORT:d}")
                conn, addr = s.accept()
                print(f"Connected by  {addr}")

                t = threading.Thread(target=on_new_client, args=(conn,))
                t.start()
            except KeyboardInterrupt:
                pass
            finally:
                s.close()

Apparently symlinking does not work, cp -a does and now I have the custom_component loaded:

2020-10-18 19:29:11 WARNING (MainThread) [homeassistant.loader] You are using a custom integration for dsmr which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant.
2020-10-18 19:29:13 ERROR (MainThread) [custom_components.dsmr.config_flow] Error connecting to DSMR
Traceback (most recent call last):
  File "/config/custom_components/dsmr/config_flow.py", line 74, in validate_connect
    transport, protocol = await asyncio.create_task(reader_factory())
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1025, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1010, in create_connection
    sock = await self._connect_sock(
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 924, in _connect_sock
    await self.sock_connect(sock, address)
  File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 494, in sock_connect
    return await fut
  File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 526, in _sock_connect_cb
    raise OSError(err, f'Connect call failed {address}')

On with debugging…

So far I have been able to debug the config_flow.py file and it seems to try and determine the obis_ref.EQUIPMENT_IDENTIFIER on an empty self._telegram in DSMRConnection.equipment_identifier() through _validate_dsmr_connection() in async_step_import().

It seems to try it twice and then return self.async_abort() due to a CannotCommunicate exception.

This is all debugged against the dsmr custom_component taken from :label:tags/0.116.4.

Maybe a bit obvious, but are you sure the daemon is working correctly? By putting it in configuration.yaml and using real hardware it still doesn’t work?

The error is in your daemon. Don’t use a raw string for the telegram.

Alright, wasn’t aware of that, fixed my daemon to use strings and \r\n as line termination (apparently DSMR parser is quite strict on line endings). Now it seems to work.

The only problem now is that I can not revert to the standard implementation anymore. It keeps saying I am using a custom component. If I delete the custom component Home Assistant won’t start anymore since it than can not reference the folder of the custom component.

Do you know how to get back to the default homeassistant implementation for the dsmr integration?

Go to the integrations in the UI and delete the DSMR here. If you then reboot without integration in custom_components it should work.

1 Like

Thanks, that did the trick.

The final answer to this question

then would then be the following fragment:

logger:
  # Home Assistant default logging level
  default: warning
  logs:
    # DSMR related logging overrides
    # Home Assistant  DSMR integration
    homeassistant.components.dsmr: info
    # DSMR telegram parser library
    dsmr_parser: debug
    # And in case of a custom component to override the default dsmr integration:
    custom_components.dsmr: info

Two notes.

1:
I’m not sure

dsmr_parser: debug

Works in all cases, because in sensor.py it overrides log settings. That should however be removed from the code because there is no need to do that. When that is done, I think it’s good to add above line to the docs for dsmr

2:
Once you have it working, you can remove the entry from configuration.yaml because there is a ConfigEntry in core.config_entries.