DLMS-SPODES 0.87.17__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 -133
  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.17.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.17.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.17.dist-info/RECORD +0 -117
  103. {dlms_spodes-0.87.17.dist-info → dlms_spodes-0.88.1.dist-info}/top_level.txt +0 -0
@@ -1,70 +1,72 @@
1
- from typing import Any, Iterable
2
- from StructResult import result
3
- from . import cosem_interface_class as ic
4
- from ..types import cdt
5
- from .parameter import Parameter
6
- from ..cosem_interface_classes import collection
7
- from ..config_parser import get_values
8
- from ..settings import settings
9
-
10
-
11
- def from_obj(
12
- col: collection.Collection,
13
- obj: ic.COSEMInterfaceClasses,
14
- attr_index_par: tuple[int, ...]
15
- ) -> result.SimpleOrError[str]:
16
- if not hasattr(from_obj, "struct_pattern"):
17
- from_obj.struct_pattern = dict(settings.report.struct)
18
- ret: str = F"[{collection.get_name(obj.logical_name)}]\n"
19
- for i in attr_index_par:
20
- par = Parameter(obj.logical_name.contents).set_i(i)
21
- if isinstance(res_data := col.par2data(par), result.Error):
22
- return res_data
23
- a_data = res_data.value
24
- if isinstance(a_data, cdt.SimpleDataType):
25
- rep = col.par2rep(par, a_data)
26
- ret += F" {obj.get_attr_element(i)}: {rep.msg}{f" {rep.unit}" if rep.unit else ""}\n"
27
- elif isinstance(a_data, cdt.ComplexDataType):
28
- ret += F" [{obj.get_attr_element(i)}]\n"
29
- stack: list[tuple[Any, Any]] = [("", iter(a_data))]
30
- while stack:
31
- name, value_it = stack[-1]
32
- indent = F"{' ' * (len(stack) + 1)}"
33
- data = next(value_it, None)
34
- if data:
35
- if not isinstance(name, str):
36
- name = str(next(name))
37
- if isinstance(data, cdt.Array):
38
- ret += F"{indent}[{name}]\n"
39
- stack.append(("*", iter(data)))
40
- elif isinstance(data, cdt.Structure):
41
- if (pattern := from_obj.struct_pattern.get(data.__class__.__name__)):
42
- val = list(pattern)
43
- val.reverse()
44
- result_ = str()
45
- while val:
46
- match val.pop():
47
- case "%":
48
- par_ = val.pop()
49
- index = int(val.pop() + val.pop())
50
- match par_:
51
- case "n":
52
- result_ += str(data.ELEMENTS[index])
53
- case "v":
54
- result_ += str(data[index])
55
- case err:
56
- raise ValueError(F"unknown macros &{err}{index}")
57
- case symbol:
58
- result_ += symbol
59
- ret += F"{indent}{result_}\n"
60
- else:
61
- if name=="":
62
- ret += "\n"
63
- else:
64
- ret += F"{indent}[{name}]\n"
65
- stack.append((iter(data.ELEMENTS), iter(data)))
66
- else:
67
- ret += F"{indent}{name}: {data}\n"
68
- else:
69
- stack.pop()
70
- return result.Simple(ret)
1
+ from typing import Any, Iterable
2
+ from StructResult import result
3
+ from . import cosem_interface_class as ic
4
+ from ..types import cdt
5
+ from .parameter import Parameter
6
+ from ..cosem_interface_classes import collection
7
+ from ..config_parser import get_values
8
+ from ..settings import settings
9
+
10
+
11
+ def from_obj(
12
+ col: collection.Collection,
13
+ obj: ic.IC,
14
+ attr_index_par: tuple[int, ...]
15
+ ) -> result.SimpleOrError[str]:
16
+ if not hasattr(from_obj, "struct_pattern"):
17
+ from_obj.struct_pattern = dict(settings.report.struct)
18
+ ret: str = F"[{collection.get_name(obj.logical_name)}]\n"
19
+ for i in attr_index_par:
20
+ par = Parameter(obj.logical_name.contents).set_i(i)
21
+ if isinstance(res_data := col.par2data(par), result.Error):
22
+ return res_data
23
+ a_data = res_data.value
24
+ if isinstance(res_a_el := obj.getAElement(i), result.Error):
25
+ return res_a_el
26
+ if isinstance(a_data, cdt.SimpleDataType):
27
+ rep = col.par2rep(par, a_data)
28
+ ret += F" {res_a_el.value}: {rep.msg}{f" {rep.unit}" if rep.unit else ""}\n"
29
+ elif isinstance(a_data, cdt.ComplexDataType):
30
+ ret += F" [{res_a_el.value}]\n"
31
+ stack: list[tuple[Any, Any]] = [("", iter(a_data))]
32
+ while stack:
33
+ name, value_it = stack[-1]
34
+ indent = F"{' ' * (len(stack) + 1)}"
35
+ data = next(value_it, None)
36
+ if data:
37
+ if not isinstance(name, str):
38
+ name = str(next(name))
39
+ if isinstance(data, cdt.Array):
40
+ ret += F"{indent}[{name}]\n"
41
+ stack.append(("*", iter(data)))
42
+ elif isinstance(data, cdt.Structure):
43
+ if (pattern := from_obj.struct_pattern.get(data.__class__.__name__)):
44
+ val = list(pattern)
45
+ val.reverse()
46
+ result_ = str()
47
+ while val:
48
+ match val.pop():
49
+ case "%":
50
+ par_ = val.pop()
51
+ index = int(val.pop() + val.pop())
52
+ match par_:
53
+ case "n":
54
+ result_ += str(data.ELEMENTS[index])
55
+ case "v":
56
+ result_ += str(data[index])
57
+ case err:
58
+ raise ValueError(F"unknown macros &{err}{index}")
59
+ case symbol:
60
+ result_ += symbol
61
+ ret += F"{indent}{result_}\n"
62
+ else:
63
+ if name == "":
64
+ ret += "\n"
65
+ else:
66
+ ret += F"{indent}[{name}]\n"
67
+ stack.append((iter(data.ELEMENTS), iter(data)))
68
+ else:
69
+ ret += F"{indent}{name}: {data}\n"
70
+ else:
71
+ stack.pop()
72
+ return result.Simple(ret)
@@ -1,176 +1,88 @@
1
- from typing import Callable, Self
2
- from itertools import count
3
- from .__class_init__ import *
4
- from .overview import VERSION_0
5
-
6
-
7
- class Index(cdt.LongUnsigned, min=1, max=9999):
8
- """ LongUnsigned type with validation """
9
- __cb_get_indexes: Callable
10
- DEFAULT = 1
11
-
12
- def set_callback(self, cb: Callable):
13
- self.__cb_get_indexes = cb
14
-
15
- def get_indexes(self) -> list[int]:
16
- """ return indexes container """
17
- return self.__cb_get_indexes()
18
-
19
- def check(self, string: str):
20
- """ raise ValueError with message if string not is valid """
21
- instance = type(self)(value=string)
22
- if int(instance) in self.__cb_get_indexes():
23
- raise ValueError('New index not unique')
24
-
25
- @classmethod
26
- def with_cb(cls, value, cb: Callable) -> Self:
27
- """ get instance with callback """
28
- ret = cls(value)
29
- ret.set_callback(cb)
30
- return ret
31
-
32
-
33
- class ScheduleTableEntry(cdt.Structure):
34
- """ Specifies the scripts to be executed at given times. There is only one script that can be executed per entry. """
35
- index: Index
36
- enable: cdt.Boolean
37
- script_logical_name: cst.LogicalName
38
- script_selector: cdt.LongUnsigned
39
- switch_time: cst.OctetStringTime
40
- validity_window: cdt.LongUnsigned
41
- exec_weekdays: cdt.BitString
42
- exec_specdays: cdt.BitString
43
- begin_date: cst.OctetStringDate
44
- end_date: cst.OctetStringDate
45
-
46
-
47
- # TODO: rewrite to new API
48
- class Entries(cdt.Array):
49
- """ Specifies the list of schedule_table_entry. Todo: validate by unique index"""
50
- TYPE = ScheduleTableEntry
51
- unique = True
52
-
53
- def __init__(self, value: bytes = None):
54
- super(Entries, self).__init__(value)
55
- # setting callback for validate schedule_table_entry index
56
- for schedule_table_entry in self:
57
- schedule_table_entry: ScheduleTableEntry
58
- schedule_table_entry.index.set_callback(self.get_indexes)
59
-
60
- def get_indexes(self) -> list[int]:
61
- """ getter for callback Index """
62
- return [entries_element.index.decode() for entries_element in self]
63
-
64
-
65
- class DataED(cdt.Structure):
66
- """ Sets the disabled bit of range A entries to true and then enables the entries of range B.
67
- * firstIndexA/B < lastIndexA/B: all entries of the range A/B are disabled/enabled
68
- * firstIndexA/B == lastIndexA/B: one entry is disabled/enabled,
69
- * firstIndexA/B > lastIndexA/B: nothing disabled/enabled,
70
- * firstIndexA/B and lastIndexA/B > 9999: no entry is disabled/enabled """
71
- firstIndexA: Index
72
- lastIndexA: Index
73
- firstIndexB: Index
74
- lastIndexB: Index
75
-
76
-
77
- class DataDelete(cdt.Structure):
78
- """ Deletes a range of entries in the table.
79
- * firstIndex < lastIndex: all entries of the range A/B are deleted,
80
- * firstIndex ::= lastIndex: one entry is deleted,
81
- * firstIndex > lastIndex: nothing deleted """
82
- firstIndex: Index
83
- lastIndex: Index
84
-
85
-
86
- class Schedule(ic.COSEMInterfaceClasses):
87
- """ The IC “Schedule” together with an object of the IC “Special days” table handles time and date driven activities within a device.
88
- The following picture gives an overview and shows the interactions between them:
89
- Schedule:
90
-
91
- Index | enable | action | Switch_time | validity_window | exec_weekdays | exec_specdays | date range
92
- | |(script)| | | Mo Tu We Th Fr Sa Su | S1 S2 ... S8 S9 | begin_date | end_date
93
- 120 Yes xxxx:yy 06:00 0xFFFF x x x x x x xx-04-01 xx-09-30
94
- 121 Yes xxxx:yy 22:00 15 x x x x x xx-04-01 xx-09-30
95
- 122 Yes xxxx:yy 12:00 0 x xx-04-01 xx-09-30
96
- 200 No xxxx:yy 06:30 x x x x x x xx-04-01 xx-09-30
97
- 201 No xxxx:yy 21:30 x x x x x xx-04-01 xx-09-30
98
- 202 No xxxx:yy 11:00 x xx-04-01 xx-09-30
99
-
100
- Special days table:
101
-
102
- Index | special_day_date | day_id
103
- 12 xx-12-24 S1
104
- 33 xx-12-25 S3
105
- 77 97-03-31 S3
106
-
107
- Recovery after power failure
108
- After a power failure, the whole schedule is processed to execute all the necessary scripts that would get lost during a power failure. For this,
109
- the entries that were not executed during the power failure must be detected. Depending on the validity window attribute they are executed in
110
- the correct order (as they would have been executed in normal operation).
111
-
112
- Handling of time changes
113
- There are four different "actions" of time changes:
114
- a) time setting forward; b) time setting backwards; c) time synchronization; d) daylight saving action.
115
- All these four actions need a different handling executed by the schedule in interaction with the time setting activity.
116
-
117
- Time setting forward*
118
- This is handled the same way as a power failure. All entries missed are executed depending on the validity window attribute.
119
- A (manufacturer specific defined) short time setting can be handled like time synchronization.
120
- * Writing to the attribute “time” of the “Clock” object.
121
-
122
- Time setting backward*
123
- This results in a repetition of those entries that are activated during the repeated time. A (manufacturer specific defined) short time setting
124
- can be handled like time synchronization.
125
- * Writing to the attribute “time” of the “Clock” object.
126
-
127
- Time synchronization*
128
- Time synchronization is used to correct small deviations between a master clock and the local clock. The algorithm is manufacturer specific.
129
- It shall guarantee that no entry of the schedule gets lost, or is executed twice. The validity window attribute has no effect, because all
130
- entries must be executed in normal operation.
131
- * Using the method “adjust_to_quarter” of the “Clock” object.
132
-
133
- Daylight saving
134
- If the clock is put forward, then all scripts, which fall into the forwarding interval (and would therefore get lost) are executed.
135
- If the clock is put back, re-execution of the scripts, which fall into the backwarding interval is suppressed. """
136
- CLASS_ID = ClassID.SCHEDULE
137
- VERSION = VERSION_0
138
- A_ELEMENTS = ic.ICAElement("entries", Entries),
139
- M_ELEMENTS = (ic.ICMElement("enable_disable", DataED),
140
- ic.ICMElement("insert", ScheduleTableEntry),
141
- ic.ICMElement("delete", DataDelete))
142
-
143
- def characteristics_init(self):
144
- self.set_attr(2, None)
145
- self._cbs_attr_post_init.update({2: self.__set_index_cbs})
146
-
147
- @property
148
- def entries(self) -> Entries:
149
- return self.get_attr(2)
150
-
151
- @property
152
- def enable_disable(self) -> DataED:
153
- return self.get_meth(1)
154
-
155
- @property
156
- def insert(self) -> ScheduleTableEntry:
157
- return self.get_meth(2)
158
-
159
- @property
160
- def delete(self) -> DataDelete:
161
- return self.get_meth(3)
162
-
163
- def __set_index_cbs(self):
164
- """ set callbacks to methods """
165
- try:
166
- indexes: Callable = self.entries.get_indexes
167
- self.enable_disable.firstIndexA.set_callback(indexes)
168
- self.enable_disable.firstIndexB.set_callback(indexes)
169
- self.enable_disable.lastIndexA.set_callback(indexes)
170
- self.enable_disable.lastIndexB.set_callback(indexes)
171
- self.insert.index.set_callback(indexes)
172
- self.delete.firstIndex.set_callback(indexes)
173
- self.delete.lastIndex.set_callback(indexes)
174
- # print('set delete')
175
- except KeyError: # At init time
176
- print('set delete NO:')
1
+ from typing import Callable, Self
2
+ from .cosem_interface_class import ICAuto, ICAElement, ICMElement
3
+ from .Overview import class_id
4
+ from ..types import cdt, cst
5
+ from ..types.type_alias import Attr
6
+
7
+
8
+ class Index(cdt.LongUnsigned, min=1, max=9999):
9
+ """ LongUnsigned type with validation """
10
+ __cb_get_indexes: Callable
11
+ DEFAULT = 1
12
+
13
+ def set_callback(self, cb: Callable):
14
+ self.__cb_get_indexes = cb
15
+
16
+ def get_indexes(self) -> list[int]:
17
+ """ return indexes container """
18
+ return self.__cb_get_indexes()
19
+
20
+ def check(self, string: str):
21
+ """ raise ValueError with message if string not is valid """
22
+ instance = type(self)(value=string)
23
+ if int(instance) in self.__cb_get_indexes():
24
+ raise ValueError('New index not unique')
25
+
26
+ @classmethod
27
+ def with_cb(cls, value, cb: Callable) -> Self:
28
+ """ get instance with callback """
29
+ ret = cls(value)
30
+ ret.set_callback(cb)
31
+ return ret
32
+
33
+
34
+ class ScheduleTableEntry(cdt.Structure):
35
+ """schedule_table_entry"""
36
+ index: Index
37
+ enable: cdt.Boolean
38
+ script_logical_name: cst.LogicalName
39
+ script_selector: cdt.LongUnsigned
40
+ switch_time: cst.OctetStringTime
41
+ validity_window: cdt.LongUnsigned
42
+ exec_weekdays: cdt.BitString
43
+ exec_specdays: cdt.BitString
44
+ begin_date: cst.OctetStringDate
45
+ end_date: cst.OctetStringDate
46
+
47
+
48
+ # TODO: rewrite to new API
49
+ class Entries(cdt.Array):
50
+ """entries attribute"""
51
+ TYPE = ScheduleTableEntry
52
+ unique = True
53
+
54
+ def __init__(self, value: bytes = None):
55
+ super(Entries, self).__init__(value)
56
+ # setting callback for validate schedule_table_entry index
57
+ for schedule_table_entry in self:
58
+ schedule_table_entry: ScheduleTableEntry
59
+ schedule_table_entry.index.set_callback(self.get_indexes)
60
+
61
+ def get_indexes(self) -> list[int]:
62
+ """ getter for callback Index """
63
+ return [entries_element.index.decode() for entries_element in self]
64
+
65
+
66
+ class DataED(cdt.Structure):
67
+ """ enable/disable"""
68
+ firstIndexA: Index
69
+ lastIndexA: Index
70
+ firstIndexB: Index
71
+ lastIndexB: Index
72
+
73
+
74
+ class DataDelete(cdt.Structure):
75
+ """delete"""
76
+ firstIndex: Index
77
+ lastIndex: Index
78
+
79
+
80
+ class Schedule(ICAuto):
81
+ """4.5.3 Schedule"""
82
+ CLASS_ID = class_id.SCHEDULE
83
+ VERSION = 0
84
+ A_ELEMENTS = ICAElement(2, "entries", Entries),
85
+ M_ELEMENTS = (ICMElement(1, "enable_disable", DataED),
86
+ ICMElement(2, "insert", ScheduleTableEntry),
87
+ ICMElement(3, "delete", DataDelete))
88
+ entries: Attr
@@ -1,87 +1,54 @@
1
- from .__class_init__ import *
2
- from ..types import choices
3
- from .overview import VERSION_0
4
-
5
-
6
- class ServiceId(cdt.Enum, elements=(1, 2)):
7
- """defines which action to be applied to the referenced object."""
8
-
9
-
10
- class ActionSpecification(cdt.Structure):
11
- """ Specifies the different scripts, i.e. the lists of actions. The first attribute (logical_name) has index 1, the first specific method has
12
- index 1 as well. NOTE The action_specification is limited to activate methods that do not produce any response (from the server to the client). """
13
- service_id: ServiceId
14
- class_id: cdt.LongUnsigned
15
- logical_name: cst.LogicalName
16
- index: cdt.Integer
17
- parameter: choices.common_dt
18
-
19
-
20
- class Actions(cdt.Array):
21
- """ Specifies the list of action specification """
22
- TYPE = ActionSpecification
23
-
24
-
25
- class Script(cdt.Structure):
26
- """ Specifies the different scripts. The script_identifier 0 is reserved. If specified with an execute method, it results in a null script (no actions to perform)"""
27
- script_identifier: cdt.LongUnsigned
28
- actions: Actions
29
-
30
-
31
- class Scripts(cdt.Array):
32
- """ Specifies the lists of actions """
33
- TYPE = Script
34
- __get_item__: Script
35
-
36
- def new_element(self) -> Script:
37
- """return default Script with vacant script_identifier"""
38
- # todo: make common function by ID element
39
- el: Script
40
- day_ids: list[int] = [int(el.script_identifier) for el in self.values]
41
- for i in range(0xffff):
42
- if i not in day_ids:
43
- return Script((i, None))
44
- raise ValueError(F"in {self} all <script_identifier> is busy")
45
-
46
-
47
- class ScriptTable(ic.COSEMInterfaceClasses):
48
- """Script table"""
49
- CLASS_ID = ClassID.SCRIPT_TABLE
50
- VERSION = VERSION_0
51
- A_ELEMENTS = ic.ICAElement("scripts", Scripts),
52
- M_ELEMENTS = ic.ICMElement("execute", cdt.LongUnsigned),
53
-
54
- def characteristics_init(self):
55
- self.set_attr(2, None)
56
- self._cbs_attr_post_init.update({2: self.__set_script_identifier_cbs})
57
-
58
- @property
59
- def scripts(self) -> Scripts:
60
- return self.get_attr(2)
61
-
62
- @property
63
- def execute(self) -> cdt.LongUnsigned:
64
- return self.get_meth(1)
65
-
66
- def __set_script_identifier_cbs(self):
67
- pass
68
- # try:
69
- # indexes: Callable = self.entries.get_indexes
70
- # self.enable_disable.firstIndexA.set_callback(indexes)
71
- # self.enable_disable.firstIndexB.set_callback(indexes)
72
- # self.enable_disable.lastIndexA.set_callback(indexes)
73
- # self.enable_disable.lastIndexB.set_callback(indexes)
74
- # self.insert.index.set_callback(indexes)
75
- # self.delete.firstIndex.set_callback(indexes)
76
- # self.delete.lastIndex.set_callback(indexes)
77
- # print('set delete')
78
- # except KeyError: # At init time
79
- # print('set delete NO:')
80
-
81
-
82
- if __name__ == '__main__':
83
- a = b'\x01\x04\x02\x02\x12\x00\x01\x01\x01\x02\x05\x16\x01\x12\x00F\t\x06\x00\x00`\x03\n\xff\x0f\x04\x16\x00\x02\x02\x12\x00\x02\x01\x01\x02\x05\x16\x02\x12\x00F\t\x06\x00\x00`\x03\n\xff\x0f\x01\x03\x00\x02\x02\x12\x00\x03\x01\x01\x02\x05\x16\x01\x12\x00F\t\x06\x00\x00`\x03\n\xff\x0f\x04\x16\x01\x02\x02\x12\x00\x04\x01\x01\x02\x05\x16\x02\x12\x00F\t\x06\x00\x00`\x03\n\xff\x0f\x01\x03\x01'
84
- b = Scripts(a)
85
- a = ScriptTable('0.0.10.0.0.255')
86
- pass
87
- print(a)
1
+ from ..types import choices, cdt, cst
2
+ from ..types.type_alias import Attr
3
+ from .cosem_interface_class import ICAuto, ICAElement, ICMElement
4
+ from .Overview import class_id
5
+
6
+
7
+ class ServiceId(cdt.Enum, elements=(1, 2)):
8
+ """defines which action to be applied to the referenced object."""
9
+
10
+
11
+ class ActionSpecification(cdt.Structure):
12
+ """ Specifies the different scripts, i.e. the lists of actions. The first attribute (logical_name) has index 1, the first specific method has
13
+ index 1 as well. NOTE The action_specification is limited to activate methods that do not produce any response (from the server to the client). """
14
+ service_id: ServiceId
15
+ class_id: cdt.LongUnsigned
16
+ logical_name: cst.LogicalName
17
+ index: cdt.Integer
18
+ parameter: choices.common_dt
19
+
20
+
21
+ class Actions(cdt.Array):
22
+ """ Specifies the list of action specification """
23
+ TYPE = ActionSpecification
24
+
25
+
26
+ class Script(cdt.Structure):
27
+ """ Specifies the different scripts. The script_identifier 0 is reserved. If specified with an execute method, it results in a null script (no actions to perform)"""
28
+ script_identifier: cdt.LongUnsigned
29
+ actions: Actions
30
+
31
+
32
+ class Scripts(cdt.Array):
33
+ """ Specifies the lists of actions """
34
+ TYPE = Script
35
+ __get_item__: Script
36
+
37
+ def new_element(self) -> Script:
38
+ """return default Script with vacant script_identifier"""
39
+ # todo: make common function by ID element
40
+ el: Script
41
+ day_ids: list[int] = [int(el.script_identifier) for el in self.values]
42
+ for i in range(0xffff):
43
+ if i not in day_ids:
44
+ return Script((i, None))
45
+ raise ValueError(F"in {self} all <script_identifier> is busy")
46
+
47
+
48
+ class ScriptTable(ICAuto):
49
+ """Script table"""
50
+ CLASS_ID = class_id.SCRIPT_TABLE
51
+ VERSION = 0
52
+ A_ELEMENTS = ICAElement(2, "scripts", Scripts),
53
+ M_ELEMENTS = ICMElement(1, "execute", cdt.LongUnsigned),
54
+ scripts: Attr