From c7ed4acb034c44ce47eaf944654b0fcc8a10a895 Mon Sep 17 00:00:00 2001 From: Ronald Pijnacker Date: Thu, 30 Dec 2021 20:23:58 +0100 Subject: [PATCH] Refactor into separate file --- dsmr_parser/clients/protocol.py | 32 ++++--------- dsmr_parser/clients/rfxtrx_protocol.py | 62 ++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 dsmr_parser/clients/rfxtrx_protocol.py diff --git a/dsmr_parser/clients/protocol.py b/dsmr_parser/clients/protocol.py index 567b0f4..4e6d85d 100644 --- a/dsmr_parser/clients/protocol.py +++ b/dsmr_parser/clients/protocol.py @@ -16,6 +16,13 @@ from dsmr_parser.clients.settings import SERIAL_SETTINGS_V2_2, \ def create_dsmr_protocol(dsmr_version, telegram_callback, loop=None, **kwargs): """Creates a DSMR asyncio protocol.""" + protocol = _create_dsmr_protocol(dsmr_version, telegram_callback, + DSMRProtocol, loop, **kwargs) + return protocol + + +def _create_dsmr_protocol(dsmr_version, telegram_callback, protocol loop=None, **kwargs): + """Creates a DSMR asyncio protocol.""" if dsmr_version == '2.2': specification = telegram_specifications.V2_2 @@ -39,7 +46,7 @@ def create_dsmr_protocol(dsmr_version, telegram_callback, loop=None, **kwargs): raise NotImplementedError("No telegram parser found for version: %s", dsmr_version) - protocol = partial(DSMRProtocol, loop, TelegramParser(specification), + protocol = partial(protocol, loop, TelegramParser(specification), telegram_callback=telegram_callback, **kwargs) return protocol, serial_settings @@ -142,26 +149,3 @@ class DSMRProtocol(asyncio.Protocol): async def wait_closed(self): """Wait until connection is closed.""" await self._closed.wait() - - -PACKETTYPE_DSMR = 0x62 -SUBTYPE_P1 = 0x01 - -class RFXtrxDSMRProtocol(DSMRProtocol): - - remaining_data = b'' - - def data_received(self, data): - """Add incoming data to buffer.""" - - data = self.remaining_data + data - - while (len(data) > 0 and (packetlength := data[0]+1) <= len(data)): - packettype = data[1] - subtype = data[2] - if (packettype == PACKETTYPE_DSMR and subtype == SUBTYPE_P1): - dsmr_data = data[4:packetlength] - super().data_received(dsmr_data) - data = data[packetlength:] - - self.remaining_data = data diff --git a/dsmr_parser/clients/rfxtrx_protocol.py b/dsmr_parser/clients/rfxtrx_protocol.py new file mode 100644 index 0000000..b8a347d --- /dev/null +++ b/dsmr_parser/clients/rfxtrx_protocol.py @@ -0,0 +1,62 @@ +"""Asyncio protocol implementation for handling telegrams over a RFXtrx connection .""" + +from functools import partial +import asyncio + +from serial_asyncio import create_serial_connection + +from .protocol import DSMRProtocol, _create_dsmr_protocol + + +def create_rfxtrx_dsmr_protocol(dsmr_version, telegram_callback, loop=None, **kwargs): + """Creates a DSMR asyncio protocol.""" + protocol = _create_dsmr_protocol(dsmr_version, telegram_callback, + RFXtrxDSMRProtocol, loop, **kwargs) + return protocol + + +def create_rfxtrx_dsmr_reader(port, dsmr_version, telegram_callback, loop=None): + """Creates a DSMR asyncio protocol coroutine using a RFXtrx serial port.""" + protocol, serial_settings = create_rfxtrx_dsmr_protocol( + dsmr_version, telegram_callback, loop=None) + serial_settings['url'] = port + + conn = create_serial_connection(loop, protocol, **serial_settings) + return conn + + +def create_rfxtrx_tcp_dsmr_reader(host, port, dsmr_version, + telegram_callback, loop=None, + keep_alive_interval=None): + """Creates a DSMR asyncio protocol coroutine using a RFXtrx TCP connection.""" + if not loop: + loop = asyncio.get_event_loop() + protocol, _ = create_rfxtrx_dsmr_protocol( + dsmr_version, telegram_callback, loop=loop, + keep_alive_interval=keep_alive_interval) + conn = loop.create_connection(protocol, host, port) + return conn + + +PACKETTYPE_DSMR = 0x62 +SUBTYPE_P1 = 0x01 + + +class RFXtrxDSMRProtocol(DSMRProtocol): + + remaining_data = b'' + + def data_received(self, data): + """Add incoming data to buffer.""" + + data = self.remaining_data + data + + while (len(data) > 0 and (packetlength := data[0]+1) <= len(data)): + packettype = data[1] + subtype = data[2] + if (packettype == PACKETTYPE_DSMR and subtype == SUBTYPE_P1): + dsmr_data = data[4:packetlength] + super().data_received(dsmr_data) + data = data[packetlength:] + + self.remaining_data = data