diff --git a/dsmr_parser/__main__.py b/dsmr_parser/__main__.py index 8813731..8d9da8b 100644 --- a/dsmr_parser/__main__.py +++ b/dsmr_parser/__main__.py @@ -1,9 +1,9 @@ +from functools import partial import argparse import asyncio import logging -from functools import partial -from .protocol import create_dsmr_reader, create_tcp_dsmr_reader +from dsmr_parser.clients import create_dsmr_reader, create_tcp_dsmr_reader def console(): diff --git a/dsmr_parser/clients/__init__.py b/dsmr_parser/clients/__init__.py new file mode 100644 index 0000000..9b8a4b0 --- /dev/null +++ b/dsmr_parser/clients/__init__.py @@ -0,0 +1,5 @@ +from dsmr_parser.clients.settings import SERIAL_SETTINGS_V2_2, \ + SERIAL_SETTINGS_V4 +from dsmr_parser.clients.serial import SerialReader, AsyncSerialReader +from dsmr_parser.clients.protocol import create_dsmr_protocol, \ + create_dsmr_reader, create_tcp_dsmr_reader diff --git a/dsmr_parser/protocol.py b/dsmr_parser/clients/protocol.py similarity index 91% rename from dsmr_parser/protocol.py rename to dsmr_parser/clients/protocol.py index 24c3184..26ff573 100644 --- a/dsmr_parser/protocol.py +++ b/dsmr_parser/clients/protocol.py @@ -6,10 +6,12 @@ from functools import partial from serial_asyncio import create_serial_connection -from . import telegram_specifications -from .exceptions import ParseError -from .parsers import TelegramParserV2_2, TelegramParserV4 -from .serial import (SERIAL_SETTINGS_V2_2, SERIAL_SETTINGS_V4, TelegramBuffer) +from dsmr_parser import telegram_specifications +from dsmr_parser.clients.telegram_buffer import TelegramBuffer +from dsmr_parser.exceptions import ParseError +from dsmr_parser.parsers import TelegramParserV2_2, TelegramParserV4 +from dsmr_parser.clients.settings import SERIAL_SETTINGS_V2_2, \ + SERIAL_SETTINGS_V4 def create_dsmr_protocol(dsmr_version, telegram_callback, loop=None): diff --git a/dsmr_parser/serial.py b/dsmr_parser/clients/serial.py similarity index 55% rename from dsmr_parser/serial.py rename to dsmr_parser/clients/serial.py index 93e31b9..f5fa6a9 100644 --- a/dsmr_parser/serial.py +++ b/dsmr_parser/clients/serial.py @@ -1,37 +1,19 @@ import asyncio import logging -import re import serial import serial_asyncio +from dsmr_parser.clients.telegram_buffer import TelegramBuffer from dsmr_parser.exceptions import ParseError from dsmr_parser.parsers import TelegramParser, TelegramParserV2_2, \ TelegramParserV4 +from dsmr_parser.clients.settings import SERIAL_SETTINGS_V2_2, \ + SERIAL_SETTINGS_V4 + logger = logging.getLogger(__name__) -SERIAL_SETTINGS_V2_2 = { - 'baudrate': 9600, - 'bytesize': serial.SEVENBITS, - 'parity': serial.PARITY_EVEN, - 'stopbits': serial.STOPBITS_ONE, - 'xonxoff': 0, - 'rtscts': 0, - 'timeout': 20 -} - -SERIAL_SETTINGS_V4 = { - 'baudrate': 115200, - 'bytesize': serial.SEVENBITS, - 'parity': serial.PARITY_EVEN, - 'stopbits': serial.STOPBITS_ONE, - 'xonxoff': 0, - 'rtscts': 0, - 'timeout': 20 -} - - class SerialReader(object): PORT_KEY = 'port' @@ -104,57 +86,4 @@ class AsyncSerialReader(SerialReader): logger.warning('Failed to parse telegram: %s', e) -class TelegramBuffer(object): - """ - Used as a buffer for a stream of telegram data. Constructs full telegram - strings from the buffered data and returns it. - """ - def __init__(self): - self._buffer = '' - - def get_all(self): - """ - Remove complete telegrams from buffer and yield them. - :rtype generator: - """ - for telegram in self._find_telegrams(): - self._remove(telegram) - yield telegram - - def append(self, data): - """ - Add telegram data to buffer. - :param str data: chars, lines or full telegram strings of telegram data - """ - self._buffer += data - - def _remove(self, telegram): - """ - Remove telegram from buffer and incomplete data preceding it. This - is easier than validating the data before adding it to the buffer. - :param str telegram: - :return: - """ - # Remove data leading up to the telegram and the telegram itself. - index = self._buffer.index(telegram) + len(telegram) - - self._buffer = self._buffer[index:] - - def _find_telegrams(self): - """ - Find complete telegrams in buffer from start ('/') till ending - checksum ('!AB12\r\n'). - :rtype: list - """ - # - Match all characters after start of telegram except for the start - # itself again '^\/]+', which eliminates incomplete preceding telegrams. - # - Do non greedy match using '?' so start is matched up to the first - # checksum that's found. - # - The checksum is optional '{0,4}' because not all telegram versions - # support it. - return re.findall( - r'\/[^\/]+?\![A-F0-9]{0,4}\r\n', - self._buffer, - re.DOTALL - ) diff --git a/dsmr_parser/clients/settings.py b/dsmr_parser/clients/settings.py new file mode 100644 index 0000000..2c2677c --- /dev/null +++ b/dsmr_parser/clients/settings.py @@ -0,0 +1,22 @@ +import serial + + +SERIAL_SETTINGS_V2_2 = { + 'baudrate': 9600, + 'bytesize': serial.SEVENBITS, + 'parity': serial.PARITY_EVEN, + 'stopbits': serial.STOPBITS_ONE, + 'xonxoff': 0, + 'rtscts': 0, + 'timeout': 20 +} + +SERIAL_SETTINGS_V4 = { + 'baudrate': 115200, + 'bytesize': serial.SEVENBITS, + 'parity': serial.PARITY_EVEN, + 'stopbits': serial.STOPBITS_ONE, + 'xonxoff': 0, + 'rtscts': 0, + 'timeout': 20 +} diff --git a/dsmr_parser/clients/telegram_buffer.py b/dsmr_parser/clients/telegram_buffer.py new file mode 100644 index 0000000..78a98eb --- /dev/null +++ b/dsmr_parser/clients/telegram_buffer.py @@ -0,0 +1,57 @@ +import re + + +class TelegramBuffer(object): + """ + Used as a buffer for a stream of telegram data. Constructs full telegram + strings from the buffered data and returns it. + """ + + def __init__(self): + self._buffer = '' + + def get_all(self): + """ + Remove complete telegrams from buffer and yield them. + :rtype generator: + """ + for telegram in self._find_telegrams(): + self._remove(telegram) + yield telegram + + def append(self, data): + """ + Add telegram data to buffer. + :param str data: chars, lines or full telegram strings of telegram data + """ + self._buffer += data + + def _remove(self, telegram): + """ + Remove telegram from buffer and incomplete data preceding it. This + is easier than validating the data before adding it to the buffer. + :param str telegram: + :return: + """ + # Remove data leading up to the telegram and the telegram itself. + index = self._buffer.index(telegram) + len(telegram) + + self._buffer = self._buffer[index:] + + def _find_telegrams(self): + """ + Find complete telegrams in buffer from start ('/') till ending + checksum ('!AB12\r\n'). + :rtype: list + """ + # - Match all characters after start of telegram except for the start + # itself again '^\/]+', which eliminates incomplete preceding telegrams. + # - Do non greedy match using '?' so start is matched up to the first + # checksum that's found. + # - The checksum is optional '{0,4}' because not all telegram versions + # support it. + return re.findall( + r'\/[^\/]+?\![A-F0-9]{0,4}\r\n', + self._buffer, + re.DOTALL + ) diff --git a/dsmr_parser/parsers.py b/dsmr_parser/parsers.py index a215a98..d36cdb6 100644 --- a/dsmr_parser/parsers.py +++ b/dsmr_parser/parsers.py @@ -3,9 +3,9 @@ import re from PyCRC.CRC16 import CRC16 -from .objects import MBusObject, MBusObjectV2_2, CosemObject -from .exceptions import ParseError, InvalidChecksumError -from .obis_references import GAS_METER_READING +from dsmr_parser.objects import MBusObject, MBusObjectV2_2, CosemObject +from dsmr_parser.exceptions import ParseError, InvalidChecksumError +from dsmr_parser.obis_references import GAS_METER_READING logger = logging.getLogger(__name__) diff --git a/dsmr_parser/telegram_specifications.py b/dsmr_parser/telegram_specifications.py index 958153b..adc5e62 100644 --- a/dsmr_parser/telegram_specifications.py +++ b/dsmr_parser/telegram_specifications.py @@ -1,8 +1,8 @@ from decimal import Decimal -from . import obis_references as obis -from .parsers import CosemParser, ValueParser, MBusParser -from .value_types import timestamp +from dsmr_parser import obis_references as obis +from dsmr_parser.parsers import CosemParser, ValueParser, MBusParser +from dsmr_parser.value_types import timestamp """ diff --git a/test/test_protocol.py b/test/test_protocol.py index d779bc7..71137e2 100644 --- a/test/test_protocol.py +++ b/test/test_protocol.py @@ -5,7 +5,7 @@ import unittest from dsmr_parser import obis_references as obis from dsmr_parser import telegram_specifications from dsmr_parser.parsers import TelegramParserV2_2 -from dsmr_parser.protocol import DSMRProtocol +from dsmr_parser.clients.protocol import DSMRProtocol TELEGRAM_V2_2 = ( diff --git a/test/test_telegram_buffer.py b/test/test_telegram_buffer.py index 7ad28ee..ef1cb4b 100644 --- a/test/test_telegram_buffer.py +++ b/test/test_telegram_buffer.py @@ -1,6 +1,6 @@ import unittest -from dsmr_parser.serial import TelegramBuffer +from dsmr_parser.clients.telegram_buffer import TelegramBuffer from test.example_telegrams import TELEGRAM_V2_2, TELEGRAM_V4_2