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,133 +1,126 @@
|
|
|
1
|
-
from . import ver0
|
|
2
|
-
from ...
|
|
3
|
-
from ... import
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
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
|
-
it:
|
|
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
|
-
el
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
remove_object: ObjectListElement
|
|
128
|
-
|
|
129
|
-
def characteristics_init(self):
|
|
130
|
-
super(AssociationLN, self).characteristics_init()
|
|
131
|
-
# References a "Security setup" object by its logical name. The referenced object manages security for a given "Association LN" object
|
|
132
|
-
# instance.
|
|
133
|
-
self.set_attr(9, None)
|
|
1
|
+
from . import ver0
|
|
2
|
+
from ... import exceptions as exc
|
|
3
|
+
from ...types.implementations import structs
|
|
4
|
+
from . import authentication_mechanism_name
|
|
5
|
+
from . import abstract
|
|
6
|
+
from ...types import choices, cdt, cst
|
|
7
|
+
from ..cosem_interface_class import ICAElement, ICMElement
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AccessMode(abstract.AccessMode, elements=tuple(range(7))):
|
|
11
|
+
"""Version 0 extension"""
|
|
12
|
+
def is_writable(self) -> bool:
|
|
13
|
+
return True if int(self) in (2, 3, 5, 6) else False
|
|
14
|
+
|
|
15
|
+
def is_readable(self) -> bool:
|
|
16
|
+
return True if int(self) in (1, 3, 4, 6) else False
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AccessModeMeth(cdt.Enum, elements=(0, 1, 2)):
|
|
20
|
+
""" Enum of access mode for methods """
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# TODO: make as subclass of ver0
|
|
24
|
+
class AttributeAccessItem(abstract.AttributeAccessItem):
|
|
25
|
+
""" Implemented attribute and it access . Use in Association LN """
|
|
26
|
+
attribute_id: cdt.Integer
|
|
27
|
+
access_mode: AccessMode
|
|
28
|
+
access_selectors: choices.access_selectors
|
|
29
|
+
|
|
30
|
+
def abstract_marker(self):
|
|
31
|
+
...
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class AttributeAccessDescriptor(abstract.AttributeAccessDescriptor):
|
|
35
|
+
""" Array of attribute_access_item """
|
|
36
|
+
TYPE = AttributeAccessItem
|
|
37
|
+
|
|
38
|
+
def set_read_access(self, attribute_id: cdt.Integer):
|
|
39
|
+
it: AttributeAccessItem
|
|
40
|
+
for it in self:
|
|
41
|
+
if it.attribute_id == attribute_id:
|
|
42
|
+
it.access_mode.set(1)
|
|
43
|
+
break
|
|
44
|
+
else:
|
|
45
|
+
self.append(AttributeAccessItem((attribute_id, AccessMode.parse("1"), None)))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# TODO: make as subclass of ver0
|
|
49
|
+
class MethodAccessItem(cdt.Structure):
|
|
50
|
+
""" Implemented method and it access . Use in Association LN """
|
|
51
|
+
method_id: cdt.Integer
|
|
52
|
+
access_mode: AccessModeMeth
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class MethodAccessDescriptor(cdt.Array):
|
|
56
|
+
""" Contain all implemented methods """
|
|
57
|
+
TYPE = MethodAccessItem
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class AccessRight(cdt.Structure):
|
|
61
|
+
""" TODO: """
|
|
62
|
+
attribute_access: AttributeAccessDescriptor
|
|
63
|
+
method_access: MethodAccessDescriptor
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ObjectListElement(structs.ObjectListElement, access_rights=AccessRight):
|
|
67
|
+
""""""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ObjectListType(ver0.ObjectListType):
|
|
71
|
+
TYPE = ObjectListElement
|
|
72
|
+
|
|
73
|
+
def is_writable(self, ln: cst.LogicalName, indexes: set[int]) -> bool:
|
|
74
|
+
""" index - DLMS object attribute index.
|
|
75
|
+
True: AccessRight is WriteOnly or ReadAndWrite """
|
|
76
|
+
el: ObjectListElement = next(filter(lambda it: it.logical_name == ln, self), None)
|
|
77
|
+
if el is None:
|
|
78
|
+
raise exc.NoObject(F"not find {ln} in object_list")
|
|
79
|
+
item: AttributeAccessItem
|
|
80
|
+
for index in indexes:
|
|
81
|
+
for item in el.access_rights.attribute_access:
|
|
82
|
+
if int(item.attribute_id) == index:
|
|
83
|
+
if int(item.access_mode) not in (2, 3, 5, 6):
|
|
84
|
+
return False
|
|
85
|
+
else:
|
|
86
|
+
break
|
|
87
|
+
else:
|
|
88
|
+
continue
|
|
89
|
+
else:
|
|
90
|
+
raise ValueError(F"not find in {ln} attribute index: {index}")
|
|
91
|
+
return True
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class ContextNameType(cdt.AXDR, ver0.ApplicationContextName):
|
|
95
|
+
""" In the COSEM environment, it is intended that an application context pre-exists and is referenced by its name during the establishment of an
|
|
96
|
+
application association. This attribute contains the name of the application context for that association."""
|
|
97
|
+
DEFAULT = b'\x09\x07\x60\x85\x74\x05\x08\x01\x01'
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MechanismNameType(cdt.AXDR, authentication_mechanism_name.AuthenticationMechanismName):
|
|
101
|
+
""" In the COSEM environment, it is intended that an application context pre-exists and is referenced by its name during the establishment of an
|
|
102
|
+
application association. This attribute contains the name of the application context for that association."""
|
|
103
|
+
DEFAULT = b'\x09\x07\x60\x85\x74\x05\x08\x02\x00'
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class AssociationLN(ver0.AssociationLN):
|
|
107
|
+
"""5.4.6 Association LN"""
|
|
108
|
+
VERSION = 1
|
|
109
|
+
A_ELEMENTS = (ICAElement(2, "object_list", ObjectListType, selective_access=ver0.SelectiveAccessDescriptor),
|
|
110
|
+
ver0.AssociationLN.getAElement(3).unwrap(), # associated_partners_id
|
|
111
|
+
ICAElement(4, "application_context_name", ContextNameType),
|
|
112
|
+
ver0.AssociationLN.getAElement(5).unwrap(), # xDLMS_context_info
|
|
113
|
+
ICAElement(6, "authentication_mechanism_name", MechanismNameType),
|
|
114
|
+
ICAElement(7, "secret", ver0.LLCSecret), # TODO: make new class Secret(LLC_Secret)
|
|
115
|
+
ver0.AssociationLN.getAElement(8).unwrap(), # association_status
|
|
116
|
+
ICAElement(9, "security_setup_reference", cst.LogicalName))
|
|
117
|
+
M_ELEMENTS = (ver0.AssociationLN.getMElement(1).unwrap(),
|
|
118
|
+
ver0.AssociationLN.getMElement(2).unwrap(),
|
|
119
|
+
ICMElement(3, "add_object", ObjectListElement),
|
|
120
|
+
ICMElement(4, "remove_object", ObjectListElement))
|
|
121
|
+
object_list: ObjectListType
|
|
122
|
+
application_context_name: ContextNameType
|
|
123
|
+
authentication_mechanism_name: MechanismNameType
|
|
124
|
+
security_setup_reference: cst.LogicalName
|
|
125
|
+
add_object: ObjectListElement
|
|
126
|
+
remove_object: ObjectListElement
|
|
@@ -1,36 +1,30 @@
|
|
|
1
|
-
from
|
|
2
|
-
from . import
|
|
3
|
-
from ...types.
|
|
4
|
-
from ..
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ver0.AssociationLN.
|
|
13
|
-
ver0.AssociationLN.
|
|
14
|
-
ver0.AssociationLN.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
ver0.AssociationLN.
|
|
24
|
-
|
|
25
|
-
ver1.AssociationLN.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
current_user: structs.UserListEntry
|
|
32
|
-
|
|
33
|
-
def characteristics_init(self):
|
|
34
|
-
super(AssociationLN, self).characteristics_init()
|
|
35
|
-
# TODO: more 2 attribute
|
|
36
|
-
# TODO: more 2 methods
|
|
1
|
+
from . import ver0, ver1
|
|
2
|
+
from ...types.implementations import arrays, structs
|
|
3
|
+
from ...types.type_alias import Attr
|
|
4
|
+
from ..cosem_interface_class import ICAElement, ICMElement
|
|
5
|
+
|
|
6
|
+
class AssociationLN(ver1.AssociationLN):
|
|
7
|
+
"""5.4.7 Association LN"""
|
|
8
|
+
VERSION = 2
|
|
9
|
+
A_ELEMENTS = (
|
|
10
|
+
ver1.AssociationLN.getAElement(2).unwrap(), # <object_list>
|
|
11
|
+
ver0.AssociationLN.getAElement(3).unwrap(), # associated_partners_id
|
|
12
|
+
ver0.AssociationLN.getAElement(4).unwrap(), # application_context_name
|
|
13
|
+
ver0.AssociationLN.getAElement(5).unwrap(), # xDLMS_context_info
|
|
14
|
+
ver0.AssociationLN.getAElement(6).unwrap(), # authentication_mechanism_name
|
|
15
|
+
ver1.AssociationLN.getAElement(7).unwrap(), # secret
|
|
16
|
+
ver0.AssociationLN.getAElement(8).unwrap(), # association_status
|
|
17
|
+
ver1.AssociationLN.getAElement(9).unwrap(), # security_setup_reference
|
|
18
|
+
ICAElement(10, "user_list", arrays.UserList),
|
|
19
|
+
ICAElement(11, "current_user", structs.UserListEntry),
|
|
20
|
+
)
|
|
21
|
+
M_ELEMENTS = (
|
|
22
|
+
ver0.AssociationLN.getMElement(1).unwrap(),
|
|
23
|
+
ver0.AssociationLN.getMElement(2).unwrap(),
|
|
24
|
+
ver1.AssociationLN.getMElement(3).unwrap(), # add_object
|
|
25
|
+
ver1.AssociationLN.getMElement(4).unwrap(), # remove_object
|
|
26
|
+
ICMElement(5, "add_user", structs.UserListEntry),
|
|
27
|
+
ICMElement(6, "remove_user", structs.UserListEntry),
|
|
28
|
+
)
|
|
29
|
+
user_list: Attr
|
|
30
|
+
current_user: Attr
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
class AssociationLN:
|
|
2
|
-
def __init__(self):
|
|
3
|
-
raise ValueError(F"version: {__name__[-1]} of {self.__class__.__name__} not support framework")
|
|
4
|
-
|
|
1
|
+
class AssociationLN:
|
|
2
|
+
def __init__(self):
|
|
3
|
+
raise ValueError(F"version: {__name__[-1]} of {self.__class__.__name__} not support framework")
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
from ..
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
from ..cosem_interface_class import ICAuto, ICAElement, Classifier, Cardinality
|
|
2
|
+
from ..Overview import class_id
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AssociationSN(ICAuto):
|
|
6
|
+
"""dummy class"""
|
|
7
|
+
VERSION = 0
|
|
8
|
+
A_ELEMENTS = ()
|
|
9
|
+
M_ELEMENTS = ()
|
|
10
|
+
CLASS_ID = class_id.ASSOCIATION_SN
|
|
11
|
+
CARDINALITY = Cardinality()
|
|
12
|
+
|
|
13
|
+
def __new__(cls, *args, **kwargs):
|
|
14
|
+
raise ValueError(F"version: {__name__[-1]} of {cls.__class__.__name__} not support framework")
|
|
@@ -1,131 +1,81 @@
|
|
|
1
|
-
import
|
|
2
|
-
from
|
|
3
|
-
from ..types.implementations import integers
|
|
4
|
-
from .
|
|
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
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def time_zone(self) -> cdt.Long:
|
|
83
|
-
return self.get_attr(3)
|
|
84
|
-
|
|
85
|
-
@property
|
|
86
|
-
def status(self) -> ClockStatus:
|
|
87
|
-
return self.get_attr(4)
|
|
88
|
-
|
|
89
|
-
@property
|
|
90
|
-
def daylight_savings_begin(self) -> cst.OctetStringDateTime:
|
|
91
|
-
return self.get_attr(5)
|
|
92
|
-
|
|
93
|
-
@property
|
|
94
|
-
def daylight_savings_end(self) -> cst.OctetStringDateTime:
|
|
95
|
-
return self.get_attr(6)
|
|
96
|
-
|
|
97
|
-
@property
|
|
98
|
-
def daylight_savings_deviation(self) -> DaylightSavingsDeviation:
|
|
99
|
-
return self.get_attr(7)
|
|
100
|
-
|
|
101
|
-
@property
|
|
102
|
-
def daylight_savings_enabled(self) -> cdt.Boolean:
|
|
103
|
-
return self.get_attr(8)
|
|
104
|
-
|
|
105
|
-
@property
|
|
106
|
-
def clock_base(self) -> ClockBase:
|
|
107
|
-
return self.get_attr(9)
|
|
108
|
-
|
|
109
|
-
@property
|
|
110
|
-
def adjust_to_quarter(self) -> integers.Only0:
|
|
111
|
-
return self.get_meth(1)
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def adjust_to_measuring_period(self) -> integers.Only0:
|
|
115
|
-
return self.get_meth(2)
|
|
116
|
-
|
|
117
|
-
@property
|
|
118
|
-
def adjust_to_minute(self) -> integers.Only0:
|
|
119
|
-
return self.get_meth(3)
|
|
120
|
-
|
|
121
|
-
@property
|
|
122
|
-
def adjust_to_preset_time(self) -> integers.Only0:
|
|
123
|
-
return self.get_meth(4)
|
|
124
|
-
|
|
125
|
-
@property
|
|
126
|
-
def preset_adjusting_time(self) -> PresetAdjustingTime:
|
|
127
|
-
return self.get_meth(5)
|
|
128
|
-
|
|
129
|
-
@property
|
|
130
|
-
def shift_time(self) -> ShiftTime:
|
|
131
|
-
return self.get_meth(6)
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from ..types import cdt, cst
|
|
3
|
+
from ..types.implementations import integers
|
|
4
|
+
from .Overview import class_id
|
|
5
|
+
from .cosem_interface_class import ICAuto, ICAElement, ICMElement, Classifier
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ClockStatus(cdt.Unsigned):
|
|
9
|
+
""" interpreted as 8 bit string """
|
|
10
|
+
|
|
11
|
+
# TODO: finish write as bit_string
|
|
12
|
+
def __str__(self) -> str:
|
|
13
|
+
value = int.from_bytes(self.contents, 'big')
|
|
14
|
+
ret = ''
|
|
15
|
+
if bool(value & 0b1):
|
|
16
|
+
ret += ' invalid value'
|
|
17
|
+
if bool(value & 0b10):
|
|
18
|
+
ret += ' doubtful value'
|
|
19
|
+
if bool(value & 0b100):
|
|
20
|
+
ret += ' different clock base'
|
|
21
|
+
if bool(value & 0b1000):
|
|
22
|
+
ret += ' invalid clock status'
|
|
23
|
+
if bool(value & 0b1000000):
|
|
24
|
+
ret += ' daylight saving active'
|
|
25
|
+
if ret == '':
|
|
26
|
+
ret = 'empty'
|
|
27
|
+
return ret
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DaylightSavingsDeviation(cdt.Integer, min=-120, max=120):
|
|
31
|
+
"""Contains the number of minutes by which the deviation in generalized time must be corrected at daylight savings begin.
|
|
32
|
+
Deviation range of up to ± 120 min"""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ClockBase(cdt.Enum, elements=(0, 1, 2, 3, 4, 5)):
|
|
36
|
+
""" Defines where the basic timing information comes from. """
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class PresetAdjustingTime(cdt.Structure):
|
|
40
|
+
""" Presets the time to a new value (preset_time) and defines a validity_interval within which the new time can be activated """
|
|
41
|
+
DEFAULT = b'\x02\x03\x19\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff' \
|
|
42
|
+
b'\x19\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff\x19\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff'
|
|
43
|
+
preset_time: cdt.DateTime
|
|
44
|
+
validity_interval_start: cdt.DateTime
|
|
45
|
+
validity_interval_end: cdt.DateTime
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ShiftTime(cdt.Long, min=-900, max=900):
|
|
49
|
+
""" Limited Long -900..900 """
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TimeZone(cdt.Long):
|
|
53
|
+
""""""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Clock(ICAuto):
|
|
57
|
+
"""4.5.1 Clock"""
|
|
58
|
+
CLASS_ID = class_id.CLOCK
|
|
59
|
+
VERSION = 0
|
|
60
|
+
A_ELEMENTS = (ICAElement(2, "time", cst.OctetStringDateTime, classifier=Classifier.DYNAMIC),
|
|
61
|
+
ICAElement(3, "time_zone", TimeZone, -720, 840),
|
|
62
|
+
ICAElement(4, "status", ClockStatus, classifier=Classifier.DYNAMIC),
|
|
63
|
+
ICAElement(5, "daylight_savings_begin", cst.OctetStringDateTime),
|
|
64
|
+
ICAElement(6, "daylight_savings_end", cst.OctetStringDateTime),
|
|
65
|
+
ICAElement(7, "daylight_savings_deviation", DaylightSavingsDeviation, -120, 120),
|
|
66
|
+
ICAElement(8, "daylight_savings_enabled", cdt.Boolean),
|
|
67
|
+
ICAElement(9, "clock_base", ClockBase))
|
|
68
|
+
M_ELEMENTS = (ICMElement(1, "adjust_to_quarter", integers.Only0),
|
|
69
|
+
ICMElement(2, "adjust_to_measuring_period", integers.Only0),
|
|
70
|
+
ICMElement(3, "adjust_to_minute", integers.Only0),
|
|
71
|
+
ICMElement(4, "adjust_to_preset_time", integers.Only0),
|
|
72
|
+
ICMElement(5, "preset_adjusting_time", PresetAdjustingTime),
|
|
73
|
+
ICMElement(6, "shift_time", ShiftTime))
|
|
74
|
+
time: Optional[cst.OctetStringDateTime]
|
|
75
|
+
time_zone: Optional[TimeZone]
|
|
76
|
+
status: Optional[ClockStatus]
|
|
77
|
+
daylight_savings_begin: Optional[cst.OctetStringDateTime]
|
|
78
|
+
daylight_savings_end: Optional[cst.OctetStringDateTime]
|
|
79
|
+
daylight_savings_deviation: Optional[DaylightSavingsDeviation]
|
|
80
|
+
daylight_savings_enabled: Optional[cdt.Boolean]
|
|
81
|
+
clock_base: Optional[ClockBase]
|