DLMS-SPODES 0.87.12__py3-none-any.whl → 0.87.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. DLMS_SPODES/Values/EN/__init__.py +1 -1
  2. DLMS_SPODES/Values/EN/actors.py +8 -8
  3. DLMS_SPODES/Values/EN/relation_to_obis_names.py +387 -387
  4. DLMS_SPODES/Values/RU/__init__.py +1 -1
  5. DLMS_SPODES/Values/RU/actors.py +8 -8
  6. DLMS_SPODES/Values/RU/relation_to_obis_names.py +396 -396
  7. DLMS_SPODES/__init__.py +6 -6
  8. DLMS_SPODES/configEN.ini +126 -126
  9. DLMS_SPODES/config_parser.py +53 -53
  10. DLMS_SPODES/cosem_interface_classes/__class_init__.py +3 -3
  11. DLMS_SPODES/cosem_interface_classes/__init__.py +1 -1
  12. DLMS_SPODES/cosem_interface_classes/a_parameter.py +20 -20
  13. DLMS_SPODES/cosem_interface_classes/activity_calendar.py +254 -254
  14. DLMS_SPODES/cosem_interface_classes/arbitrator.py +105 -105
  15. DLMS_SPODES/cosem_interface_classes/association_ln/abstract.py +34 -34
  16. DLMS_SPODES/cosem_interface_classes/association_ln/authentication_mechanism_name.py +25 -25
  17. DLMS_SPODES/cosem_interface_classes/association_ln/mechanism_id.py +25 -25
  18. DLMS_SPODES/cosem_interface_classes/association_ln/method.py +5 -5
  19. DLMS_SPODES/cosem_interface_classes/association_ln/ver0.py +485 -485
  20. DLMS_SPODES/cosem_interface_classes/association_ln/ver1.py +133 -133
  21. DLMS_SPODES/cosem_interface_classes/association_ln/ver2.py +36 -36
  22. DLMS_SPODES/cosem_interface_classes/association_ln/ver3.py +4 -4
  23. DLMS_SPODES/cosem_interface_classes/association_sn/ver0.py +12 -12
  24. DLMS_SPODES/cosem_interface_classes/attr_indexes.py +12 -12
  25. DLMS_SPODES/cosem_interface_classes/clock.py +131 -131
  26. DLMS_SPODES/cosem_interface_classes/collection.py +2122 -2122
  27. DLMS_SPODES/cosem_interface_classes/cosem_interface_class.py +583 -583
  28. DLMS_SPODES/cosem_interface_classes/data.py +21 -21
  29. DLMS_SPODES/cosem_interface_classes/demand_register/ver0.py +59 -59
  30. DLMS_SPODES/cosem_interface_classes/disconnect_control.py +74 -74
  31. DLMS_SPODES/cosem_interface_classes/extended_register.py +27 -27
  32. DLMS_SPODES/cosem_interface_classes/gprs_modem_setup.py +43 -43
  33. DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver0.py +103 -103
  34. DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver1.py +40 -40
  35. DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver2.py +9 -9
  36. DLMS_SPODES/cosem_interface_classes/iec_hdlc_setup/ver0.py +11 -11
  37. DLMS_SPODES/cosem_interface_classes/iec_hdlc_setup/ver1.py +53 -53
  38. DLMS_SPODES/cosem_interface_classes/iec_local_port_setup.py +11 -11
  39. DLMS_SPODES/cosem_interface_classes/image_transfer/image_transfer_status.py +15 -15
  40. DLMS_SPODES/cosem_interface_classes/image_transfer/ver0.py +126 -126
  41. DLMS_SPODES/cosem_interface_classes/implementations/__init__.py +3 -3
  42. DLMS_SPODES/cosem_interface_classes/implementations/arbitrator.py +19 -19
  43. DLMS_SPODES/cosem_interface_classes/implementations/data.py +487 -487
  44. DLMS_SPODES/cosem_interface_classes/implementations/profile_generic.py +83 -83
  45. DLMS_SPODES/cosem_interface_classes/ipv4_setup.py +72 -72
  46. DLMS_SPODES/cosem_interface_classes/limiter.py +111 -111
  47. DLMS_SPODES/cosem_interface_classes/ln_pattern.py +333 -333
  48. DLMS_SPODES/cosem_interface_classes/modem_configuration/ver0.py +65 -65
  49. DLMS_SPODES/cosem_interface_classes/modem_configuration/ver1.py +39 -39
  50. DLMS_SPODES/cosem_interface_classes/ntp_setup/ver0.py +67 -67
  51. DLMS_SPODES/cosem_interface_classes/obis.py +23 -23
  52. DLMS_SPODES/cosem_interface_classes/overview.py +197 -197
  53. DLMS_SPODES/cosem_interface_classes/parameter.py +547 -547
  54. DLMS_SPODES/cosem_interface_classes/parameters.py +172 -172
  55. DLMS_SPODES/cosem_interface_classes/profile_generic/ver0.py +122 -122
  56. DLMS_SPODES/cosem_interface_classes/profile_generic/ver1.py +277 -277
  57. DLMS_SPODES/cosem_interface_classes/push_setup/ver0.py +12 -12
  58. DLMS_SPODES/cosem_interface_classes/push_setup/ver1.py +10 -10
  59. DLMS_SPODES/cosem_interface_classes/push_setup/ver2.py +166 -166
  60. DLMS_SPODES/cosem_interface_classes/register.py +45 -45
  61. DLMS_SPODES/cosem_interface_classes/register_activation/ver0.py +80 -80
  62. DLMS_SPODES/cosem_interface_classes/register_monitor.py +46 -46
  63. DLMS_SPODES/cosem_interface_classes/reports.py +70 -70
  64. DLMS_SPODES/cosem_interface_classes/schedule.py +176 -176
  65. DLMS_SPODES/cosem_interface_classes/script_table.py +87 -87
  66. DLMS_SPODES/cosem_interface_classes/security_setup/ver0.py +68 -68
  67. DLMS_SPODES/cosem_interface_classes/security_setup/ver1.py +158 -158
  68. DLMS_SPODES/cosem_interface_classes/single_action_schedule.py +50 -50
  69. DLMS_SPODES/cosem_interface_classes/special_days_table.py +84 -84
  70. DLMS_SPODES/cosem_interface_classes/tcp_udp_setup.py +42 -42
  71. DLMS_SPODES/cosem_pdu.py +93 -93
  72. DLMS_SPODES/enums.py +625 -625
  73. DLMS_SPODES/exceptions.py +106 -106
  74. DLMS_SPODES/firmwares.py +99 -99
  75. DLMS_SPODES/hdlc/frame.py +875 -875
  76. DLMS_SPODES/hdlc/sub_layer.py +54 -54
  77. DLMS_SPODES/literals.py +17 -17
  78. DLMS_SPODES/obis/__init__.py +1 -1
  79. DLMS_SPODES/obis/media_id.py +931 -931
  80. DLMS_SPODES/pardata.py +22 -22
  81. DLMS_SPODES/pdu_enums.py +98 -98
  82. DLMS_SPODES/relation_to_OBIS.py +465 -463
  83. DLMS_SPODES/settings.py +551 -551
  84. DLMS_SPODES/types/choices.py +142 -142
  85. DLMS_SPODES/types/common_data_types.py +2401 -2399
  86. DLMS_SPODES/types/cosem_service_types.py +109 -109
  87. DLMS_SPODES/types/implementations/arrays.py +25 -25
  88. DLMS_SPODES/types/implementations/bitstrings.py +97 -97
  89. DLMS_SPODES/types/implementations/double_long_usingneds.py +35 -35
  90. DLMS_SPODES/types/implementations/enums.py +57 -57
  91. DLMS_SPODES/types/implementations/integers.py +11 -11
  92. DLMS_SPODES/types/implementations/long_unsigneds.py +127 -127
  93. DLMS_SPODES/types/implementations/octet_string.py +11 -11
  94. DLMS_SPODES/types/implementations/structs.py +64 -64
  95. DLMS_SPODES/types/useful_types.py +677 -677
  96. {dlms_spodes-0.87.12.dist-info → dlms_spodes-0.87.15.dist-info}/METADATA +30 -30
  97. dlms_spodes-0.87.15.dist-info/RECORD +117 -0
  98. {dlms_spodes-0.87.12.dist-info → dlms_spodes-0.87.15.dist-info}/WHEEL +1 -1
  99. dlms_spodes-0.87.12.dist-info/RECORD +0 -117
  100. {dlms_spodes-0.87.12.dist-info → dlms_spodes-0.87.15.dist-info}/top_level.txt +0 -0
@@ -1,50 +1,50 @@
1
- from .__class_init__ import *
2
- from ..types.implementations import structs
3
- from .overview import VERSION_0
4
-
5
-
6
- class TYPE(cdt.Enum, elements=(1, 2, 3, 4, 5)):
7
- """"""
8
-
9
-
10
- class ExecutionTimeDate(cdt.Structure):
11
- """ Specifies the time and teh date when the script is executed. The two octet-string s contain time and date, in this order; time and date are
12
- formatted as specified in DLMS UA 1000-1 Ed.12.0 4.1.6.1. Hundredths of second shall be zero. """
13
- time: cst.OctetStringTime
14
- date: cst.OctetStringDate
15
-
16
-
17
- class ExecutionTime(cdt.Array):
18
- """ Specifies the list of execution time and date """
19
- TYPE = ExecutionTimeDate
20
-
21
-
22
- class SingleActionSchedule(ic.COSEMInterfaceClasses):
23
- """ This IC allows modelling the execution of periodic actions within a meter. Such actions are not necessarily linked to tariffication
24
- (see “Activity calendar” or “Schedule”). """
25
- CLASS_ID = ClassID.SINGLE_ACTION_SCHEDULE
26
- VERSION = VERSION_0
27
- A_ELEMENTS = (ic.ICAElement("executed_script", structs.ActionItem),
28
- ic.ICAElement("type", TYPE),
29
- ic.ICAElement("execution_time", ExecutionTime))
30
-
31
- def characteristics_init(self):
32
- """nothing do it"""
33
-
34
- @property
35
- def executed_script(self) -> structs.ActionItem:
36
- return self.get_attr(2)
37
-
38
- @property
39
- def type_(self) -> TYPE:
40
- return self.get_attr(3)
41
-
42
- @property
43
- def execution_time(self) -> ExecutionTime:
44
- return self.get_attr(4)
45
-
46
-
47
- if __name__ == '__main__':
48
- a = ExecutionTimeDate(b'\x02\x02\t\x04\x12\x007\x00\t\x05\x07\xe5\x05\x1f\x01')
49
- a = SingleActionSchedule('0.0.15.0.0.255')
50
- print(a)
1
+ from .__class_init__ import *
2
+ from ..types.implementations import structs
3
+ from .overview import VERSION_0
4
+
5
+
6
+ class TYPE(cdt.Enum, elements=(1, 2, 3, 4, 5)):
7
+ """"""
8
+
9
+
10
+ class ExecutionTimeDate(cdt.Structure):
11
+ """ Specifies the time and teh date when the script is executed. The two octet-string s contain time and date, in this order; time and date are
12
+ formatted as specified in DLMS UA 1000-1 Ed.12.0 4.1.6.1. Hundredths of second shall be zero. """
13
+ time: cst.OctetStringTime
14
+ date: cst.OctetStringDate
15
+
16
+
17
+ class ExecutionTime(cdt.Array):
18
+ """ Specifies the list of execution time and date """
19
+ TYPE = ExecutionTimeDate
20
+
21
+
22
+ class SingleActionSchedule(ic.COSEMInterfaceClasses):
23
+ """ This IC allows modelling the execution of periodic actions within a meter. Such actions are not necessarily linked to tariffication
24
+ (see “Activity calendar” or “Schedule”). """
25
+ CLASS_ID = ClassID.SINGLE_ACTION_SCHEDULE
26
+ VERSION = VERSION_0
27
+ A_ELEMENTS = (ic.ICAElement("executed_script", structs.ActionItem),
28
+ ic.ICAElement("type", TYPE),
29
+ ic.ICAElement("execution_time", ExecutionTime))
30
+
31
+ def characteristics_init(self):
32
+ """nothing do it"""
33
+
34
+ @property
35
+ def executed_script(self) -> structs.ActionItem:
36
+ return self.get_attr(2)
37
+
38
+ @property
39
+ def type_(self) -> TYPE:
40
+ return self.get_attr(3)
41
+
42
+ @property
43
+ def execution_time(self) -> ExecutionTime:
44
+ return self.get_attr(4)
45
+
46
+
47
+ if __name__ == '__main__':
48
+ a = ExecutionTimeDate(b'\x02\x02\t\x04\x12\x007\x00\t\x05\x07\xe5\x05\x1f\x01')
49
+ a = SingleActionSchedule('0.0.15.0.0.255')
50
+ print(a)
@@ -1,84 +1,84 @@
1
- import datetime
2
- from .__class_init__ import *
3
- from .overview import VERSION_0
4
-
5
-
6
- class SpecDayEntry(cdt.Structure):
7
- """ Specifies a special day identifier for a given date. The date may have wildcards for repeating special days like Christmas. """
8
- index: cdt.LongUnsigned
9
- specialday_date: cst.OctetStringDate
10
- day_id: cdt.Unsigned
11
-
12
-
13
- class Entries(cdt.Array):
14
- """ Specifies the list of spec_day_entry """
15
- TYPE = SpecDayEntry
16
- values: list[SpecDayEntry]
17
- __getitem__: SpecDayEntry
18
-
19
- def new_element(self) -> SpecDayEntry:
20
- indexes: list[int] = [int(el.index) for el in self.values]
21
- for i in range(0x1_00_00):
22
- if i not in indexes:
23
- return SpecDayEntry((i, None, None)) # TODO: insert first DayID from ActiveCalendar as 3 element
24
- raise ValueError(F'in {self} all indexes is busy')
25
-
26
- def __check_index(self, value):
27
- """validate day_id from DayProfile"""
28
- if cdt.LongUnsigned(value) in (entry.index for entry in self.values):
29
- raise ValueError(F'{cdt.LongUnsigned(value)} already exist in {self}')
30
- else:
31
- """validate OK"""
32
-
33
- def validate_exist_index(self, value):
34
- """pass if value in indexes"""
35
- if cdt.LongUnsigned(value) not in (entry.index for entry in self.values):
36
- raise ValueError(F'{cdt.LongUnsigned(value)} not exist in {self}')
37
- else:
38
- """validate OK"""
39
-
40
- def get_indexes(self) -> list[int]:
41
- """ getter for callback Index """
42
- return [int(entries_element.index) for entries_element in self.values]
43
-
44
-
45
- class SpecialDaysTable(ic.COSEMInterfaceClasses):
46
- """ The interface class allows defining dates, which will override normal switching behaviour for special days. The interface class works in
47
- conjunction with the class "Schedule" or "Activity calendar" and the linking data item is day_id """
48
- CLASS_ID = ClassID.SPECIAL_DAYS_TABLE
49
- VERSION = VERSION_0
50
- A_ELEMENTS = ic.ICAElement("entries", Entries),
51
- M_ELEMENTS = (ic.ICMElement("insert", SpecDayEntry),
52
- ic.ICMElement("delete", cdt.LongUnsigned)) # Todo: was Delete.with_cb(None, self.entries.get_indexes)
53
-
54
- def characteristics_init(self):
55
- self._cbs_attr_post_init.update({2: self.__set_delete})
56
- self.set_attr(2, None)
57
-
58
- @property
59
- def entries(self) -> Entries:
60
- return self.get_attr(2)
61
-
62
- @property
63
- def insert(self) -> SpecDayEntry:
64
- return self.get_meth(1)
65
-
66
- @property
67
- def delete(self) -> cdt.LongUnsigned:
68
- return self.get_meth(2)
69
-
70
- def __set_delete(self):
71
- try:
72
- self.delete.register_cb_preset(self.entries.validate_exist_index)
73
- self.insert.index.register_cb_preset(self.entries.validate_exist_index)
74
- except KeyError: # At init time
75
- print('set delete NO:')
76
-
77
- def __delete_entry(self):
78
- """remove one entry by according delete method index. Call after execute"""
79
- for entry in self.entries.values:
80
- if entry.index == self.delete:
81
- self.entries.values.remove(entry)
82
- return
83
- else:
84
- raise ValueError(F'not found entry with index {self.delete} for remove')
1
+ import datetime
2
+ from .__class_init__ import *
3
+ from .overview import VERSION_0
4
+
5
+
6
+ class SpecDayEntry(cdt.Structure):
7
+ """ Specifies a special day identifier for a given date. The date may have wildcards for repeating special days like Christmas. """
8
+ index: cdt.LongUnsigned
9
+ specialday_date: cst.OctetStringDate
10
+ day_id: cdt.Unsigned
11
+
12
+
13
+ class Entries(cdt.Array):
14
+ """ Specifies the list of spec_day_entry """
15
+ TYPE = SpecDayEntry
16
+ values: list[SpecDayEntry]
17
+ __getitem__: SpecDayEntry
18
+
19
+ def new_element(self) -> SpecDayEntry:
20
+ indexes: list[int] = [int(el.index) for el in self.values]
21
+ for i in range(0x1_00_00):
22
+ if i not in indexes:
23
+ return SpecDayEntry((i, None, None)) # TODO: insert first DayID from ActiveCalendar as 3 element
24
+ raise ValueError(F'in {self} all indexes is busy')
25
+
26
+ def __check_index(self, value):
27
+ """validate day_id from DayProfile"""
28
+ if cdt.LongUnsigned(value) in (entry.index for entry in self.values):
29
+ raise ValueError(F'{cdt.LongUnsigned(value)} already exist in {self}')
30
+ else:
31
+ """validate OK"""
32
+
33
+ def validate_exist_index(self, value):
34
+ """pass if value in indexes"""
35
+ if cdt.LongUnsigned(value) not in (entry.index for entry in self.values):
36
+ raise ValueError(F'{cdt.LongUnsigned(value)} not exist in {self}')
37
+ else:
38
+ """validate OK"""
39
+
40
+ def get_indexes(self) -> list[int]:
41
+ """ getter for callback Index """
42
+ return [int(entries_element.index) for entries_element in self.values]
43
+
44
+
45
+ class SpecialDaysTable(ic.COSEMInterfaceClasses):
46
+ """ The interface class allows defining dates, which will override normal switching behaviour for special days. The interface class works in
47
+ conjunction with the class "Schedule" or "Activity calendar" and the linking data item is day_id """
48
+ CLASS_ID = ClassID.SPECIAL_DAYS_TABLE
49
+ VERSION = VERSION_0
50
+ A_ELEMENTS = ic.ICAElement("entries", Entries),
51
+ M_ELEMENTS = (ic.ICMElement("insert", SpecDayEntry),
52
+ ic.ICMElement("delete", cdt.LongUnsigned)) # Todo: was Delete.with_cb(None, self.entries.get_indexes)
53
+
54
+ def characteristics_init(self):
55
+ self._cbs_attr_post_init.update({2: self.__set_delete})
56
+ self.set_attr(2, None)
57
+
58
+ @property
59
+ def entries(self) -> Entries:
60
+ return self.get_attr(2)
61
+
62
+ @property
63
+ def insert(self) -> SpecDayEntry:
64
+ return self.get_meth(1)
65
+
66
+ @property
67
+ def delete(self) -> cdt.LongUnsigned:
68
+ return self.get_meth(2)
69
+
70
+ def __set_delete(self):
71
+ try:
72
+ self.delete.register_cb_preset(self.entries.validate_exist_index)
73
+ self.insert.index.register_cb_preset(self.entries.validate_exist_index)
74
+ except KeyError: # At init time
75
+ print('set delete NO:')
76
+
77
+ def __delete_entry(self):
78
+ """remove one entry by according delete method index. Call after execute"""
79
+ for entry in self.entries.values:
80
+ if entry.index == self.delete:
81
+ self.entries.values.remove(entry)
82
+ return
83
+ else:
84
+ raise ValueError(F'not found entry with index {self.delete} for remove')
@@ -1,42 +1,42 @@
1
- from .__class_init__ import *
2
- from .overview import VERSION_0
3
-
4
-
5
- class TCPUDPSetup(ic.COSEMInterfaceClasses):
6
- """ This IC allows modelling the setup of the TCP or UDP sub-layer of the COSEM TCP or UDP based transport layer of a TCP-UDP/IP based communication profile.
7
- In TCP-UDP/IP based communication profiles, all AAs between a physical device hosting one or more COSEM client application processes and a physical device hosting one or more
8
- COSEM server APs rely on a single TCP or UDP connection. The TCP or UDP entity is wrapped in the COSEM TCP-UDP based transport layer. Within a physical device, each
9
- AP - client AP or server logical device - is bound to a Wrapper Port (WPort). The binding is done with the help of the SAP Assignment object. See 4.4.5 DLMS 1000-1 Ed. 12.0.
10
- On the other hand, COSEM TCP or UDP based transport layer may be capable to support more than one TCP or UDP connections, between a physical device and several peer physical
11
- devices hosting COSEM APs.
12
- When a COSEM physical device supports various data link layers - for example Ethernet and PPP - an instance of the TCP-UDP setup object is necessary for each of them. """
13
- CLASS_ID = ClassID.TCP_UDP_SETUP
14
- VERSION = VERSION_0
15
- A_ELEMENTS = (ic.ICAElement("TCP_UDP_port", cdt.LongUnsigned, default=4059),
16
- ic.ICAElement("IP_reference", cst.LogicalName),
17
- ic.ICAElement("MMS", cdt.LongUnsigned, 40, 535, 535), # TODO: max, def not according by BlueBook
18
- ic.ICAElement("nb_of_sim_conn", cdt.Unsigned, 1),
19
- ic.ICAElement("inactivity_time_out", cdt.LongUnsigned, default=180))
20
-
21
- def characteristics_init(self):
22
- """nothing do it"""
23
-
24
- @property
25
- def TCP_UDP_port(self) -> cdt.LongUnsigned:
26
- return self.get_attr(2)
27
-
28
- @property
29
- def IP_reference(self) -> cst.LogicalName:
30
- return self.get_attr(3)
31
-
32
- @property
33
- def MMS(self) -> cdt.LongUnsigned:
34
- return self.get_attr(4)
35
-
36
- @property
37
- def nb_of_sim_conn(self) -> cdt.Unsigned:
38
- return self.get_attr(5)
39
-
40
- @property
41
- def inactivity_time_out(self) -> cdt.LongUnsigned:
42
- return self.get_attr(6)
1
+ from .__class_init__ import *
2
+ from .overview import VERSION_0
3
+
4
+
5
+ class TCPUDPSetup(ic.COSEMInterfaceClasses):
6
+ """ This IC allows modelling the setup of the TCP or UDP sub-layer of the COSEM TCP or UDP based transport layer of a TCP-UDP/IP based communication profile.
7
+ In TCP-UDP/IP based communication profiles, all AAs between a physical device hosting one or more COSEM client application processes and a physical device hosting one or more
8
+ COSEM server APs rely on a single TCP or UDP connection. The TCP or UDP entity is wrapped in the COSEM TCP-UDP based transport layer. Within a physical device, each
9
+ AP - client AP or server logical device - is bound to a Wrapper Port (WPort). The binding is done with the help of the SAP Assignment object. See 4.4.5 DLMS 1000-1 Ed. 12.0.
10
+ On the other hand, COSEM TCP or UDP based transport layer may be capable to support more than one TCP or UDP connections, between a physical device and several peer physical
11
+ devices hosting COSEM APs.
12
+ When a COSEM physical device supports various data link layers - for example Ethernet and PPP - an instance of the TCP-UDP setup object is necessary for each of them. """
13
+ CLASS_ID = ClassID.TCP_UDP_SETUP
14
+ VERSION = VERSION_0
15
+ A_ELEMENTS = (ic.ICAElement("TCP_UDP_port", cdt.LongUnsigned, default=4059),
16
+ ic.ICAElement("IP_reference", cst.LogicalName),
17
+ ic.ICAElement("MMS", cdt.LongUnsigned, 40, 535, 535), # TODO: max, def not according by BlueBook
18
+ ic.ICAElement("nb_of_sim_conn", cdt.Unsigned, 1),
19
+ ic.ICAElement("inactivity_time_out", cdt.LongUnsigned, default=180))
20
+
21
+ def characteristics_init(self):
22
+ """nothing do it"""
23
+
24
+ @property
25
+ def TCP_UDP_port(self) -> cdt.LongUnsigned:
26
+ return self.get_attr(2)
27
+
28
+ @property
29
+ def IP_reference(self) -> cst.LogicalName:
30
+ return self.get_attr(3)
31
+
32
+ @property
33
+ def MMS(self) -> cdt.LongUnsigned:
34
+ return self.get_attr(4)
35
+
36
+ @property
37
+ def nb_of_sim_conn(self) -> cdt.Unsigned:
38
+ return self.get_attr(5)
39
+
40
+ @property
41
+ def inactivity_time_out(self) -> cdt.LongUnsigned:
42
+ return self.get_attr(6)
DLMS_SPODES/cosem_pdu.py CHANGED
@@ -1,93 +1,93 @@
1
- from __future__ import annotations
2
- from typing import Dict, Type, Union
3
- from abc import ABC, abstractmethod
4
- from struct import pack
5
-
6
-
7
- _services: Dict[int, Type[Union[AARE, ]]] = dict()
8
- """ COSEM Services dictionary """
9
-
10
-
11
- class Tag:
12
- """ APDU tag TODO: """
13
- value: int
14
-
15
- def __init__(self, value: int):
16
- self.value = value
17
-
18
- def __get__(self, instance, owner: COSEMPdu) -> int:
19
- return self.value
20
-
21
- def __set__(self, instance, value):
22
- raise ValueError("Tag no supported change")
23
-
24
-
25
- class COSEMPdu(ABC):
26
- """ TODO: """
27
- tag: Tag
28
-
29
- def __init__(self, content: bytearray):
30
- if content.pop(0) != self.tag:
31
- raise ValueError(F'Wrong {self.__class__.__name__} tag, expected {self.tag}')
32
- length = content.pop(0)
33
- if len(content) != length:
34
- raise ValueError(F'Wrong PDU length, expected {length}, got {len(content)}')
35
-
36
- def __init_subclass__(cls, **kwargs):
37
- """ register subclass in _types with unique tag """
38
- super().__init_subclass__(**kwargs)
39
- if hasattr(cls, 'tag'):
40
- _services.setdefault(cls.tag, cls)
41
- else:
42
- """ Handler for subclass without tag """
43
-
44
- @classmethod
45
- def from_content(cls, content: bytearray):
46
- tag = content[0]
47
- service = _services.get(tag, None)(content)
48
- if service is None:
49
- raise ValueError(F'service with tag:{tag} is absence in Service Dictionary')
50
- else:
51
- return service
52
-
53
- @property
54
- @abstractmethod
55
- def info(self) -> bytes:
56
- """ return info. All services, objects etc... TODO: """
57
-
58
- def content(self) -> bytes:
59
- return pack('BB', self.tag, len(self.info)) + self.info
60
-
61
-
62
- class ACSE(COSEMPdu, ABC):
63
- """ TODO: """
64
-
65
-
66
- class AARE(ACSE):
67
- """ TODO: """
68
- tag = Tag(61)
69
-
70
- def __init__(self, content: bytearray):
71
- super(AARE, self).__init__(content)
72
-
73
- @property
74
- def info(self) -> bytes:
75
- return bytes()
76
-
77
-
78
- class AARQ(ACSE):
79
- """ TODO: """
80
- tag = Tag(60)
81
-
82
- def __init__(self, content: bytearray):
83
- super(AARQ, self).__init__(content)
84
-
85
- @property
86
- def info(self) -> bytes:
87
- return bytes()
88
-
89
-
90
- if __name__ == '__main__':
91
- a = COSEMPdu.from_content(bytearray((61,3,1,2,4)))
92
- b = a.content().hex(' ')
93
- print(a)
1
+ from __future__ import annotations
2
+ from typing import Dict, Type, Union
3
+ from abc import ABC, abstractmethod
4
+ from struct import pack
5
+
6
+
7
+ _services: Dict[int, Type[Union[AARE, ]]] = dict()
8
+ """ COSEM Services dictionary """
9
+
10
+
11
+ class Tag:
12
+ """ APDU tag TODO: """
13
+ value: int
14
+
15
+ def __init__(self, value: int):
16
+ self.value = value
17
+
18
+ def __get__(self, instance, owner: COSEMPdu) -> int:
19
+ return self.value
20
+
21
+ def __set__(self, instance, value):
22
+ raise ValueError("Tag no supported change")
23
+
24
+
25
+ class COSEMPdu(ABC):
26
+ """ TODO: """
27
+ tag: Tag
28
+
29
+ def __init__(self, content: bytearray):
30
+ if content.pop(0) != self.tag:
31
+ raise ValueError(F'Wrong {self.__class__.__name__} tag, expected {self.tag}')
32
+ length = content.pop(0)
33
+ if len(content) != length:
34
+ raise ValueError(F'Wrong PDU length, expected {length}, got {len(content)}')
35
+
36
+ def __init_subclass__(cls, **kwargs):
37
+ """ register subclass in _types with unique tag """
38
+ super().__init_subclass__(**kwargs)
39
+ if hasattr(cls, 'tag'):
40
+ _services.setdefault(cls.tag, cls)
41
+ else:
42
+ """ Handler for subclass without tag """
43
+
44
+ @classmethod
45
+ def from_content(cls, content: bytearray):
46
+ tag = content[0]
47
+ service = _services.get(tag, None)(content)
48
+ if service is None:
49
+ raise ValueError(F'service with tag:{tag} is absence in Service Dictionary')
50
+ else:
51
+ return service
52
+
53
+ @property
54
+ @abstractmethod
55
+ def info(self) -> bytes:
56
+ """ return info. All services, objects etc... TODO: """
57
+
58
+ def content(self) -> bytes:
59
+ return pack('BB', self.tag, len(self.info)) + self.info
60
+
61
+
62
+ class ACSE(COSEMPdu, ABC):
63
+ """ TODO: """
64
+
65
+
66
+ class AARE(ACSE):
67
+ """ TODO: """
68
+ tag = Tag(61)
69
+
70
+ def __init__(self, content: bytearray):
71
+ super(AARE, self).__init__(content)
72
+
73
+ @property
74
+ def info(self) -> bytes:
75
+ return bytes()
76
+
77
+
78
+ class AARQ(ACSE):
79
+ """ TODO: """
80
+ tag = Tag(60)
81
+
82
+ def __init__(self, content: bytearray):
83
+ super(AARQ, self).__init__(content)
84
+
85
+ @property
86
+ def info(self) -> bytes:
87
+ return bytes()
88
+
89
+
90
+ if __name__ == '__main__':
91
+ a = COSEMPdu.from_content(bytearray((61,3,1,2,4)))
92
+ b = a.content().hex(' ')
93
+ print(a)