added telegram CRC verification
This commit is contained in:
@@ -6,51 +6,77 @@ import pytz
|
||||
|
||||
from dsmr_parser import obis_references as obis
|
||||
from dsmr_parser import telegram_specifications
|
||||
from dsmr_parser.exceptions import InvalidChecksumError, ParseError
|
||||
from dsmr_parser.objects import CosemObject, MBusObject
|
||||
from dsmr_parser.parsers import TelegramParser
|
||||
from dsmr_parser.parsers import TelegramParser, TelegramParserV4
|
||||
|
||||
TELEGRAM_V4_2 = [
|
||||
'1-3:0.2.8(42)',
|
||||
'0-0:1.0.0(161113205757W)',
|
||||
'0-0:96.1.1(1231231231231231231231231231231231)',
|
||||
'1-0:1.8.1(001511.267*kWh)',
|
||||
'1-0:1.8.2(001265.173*kWh)',
|
||||
'1-0:2.8.1(000000.000*kWh)',
|
||||
'1-0:2.8.2(000000.000*kWh)',
|
||||
'0-0:96.14.0(0001)',
|
||||
'1-0:1.7.0(00.235*kW)',
|
||||
'1-0:2.7.0(00.000*kW)',
|
||||
'0-0:96.7.21(00015)',
|
||||
'0-0:96.7.9(00007)',
|
||||
('1-0:99.97.0(3)(0-0:96.7.19)(000103180420W)(0000237126*s)'
|
||||
'(000101000001W)(2147483647*s)(000101000001W)(2147483647*s)'),
|
||||
'1-0:32.32.0(00000)',
|
||||
'1-0:52.32.0(00000)',
|
||||
'1-0:72.32.0(00000)',
|
||||
'1-0:32.36.0(00000)',
|
||||
'1-0:52.36.0(00000)',
|
||||
'1-0:72.36.0(00000)',
|
||||
'0-0:96.13.1()',
|
||||
'0-0:96.13.0()',
|
||||
'1-0:31.7.0(000*A)',
|
||||
'1-0:51.7.0(000*A)',
|
||||
'1-0:71.7.0(000*A)',
|
||||
'1-0:21.7.0(00.095*kW)',
|
||||
'1-0:22.7.0(00.000*kW)',
|
||||
'1-0:41.7.0(00.025*kW)',
|
||||
'1-0:42.7.0(00.000*kW)',
|
||||
'1-0:61.7.0(00.115*kW)',
|
||||
'1-0:62.7.0(00.000*kW)',
|
||||
'0-1:24.1.0(003)',
|
||||
'0-1:96.1.0(3404856892390357246729543587524029)',
|
||||
'0-1:24.2.1(161113200000W)(00915.219*m3)',
|
||||
'!5D83',
|
||||
'/KFM5KAIFA-METER\r\n',
|
||||
'\r\n',
|
||||
'1-3:0.2.8(42)\r\n',
|
||||
'0-0:1.0.0(161113205757W)\r\n',
|
||||
'0-0:96.1.1(3960221976967177082151037881335713)\r\n',
|
||||
'1-0:1.8.1(001581.123*kWh)\r\n',
|
||||
'1-0:1.8.2(001435.706*kWh)\r\n',
|
||||
'1-0:2.8.1(000000.000*kWh)\r\n',
|
||||
'1-0:2.8.2(000000.000*kWh)\r\n',
|
||||
'0-0:96.14.0(0002)\r\n',
|
||||
'1-0:1.7.0(02.027*kW)\r\n',
|
||||
'1-0:2.7.0(00.000*kW)\r\n',
|
||||
'0-0:96.7.21(00015)\r\n',
|
||||
'0-0:96.7.9(00007)\r\n',
|
||||
'1-0:99.97.0(3)(0-0:96.7.19)(000104180320W)(0000237126*s)(000101000001W)'
|
||||
'(2147583646*s)(000102000003W)(2317482647*s)\r\n',
|
||||
'1-0:32.32.0(00000)\r\n',
|
||||
'1-0:52.32.0(00000)\r\n',
|
||||
'1-0:72.32.0(00000)\r\n',
|
||||
'1-0:32.36.0(00000)\r\n',
|
||||
'1-0:52.36.0(00000)\r\n',
|
||||
'1-0:72.36.0(00000)\r\n',
|
||||
'0-0:96.13.1()\r\n',
|
||||
'0-0:96.13.0()\r\n',
|
||||
'1-0:31.7.0(000*A)\r\n',
|
||||
'1-0:51.7.0(006*A)\r\n',
|
||||
'1-0:71.7.0(002*A)\r\n',
|
||||
'1-0:21.7.0(00.170*kW)\r\n',
|
||||
'1-0:22.7.0(00.000*kW)\r\n',
|
||||
'1-0:41.7.0(01.247*kW)\r\n',
|
||||
'1-0:42.7.0(00.000*kW)\r\n',
|
||||
'1-0:61.7.0(00.209*kW)\r\n',
|
||||
'1-0:62.7.0(00.000*kW)\r\n',
|
||||
'0-1:24.1.0(003)\r\n',
|
||||
'0-1:96.1.0(4819243993373755377509728609491464)\r\n',
|
||||
'0-1:24.2.1(161129200000W)(00981.443*m3)\r\n',
|
||||
'!6796\r\n'
|
||||
]
|
||||
|
||||
|
||||
class TelegramParserV4_2Test(unittest.TestCase):
|
||||
""" Test parsing of a DSMR v4.2 telegram. """
|
||||
|
||||
def test_valid(self):
|
||||
# No exception is raised.
|
||||
TelegramParserV4.validate_telegram_checksum(
|
||||
TELEGRAM_V4_2
|
||||
)
|
||||
|
||||
def test_invalid(self):
|
||||
# Remove one the electricty used data value. This causes the checksum to
|
||||
# not match anymore.
|
||||
telegram = [line
|
||||
for line in TELEGRAM_V4_2
|
||||
if '1-0:1.8.1' not in line]
|
||||
|
||||
with self.assertRaises(InvalidChecksumError):
|
||||
TelegramParserV4.validate_telegram_checksum(telegram)
|
||||
|
||||
def test_missing_checksum(self):
|
||||
# Remove the checksum value causing a ParseError.
|
||||
telegram = TELEGRAM_V4_2[:-1]
|
||||
|
||||
with self.assertRaises(ParseError):
|
||||
TelegramParserV4.validate_telegram_checksum(telegram)
|
||||
|
||||
def test_parse(self):
|
||||
parser = TelegramParser(telegram_specifications.V4)
|
||||
result = parser.parse(TELEGRAM_V4_2)
|
||||
@@ -72,13 +98,13 @@ class TelegramParserV4_2Test(unittest.TestCase):
|
||||
assert isinstance(result[obis.ELECTRICITY_USED_TARIFF_1], CosemObject)
|
||||
assert result[obis.ELECTRICITY_USED_TARIFF_1].unit == 'kWh'
|
||||
assert isinstance(result[obis.ELECTRICITY_USED_TARIFF_1].value, Decimal)
|
||||
assert result[obis.ELECTRICITY_USED_TARIFF_1].value == Decimal('1511.267')
|
||||
assert result[obis.ELECTRICITY_USED_TARIFF_1].value == Decimal('1581.123')
|
||||
|
||||
# ELECTRICITY_USED_TARIFF_2 (1-0:1.8.2)
|
||||
assert isinstance(result[obis.ELECTRICITY_USED_TARIFF_2], CosemObject)
|
||||
assert result[obis.ELECTRICITY_USED_TARIFF_2].unit == 'kWh'
|
||||
assert isinstance(result[obis.ELECTRICITY_USED_TARIFF_2].value, Decimal)
|
||||
assert result[obis.ELECTRICITY_USED_TARIFF_2].value == Decimal('1265.173')
|
||||
assert result[obis.ELECTRICITY_USED_TARIFF_2].value == Decimal('1435.706')
|
||||
|
||||
# ELECTRICITY_DELIVERED_TARIFF_1 (1-0:2.8.1)
|
||||
assert isinstance(result[obis.ELECTRICITY_DELIVERED_TARIFF_1], CosemObject)
|
||||
@@ -96,19 +122,19 @@ class TelegramParserV4_2Test(unittest.TestCase):
|
||||
assert isinstance(result[obis.ELECTRICITY_ACTIVE_TARIFF], CosemObject)
|
||||
assert result[obis.ELECTRICITY_ACTIVE_TARIFF].unit is None
|
||||
assert isinstance(result[obis.ELECTRICITY_ACTIVE_TARIFF].value, str)
|
||||
assert result[obis.ELECTRICITY_ACTIVE_TARIFF].value == '0001'
|
||||
assert result[obis.ELECTRICITY_ACTIVE_TARIFF].value == '0002'
|
||||
|
||||
# EQUIPMENT_IDENTIFIER (0-0:96.1.1)
|
||||
assert isinstance(result[obis.EQUIPMENT_IDENTIFIER], CosemObject)
|
||||
assert result[obis.EQUIPMENT_IDENTIFIER].unit is None
|
||||
assert isinstance(result[obis.EQUIPMENT_IDENTIFIER].value, str)
|
||||
assert result[obis.EQUIPMENT_IDENTIFIER].value == '1231231231231231231231231231231231'
|
||||
assert result[obis.EQUIPMENT_IDENTIFIER].value == '3960221976967177082151037881335713'
|
||||
|
||||
# CURRENT_ELECTRICITY_USAGE (1-0:1.7.0)
|
||||
assert isinstance(result[obis.CURRENT_ELECTRICITY_USAGE], CosemObject)
|
||||
assert result[obis.CURRENT_ELECTRICITY_USAGE].unit == 'kW'
|
||||
assert isinstance(result[obis.CURRENT_ELECTRICITY_USAGE].value, Decimal)
|
||||
assert result[obis.CURRENT_ELECTRICITY_USAGE].value == Decimal('0.235')
|
||||
assert result[obis.CURRENT_ELECTRICITY_USAGE].value == Decimal('2.027')
|
||||
|
||||
# CURRENT_ELECTRICITY_DELIVERY (1-0:2.7.0)
|
||||
assert isinstance(result[obis.CURRENT_ELECTRICITY_DELIVERY], CosemObject)
|
||||
@@ -178,19 +204,19 @@ class TelegramParserV4_2Test(unittest.TestCase):
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE], CosemObject)
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE].unit == 'kW'
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE].value, Decimal)
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE].value == Decimal('0.095')
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L1_POSITIVE].value == Decimal('0.170')
|
||||
|
||||
# INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE (1-0:41.7.0)
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE], CosemObject)
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE].unit == 'kW'
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE].value, Decimal)
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE].value == Decimal('0.025')
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L2_POSITIVE].value == Decimal('1.247')
|
||||
|
||||
# INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE (1-0:61.7.0)
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE], CosemObject)
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE].unit == 'kW'
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE].value, Decimal)
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE].value == Decimal('0.115')
|
||||
assert result[obis.INSTANTANEOUS_ACTIVE_POWER_L3_POSITIVE].value == Decimal('0.209')
|
||||
|
||||
# INSTANTANEOUS_ACTIVE_POWER_L1_NEGATIVE (1-0:22.7.0)
|
||||
assert isinstance(result[obis.INSTANTANEOUS_ACTIVE_POWER_L1_NEGATIVE], CosemObject)
|
||||
@@ -214,13 +240,13 @@ class TelegramParserV4_2Test(unittest.TestCase):
|
||||
assert isinstance(result[obis.EQUIPMENT_IDENTIFIER_GAS], CosemObject)
|
||||
assert result[obis.EQUIPMENT_IDENTIFIER_GAS].unit is None
|
||||
assert isinstance(result[obis.EQUIPMENT_IDENTIFIER_GAS].value, str)
|
||||
assert result[obis.EQUIPMENT_IDENTIFIER_GAS].value == '3404856892390357246729543587524029'
|
||||
assert result[obis.EQUIPMENT_IDENTIFIER_GAS].value == '4819243993373755377509728609491464'
|
||||
|
||||
# HOURLY_GAS_METER_READING (0-1:24.2.1)
|
||||
assert isinstance(result[obis.HOURLY_GAS_METER_READING], MBusObject)
|
||||
assert result[obis.HOURLY_GAS_METER_READING].unit == 'm3'
|
||||
assert isinstance(result[obis.HOURLY_GAS_METER_READING].value, Decimal)
|
||||
assert result[obis.HOURLY_GAS_METER_READING].value == Decimal('915.219')
|
||||
assert result[obis.HOURLY_GAS_METER_READING].value == Decimal('981.443')
|
||||
|
||||
# POWER_EVENT_FAILURE_LOG (99.97.0)
|
||||
# TODO to be implemented
|
||||
|
||||
Reference in New Issue
Block a user