diff --git a/test/resources/stubs/ets6_free.json b/test/resources/stubs/ets6_free.json index ccf1b0f..ed83105 100644 --- a/test/resources/stubs/ets6_free.json +++ b/test/resources/stubs/ets6_free.json @@ -8,7 +8,7 @@ "created_by": "ETS6", "schema_version": "22", "tool_version": "6.1.5686.0", - "xknxproject_version": "3.2.0", + "xknxproject_version": "3.3.0", "language_code": "de-DE" }, "communication_objects": {}, @@ -53,6 +53,7 @@ "address": "3", "project_uid": 16, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "", "comment": "" @@ -64,6 +65,7 @@ "address": "2", "project_uid": 14, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "", "comment": "" @@ -75,6 +77,7 @@ "address": "1", "project_uid": 12, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "", "comment": "" @@ -86,6 +89,7 @@ "address": "1025", "project_uid": 21, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "", "comment": "" diff --git a/test/resources/stubs/ets6_two_level.json b/test/resources/stubs/ets6_two_level.json index 1da22db..51e22a5 100644 --- a/test/resources/stubs/ets6_two_level.json +++ b/test/resources/stubs/ets6_two_level.json @@ -8,7 +8,7 @@ "created_by": "ETS6", "schema_version": "22", "tool_version": "6.1.5686.0", - "xknxproject_version": "3.2.0", + "xknxproject_version": "3.3.0", "language_code": "de-DE" }, "communication_objects": {}, @@ -59,6 +59,7 @@ "address": "0/1", "project_uid": 6, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "", "comment": "" @@ -70,6 +71,7 @@ "address": "1/1", "project_uid": 8, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "", "comment": "" diff --git a/test/resources/stubs/module-definition-test.json b/test/resources/stubs/module-definition-test.json index 6ad1ea9..fb04d83 100644 --- a/test/resources/stubs/module-definition-test.json +++ b/test/resources/stubs/module-definition-test.json @@ -8,7 +8,7 @@ "created_by": "ETS5", "schema_version": "20", "tool_version": "5.7.1428.39779", - "xknxproject_version": "3.2.0", + "xknxproject_version": "3.3.0", "language_code": "de-DE" }, "communication_objects": { @@ -246,6 +246,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.1/MD-2_M-1_MI-1_O-2-1_R-1" ], @@ -262,6 +263,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.1/MD-2_M-1_MI-1_O-2-2_R-3" ], @@ -278,6 +280,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.1/O-334_R-21" ], @@ -294,6 +297,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.1/MD-2_M-2_MI-1_O-2-2_R-3" ], @@ -310,6 +314,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.1/MD-2_M-2_MI-1_O-2-1_R-1" ], @@ -326,6 +331,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.2/MD-2_M-1_MI-1_O-2-2_R-3" ], @@ -342,6 +348,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.1/MD-2_M-1_MI-1_O-2-2_R-3", "1.1.1/MD-2_M-2_MI-1_O-2-2_R-3", diff --git a/test/resources/stubs/test_project-ets4.json b/test/resources/stubs/test_project-ets4.json index af0bbb1..78b47ea 100644 --- a/test/resources/stubs/test_project-ets4.json +++ b/test/resources/stubs/test_project-ets4.json @@ -8,7 +8,7 @@ "created_by": "ETS4", "schema_version": "11", "tool_version": "ETS 4.2.0 (Build 3884)", - "xknxproject_version": "3.2.0", + "xknxproject_version": "3.3.0", "language_code": "de-DE" }, "communication_objects": { @@ -199,6 +199,7 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "0.0.1/M-0083_A-0013-11-A9D6_O-0_R-10000", "0.0.2/M-0002_A-A061-14-BE27_O-10_R-485" @@ -216,6 +217,7 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "0.0.1/M-0083_A-0013-11-A9D6_O-5_R-10005", "0.0.2/M-0002_A-A061-14-BE27_O-71_R-1506" @@ -233,6 +235,7 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "0.0.1/M-0083_A-0013-11-A9D6_O-13_R-4", "0.0.2/M-0002_A-A061-14-BE27_O-10_R-485" diff --git a/test/resources/stubs/testprojekt-ets6-functions.json b/test/resources/stubs/testprojekt-ets6-functions.json index 2134b9a..f520ed4 100644 --- a/test/resources/stubs/testprojekt-ets6-functions.json +++ b/test/resources/stubs/testprojekt-ets6-functions.json @@ -8,7 +8,7 @@ "created_by": "ETS6", "schema_version": "22", "tool_version": "6.1.5686.0", - "xknxproject_version": "3.2.0", + "xknxproject_version": "3.3.0", "language_code": "de-DE" }, "communication_objects": {}, @@ -56,6 +56,7 @@ "main": 1, "sub": 1 }, + "data_secure": false, "communication_object_ids": [], "description": "Livingroom LivingroomLight", "comment": "" @@ -70,6 +71,7 @@ "main": 1, "sub": 1 }, + "data_secure": false, "communication_object_ids": [], "description": "Livingroom LivingroomLight", "comment": "" diff --git a/test/resources/stubs/xknx_test_project.json b/test/resources/stubs/xknx_test_project.json index 94c463d..2deba9d 100644 --- a/test/resources/stubs/xknx_test_project.json +++ b/test/resources/stubs/xknx_test_project.json @@ -2,13 +2,13 @@ "info": { "project_id": "P-0242", "name": "xknx test project", - "last_modified": "2023-05-05T14:02:49.64676Z", + "last_modified": "2023-09-29T21:48:57.7711452Z", "group_address_style": "ThreeLevel", "guid": "7aceb083-274e-4568-806f-b8f9df992873", "created_by": "ETS5", "schema_version": "20", "tool_version": "5.7.1428.39779", - "xknxproject_version": "3.2.0", + "xknxproject_version": "3.3.0", "language_code": null }, "communication_objects": { @@ -384,7 +384,112 @@ "transmit": true }, "group_address_links": [ - "2/1/23" + "2/1/23", + "7/1/2" + ] + }, + "1.1.7/MD-2_M-20_MI-1_O-2-2_R-3": { + "name": "RTR1 - 2 - Controller", + "number": 2, + "text": "RTR 1 (...) - Ausgang", + "function_text": "Command value - Heating", + "description": "", + "device_address": "1.1.7", + "dpts": [ + { + "main": 5, + "sub": 1 + } + ], + "object_size": "1 Byte", + "flags": { + "read": true, + "write": false, + "communication": true, + "update": true, + "read_on_init": false, + "transmit": true + }, + "group_address_links": [ + "7/1/1" + ] + }, + "1.1.7/MD-2_M-20_MI-1_O-5-0_R-17": { + "name": "RTR1 - 0 - RSM", + "number": 0, + "text": "RTR 1 (...) - Eingang", + "function_text": "Setpoint temperature - Active operating mode", + "description": "", + "device_address": "1.1.7", + "dpts": [ + { + "main": 9, + "sub": 1 + } + ], + "object_size": "2 Bytes", + "flags": { + "read": false, + "write": true, + "communication": true, + "update": true, + "read_on_init": false, + "transmit": false + }, + "group_address_links": [ + "7/1/0" + ] + }, + "1.1.7/MD-2_M-20_MI-1_O-5-10_R-18": { + "name": "RTR1 - 10 - RSM", + "number": 10, + "text": "RTR 1 (...) - Ausgang", + "function_text": "Setpoint temperature - Active operating mode - Status", + "description": "", + "device_address": "1.1.7", + "dpts": [ + { + "main": 9, + "sub": 1 + } + ], + "object_size": "2 Bytes", + "flags": { + "read": true, + "write": false, + "communication": true, + "update": true, + "read_on_init": false, + "transmit": true + }, + "group_address_links": [ + "7/0/0" + ] + }, + "1.1.7/MD-2_M-20_MI-1_O-7-1_R-45": { + "name": "RTR1 - 1 - Sensor", + "number": 1, + "text": "RTR 1 (...) - Eingang", + "function_text": "Room temperature - Measured value 1", + "description": "", + "device_address": "1.1.7", + "dpts": [ + { + "main": 9, + "sub": 1 + } + ], + "object_size": "2 Bytes", + "flags": { + "read": false, + "write": true, + "communication": true, + "update": true, + "read_on_init": false, + "transmit": true + }, + "group_address_links": [ + "7/1/2" ] } }, @@ -417,7 +522,8 @@ "devices": [ "1.1.0", "1.1.5", - "1.1.6" + "1.1.6", + "1.1.7" ], "medium_type": "Twisted Pair (TP)" } @@ -464,6 +570,20 @@ "1.1.6/O-9_R-9073", "1.1.6/O-18_R-7994" ] + }, + "1.1.7": { + "name": "Heating actuator 6-gang with controller", + "hardware_name": "Heizungsaktor 6fach mit Regler Secure", + "description": "", + "manufacturer_name": "GIRA Giersiepen", + "individual_address": "1.1.7", + "project_uid": 60, + "communication_object_ids": [ + "1.1.7/MD-2_M-20_MI-1_O-2-2_R-3", + "1.1.7/MD-2_M-20_MI-1_O-5-0_R-17", + "1.1.7/MD-2_M-20_MI-1_O-5-10_R-18", + "1.1.7/MD-2_M-20_MI-1_O-7-1_R-45" + ] } }, "group_addresses": { @@ -477,6 +597,7 @@ "main": 1, "sub": 8 }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-101_R-1578" ], @@ -493,6 +614,7 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-100_R-1577" ], @@ -509,6 +631,7 @@ "main": 1, "sub": 8 }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-71_R-1506" ], @@ -525,6 +648,7 @@ "main": 1, "sub": 8 }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-70_R-1505" ], @@ -541,6 +665,7 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-41_R-1434" ], @@ -557,6 +682,7 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-40_R-1433" ], @@ -573,6 +699,7 @@ "main": 1, "sub": 1 }, + "data_secure": false, "communication_object_ids": [ "1.1.5/O-4_R-1417" ], @@ -586,6 +713,7 @@ "address": "2/1/1", "project_uid": 43, "dpt": null, + "data_secure": false, "communication_object_ids": [], "description": "no dpt", "comment": "" @@ -600,6 +728,7 @@ "main": 9, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.6/O-0_R-665", "1.1.6/O-9_R-9073" @@ -617,6 +746,7 @@ "main": 9, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.6/O-9_R-9073", "1.1.6/O-18_R-7994" @@ -634,6 +764,7 @@ "main": 9, "sub": 1 }, + "data_secure": false, "communication_object_ids": [], "description": "temperature", "comment": "" @@ -648,6 +779,7 @@ "main": 9, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.6/O-9_R-9073" ], @@ -664,11 +796,81 @@ "main": 1, "sub": null }, + "data_secure": false, "communication_object_ids": [ "1.1.6/O-20_R-8108" ], "description": "", "comment": "" + }, + "7/0/0": { + "name": "ds 0", + "identifier": "GA-15", + "raw_address": 14336, + "address": "7/0/0", + "project_uid": 58, + "dpt": { + "main": 9, + "sub": 1 + }, + "data_secure": false, + "communication_object_ids": [ + "1.1.7/MD-2_M-20_MI-1_O-5-10_R-18" + ], + "description": "security: off (inherited from middle group)", + "comment": "" + }, + "7/1/0": { + "name": "ds 1", + "identifier": "GA-14", + "raw_address": 14592, + "address": "7/1/0", + "project_uid": 57, + "dpt": { + "main": 9, + "sub": 1 + }, + "data_secure": true, + "communication_object_ids": [ + "1.1.7/MD-2_M-20_MI-1_O-5-0_R-17" + ], + "description": "security: auto", + "comment": "" + }, + "7/1/1": { + "name": "ds 2", + "identifier": "GA-16", + "raw_address": 14593, + "address": "7/1/1", + "project_uid": 59, + "dpt": { + "main": 5, + "sub": 1 + }, + "data_secure": true, + "communication_object_ids": [ + "1.1.7/MD-2_M-20_MI-1_O-2-2_R-3" + ], + "description": "security: on", + "comment": "" + }, + "7/1/2": { + "name": "ds + non ds", + "identifier": "GA-17", + "raw_address": 14594, + "address": "7/1/2", + "project_uid": 64, + "dpt": { + "main": 9, + "sub": 1 + }, + "data_secure": false, + "communication_object_ids": [ + "1.1.6/O-18_R-7994", + "1.1.7/MD-2_M-20_MI-1_O-7-1_R-45" + ], + "description": "", + "comment": "" } }, "group_ranges": { @@ -729,6 +931,37 @@ "group_ranges": {} } } + }, + "7": { + "name": "DataSecureTest", + "address_start": 14336, + "address_end": 16383, + "group_addresses": [], + "comment": "", + "group_ranges": { + "7/0": { + "name": "Non-DS", + "address_start": 14336, + "address_end": 14591, + "group_addresses": [ + "7/0/0" + ], + "comment": "", + "group_ranges": {} + }, + "7/1": { + "name": "DS-Auto", + "address_start": 14592, + "address_end": 14847, + "group_addresses": [ + "7/1/0", + "7/1/1", + "7/1/2" + ], + "comment": "", + "group_ranges": {} + } + } } }, "locations": { diff --git a/test/resources/xknx_test_project.knxproj b/test/resources/xknx_test_project.knxproj index 313a002..57cf810 100644 Binary files a/test/resources/xknx_test_project.knxproj and b/test/resources/xknx_test_project.knxproj differ diff --git a/test/xml/test_parser.py b/test/xml/test_parser.py index dded9ba..79abf0a 100644 --- a/test/xml/test_parser.py +++ b/test/xml/test_parser.py @@ -37,7 +37,7 @@ def test_parse_project_ets5(): parser = XMLParser(knx_project_contents) parser.parse() - assert len(parser.group_addresses) == 13 + assert len(parser.group_addresses) == 17 parsed_gas = {ga.address for ga in parser.group_addresses} assert len(parsed_gas) == len(parser.group_addresses) assert parsed_gas == { @@ -54,11 +54,15 @@ def test_parse_project_ets5(): "2/1/21", "2/1/22", "2/1/23", + "7/0/0", + "7/1/0", + "7/1/1", + "7/1/2", } assert len(parser.areas) == 2 assert len(parser.areas[1].lines) == 2 - assert len(parser.areas[1].lines[1].devices) == 3 + assert len(parser.areas[1].lines[1].devices) == 4 assert len(parser.areas[1].lines[1].devices[0].additional_addresses) == 4 assert len(parser.areas[1].lines[1].devices[1].com_object_instance_refs) == 7 diff --git a/xknxproject/loader/project_loader.py b/xknxproject/loader/project_loader.py index 2116cfd..b2a1b41 100644 --- a/xknxproject/loader/project_loader.py +++ b/xknxproject/loader/project_loader.py @@ -141,6 +141,7 @@ def load( project_uid=int(project_uid) if project_uid else None, description=group_address_element.get("Description", ""), dpt=get_dpt_type(group_address_element.get("DatapointType")), + data_secure_key=group_address_element.get("Key"), comment=group_address_element.get("Comment", ""), style=group_address_style, ) diff --git a/xknxproject/models/knxproject.py b/xknxproject/models/knxproject.py index 41d5f9b..fadac77 100644 --- a/xknxproject/models/knxproject.py +++ b/xknxproject/models/knxproject.py @@ -75,6 +75,7 @@ class GroupAddress(TypedDict): address: str project_uid: int | None dpt: DPTType | None + data_secure: bool communication_object_ids: list[str] description: str comment: str diff --git a/xknxproject/models/models.py b/xknxproject/models/models.py index 4c5febe..6f029f4 100644 --- a/xknxproject/models/models.py +++ b/xknxproject/models/models.py @@ -22,6 +22,7 @@ def __init__( project_uid: int | None, description: str, dpt: DPTType | None, + data_secure_key: str | None, comment: str, style: GroupAddressStyle, ): @@ -32,6 +33,7 @@ def __init__( self.project_uid = project_uid self.description = description self.dpt = dpt + self.data_secure_key = data_secure_key # Key as base64 encoded string or None self.comment = comment self.style = style self.address = XMLGroupAddress.str_address(self.raw_address, self.style) diff --git a/xknxproject/xml/parser.py b/xknxproject/xml/parser.py index 500aca7..bee57c7 100644 --- a/xknxproject/xml/parser.py +++ b/xknxproject/xml/parser.py @@ -144,6 +144,7 @@ def parse(self, language: str | None = None) -> KNXProject: address=group_address.address, project_uid=group_address.project_uid, dpt=group_address.dpt, + data_secure=bool(group_address.data_secure_key), communication_object_ids=_com_object_ids, description=group_address.description, comment=html.unescape(rtf_to_text(group_address.comment)),