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.
- DLMS_SPODES/Values/EN/__init__.py +1 -1
- DLMS_SPODES/Values/EN/actors.py +8 -8
- DLMS_SPODES/Values/EN/relation_to_obis_names.py +387 -387
- DLMS_SPODES/Values/RU/__init__.py +1 -1
- DLMS_SPODES/Values/RU/actors.py +8 -8
- DLMS_SPODES/Values/RU/relation_to_obis_names.py +396 -396
- DLMS_SPODES/__init__.py +6 -6
- DLMS_SPODES/configEN.ini +126 -126
- DLMS_SPODES/config_parser.py +53 -53
- DLMS_SPODES/cosem_interface_classes/Overview/__init__.py +0 -0
- DLMS_SPODES/cosem_interface_classes/Overview/class_id.py +107 -0
- DLMS_SPODES/cosem_interface_classes/__class_init__.py +3 -3
- DLMS_SPODES/cosem_interface_classes/__init__.py +3 -2
- DLMS_SPODES/cosem_interface_classes/activity_calendar.py +210 -254
- DLMS_SPODES/cosem_interface_classes/arbitrator.py +78 -105
- DLMS_SPODES/cosem_interface_classes/association_ln/abstract.py +50 -34
- DLMS_SPODES/cosem_interface_classes/association_ln/authentication_mechanism_name.py +25 -25
- DLMS_SPODES/cosem_interface_classes/association_ln/mechanism_id.py +25 -25
- DLMS_SPODES/cosem_interface_classes/association_ln/method.py +5 -5
- DLMS_SPODES/cosem_interface_classes/association_ln/ver0.py +440 -485
- DLMS_SPODES/cosem_interface_classes/association_ln/ver1.py +126 -133
- DLMS_SPODES/cosem_interface_classes/association_ln/ver2.py +30 -36
- DLMS_SPODES/cosem_interface_classes/association_ln/ver3.py +3 -4
- DLMS_SPODES/cosem_interface_classes/association_sn/ver0.py +14 -12
- DLMS_SPODES/cosem_interface_classes/clock.py +81 -131
- DLMS_SPODES/cosem_interface_classes/collection.py +2106 -2122
- DLMS_SPODES/cosem_interface_classes/cosem_interface_class.py +525 -583
- DLMS_SPODES/cosem_interface_classes/data.py +12 -21
- DLMS_SPODES/cosem_interface_classes/demand_register/ver0.py +32 -59
- DLMS_SPODES/cosem_interface_classes/disconnect_control.py +56 -74
- DLMS_SPODES/cosem_interface_classes/extended_register.py +18 -27
- DLMS_SPODES/cosem_interface_classes/gprs_modem_setup.py +33 -43
- DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver0.py +78 -103
- DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver1.py +42 -40
- DLMS_SPODES/cosem_interface_classes/gsm_diagnostic/ver2.py +6 -9
- DLMS_SPODES/cosem_interface_classes/iec_hdlc_setup/ver0.py +11 -11
- DLMS_SPODES/cosem_interface_classes/iec_hdlc_setup/ver1.py +27 -53
- DLMS_SPODES/cosem_interface_classes/iec_local_port_setup.py +9 -11
- DLMS_SPODES/cosem_interface_classes/image_transfer/image_transfer_status.py +15 -15
- DLMS_SPODES/cosem_interface_classes/image_transfer/ver0.py +54 -126
- DLMS_SPODES/cosem_interface_classes/implementations/__init__.py +3 -3
- DLMS_SPODES/cosem_interface_classes/implementations/arbitrator.py +19 -19
- DLMS_SPODES/cosem_interface_classes/implementations/data.py +491 -487
- DLMS_SPODES/cosem_interface_classes/implementations/profile_generic.py +85 -83
- DLMS_SPODES/cosem_interface_classes/ipv4_setup.py +42 -72
- DLMS_SPODES/cosem_interface_classes/limiter.py +77 -111
- DLMS_SPODES/cosem_interface_classes/ln_pattern.py +334 -333
- DLMS_SPODES/cosem_interface_classes/modem_configuration/ver0.py +51 -65
- DLMS_SPODES/cosem_interface_classes/modem_configuration/ver1.py +27 -39
- DLMS_SPODES/cosem_interface_classes/ntp_setup/ver0.py +48 -67
- DLMS_SPODES/cosem_interface_classes/obis.py +28 -23
- DLMS_SPODES/cosem_interface_classes/overview.py +198 -197
- DLMS_SPODES/cosem_interface_classes/parameter.py +548 -547
- DLMS_SPODES/cosem_interface_classes/parameters.py +172 -172
- DLMS_SPODES/cosem_interface_classes/profile_generic/ver0.py +90 -122
- DLMS_SPODES/cosem_interface_classes/profile_generic/ver1.py +268 -277
- DLMS_SPODES/cosem_interface_classes/push_setup/ver0.py +13 -12
- DLMS_SPODES/cosem_interface_classes/push_setup/ver1.py +9 -10
- DLMS_SPODES/cosem_interface_classes/push_setup/ver2.py +124 -166
- DLMS_SPODES/cosem_interface_classes/register.py +18 -45
- DLMS_SPODES/cosem_interface_classes/register_activation/ver0.py +45 -80
- DLMS_SPODES/cosem_interface_classes/register_monitor.py +33 -46
- DLMS_SPODES/cosem_interface_classes/reports.py +72 -70
- DLMS_SPODES/cosem_interface_classes/schedule.py +88 -176
- DLMS_SPODES/cosem_interface_classes/script_table.py +54 -87
- DLMS_SPODES/cosem_interface_classes/security_setup/ver0.py +45 -68
- DLMS_SPODES/cosem_interface_classes/security_setup/ver1.py +122 -158
- DLMS_SPODES/cosem_interface_classes/single_action_schedule.py +34 -50
- DLMS_SPODES/cosem_interface_classes/special_days_table.py +54 -84
- DLMS_SPODES/cosem_interface_classes/tcp_udp_setup.py +20 -42
- DLMS_SPODES/cosem_pdu.py +93 -93
- DLMS_SPODES/enums.py +625 -625
- DLMS_SPODES/exceptions.py +106 -106
- DLMS_SPODES/firmwares.py +99 -99
- DLMS_SPODES/hdlc/frame.py +875 -875
- DLMS_SPODES/hdlc/sub_layer.py +54 -54
- DLMS_SPODES/literals.py +17 -17
- DLMS_SPODES/obis/__init__.py +1 -1
- DLMS_SPODES/obis/media_id.py +931 -931
- DLMS_SPODES/pardata.py +22 -22
- DLMS_SPODES/pdu_enums.py +98 -98
- DLMS_SPODES/relation_to_OBIS.py +463 -465
- DLMS_SPODES/settings.py +551 -551
- DLMS_SPODES/types/choices.py +140 -142
- DLMS_SPODES/types/common_data_types.py +2379 -2401
- DLMS_SPODES/types/cosem_service_types.py +109 -109
- DLMS_SPODES/types/implementations/arrays.py +25 -25
- DLMS_SPODES/types/implementations/bitstrings.py +97 -97
- DLMS_SPODES/types/implementations/double_long_usingneds.py +35 -35
- DLMS_SPODES/types/implementations/enums.py +57 -57
- DLMS_SPODES/types/implementations/integers.py +12 -11
- DLMS_SPODES/types/implementations/long_unsigneds.py +127 -127
- DLMS_SPODES/types/implementations/octet_string.py +11 -11
- DLMS_SPODES/types/implementations/structs.py +64 -64
- DLMS_SPODES/types/type_alias.py +74 -0
- DLMS_SPODES/types/useful_types.py +627 -677
- {dlms_spodes-0.87.16.dist-info → dlms_spodes-0.88.1.dist-info}/METADATA +30 -30
- dlms_spodes-0.88.1.dist-info/RECORD +118 -0
- {dlms_spodes-0.87.16.dist-info → dlms_spodes-0.88.1.dist-info}/WHEEL +1 -1
- DLMS_SPODES/cosem_interface_classes/a_parameter.py +0 -20
- DLMS_SPODES/cosem_interface_classes/attr_indexes.py +0 -12
- dlms_spodes-0.87.16.dist-info/RECORD +0 -117
- {dlms_spodes-0.87.16.dist-info → dlms_spodes-0.88.1.dist-info}/top_level.txt +0 -0
|
@@ -1,83 +1,85 @@
|
|
|
1
|
-
from ..
|
|
2
|
-
from
|
|
3
|
-
from ...types import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
ver1.ProfileGeneric.A_ELEMENTS[
|
|
46
|
-
ver1.ProfileGeneric.A_ELEMENTS[
|
|
47
|
-
ver1.ProfileGeneric.A_ELEMENTS[
|
|
48
|
-
ver1.ProfileGeneric.A_ELEMENTS[
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
self.
|
|
55
|
-
|
|
56
|
-
self.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
1
|
+
from ..cosem_interface_class import ICAElement
|
|
2
|
+
from ..profile_generic import ver0, ver1
|
|
3
|
+
from ...types.implementations import structs, enums
|
|
4
|
+
from ...types import ut, cdt
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SPODES3ScalesProfile(ver1.ProfileGeneric):
|
|
8
|
+
"""Cosem3 Для профилей масштаба"""
|
|
9
|
+
A_ELEMENTS = (
|
|
10
|
+
ICAElement(
|
|
11
|
+
i=2,
|
|
12
|
+
NAME=ver1.ProfileGeneric.A_ELEMENTS[0].NAME,
|
|
13
|
+
DATA_TYPE=ver1.ProfileGeneric.A_ELEMENTS[0].DATA_TYPE),
|
|
14
|
+
*ver1.ProfileGeneric.A_ELEMENTS[1:])
|
|
15
|
+
"""override buffer with STATIC classifier"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SPODES3CurrentProfile(ver1.ProfileGeneric):
|
|
19
|
+
"""Cosem3 Б.1 Текущие значения"""
|
|
20
|
+
scaler_profile_key = bytes((1, 0, 94, 7, 3, 255))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SPODES3MonthProfile(ver1.ProfileGeneric):
|
|
24
|
+
"""СПОДЭС3 В.4 Параметры ежемесячного профиля"""
|
|
25
|
+
scaler_profile_key = bytes((1, 0, 94, 7, 1, 255))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SPODES3DailyProfile(ver1.ProfileGeneric):
|
|
29
|
+
"""СПОДЭС3 В.3 Параметры ежесуточного профиля"""
|
|
30
|
+
scaler_profile_key = bytes((1, 0, 94, 7, 2, 255))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SPODES3LoadProfile(ver1.ProfileGeneric):
|
|
34
|
+
"""СПОДЭС3 В.2 Параметры профиля нагрузки"""
|
|
35
|
+
scaler_profile_key = bytes((1, 0, 94, 7, 4, 255))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CaptureObjectsDisplayReadout(ver1.CaptureObjects):
|
|
39
|
+
"""for DisplayReadout special"""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SPODES3DisplayReadout(ver1.ProfileGeneric):
|
|
43
|
+
"""СПОДЭС3 13.12. Настройка индикации"""
|
|
44
|
+
A_ELEMENTS = (ver1.ProfileGeneric.A_ELEMENTS[0],
|
|
45
|
+
ver1.ProfileGeneric.A_ELEMENTS[1].get_change(data_type=CaptureObjectsDisplayReadout),
|
|
46
|
+
ver1.ProfileGeneric.A_ELEMENTS[2],
|
|
47
|
+
ver1.ProfileGeneric.A_ELEMENTS[3],
|
|
48
|
+
ver1.ProfileGeneric.A_ELEMENTS[4],
|
|
49
|
+
ver1.ProfileGeneric.A_ELEMENTS[5],
|
|
50
|
+
ver1.ProfileGeneric.A_ELEMENTS[6])
|
|
51
|
+
|
|
52
|
+
def characteristics_init(self):
|
|
53
|
+
self.set_attr(ver0.BUFFER, None)
|
|
54
|
+
self.buffer.register_cb_preset(lambda _: self.__create_buffer_struct_type()) # value not used for creating struct type
|
|
55
|
+
|
|
56
|
+
self._cbs_attr_post_init.update({ver0.CAPTURE_OBJECTS: self.__create_buffer_struct_type})
|
|
57
|
+
|
|
58
|
+
self.buffer_capture_objects = self.capture_objects
|
|
59
|
+
""" objects for buffer. Change with access_selection """
|
|
60
|
+
|
|
61
|
+
def __create_buffer_struct_type(self):
|
|
62
|
+
""" TODO: more refactoring !!! """
|
|
63
|
+
# rename CaptureObjectDefinition's and adding object if it absense in collection
|
|
64
|
+
for el_value in self.capture_objects:
|
|
65
|
+
el_value: structs.CaptureObjectDefinition
|
|
66
|
+
obj = self.collection.add_if_missing(class_id=ut.CosemClassId(el_value.class_id.contents),
|
|
67
|
+
version=None,
|
|
68
|
+
logical_name=el_value.logical_name)
|
|
69
|
+
el_value.set_name(self.collection.get_name_and_type(el_value)[0][-1])
|
|
70
|
+
self.buffer_capture_objects = self.capture_objects
|
|
71
|
+
buffer_elements: list[cdt.StructElement] = list()
|
|
72
|
+
for el_value in self.buffer_capture_objects:
|
|
73
|
+
names, type_ = self.collection.get_name_and_type(el_value)
|
|
74
|
+
buffer_elements.append(cdt.StructElement(NAME=". ".join(names), TYPE=cdt.Boolean))
|
|
75
|
+
|
|
76
|
+
class Entry(cdt.Structure):
|
|
77
|
+
""" The number and the order of the elements of the structure holding the entries is the same as in the definition of the capture_objects.
|
|
78
|
+
The buffer is filled by auto captures or by subsequent calls of the method (capture). The sequence of the entries within the array is ordered
|
|
79
|
+
according to the sort method specified. Default: The buffer is empty after reset.
|
|
80
|
+
REMARK 1 Reading the entire buffer delivers only those entries, which are “in use”.
|
|
81
|
+
REMARK 2 The value of a captured object may be replaced by “null-data” if it can be unambiguously recovered from the previous value
|
|
82
|
+
(e.g. for time: if it can be calculated from the previous value and capture_period; or for a value: if it is equal to the previous value). """
|
|
83
|
+
ELEMENTS = tuple(buffer_elements)
|
|
84
|
+
|
|
85
|
+
self.buffer.set_type(Entry)
|
|
@@ -1,72 +1,42 @@
|
|
|
1
|
-
from .
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
CLASS_ID =
|
|
21
|
-
VERSION =
|
|
22
|
-
# TODO: more
|
|
23
|
-
A_ELEMENTS = (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# TODO: more 3 methods
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def IP_address(self) -> double_long_usingneds.IPAddress:
|
|
44
|
-
return self.get_attr(3)
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def multicast_IP_address(self) -> arrays.MulticastIPAddress:
|
|
48
|
-
return self.get_attr(4)
|
|
49
|
-
|
|
50
|
-
@property
|
|
51
|
-
def IP_options(self) -> IPOptions:
|
|
52
|
-
return self.get_attr(5)
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def subnet_mask(self) -> double_long_usingneds.IPAddress:
|
|
56
|
-
return self.get_attr(6)
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def gateway_IP_address(self) -> double_long_usingneds.IPAddress:
|
|
60
|
-
return self.get_attr(7)
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def use_DHCP_flag(self) -> cdt.Boolean:
|
|
64
|
-
return self.get_attr(8)
|
|
65
|
-
|
|
66
|
-
@property
|
|
67
|
-
def primary_DNS_address(self) -> double_long_usingneds.IPAddress:
|
|
68
|
-
return self.get_attr(9)
|
|
69
|
-
|
|
70
|
-
@property
|
|
71
|
-
def secondary_DNS_address(self) -> double_long_usingneds.IPAddress:
|
|
72
|
-
return self.get_attr(10)
|
|
1
|
+
from ..types.implementations import double_long_usingneds, arrays
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from ..types import cdt, cst
|
|
4
|
+
from .cosem_interface_class import ICAElement, ICAuto
|
|
5
|
+
from .Overview import class_id
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IPOptionsElement(cdt.Structure):
|
|
9
|
+
IP_Option_Type: cdt.Unsigned
|
|
10
|
+
IP_Option_Length: cdt.Unsigned
|
|
11
|
+
IP_Option_Data: cdt.OctetString
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IPOptions(cdt.Array):
|
|
15
|
+
TYPE = IPOptionsElement
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class IPv4Setup(ICAuto):
|
|
19
|
+
"""4.9.2 IPv4 setup"""
|
|
20
|
+
CLASS_ID = class_id.IPV4_SETUP
|
|
21
|
+
VERSION = 0
|
|
22
|
+
# TODO: more 3 methods
|
|
23
|
+
A_ELEMENTS = (ICAElement(2, "DL_reference", cst.LogicalName),
|
|
24
|
+
ICAElement(3, "IP_address", double_long_usingneds.IPAddress),
|
|
25
|
+
ICAElement(4, "multicast_IP_address", arrays.MulticastIPAddress),
|
|
26
|
+
ICAElement(5, "IP_options", IPOptions),
|
|
27
|
+
ICAElement(6, "subnet_mask", double_long_usingneds.IPAddress),
|
|
28
|
+
ICAElement(7, "gateway_IP_address", double_long_usingneds.IPAddress),
|
|
29
|
+
ICAElement(8, "use_DHCP_flag", cdt.Boolean),
|
|
30
|
+
ICAElement(9, "primary_DNS_address", double_long_usingneds.IPAddress),
|
|
31
|
+
ICAElement(10, "secondary_DNS_address", double_long_usingneds.IPAddress),
|
|
32
|
+
# TODO: more 3 methods
|
|
33
|
+
)
|
|
34
|
+
DL_reference: Optional[cdt.OctetString]
|
|
35
|
+
IP_address: Optional[double_long_usingneds.IPAddress]
|
|
36
|
+
multicast_IP_address: Optional[arrays.MulticastIPAddress]
|
|
37
|
+
IP_options: Optional[IPOptions]
|
|
38
|
+
subnet_mask: Optional[double_long_usingneds.IPAddress]
|
|
39
|
+
gateway_IP_address: Optional[double_long_usingneds.IPAddress]
|
|
40
|
+
use_DHCP_flag: Optional[cdt.Boolean]
|
|
41
|
+
primary_DNS_address: Optional[double_long_usingneds.IPAddress]
|
|
42
|
+
secondary_DNS_address: Optional[double_long_usingneds.IPAddress]
|
|
@@ -1,111 +1,77 @@
|
|
|
1
|
-
from .. import
|
|
2
|
-
from .. import
|
|
3
|
-
from .
|
|
4
|
-
from ..types import
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
emergency_activation_time and emergency_duration
|
|
23
|
-
emergency_profile_id
|
|
24
|
-
emergency_activation_time
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@property
|
|
80
|
-
def threshold_emergency(self) -> choices.simple_dt:
|
|
81
|
-
return self.get_attr(5)
|
|
82
|
-
|
|
83
|
-
@property
|
|
84
|
-
def min_over_threshold_duration(self) -> double_long_usingneds.DoubleLongUnsignedSecond:
|
|
85
|
-
return self.get_attr(6)
|
|
86
|
-
|
|
87
|
-
@property
|
|
88
|
-
def min_under_threshold_duration(self) -> double_long_usingneds.DoubleLongUnsignedSecond:
|
|
89
|
-
return self.get_attr(7)
|
|
90
|
-
|
|
91
|
-
@property
|
|
92
|
-
def emergency_profile(self) -> EmergencyProfileType:
|
|
93
|
-
return self.get_attr(8)
|
|
94
|
-
|
|
95
|
-
@property
|
|
96
|
-
def emergency_profile_group_id_list(self) -> EmergencyProfileGroupIdList:
|
|
97
|
-
return self.get_attr(9)
|
|
98
|
-
|
|
99
|
-
@property
|
|
100
|
-
def emergency_profile_active(self) -> cdt.Boolean:
|
|
101
|
-
return self.get_attr(10)
|
|
102
|
-
|
|
103
|
-
@property
|
|
104
|
-
def actions(self) -> ActionType:
|
|
105
|
-
return self.get_attr(11)
|
|
106
|
-
|
|
107
|
-
def __validate_threshold_scaler_unit(self, index: int, value: cdt.CommonDataTypes):
|
|
108
|
-
if self.monitored_value is not None:
|
|
109
|
-
"""let setup"""
|
|
110
|
-
else:
|
|
111
|
-
raise exc.EmptyObj(F"don't set attribute: {index} with {value=} because {self} monitored_value is empty")
|
|
1
|
+
from .. import exceptions as exc
|
|
2
|
+
from ..types import choices
|
|
3
|
+
from ..types.implementations import structs
|
|
4
|
+
from ..types.implementations import double_long_usingneds
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from ..types import cdt, cst
|
|
7
|
+
from .cosem_interface_class import ICAElement, ICAuto, Classifier
|
|
8
|
+
from .Overview import class_id
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
threshold_scaler_unit = cdt.ScalUnitType(b'\x02\x02\x0f\x00\x16\x07')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ValueDefinitionType(cdt.Structure):
|
|
15
|
+
""" Defines an attribute of an object to be monitored. Only attributes with simple data types are allowed. """
|
|
16
|
+
class_id: cdt.LongUnsigned
|
|
17
|
+
logical_name: cst.LogicalName
|
|
18
|
+
attribute_index: cdt.Integer
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class EmergencyProfileType(cdt.Structure):
|
|
22
|
+
""" An emergency_profile is defined by three elements: emergency_profile_id, emergency_activation_time and emergency_duration.
|
|
23
|
+
An emergency profile is activated if the emergency_profile_id element matches one of the elements on the emergency_profile _group_id_list, and time matches the
|
|
24
|
+
emergency_activation_time and emergency_duration element """
|
|
25
|
+
emergency_profile_id: cdt.LongUnsigned
|
|
26
|
+
emergency_activation_time: cst.OctetStringDateTime
|
|
27
|
+
emergency_duration: double_long_usingneds.DoubleLongUnsignedSecond
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class EmergencyProfileGroupIdList(cdt.Array):
|
|
31
|
+
""" A list of group id-s of the emergency profile. The emergency profile can be activated only if emergency_profile_id element of the emergency_profile_type matches one of the
|
|
32
|
+
elements on the emergency_profile_group_id list """
|
|
33
|
+
TYPE = cdt.LongUnsigned
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ActionType(cdt.Structure):
|
|
37
|
+
""" Defines the scripts to be executed when the monitored value crosses the threshold for minimal duration time. """
|
|
38
|
+
action_over_threshold: structs.ActionItem
|
|
39
|
+
action_under_threshold: structs.ActionItem
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Limiter(ICAuto):
|
|
43
|
+
"""4.5.9 Limiter"""
|
|
44
|
+
CLASS_ID = class_id.LIMITER
|
|
45
|
+
VERSION = 0
|
|
46
|
+
A_ELEMENTS = (ICAElement(2, "monitored_value", structs.ValueDefinition),
|
|
47
|
+
ICAElement(3, "threshold_active", choices.simple_dt, classifier=Classifier.DYNAMIC),
|
|
48
|
+
ICAElement(4, "threshold_normal", choices.simple_dt),
|
|
49
|
+
ICAElement(5, "threshold_emergency", choices.simple_dt),
|
|
50
|
+
ICAElement(6, "min_over_threshold_duration", double_long_usingneds.DoubleLongUnsignedSecond),
|
|
51
|
+
ICAElement(7, "min_under_threshold_duration", double_long_usingneds.DoubleLongUnsignedSecond),
|
|
52
|
+
ICAElement(8, "emergency_profile", EmergencyProfileType),
|
|
53
|
+
ICAElement(9, "emergency_profile_group_id_list", EmergencyProfileGroupIdList),
|
|
54
|
+
ICAElement(10, "emergency_profile_active", cdt.Boolean, classifier=Classifier.DYNAMIC),
|
|
55
|
+
ICAElement(11, "actions", ActionType))
|
|
56
|
+
monitored_value: Optional[structs.ValueDefinition]
|
|
57
|
+
threshold_active: Optional[choices.simple_dt]
|
|
58
|
+
threshold_normal: Optional[choices.simple_dt]
|
|
59
|
+
threshold_emergency: Optional[choices.simple_dt]
|
|
60
|
+
min_over_threshold_duration: Optional[double_long_usingneds.DoubleLongUnsignedSecond]
|
|
61
|
+
min_under_threshold_duration: Optional[double_long_usingneds.DoubleLongUnsignedSecond]
|
|
62
|
+
emergency_profile: Optional[EmergencyProfileType]
|
|
63
|
+
emergency_profile_group_id_list: Optional[EmergencyProfileGroupIdList]
|
|
64
|
+
emergency_profile_active: Optional[cdt.Boolean]
|
|
65
|
+
actions: Optional[ActionType]
|
|
66
|
+
|
|
67
|
+
def characteristics_init(self):
|
|
68
|
+
self._cbs_attr_before_init.update({
|
|
69
|
+
3: lambda value: self.__validate_threshold_scaler_unit(3, value),
|
|
70
|
+
4: lambda value: self.__validate_threshold_scaler_unit(4, value),
|
|
71
|
+
5: lambda value: self.__validate_threshold_scaler_unit(5, value)})
|
|
72
|
+
|
|
73
|
+
def __validate_threshold_scaler_unit(self, index: int, value: cdt.CommonDataTypes):
|
|
74
|
+
if self.monitored_value is not None:
|
|
75
|
+
"""let setup"""
|
|
76
|
+
else:
|
|
77
|
+
raise exc.EmptyObj(F"don't set attribute: {index} with {value=} because {self} monitored_value is empty")
|