From 6305d3d37f84739e40a1b4d091ecaf6e74aeecf3 Mon Sep 17 00:00:00 2001 From: Nigel Dokter Date: Thu, 2 Mar 2017 19:05:17 +0100 Subject: [PATCH 1/2] finished match_telegram_specification --- dsmr_parser/exceptions.py | 4 ++++ dsmr_parser/parsers.py | 17 +++++++++++++---- test/test_match_telegram_specification.py | 6 +++++- test/test_parse_v2_2.py | 9 +++++++++ test/test_parse_v3.py | 9 +++++++++ test/test_parse_v4_2.py | 9 +++++++++ test/test_parse_v5.py | 9 +++++++++ 7 files changed, 58 insertions(+), 5 deletions(-) diff --git a/dsmr_parser/exceptions.py b/dsmr_parser/exceptions.py index a5fa8f4..4babfd6 100644 --- a/dsmr_parser/exceptions.py +++ b/dsmr_parser/exceptions.py @@ -4,3 +4,7 @@ class ParseError(Exception): class InvalidChecksumError(ParseError): pass + + +class TelegramSpecificationMatchError(ParseError): + pass diff --git a/dsmr_parser/parsers.py b/dsmr_parser/parsers.py index 6a9f465..7d238b7 100644 --- a/dsmr_parser/parsers.py +++ b/dsmr_parser/parsers.py @@ -4,16 +4,18 @@ from PyCRC.CRC16 import CRC16 from dsmr_parser.objects import MBusObject, CosemObject -from dsmr_parser.exceptions import ParseError, InvalidChecksumError +from dsmr_parser.exceptions import ParseError, InvalidChecksumError, \ + TelegramSpecificationMatchError logger = logging.getLogger(__name__) class TelegramParser(object): - def __init__(self, telegram_specification, apply_checksum_validation=True): + def __init__(self, telegram_specification=None, apply_checksum_validation=True): """ - :param telegram_specification: determines how the telegram is parsed + :param telegram_specification: determines how the telegram is parsed. + Will attempt to autodetect if omitted. :param apply_checksum_validation: validate checksum if applicable for telegram DSMR version (v4 and up). :type telegram_specification: dict @@ -39,8 +41,10 @@ def parse(self, telegram_data): .. } :raises ParseError: - :raises InvalidChecksumError: """ + if not self.telegram_specification: + self.telegram_specification = \ + match_telegram_specification(telegram_data) if self.apply_checksum_validation \ and self.telegram_specification['checksum_support']: @@ -118,6 +122,11 @@ def match_telegram_specification(telegram_data): else: return specification + raise TelegramSpecificationMatchError( + 'Could automatically match telegram specification. Make sure the data' + 'is not corrupt. Alternatively manually specify one.' + ) + class DSMRObjectParser(object): """ diff --git a/test/test_match_telegram_specification.py b/test/test_match_telegram_specification.py index 1385b82..6f5134f 100644 --- a/test/test_match_telegram_specification.py +++ b/test/test_match_telegram_specification.py @@ -1,5 +1,6 @@ import unittest +from dsmr_parser.exceptions import TelegramSpecificationMatchError from dsmr_parser.parsers import match_telegram_specification from dsmr_parser import telegram_specifications from test import example_telegrams @@ -7,7 +8,6 @@ class MatchTelegramSpecificationTest(unittest.TestCase): - def test_v2_2(self): assert match_telegram_specification(example_telegrams.TELEGRAM_V2_2) \ == telegram_specifications.V2_2 @@ -23,3 +23,7 @@ def test_v4_2(self): def test_v5(self): assert match_telegram_specification(example_telegrams.TELEGRAM_V5) \ == telegram_specifications.V5 + + def test_malformed_telegram(self): + with self.assertRaises(TelegramSpecificationMatchError): + match_telegram_specification(example_telegrams.TELEGRAM_V5[:-4]) diff --git a/test/test_parse_v2_2.py b/test/test_parse_v2_2.py index e7203ab..cba1a4d 100644 --- a/test/test_parse_v2_2.py +++ b/test/test_parse_v2_2.py @@ -12,6 +12,15 @@ class TelegramParserV2_2Test(unittest.TestCase): """ Test parsing of a DSMR v2.2 telegram. """ + def test_telegram_specification_matching(self): + parser = TelegramParser() + parser.parse(TELEGRAM_V2_2) + + self.assertEqual( + parser.telegram_specification, + telegram_specifications.V2_2 + ) + def test_parse(self): parser = TelegramParser(telegram_specifications.V2_2) result = parser.parse(TELEGRAM_V2_2) diff --git a/test/test_parse_v3.py b/test/test_parse_v3.py index c50a86e..c583835 100644 --- a/test/test_parse_v3.py +++ b/test/test_parse_v3.py @@ -12,6 +12,15 @@ class TelegramParserV3Test(unittest.TestCase): """ Test parsing of a DSMR v3 telegram. """ + def test_telegram_specification_matching(self): + parser = TelegramParser() + parser.parse(TELEGRAM_V3) + + self.assertEqual( + parser.telegram_specification, + telegram_specifications.V3 + ) + def test_parse(self): parser = TelegramParser(telegram_specifications.V3) result = parser.parse(TELEGRAM_V3) diff --git a/test/test_parse_v4_2.py b/test/test_parse_v4_2.py index 681783b..ba3ecbd 100644 --- a/test/test_parse_v4_2.py +++ b/test/test_parse_v4_2.py @@ -15,6 +15,15 @@ class TelegramParserV4_2Test(unittest.TestCase): """ Test parsing of a DSMR v4.2 telegram. """ + def test_telegram_specification_matching(self): + parser = TelegramParser() + parser.parse(TELEGRAM_V4_2) + + self.assertEqual( + parser.telegram_specification, + telegram_specifications.V4 + ) + def test_parse(self): parser = TelegramParser(telegram_specifications.V4) result = parser.parse(TELEGRAM_V4_2) diff --git a/test/test_parse_v5.py b/test/test_parse_v5.py index 550fde9..b26cb60 100644 --- a/test/test_parse_v5.py +++ b/test/test_parse_v5.py @@ -16,6 +16,15 @@ class TelegramParserV5Test(unittest.TestCase): """ Test parsing of a DSMR v5.x telegram. """ + def test_telegram_specification_matching(self): + parser = TelegramParser() + parser.parse(TELEGRAM_V5) + + self.assertEqual( + parser.telegram_specification, + telegram_specifications.V5 + ) + def test_parse(self): parser = TelegramParser(telegram_specifications.V5) result = parser.parse(TELEGRAM_V5) From d216996fe61088030edaab1d536fc29391ebd081 Mon Sep 17 00:00:00 2001 From: Nigel Dokter Date: Thu, 2 Mar 2017 19:15:19 +0100 Subject: [PATCH 2/2] updated changelog in preparation of v0.9 --- CHANGELOG.rst | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1d34527..8253177 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,10 @@ Change Log ---------- +**0.9** (2017-03-02) + +- allow the telegram specification to optionally be autodetected + **0.8** (2017-01-26) - added support for DSMR v3 diff --git a/setup.py b/setup.py index a4b5fdd..b8dc651 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ author='Nigel Dokter', author_email='nigeldokter@gmail.com', url='https://github.com/ndokter/dsmr_parser', - version='0.8', + version='0.9', packages=find_packages(), install_requires=[ 'pyserial>=3,<4',