DLMS-SPODES 0.87.16__py3-none-any.whl → 0.88.1__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 (103) 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/Overview/__init__.py +0 -0
  11. DLMS_SPODES/cosem_interface_classes/Overview/class_id.py +107 -0
  12. DLMS_SPODES/cosem_interface_classes/__class_init__.py +3 -3
  13. DLMS_SPODES/cosem_interface_classes/__init__.py +3 -2
  14. DLMS_SPODES/cosem_interface_classes/activity_calendar.py +210 -254
  15. DLMS_SPODES/cosem_interface_classes/arbitrator.py +78 -105
  16. DLMS_SPODES/cosem_interface_classes/association_ln/abstract.py +50 -34
  17. DLMS_SPODES/cosem_interface_classes/association_ln/authentication_mechanism_name.py +25 -25
  18. DLMS_SPODES/cosem_interface_classes/association_ln/mechanism_id.py +25 -25
  19. DLMS_SPODES/cosem_interface_classes/association_ln/method.py +5 -5
  20. DLMS_SPODES/cosem_interface_classes/association_ln/ver0.py +440 -485
  21. DLMS_SPODES/cosem_interface_classes/association_ln/ver1.py +126 -133
  22. DLMS_SPODES/cosem_interface_classes/association_ln/ver2.py +30 -36
  23. DLMS_SPODES/cosem_interface_classes/association_ln/ver3.py +3 -4
  24. DLMS_SPODES/cosem_interface_classes/association_sn/ver0.py +14 -12
  25. DLMS_SPODES/cosem_interface_classes/clock.py +81 -131
  26. DLMS_SPODES/cosem_interface_classes/collection.py +2106 -2122
  27. DLMS_SPODES/cosem_interface_classes/cosem_interface_class.py +525 -583
  28. DLMS_SPODES/cosem_interface_classes/data.py +12 -21
  29. DLMS_SPODES/cosem_interface_classes/demand_register/ver0.py +32 -59
  30. DLMS_SPODES/cosem_interface_classes/disconnect_control.py +56 -74
  31. DLMS_SPODES/cosem_interface_classes/extended_register.py +18 -27
  32. DLMS_SPODES/cosem_interface_classes/gprs_modem_setup.py +33 -43
  33. DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver0.py +78 -103
  34. DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver1.py +42 -40
  35. DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver2.py +6 -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 +27 -53
  38. DLMS_SPODES/cosem_interface_classes/iec_local_port_setup.py +9 -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 +54 -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 +491 -487
  44. DLMS_SPODES/cosem_interface_classes/implementations/profile_generic.py +85 -83
  45. DLMS_SPODES/cosem_interface_classes/ipv4_setup.py +42 -72
  46. DLMS_SPODES/cosem_interface_classes/limiter.py +77 -111
  47. DLMS_SPODES/cosem_interface_classes/ln_pattern.py +334 -333
  48. DLMS_SPODES/cosem_interface_classes/modem_configuration/ver0.py +51 -65
  49. DLMS_SPODES/cosem_interface_classes/modem_configuration/ver1.py +27 -39
  50. DLMS_SPODES/cosem_interface_classes/ntp_setup/ver0.py +48 -67
  51. DLMS_SPODES/cosem_interface_classes/obis.py +28 -23
  52. DLMS_SPODES/cosem_interface_classes/overview.py +198 -197
  53. DLMS_SPODES/cosem_interface_classes/parameter.py +548 -547
  54. DLMS_SPODES/cosem_interface_classes/parameters.py +172 -172
  55. DLMS_SPODES/cosem_interface_classes/profile_generic/ver0.py +90 -122
  56. DLMS_SPODES/cosem_interface_classes/profile_generic/ver1.py +268 -277
  57. DLMS_SPODES/cosem_interface_classes/push_setup/ver0.py +13 -12
  58. DLMS_SPODES/cosem_interface_classes/push_setup/ver1.py +9 -10
  59. DLMS_SPODES/cosem_interface_classes/push_setup/ver2.py +124 -166
  60. DLMS_SPODES/cosem_interface_classes/register.py +18 -45
  61. DLMS_SPODES/cosem_interface_classes/register_activation/ver0.py +45 -80
  62. DLMS_SPODES/cosem_interface_classes/register_monitor.py +33 -46
  63. DLMS_SPODES/cosem_interface_classes/reports.py +72 -70
  64. DLMS_SPODES/cosem_interface_classes/schedule.py +88 -176
  65. DLMS_SPODES/cosem_interface_classes/script_table.py +54 -87
  66. DLMS_SPODES/cosem_interface_classes/security_setup/ver0.py +45 -68
  67. DLMS_SPODES/cosem_interface_classes/security_setup/ver1.py +122 -158
  68. DLMS_SPODES/cosem_interface_classes/single_action_schedule.py +34 -50
  69. DLMS_SPODES/cosem_interface_classes/special_days_table.py +54 -84
  70. DLMS_SPODES/cosem_interface_classes/tcp_udp_setup.py +20 -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 +463 -465
  83. DLMS_SPODES/settings.py +551 -551
  84. DLMS_SPODES/types/choices.py +140 -142
  85. DLMS_SPODES/types/common_data_types.py +2379 -2401
  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 +12 -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/type_alias.py +74 -0
  96. DLMS_SPODES/types/useful_types.py +627 -677
  97. {dlms_spodes-0.87.16.dist-info → dlms_spodes-0.88.1.dist-info}/METADATA +30 -30
  98. dlms_spodes-0.88.1.dist-info/RECORD +118 -0
  99. {dlms_spodes-0.87.16.dist-info → dlms_spodes-0.88.1.dist-info}/WHEEL +1 -1
  100. DLMS_SPODES/cosem_interface_classes/a_parameter.py +0 -20
  101. DLMS_SPODES/cosem_interface_classes/attr_indexes.py +0 -12
  102. dlms_spodes-0.87.16.dist-info/RECORD +0 -117
  103. {dlms_spodes-0.87.16.dist-info → dlms_spodes-0.88.1.dist-info}/top_level.txt +0 -0
@@ -1,277 +1,268 @@
1
- """DLMS UA 1000-1 Ed. 14"""
2
- from . import ver0
3
- from typing import Type, Iterator
4
- from ... import cosem_interface_classes
5
- from ...relation_to_OBIS import get_name
6
- from ... import exceptions as exc
7
- from ..__class_init__ import *
8
- from ...types.implementations import integers, arrays, structs
9
- from ...types.choices import CommonDataTypeChoiceBase
10
- from ..overview import VERSION_1
11
-
12
-
13
- class CaptureObjects(cdt.Array):
14
- """ Specifies the list of capture objects """
15
- TYPE = structs.CaptureObjectDefinition
16
-
17
-
18
- class FromEntry(cdt.DoubleLongUnsigned, min=1):
19
- """ Access selector value for selective access to the object_list attribute """
20
-
21
-
22
- class EntryDescriptor(cdt.Structure):
23
- """ Only buffer elements corresponding to the entry_descriptor shall be returned in the response.
24
- NOTE: from_entry and to_entry identify the lines, from_selected_value to_selected_value identify the columns of the buffer to be retrieved. """
25
- DEFAULT = (1, 0, 1, 0)
26
- from_entry: FromEntry
27
- to_entry: cdt.DoubleLongUnsigned
28
- from_selected_value: cdt.LongUnsigned
29
- to_selected_value: cdt.LongUnsigned
30
-
31
-
32
- class AccessSelector(ut.Unsigned8):
33
- """ Unsigned8 1..2. Default is 2 for read all buffer """
34
- def __init__(self, value: int | str | ut.Unsigned8 = 2):
35
- super(AccessSelector, self).__init__(value)
36
- if int(self) not in (1, 2):
37
- raise ValueError(F'The {self.__class__.__name__} got {int(self)}, expected 1..2')
38
-
39
-
40
- class RangeDescriptorValueChoice(CommonDataTypeChoiceBase, types=(
41
- cdt.DoubleLong,
42
- cdt.DoubleLongUnsigned,
43
- cdt.OctetString,
44
- cdt.VisibleString,
45
- cdt.Utf8String,
46
- cdt.Integer,
47
- cdt.Unsigned,
48
- cdt.LongUnsigned,
49
- cdt.Long,
50
- cdt.Long64Unsigned,
51
- cdt.Float32,
52
- cdt.Float64,
53
- cdt.DateTime,
54
- cdt.Date,
55
- cdt.Time
56
- )):
57
- """Types of range_descriptor.from_value/to_value"""
58
-
59
-
60
- # class RangeDescriptor(cdt.Structure):
61
- # restricting_object: structs.CaptureObjectDefinition
62
- # from_value: RangeDescriptorValueChoice
63
- # to_value: RangeDescriptorValueChoice
64
- # selected_values: CaptureObjects
65
- #
66
- # def __setattr__(self, key, value):
67
- # """Allow setting from_value and to_value with a CommonDataType of allowed types.
68
- # Other attributes remain immutable as per base Structure behavior."""
69
- # if key in ("from_value", "to_value"):
70
- # index = 1 if key == "from_value" else 2
71
- # # Accept only CommonDataType instances of allowed types
72
- # if isinstance(value, cdt.CommonDataType):
73
- # # Build allowed types tuple from Choice definition
74
- # allowed_types = tuple(el.TYPE if isinstance(el, ut.SequenceElement) else None for el in RangeDescriptorValueChoice.ELEMENTS.values())
75
- # allowed_types = tuple(t for t in allowed_types if t is not None)
76
- # if isinstance(value, allowed_types):
77
- # self.values[index] = value
78
- # return
79
- # else:
80
- # raise ValueError(F"Type got {value.__class__.__name__}, expected one of: "
81
- # + ", ".join(t.__name__ for t in allowed_types))
82
- # else:
83
- # raise TypeError(F"Unsupported value type for {key}: {value.__class__.__name__}. Provide a CommonDataType instance.")
84
- # else:
85
- # super().__setattr__(key, value)
86
- #
87
- #
88
- # class Data(ut.Data):
89
- # restricting_object: structs.CaptureObjectDefinition
90
- # from_value: cdt.SimpleDataType
91
- # to_value: cdt.SimpleDataType
92
- # selected_values: CaptureObjects
93
- # from_entry: FromEntry
94
- # to_entry: cdt.DoubleLongUnsigned
95
- # from_selected_value: cdt.LongUnsigned
96
- # to_selected_value: cdt.LongUnsigned
97
- # ELEMENTS = {1: ut.SequenceElement('range_descriptor', RangeDescriptor),
98
- # 2: ut.SequenceElement('entry_descriptor', EntryDescriptor)}
99
- #
100
- #
101
- # class SelectiveAccessDescriptor(ut.SelectiveAccessDescriptor):
102
- # access_selector: AccessSelector
103
- # access_parameters: Data
104
- # ELEMENTS = (ut.SequenceElement('access_selector', AccessSelector),
105
- # ut.SequenceElement('access_parameters', Data))
106
- #
107
- #
108
- # class CosemAttributeDescriptorWithSelection(ut.CosemAttributeDescriptorWithSelection):
109
- # access_selection: SelectiveAccessDescriptor
110
- # ELEMENTS = (ut.SequenceElement('cosem_attribute_descriptor', ut.CosemAttributeDescriptor),
111
- # ut.SequenceElement('access_selection', SelectiveAccessDescriptor))
112
-
113
-
114
- class ProfileGeneric(ver0.ProfileGeneric):
115
- """4.3.6 Profile generic"""
116
- VERSION = VERSION_1
117
- A_ELEMENTS = (ic.ICAElement("buffer", arrays.SelectionAccess, classifier=ic.Classifier.DYNAMIC),
118
- ic.ICAElement("capture_objects", CaptureObjects),
119
- ver0.ProfileGeneric.get_attr_element(4),
120
- ver0.ProfileGeneric.get_attr_element(5),
121
- ic.ICAElement("sort_object", structs.CaptureObjectDefinition),
122
- ic.ICAElement("entries_in_use", cdt.DoubleLongUnsigned, 0, default=0, classifier=ic.Classifier.DYNAMIC),
123
- ic.ICAElement("profile_entries", cdt.DoubleLongUnsigned, 1, default=1))
124
- M_ELEMENTS = (
125
- ver0.ProfileGeneric.get_meth_element(1),
126
- ver0.ProfileGeneric.get_meth_element(2)
127
- )
128
-
129
- def characteristics_init(self):
130
- self.set_attr(ver0.BUFFER, None)
131
-
132
- # todo remove it
133
- self.buffer.register_cb_preset(lambda _: self.__create_buffer_struct_type()) # value not used for creating struct type
134
-
135
- self._cbs_attr_post_init.update({ver0.CAPTURE_OBJECTS: self.__create_buffer_struct_type,
136
- ver0.SORT_OBJECT: self.__create_selective_access_descriptor})
137
-
138
- self.buffer_capture_objects = self.capture_objects
139
- """ objects for buffer. Change with access_selection """
140
-
141
- @property
142
- def buffer(self) -> arrays.SelectionAccess:
143
- return self.get_attr(2)
144
-
145
- @property
146
- def capture_objects(self) -> CaptureObjects:
147
- return self.get_attr(3)
148
-
149
- @property
150
- def sort_object(self) -> structs.CaptureObjectDefinition:
151
- return self.get_attr(6)
152
-
153
- def get_attr_descriptor(self,
154
- value: int,
155
- with_selection: bool = False) -> ut.CosemAttributeDescriptor | ut.CosemAttributeDescriptorWithSelection:
156
- """ with selection for object_list. TODO: Copypast AssociationLN"""
157
- descriptor: ut.CosemAttributeDescriptor = super(ProfileGeneric, self).get_attr_descriptor(value)
158
- if value == ver0.BUFFER and with_selection:
159
- if self.attr_descriptor_with_selection is None:
160
- self.__create_selective_access_descriptor()
161
- return self.attr_descriptor_with_selection((descriptor.contents, self.buffer.selective_access.contents))
162
- else:
163
- return descriptor
164
-
165
- def __create_buffer_struct_type(self):
166
- """ TODO: more refactoring !!! """
167
- # rename CaptureObjectDefinition's and adding object if it absense in collection
168
- if self.buffer.selective_access is None:
169
- self.__create_selective_access_descriptor()
170
- if self.capture_objects is None:
171
- raise ValueError(F"{self}: create buffer Struct type, not set <capture_object> attribute. Need initiate <capture_objects> before")
172
- for el_value in self.capture_objects:
173
- el_value: structs.CaptureObjectDefinition
174
- obj = self.collection.add_if_missing(class_id=ut.CosemClassId(el_value.class_id.contents),
175
- version=None,
176
- logical_name=el_value.logical_name)
177
- el_value.set_name(self.collection.get_name_and_type(el_value)[0][-1])
178
- match self.buffer.selective_access:
179
- case ut.SelectiveAccessDescriptor() as desc:
180
- match int(desc.access_selector):
181
- # case 0: self.buffer_capture_objects = self.capture_objects
182
- case 1 if len(desc.access_parameters.selected_values) == 0: self.buffer_capture_objects = self.capture_objects
183
- case 1: self.buffer_capture_objects = desc.access_parameters.selected_values
184
- case 2:
185
- from_selected_value = int(desc.access_parameters.from_selected_value)-1
186
- to_selected_value = int(desc.access_parameters.to_selected_value)
187
- if to_selected_value == 0:
188
- to_selected_value = len(self.capture_objects)
189
- self.buffer_capture_objects = self.capture_objects[from_selected_value:to_selected_value]
190
- case _ as err: raise ValueError(F'access_selection out of range, got {err}, must be (0..2)')
191
- case None:
192
- self.clear_attr(ver0.CAPTURE_OBJECTS)
193
- self._cbs_attr_post_init[ver0.CAPTURE_OBJECTS] = self.__create_buffer_struct_type
194
- raise exc.EmptyObj(F"need set <sort_object> before for {self}")
195
- buffer_elements: list[cdt.StructElement] = list()
196
- for el_value in self.buffer_capture_objects:
197
- names, type_ = self.collection.get_name_and_type(el_value)
198
- buffer_elements.append(cdt.StructElement(NAME=". ".join(names), TYPE=type_))
199
-
200
- class Entry(cdt.Structure):
201
- """4.3.6 Profile generic: entry"""
202
- ELEMENTS = tuple(buffer_elements)
203
-
204
- self.buffer.set_type(Entry)
205
-
206
- def __create_selective_access_descriptor(self):
207
- """ Available after got sort object. TODO: need rewrite. maybe replace to collection level. Wrong used sort_obj, it can be any element from capture_objects"""
208
- if self.sort_object is None:
209
- raise exc.EmptyObj(F"<sort object> is empty")
210
- sort_obj: ic.COSEMInterfaceClasses = self.collection.get_object(self.sort_object.logical_name)
211
- if sort_obj.CLASS_ID.contents == self.sort_object.class_id.contents:
212
- value_type: Type[cdt.CommonDataType] = sort_obj.get_attr_data_type(int(self.sort_object.attribute_index))
213
- else:
214
- exc.NoObject(F"got {self.sort_object.class_id=}, expected {sort_obj.CLASS_ID=} from collection")
215
-
216
- class RangeDescriptor(cdt.Structure):
217
- # cb_preset = TODO: make check 'selected_values' from self.capture_objects or
218
- # cb_post_set = TODO: make check 'selected_values' from self.capture_objects
219
- DEFAULT = b'\x02\x04\x02\x04\x12\x00\x01\x09\x06\x00\x00\x01\x00\x00\xff\x0f\x02\x12\x00\x00\x09\x0c\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff' \
220
- b'\x09\x0c\x07\xe4\x01\x02\xff\xff\xff\xff\xff\x80\x00\xff\x01\x00'
221
- restricting_object: structs.CaptureObjectDefinition
222
- from_value: value_type
223
- to_value: value_type
224
- selected_values: CaptureObjects
225
-
226
- class Data(ut.Data):
227
- restricting_object: structs.CaptureObjectDefinition
228
- from_value: cdt.SimpleDataType
229
- to_value: cdt.SimpleDataType
230
- selected_values: CaptureObjects
231
- from_entry: FromEntry
232
- to_entry: cdt.DoubleLongUnsigned
233
- from_selected_value: cdt.LongUnsigned
234
- to_selected_value: cdt.LongUnsigned
235
- ELEMENTS = {1: ut.SequenceElement('range_descriptor', RangeDescriptor),
236
- 2: ut.SequenceElement('entry_descriptor', EntryDescriptor)}
237
-
238
- class SelectiveAccessDescriptor(ut.SelectiveAccessDescriptor):
239
- access_selector: AccessSelector
240
- access_parameters: Data
241
- ELEMENTS = (ut.SequenceElement('access_selector', AccessSelector),
242
- ut.SequenceElement('access_parameters', Data))
243
-
244
- class CosemAttributeDescriptorWithSelection(ut.CosemAttributeDescriptorWithSelection):
245
- access_selection: SelectiveAccessDescriptor
246
- ELEMENTS = (ut.SequenceElement('cosem_attribute_descriptor', ut.CosemAttributeDescriptor),
247
- ut.SequenceElement('access_selection', SelectiveAccessDescriptor))
248
-
249
- self.attr_descriptor_with_selection = CosemAttributeDescriptorWithSelection
250
- self.buffer.selective_access = SelectiveAccessDescriptor()
251
-
252
- def get_capture_object_names(self) -> list[str]:
253
- """ return all capture object names from collection """
254
- if self.capture_objects is None:
255
- raise ValueError(F'{self}: Empty capture objects')
256
- else:
257
- definition: structs.CaptureObjectDefinition
258
- ret = list()
259
- for definition in self.capture_objects:
260
- ret.append(get_name(definition.logical_name))
261
- return ret
262
-
263
- def get_buffer_objects(self) -> list[cosem_interface_classes.cosem_interface_class.COSEMInterfaceClasses]:
264
- """ get objects of current buffer container """
265
- return [self.collection.get(obj_def.logical_name.contents) for obj_def in self.buffer_capture_objects]
266
-
267
- # todo remove it
268
- def get_index_with_attributes(self, in_init_order: bool = False) -> Iterator[tuple[int, cdt.CommonDataType | None]]:
269
- """ override common method """
270
- return iter(((1, self.logical_name),
271
- (6, self.sort_object),
272
- (3, self.capture_objects),
273
- (2, self.buffer),
274
- (4, self.capture_period),
275
- (5, self.sort_method),
276
- (7, self.entries_in_use),
277
- (8, self.profile_entries)))
1
+ """DLMS UA 1000-1 Ed. 14"""
2
+ from . import ver0
3
+ from typing import Iterator, Optional
4
+ from ... import cosem_interface_classes
5
+ from ...relation_to_OBIS import get_name
6
+ from ... import exceptions as exc
7
+ from ...types.implementations import arrays, structs
8
+ from ...types.choices import CommonDataTypeChoiceBase
9
+ from ...types import cdt, ut
10
+ from ..cosem_interface_class import ICAElement, Classifier
11
+
12
+
13
+ class CaptureObjects(cdt.Array):
14
+ """ Specifies the list of capture objects """
15
+ TYPE = structs.CaptureObjectDefinition
16
+
17
+
18
+ class FromEntry(cdt.DoubleLongUnsigned, min=1):
19
+ """ Access selector value for selective access to the object_list attribute """
20
+
21
+
22
+ class EntryDescriptor(cdt.Structure):
23
+ """ Only buffer elements corresponding to the entry_descriptor shall be returned in the response.
24
+ NOTE: from_entry and to_entry identify the lines, from_selected_value to_selected_value identify the columns of the buffer to be retrieved. """
25
+ DEFAULT = (1, 0, 1, 0)
26
+ from_entry: FromEntry
27
+ to_entry: cdt.DoubleLongUnsigned
28
+ from_selected_value: cdt.LongUnsigned
29
+ to_selected_value: cdt.LongUnsigned
30
+
31
+
32
+ class AccessSelector(ut.Unsigned8):
33
+ """ Unsigned8 1..2. Default is 2 for read all buffer """
34
+ def __init__(self, value: int | str | ut.Unsigned8 = 2):
35
+ super(AccessSelector, self).__init__(value)
36
+ if int(self) not in (1, 2):
37
+ raise ValueError(F'The {self.__class__.__name__} got {int(self)}, expected 1..2')
38
+
39
+
40
+ class RangeDescriptorValueChoice(CommonDataTypeChoiceBase, types=(
41
+ cdt.DoubleLong,
42
+ cdt.DoubleLongUnsigned,
43
+ cdt.OctetString,
44
+ cdt.VisibleString,
45
+ cdt.Utf8String,
46
+ cdt.Integer,
47
+ cdt.Unsigned,
48
+ cdt.LongUnsigned,
49
+ cdt.Long,
50
+ cdt.Long64Unsigned,
51
+ cdt.Float32,
52
+ cdt.Float64,
53
+ cdt.DateTime,
54
+ cdt.Date,
55
+ cdt.Time
56
+ )):
57
+ """Types of range_descriptor.from_value/to_value"""
58
+
59
+
60
+ # class RangeDescriptor(cdt.Structure):
61
+ # restricting_object: structs.CaptureObjectDefinition
62
+ # from_value: RangeDescriptorValueChoice
63
+ # to_value: RangeDescriptorValueChoice
64
+ # selected_values: CaptureObjects
65
+ #
66
+ # def __setattr__(self, key, value):
67
+ # """Allow setting from_value and to_value with a CommonDataType of allowed types.
68
+ # Other attributes remain immutable as per base Structure behavior."""
69
+ # if key in ("from_value", "to_value"):
70
+ # index = 1 if key == "from_value" else 2
71
+ # # Accept only CommonDataType instances of allowed types
72
+ # if isinstance(value, cdt.CommonDataType):
73
+ # # Build allowed types tuple from Choice definition
74
+ # allowed_types = tuple(el.TYPE if isinstance(el, ut.SequenceElement) else None for el in RangeDescriptorValueChoice.ELEMENTS.values())
75
+ # allowed_types = tuple(t for t in allowed_types if t is not None)
76
+ # if isinstance(value, allowed_types):
77
+ # self.values[index] = value
78
+ # return
79
+ # else:
80
+ # raise ValueError(F"Type got {value.__class__.__name__}, expected one of: "
81
+ # + ", ".join(t.__name__ for t in allowed_types))
82
+ # else:
83
+ # raise TypeError(F"Unsupported value type for {key}: {value.__class__.__name__}. Provide a CommonDataType instance.")
84
+ # else:
85
+ # super().__setattr__(key, value)
86
+ #
87
+ #
88
+ # class Data(ut.Data):
89
+ # restricting_object: structs.CaptureObjectDefinition
90
+ # from_value: cdt.SimpleDataType
91
+ # to_value: cdt.SimpleDataType
92
+ # selected_values: CaptureObjects
93
+ # from_entry: FromEntry
94
+ # to_entry: cdt.DoubleLongUnsigned
95
+ # from_selected_value: cdt.LongUnsigned
96
+ # to_selected_value: cdt.LongUnsigned
97
+ # ELEMENTS = {1: ut.SequenceElement('range_descriptor', RangeDescriptor),
98
+ # 2: ut.SequenceElement('entry_descriptor', EntryDescriptor)}
99
+ #
100
+ #
101
+ # class SelectiveAccessDescriptor(ut.SelectiveAccessDescriptor):
102
+ # access_selector: AccessSelector
103
+ # access_parameters: Data
104
+ # ELEMENTS = (ut.SequenceElement('access_selector', AccessSelector),
105
+ # ut.SequenceElement('access_parameters', Data))
106
+ #
107
+ #
108
+ # class CosemAttributeDescriptorWithSelection(ut.CosemAttributeDescriptorWithSelection):
109
+ # access_selection: SelectiveAccessDescriptor
110
+ # ELEMENTS = (ut.SequenceElement('cosem_attribute_descriptor', ut.CosemAttributeDescriptor),
111
+ # ut.SequenceElement('access_selection', SelectiveAccessDescriptor))
112
+
113
+
114
+ class ProfileGeneric(ver0.ProfileGeneric):
115
+ """4.3.6 Profile generic"""
116
+ VERSION = 1
117
+ A_ELEMENTS = (ICAElement(2, "buffer", arrays.SelectionAccess, classifier=Classifier.DYNAMIC),
118
+ ICAElement(3, "capture_objects", CaptureObjects),
119
+ ver0.ProfileGeneric.getAElement(4).unwrap(),
120
+ ver0.ProfileGeneric.getAElement(5).unwrap(),
121
+ ICAElement(6, "sort_object", structs.CaptureObjectDefinition),
122
+ ICAElement(7, "entries_in_use", cdt.DoubleLongUnsigned, 0, default=0, classifier=Classifier.DYNAMIC),
123
+ ICAElement(8, "profile_entries", cdt.DoubleLongUnsigned, 1, default=1))
124
+ M_ELEMENTS = (
125
+ ver0.ProfileGeneric.getMElement(1).unwrap(),
126
+ ver0.ProfileGeneric.getMElement(2).unwrap())
127
+ buffer: Optional[cdt.Array]
128
+ capture_objects: Optional[CaptureObjects]
129
+ sort_method: Optional[ver0.SortMethod]
130
+ sort_object: Optional[structs.CaptureObjectDefinition]
131
+
132
+ def characteristics_init(self):
133
+ self.set_attr(ver0.BUFFER, None)
134
+
135
+ # todo remove it
136
+ self.buffer.register_cb_preset(lambda _: self.__create_buffer_struct_type()) # value not used for creating struct type
137
+
138
+ self._cbs_attr_post_init.update({ver0.CAPTURE_OBJECTS: self.__create_buffer_struct_type,
139
+ ver0.SORT_OBJECT: self.__create_selective_access_descriptor})
140
+
141
+ self.buffer_capture_objects = self.capture_objects
142
+ """ objects for buffer. Change with access_selection """
143
+
144
+ # def get_attr_descriptor(self,
145
+ # i: int,
146
+ # with_selection: bool = False) -> ut.CosemAttributeDescriptor | ut.CosemAttributeDescriptorWithSelection:
147
+ # """ with selection for object_list. TODO: Copypast AssociationLN"""
148
+ # descriptor: ut.CosemAttributeDescriptor = super(ProfileGeneric, self).get_attr_descriptor(i)
149
+ # if value == ver0.BUFFER and with_selection:
150
+ # if self.attr_descriptor_with_selection is None:
151
+ # self.__create_selective_access_descriptor()
152
+ # return self.attr_descriptor_with_selection((descriptor.contents, self.buffer.selective_access.contents))
153
+ # else:
154
+ # return descriptor
155
+
156
+ def __create_buffer_struct_type(self):
157
+ """ TODO: more refactoring !!! """
158
+ # rename CaptureObjectDefinition's and adding object if it absense in collection
159
+ if self.buffer.selective_access is None:
160
+ self.__create_selective_access_descriptor()
161
+ if self.capture_objects is None:
162
+ raise ValueError(F"{self}: create buffer Struct type, not set <capture_object> attribute. Need initiate <capture_objects> before")
163
+ for el_value in self.capture_objects:
164
+ el_value: structs.CaptureObjectDefinition
165
+ obj = self.collection.add_if_missing(class_id=ut.CosemClassId(el_value.class_id.contents),
166
+ version=None,
167
+ logical_name=el_value.logical_name)
168
+ el_value.set_name(self.collection.get_name_and_type(el_value)[0][-1])
169
+ match self.buffer.selective_access:
170
+ case ut.SelectiveAccessDescriptor() as desc:
171
+ match int(desc.access_selector):
172
+ # case 0: self.buffer_capture_objects = self.capture_objects
173
+ case 1 if len(desc.access_parameters.selected_values) == 0: self.buffer_capture_objects = self.capture_objects
174
+ case 1: self.buffer_capture_objects = desc.access_parameters.selected_values
175
+ case 2:
176
+ from_selected_value = int(desc.access_parameters.from_selected_value)-1
177
+ to_selected_value = int(desc.access_parameters.to_selected_value)
178
+ if to_selected_value == 0:
179
+ to_selected_value = len(self.capture_objects)
180
+ self.buffer_capture_objects = self.capture_objects[from_selected_value:to_selected_value]
181
+ case _ as err: raise ValueError(F'access_selection out of range, got {err}, must be (0..2)')
182
+ case None:
183
+ self.clear_attr(ver0.CAPTURE_OBJECTS)
184
+ self._cbs_attr_post_init[ver0.CAPTURE_OBJECTS] = self.__create_buffer_struct_type
185
+ raise exc.EmptyObj(F"need set <sort_object> before for {self}")
186
+ buffer_elements: list[cdt.StructElement] = list()
187
+ for el_value in self.buffer_capture_objects:
188
+ names, type_ = self.collection.get_name_and_type(el_value)
189
+ buffer_elements.append(cdt.StructElement(NAME=". ".join(names), TYPE=type_))
190
+
191
+ class Entry(cdt.Structure):
192
+ """4.3.6 Profile generic: entry"""
193
+ ELEMENTS = tuple(buffer_elements)
194
+
195
+ self.buffer.set_type(Entry)
196
+
197
+ def __create_selective_access_descriptor(self):
198
+ """ Available after got sort object. TODO: need rewrite. maybe replace to collection level. Wrong used sort_obj, it can be any element from capture_objects"""
199
+ if self.sort_object is None:
200
+ raise exc.EmptyObj(F"<sort object> is empty")
201
+ sort_obj: ic.COSEMInterfaceClasses = self.collection.get_object(self.sort_object.logical_name)
202
+ if sort_obj.CLASS_ID.contents == self.sort_object.class_id.contents:
203
+ value_type: Type[cdt.CommonDataType] = sort_obj.get_attr_data_type(int(self.sort_object.attribute_index))
204
+ else:
205
+ exc.NoObject(F"got {self.sort_object.class_id=}, expected {sort_obj.CLASS_ID=} from collection")
206
+
207
+ class RangeDescriptor(cdt.Structure):
208
+ # cb_preset = TODO: make check 'selected_values' from self.capture_objects or
209
+ # cb_post_set = TODO: make check 'selected_values' from self.capture_objects
210
+ DEFAULT = b'\x02\x04\x02\x04\x12\x00\x01\x09\x06\x00\x00\x01\x00\x00\xff\x0f\x02\x12\x00\x00\x09\x0c\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff' \
211
+ b'\x09\x0c\x07\xe4\x01\x02\xff\xff\xff\xff\xff\x80\x00\xff\x01\x00'
212
+ restricting_object: structs.CaptureObjectDefinition
213
+ from_value: value_type
214
+ to_value: value_type
215
+ selected_values: CaptureObjects
216
+
217
+ class Data(ut.Data):
218
+ restricting_object: structs.CaptureObjectDefinition
219
+ from_value: cdt.SimpleDataType
220
+ to_value: cdt.SimpleDataType
221
+ selected_values: CaptureObjects
222
+ from_entry: FromEntry
223
+ to_entry: cdt.DoubleLongUnsigned
224
+ from_selected_value: cdt.LongUnsigned
225
+ to_selected_value: cdt.LongUnsigned
226
+ ELEMENTS = {1: ut.SequenceElement('range_descriptor', RangeDescriptor),
227
+ 2: ut.SequenceElement('entry_descriptor', EntryDescriptor)}
228
+
229
+ class SelectiveAccessDescriptor(ut.SelectiveAccessDescriptor):
230
+ access_selector: AccessSelector
231
+ access_parameters: Data
232
+ ELEMENTS = (ut.SequenceElement('access_selector', AccessSelector),
233
+ ut.SequenceElement('access_parameters', Data))
234
+
235
+ class CosemAttributeDescriptorWithSelection(ut.CosemAttributeDescriptorWithSelection):
236
+ access_selection: SelectiveAccessDescriptor
237
+ ELEMENTS = (ut.SequenceElement('cosem_attribute_descriptor', ut.CosemAttributeDescriptor),
238
+ ut.SequenceElement('access_selection', SelectiveAccessDescriptor))
239
+
240
+ self.attr_descriptor_with_selection = CosemAttributeDescriptorWithSelection
241
+ self.buffer.selective_access = SelectiveAccessDescriptor()
242
+
243
+ def get_capture_object_names(self) -> list[str]:
244
+ """ return all capture object names from collection """
245
+ if self.capture_objects is None:
246
+ raise ValueError(F'{self}: Empty capture objects')
247
+ else:
248
+ definition: structs.CaptureObjectDefinition
249
+ ret = list()
250
+ for definition in self.capture_objects:
251
+ ret.append(get_name(definition.logical_name))
252
+ return ret
253
+
254
+ def get_buffer_objects(self) -> list[cosem_interface_classes.cosem_interface_class.IC]:
255
+ """ get objects of current buffer container """
256
+ return [self.collection.get(obj_def.logical_name.contents) for obj_def in self.buffer_capture_objects]
257
+
258
+ # todo remove it
259
+ def get_index_with_attributes(self, in_init_order: bool = False) -> Iterator[tuple[int, cdt.CommonDataType | None]]:
260
+ """ override common method """
261
+ return iter(((1, self.logical_name),
262
+ (6, self.sort_object),
263
+ (3, self.capture_objects),
264
+ (2, self.buffer),
265
+ (4, self.capture_period),
266
+ (5, self.sort_method),
267
+ (7, self.entries_in_use),
268
+ (8, self.profile_entries)))
@@ -1,12 +1,13 @@
1
- from ..__class_init__ import *
2
-
3
-
4
- class PushSetup(ic.COSEMInterfaceClasses):
5
- """dummy class"""
6
- CLASS_ID = ClassID.PUSH_SETUP
7
-
8
- def __new__(cls, *args, **kwargs):
9
- raise ValueError(F"version: {__name__[-1]} of {cls.__class__.__name__} not support framework")
10
-
11
- def characteristics_init(self):
12
- """ initiate all attributes and methods of class """
1
+ from ..cosem_interface_class import ICAElement, ICAuto
2
+ from ..Overview import class_id
3
+
4
+
5
+ class PushSetup(ICAuto):
6
+ """dummy class"""
7
+ CLASS_ID = class_id.PUSH_SETUP
8
+ VERSION = 0
9
+ A_ELEMENTS = ()
10
+ M_ELEMENTS = ()
11
+
12
+ def __new__(cls, *args, **kwargs):
13
+ raise ValueError(F"version: {__name__[-1]} of {cls.__class__.__name__} not support framework")
@@ -1,10 +1,9 @@
1
- from ..__class_init__ import *
2
-
3
-
4
- class PushSetup(ic.COSEMInterfaceClasses):
5
- """dummy class"""
6
- def __new__(cls, *args, **kwargs):
7
- raise ValueError(F"version: {__name__[-1]} of {cls.__class__.__name__} not support framework")
8
-
9
- def characteristics_init(self):
10
- """ initiate all attributes and methods of class """
1
+ from . import ver0
2
+ from ..cosem_interface_class import ICAElement, ICAuto
3
+ from ..Overview import class_id
4
+
5
+
6
+ class PushSetup(ver0.PushSetup):
7
+ """dummy class"""
8
+ def __new__(cls, *args, **kwargs):
9
+ raise ValueError(F"version: {__name__[-1]} of {cls.__class__.__name__} not support framework")