diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8c24591..d539d2b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ Change Log ---------- +**0.30** (2021-08-18) +- Add support for Swedish smart meters (`pull request #86 `_). + +**0.29** (2021-04-18) +- Add value and unit properties to ProfileGenericObject to make sure that code like iterators that rely on that do not break (`pull request #71 `_). +Remove deprecated asyncio coroutine decorator (`pull request #76 `_). + **0.28** (2021-02-21) - Optional keep alive monitoring for TCP/IP connections (`pull request #73 `_). - Catch parse errors in TelegramParser, ignore lines that can not be parsed (`pull request #74 `_). diff --git a/dsmr_parser/__main__.py b/dsmr_parser/__main__.py index a9fbaa0..a24a6a2 100644 --- a/dsmr_parser/__main__.py +++ b/dsmr_parser/__main__.py @@ -16,8 +16,8 @@ def console(): help='alternatively connect using TCP host.') parser.add_argument('--port', default=None, help='TCP port to use for connection') - parser.add_argument('--version', default='2.2', choices=['2.2', '4', '5', '5B', '5L'], - help='DSMR version (2.2, 4, 5, 5B, 5L)') + parser.add_argument('--version', default='2.2', choices=['2.2', '4', '5', '5B', '5L', '5S'], + help='DSMR version (2.2, 4, 5, 5B, 5L, 5S)') parser.add_argument('--verbose', '-v', action='count') args = parser.parse_args() diff --git a/dsmr_parser/clients/protocol.py b/dsmr_parser/clients/protocol.py index 06ff997..f520b59 100644 --- a/dsmr_parser/clients/protocol.py +++ b/dsmr_parser/clients/protocol.py @@ -35,6 +35,9 @@ def create_dsmr_protocol(dsmr_version, telegram_callback, loop=None, **kwargs): elif dsmr_version == "5L": specification = telegram_specifications.LUXEMBOURG_SMARTY serial_settings = SERIAL_SETTINGS_V5 + elif dsmr_version == "5S": + specification = telegram_specifications.SWEDEN + serial_settings = SERIAL_SETTINGS_V5 else: raise NotImplementedError("No telegram parser found for version: %s", dsmr_version) diff --git a/dsmr_parser/obis_name_mapping.py b/dsmr_parser/obis_name_mapping.py index bf00f13..4028890 100644 --- a/dsmr_parser/obis_name_mapping.py +++ b/dsmr_parser/obis_name_mapping.py @@ -52,7 +52,9 @@ EN = { obis.BELGIUM_HOURLY_GAS_METER_READING: 'BELGIUM_HOURLY_GAS_METER_READING', obis.LUXEMBOURG_EQUIPMENT_IDENTIFIER: 'LUXEMBOURG_EQUIPMENT_IDENTIFIER', obis.LUXEMBOURG_ELECTRICITY_USED_TARIFF_GLOBAL: 'LUXEMBOURG_ELECTRICITY_USED_TARIFF_GLOBAL', - obis.LUXEMBOURG_ELECTRICITY_DELIVERED_TARIFF_GLOBAL: 'LUXEMBOURG_ELECTRICITY_DELIVERED_TARIFF_GLOBAL' + obis.LUXEMBOURG_ELECTRICITY_DELIVERED_TARIFF_GLOBAL: 'LUXEMBOURG_ELECTRICITY_DELIVERED_TARIFF_GLOBAL', + obis.SWEDEN_ELECTRICITY_USED_TARIFF_GLOBAL: 'SWEDEN_ELECTRICITY_USED_TARIFF_GLOBAL', + obis.SWEDEN_ELECTRICITY_DELIVERED_TARIFF_GLOBAL: 'SWEDEN_ELECTRICITY_DELIVERED_TARIFF_GLOBAL', } REVERSE_EN = dict([(v, k) for k, v in EN.items()]) diff --git a/dsmr_parser/obis_references.py b/dsmr_parser/obis_references.py index fe8952e..5ac3b66 100644 --- a/dsmr_parser/obis_references.py +++ b/dsmr_parser/obis_references.py @@ -66,3 +66,5 @@ BELGIUM_HOURLY_GAS_METER_READING = r'\d-\d:24\.2\.3.+?\r\n' # Different code, s LUXEMBOURG_EQUIPMENT_IDENTIFIER = r'\d-\d:42\.0\.0.+?\r\n' # Logical device name LUXEMBOURG_ELECTRICITY_USED_TARIFF_GLOBAL = r'\d-\d:1\.8\.0.+?\r\n' # Total imported energy register (P+) LUXEMBOURG_ELECTRICITY_DELIVERED_TARIFF_GLOBAL = r'\d-\d:2\.8\.0.+?\r\n' # Total exported energy register (P-) +SWEDEN_ELECTRICITY_USED_TARIFF_GLOBAL = r'\d-\d:1\.8\.0.+?\r\n' # Total imported energy register (P+) +SWEDEN_ELECTRICITY_DELIVERED_TARIFF_GLOBAL = r'\d-\d:2\.8\.0.+?\r\n' # Total exported energy register (P-) diff --git a/dsmr_parser/telegram_specifications.py b/dsmr_parser/telegram_specifications.py index b06e4f4..4e59f51 100644 --- a/dsmr_parser/telegram_specifications.py +++ b/dsmr_parser/telegram_specifications.py @@ -156,3 +156,28 @@ LUXEMBOURG_SMARTY['objects'].update({ obis.LUXEMBOURG_ELECTRICITY_USED_TARIFF_GLOBAL: CosemParser(ValueParser(Decimal)), obis.LUXEMBOURG_ELECTRICITY_DELIVERED_TARIFF_GLOBAL: CosemParser(ValueParser(Decimal)), }) + +# Source: https://www.energiforetagen.se/globalassets/energiforetagen/det-erbjuder-vi/kurser-och-konferenser/elnat/branschrekommendation-lokalt-granssnitt-v2_0-201912.pdf +SWEDEN = { + 'checksum_support': True, + 'objects': { + obis.P1_MESSAGE_HEADER: CosemParser(ValueParser(str)), + obis.P1_MESSAGE_TIMESTAMP: CosemParser(ValueParser(timestamp)), + obis.SWEDEN_ELECTRICITY_USED_TARIFF_GLOBAL: CosemParser(ValueParser(Decimal)), + obis.SWEDEN_ELECTRICITY_DELIVERED_TARIFF_GLOBAL: CosemParser(ValueParser(Decimal)), + obis.CURRENT_ELECTRICITY_USAGE: CosemParser(ValueParser(Decimal)), + obis.CURRENT_ELECTRICITY_DELIVERY: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_ACTIVE_POWER_L1_NEGATIVE: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_ACTIVE_POWER_L2_NEGATIVE: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_ACTIVE_POWER_L3_NEGATIVE: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_VOLTAGE_L1: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_VOLTAGE_L2: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_VOLTAGE_L3: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_CURRENT_L1: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_CURRENT_L2: CosemParser(ValueParser(Decimal)), + obis.INSTANTANEOUS_CURRENT_L3: CosemParser(ValueParser(Decimal)), + } +} diff --git a/setup.py b/setup.py index 0551d71..7ad7c68 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( author_email='nigel@nldr.net', license='MIT', url='https://github.com/ndokter/dsmr_parser', - version='0.28', + version='0.30', packages=find_packages(exclude=('test', 'test.*')), install_requires=[ 'pyserial>=3,<4',