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,109 +1,109 @@
1
- from typing import Self
2
- import re
3
- from ..types import common_data_types as cdt
4
- import datetime
5
-
6
-
7
- class LogicalName(cdt.ReportMixin, cdt.OctetString, size=6):
8
- """ Logical Name type. Default is CLock#1 """
9
- __pattern = re.compile("(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})")
10
- __match_args__ = ('a', 'b', 'c', 'd', 'e', 'f')
11
- DEFAULT = b'\x00\x00\x01\x00\x00\xff'
12
-
13
- @classmethod
14
- def from_obis(cls, value: str) -> Self:
15
- """ create logical_name: octet_string from string type ddd.ddd.ddd.ddd.ddd.ddd, ex.: 0.0.1.0.0.255 """
16
- if (res := cls.__pattern.search(value)) is None:
17
- raise ValueError(F"got wrong obis: {value}")
18
- else:
19
- return cls(bytearray(map(int, res.groups())))
20
-
21
- def get_report(self) -> cdt.Report:
22
- return cdt.Report('.'.join(map(str, self.contents))) # todo: add error handle
23
-
24
- def validate_from(self, value: str, cursor_position=None) -> tuple[str, int]:
25
- try:
26
- possible = type(self)(value)
27
- return value, cursor_position # TODO: wrong position ???
28
- except ValueError:
29
- with_separator = F'{value[:-1]}.{value[-1]}'
30
- type(self)(with_separator) # check possible
31
- return with_separator, cursor_position
32
-
33
- def __hash__(self) -> int:
34
- return int.from_bytes(self.contents, 'big')
35
-
36
- @property
37
- def a(self) -> int:
38
- """ group A """
39
- return self.contents[0]
40
-
41
- @property
42
- def b(self) -> int:
43
- """ group B """
44
- return self.contents[1]
45
-
46
- @property
47
- def c(self) -> int:
48
- """ group C """
49
- return self.contents[2]
50
-
51
- @property
52
- def d(self) -> int:
53
- """ group D """
54
- return self.contents[3]
55
-
56
- @property
57
- def e(self) -> int:
58
- """ group E """
59
- return self.contents[4]
60
-
61
- @property
62
- def f(self) -> int:
63
- """ group F """
64
- return self.contents[5]
65
-
66
- def __lt__(self, other: Self) -> bool:
67
- return self.contents < other.contents
68
-
69
-
70
- class OctetStringDateTime(cdt.DateTime, tag=9, size=12):
71
- """ type Time in OctetString(SIZE(12)) """
72
-
73
- def __init__(self, value: bytes | bytearray | str | int | datetime.datetime | datetime.date | datetime.time = b'\x09\x0c\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff'):
74
- match value: # TODO: common for all OctetDateTimes
75
- case bytes() if value[1] == len(self): super().__init__(self.TAG+value[2:])
76
- case bytes(): raise ValueError(F'in create {self.__class__.__name__} got tag, size: {cdt.TAG(value[0])} {value[1]}, expected {self.TAG} {len(self)}')
77
- case _: super().__init__(value)
78
-
79
- @property
80
- def encoding(self) -> bytes:
81
- return b'\x09\x0c' + self.contents
82
-
83
-
84
- class OctetStringDate(cdt.Date, tag=9, size=5):
85
- """ type Time in OctetString(SIZE(5)) """
86
-
87
- def __init__(self, value: bytes | bytearray | str | int | datetime.datetime | datetime.date = b'\x09\x05\x07\xe4\x01\x01\xff'):
88
- match value: # TODO: replace priority case
89
- case bytes() if value[1] == len(self): super().__init__(self.TAG+value[2:])
90
- case bytes(): raise ValueError(F'in create {self.__class__.__name__} got tag, size: {cdt.TAG(value[0])} {value[1]}, expected {self.TAG} {len(self)}')
91
- case _: super().__init__(value)
92
-
93
- @property
94
- def encoding(self) -> bytes:
95
- return b'\x09\x05' + self.contents
96
-
97
-
98
- class OctetStringTime(cdt.Time, tag=9, size=4):
99
- """ type Time in OctetString(SIZE(4)) """
100
-
101
- def __init__(self, value: bytes | bytearray | str | int | datetime.datetime | datetime.time = b'\x09\x04\x00\x00\x00\x00'):
102
- match value: # TODO: replace priority case
103
- case bytes() if value[1] == len(self): super().__init__(self.TAG+value[2:])
104
- case bytes(): raise ValueError(F'in create {self.__class__.__name__} got tag, size: {cdt.TAG(value[0])} {value[1]}, expected {self.TAG} {len(self)}')
105
- case _: super().__init__(value)
106
-
107
- @property
108
- def encoding(self) -> bytes:
109
- return b'\x09\x04' + self.contents
1
+ from typing import Self
2
+ import re
3
+ from ..types import common_data_types as cdt
4
+ import datetime
5
+
6
+
7
+ class LogicalName(cdt.OctetString, cdt.ReportMixin, size=6):
8
+ """ Logical Name type. Default is CLock#1 """
9
+ __pattern = re.compile("(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})")
10
+ __match_args__ = ('a', 'b', 'c', 'd', 'e', 'f')
11
+ DEFAULT = b'\x00\x00\x01\x00\x00\xff'
12
+
13
+ @classmethod
14
+ def from_obis(cls, value: str) -> Self:
15
+ """ create logical_name: octet_string from string type ddd.ddd.ddd.ddd.ddd.ddd, ex.: 0.0.1.0.0.255 """
16
+ if (res := cls.__pattern.search(value)) is None:
17
+ raise ValueError(F"got wrong obis: {value}")
18
+ else:
19
+ return cls(bytearray(map(int, res.groups())))
20
+
21
+ def get_report(self) -> cdt.Report:
22
+ return cdt.Report('.'.join(map(str, self.contents))) # todo: add error handle
23
+
24
+ def validate_from(self, value: str, cursor_position=None) -> tuple[str, int]:
25
+ try:
26
+ possible = type(self)(value)
27
+ return value, cursor_position # TODO: wrong position ???
28
+ except ValueError:
29
+ with_separator = F'{value[:-1]}.{value[-1]}'
30
+ type(self)(with_separator) # check possible
31
+ return with_separator, cursor_position
32
+
33
+ def __hash__(self) -> int:
34
+ return int.from_bytes(self.contents, 'big')
35
+
36
+ @property
37
+ def a(self) -> int:
38
+ """ group A """
39
+ return self.contents[0]
40
+
41
+ @property
42
+ def b(self) -> int:
43
+ """ group B """
44
+ return self.contents[1]
45
+
46
+ @property
47
+ def c(self) -> int:
48
+ """ group C """
49
+ return self.contents[2]
50
+
51
+ @property
52
+ def d(self) -> int:
53
+ """ group D """
54
+ return self.contents[3]
55
+
56
+ @property
57
+ def e(self) -> int:
58
+ """ group E """
59
+ return self.contents[4]
60
+
61
+ @property
62
+ def f(self) -> int:
63
+ """ group F """
64
+ return self.contents[5]
65
+
66
+ def __lt__(self, other: Self) -> bool:
67
+ return self.contents < other.contents
68
+
69
+
70
+ class OctetStringDateTime(cdt.DateTime, tag=9, size=12):
71
+ """ type Time in OctetString(SIZE(12)) """
72
+
73
+ def __init__(self, value: bytes | bytearray | str | int | datetime.datetime | datetime.date | datetime.time = b'\x09\x0c\x07\xe4\x01\x01\xff\xff\xff\xff\xff\x80\x00\xff'):
74
+ match value: # TODO: common for all OctetDateTimes
75
+ case bytes() if value[1] == len(self): super().__init__(self.TAG+value[2:])
76
+ case bytes(): raise ValueError(F'in create {self.__class__.__name__} got tag, size: {cdt.TAG(value[0])} {value[1]}, expected {self.TAG} {len(self)}')
77
+ case _: super().__init__(value)
78
+
79
+ @property
80
+ def encoding(self) -> bytes:
81
+ return b'\x09\x0c' + self.contents
82
+
83
+
84
+ class OctetStringDate(cdt.Date, tag=9, size=5):
85
+ """ type Time in OctetString(SIZE(5)) """
86
+
87
+ def __init__(self, value: bytes | bytearray | str | int | datetime.datetime | datetime.date = b'\x09\x05\x07\xe4\x01\x01\xff'):
88
+ match value: # TODO: replace priority case
89
+ case bytes() if value[1] == len(self): super().__init__(self.TAG+value[2:])
90
+ case bytes(): raise ValueError(F'in create {self.__class__.__name__} got tag, size: {cdt.TAG(value[0])} {value[1]}, expected {self.TAG} {len(self)}')
91
+ case _: super().__init__(value)
92
+
93
+ @property
94
+ def encoding(self) -> bytes:
95
+ return b'\x09\x05' + self.contents
96
+
97
+
98
+ class OctetStringTime(cdt.Time, tag=9, size=4):
99
+ """ type Time in OctetString(SIZE(4)) """
100
+
101
+ def __init__(self, value: bytes | bytearray | str | int | datetime.datetime | datetime.time = b'\x09\x04\x00\x00\x00\x00'):
102
+ match value: # TODO: replace priority case
103
+ case bytes() if value[1] == len(self): super().__init__(self.TAG+value[2:])
104
+ case bytes(): raise ValueError(F'in create {self.__class__.__name__} got tag, size: {cdt.TAG(value[0])} {value[1]}, expected {self.TAG} {len(self)}')
105
+ case _: super().__init__(value)
106
+
107
+ @property
108
+ def encoding(self) -> bytes:
109
+ return b'\x09\x04' + self.contents
@@ -1,25 +1,25 @@
1
- from typing import Any
2
- from abc import ABC, abstractmethod
3
- from ...types import common_data_types as cdt
4
- from .structs import UserListEntry
5
- from .double_long_usingneds import IPAddress
6
-
7
-
8
- class SelectionAccess(cdt.Array):
9
- """Use as buffer in ProfileGeneric and object_list in AssociationLN"""
10
- selective_access: Any | None = None
11
- TYPE: cdt.Structure
12
-
13
- # @abstractmethod
14
- # def is_writable(self, ln: cst.LogicalName, indexes: set[int]) -> bool:
15
- # """ index - DLMS object attribute index.
16
- # True: DLMS object with ln and index has writable Access"""
17
-
18
-
19
- class MulticastIPAddress(cdt.Array):
20
- TYPE = IPAddress
21
-
22
-
23
- class UserList(cdt.Array):
24
- """user_list. for AssociationLN(SN)"""
25
- TYPE = UserListEntry
1
+ from typing import Any
2
+ from abc import ABC, abstractmethod
3
+ from ...types import common_data_types as cdt
4
+ from .structs import UserListEntry
5
+ from .double_long_usingneds import IPAddress
6
+
7
+
8
+ class SelectionAccess(cdt.Array):
9
+ """Use as buffer in ProfileGeneric and object_list in AssociationLN"""
10
+ selective_access: Any | None = None
11
+ TYPE: cdt.Structure
12
+
13
+ # @abstractmethod
14
+ # def is_writable(self, ln: cst.LogicalName, indexes: set[int]) -> bool:
15
+ # """ index - DLMS object attribute index.
16
+ # True: DLMS object with ln and index has writable Access"""
17
+
18
+
19
+ class MulticastIPAddress(cdt.Array):
20
+ TYPE = IPAddress
21
+
22
+
23
+ class UserList(cdt.Array):
24
+ """user_list. for AssociationLN(SN)"""
25
+ TYPE = UserListEntry
@@ -1,97 +1,97 @@
1
- from ...types import common_data_types as cdt
2
- from ...config_parser import get_values
3
- from ...settings import settings
4
-
5
-
6
- base = get_values("DLMS", "Conformance")
7
-
8
-
9
- # TODO: join with cdt.FlagMixin
10
- class Conformance(cdt.BitString):
11
- ELEMENTS = ("reserved-zero",
12
- "general-protection",
13
- "general-block-transfer",
14
- "read",
15
- "write",
16
- "unconfirmed-write",
17
- "reserved-six",
18
- "reserved-seven",
19
- "attribute0-supported-with-set",
20
- "priority-mgmt-supported",
21
- "attribute0-supported-with-get",
22
- "block-transfer-with-get-or-read",
23
- "block-transfer-with-set-or-write",
24
- "block-transfer-with-action",
25
- "multiple-references",
26
- "information-report",
27
- "data-notification",
28
- "access",
29
- "parameterized-access",
30
- "get",
31
- "set",
32
- "selective-access",
33
- "event-notification",
34
- "action")
35
- if base is not None:
36
- ELEMENTS = tuple(base[el] for el in ELEMENTS)
37
- default = '011111111111111111111111' # zero only 1 bit
38
-
39
- def __init__(self, value: bytes | bytearray | str | int | cdt.BitString = None):
40
- super(Conformance, self).__init__(value)
41
- if self.ELEMENTS is not None and len(self) != len(self.ELEMENTS):
42
- raise ValueError(F'For {self.__class__.__name__} get {len(self)} bits, expected {len(self.ELEMENTS)}')
43
-
44
- def __len__(self):
45
- return 24
46
-
47
- def from_bytes(self, value: bytes) -> bytes:
48
- length, pdu = cdt.get_length_and_pdu(value[1:])
49
- if length != len(self):
50
- raise ValueError(F'Got {length=}, expected {len(self)}')
51
- match value[:1]:
52
- case self.TAG if len(self) <= len(pdu) * 8: return pdu[:3]
53
- case self.TAG: raise ValueError(F'Got pdu length:{len(pdu)}, expected at least {len(self) >> 3}')
54
- case _ as error: raise TypeError(F'Expected {self.NAME} type, got {cdt.get_common_data_type_from(error).NAME}')
55
-
56
- def from_str(self, value: str) -> bytes:
57
- value = value + '0' * ((8 - len(self)) % 8)
58
- list_ = [value[count:(count + 8)] for count in range(0, len(self), 8)]
59
- value = b''
60
- for byte in list_:
61
- value += int(byte, base=2).to_bytes(1, byteorder='little')
62
- return value
63
-
64
- def from_int(self, value: int) -> bytes:
65
- if value < 0:
66
- raise ValueError
67
- res = 0
68
- start_bit = 2 ** (len(self) - 1)
69
- for i in range(len(self)):
70
- if value & (1 << i):
71
- res += start_bit >> i
72
- return res.to_bytes(len(self) // 8, byteorder='big')
73
-
74
- def from_bytearray(self, value: bytearray) -> bytes:
75
- return bytes(value)
76
-
77
- @classmethod
78
- def get_values(cls) -> list[str]:
79
- """ TODO: """
80
- return cls.ELEMENTS
81
-
82
- def validate_from(self, value: str, cursor_position: int) -> tuple[str, int]:
83
- """ return validated value and cursor position. TODO: copypast FlagMixin """
84
- type(self)(value=value.zfill(len(self)))
85
- return value, cursor_position
86
-
87
- @property
88
- def general_protection(self) -> int:
89
- return tuple(self)[1]
90
-
91
- @property
92
- def general_block_transfer(self) -> int:
93
- return tuple(self)[2]
94
-
95
- @property
96
- def selective_access(self) -> int:
97
- return tuple(self)[21]
1
+ from ...types import common_data_types as cdt
2
+ from ...config_parser import get_values
3
+ from ...settings import settings
4
+
5
+
6
+ base = get_values("DLMS", "Conformance")
7
+
8
+
9
+ # TODO: join with cdt.FlagMixin
10
+ class Conformance(cdt.BitString):
11
+ ELEMENTS = ("reserved-zero",
12
+ "general-protection",
13
+ "general-block-transfer",
14
+ "read",
15
+ "write",
16
+ "unconfirmed-write",
17
+ "reserved-six",
18
+ "reserved-seven",
19
+ "attribute0-supported-with-set",
20
+ "priority-mgmt-supported",
21
+ "attribute0-supported-with-get",
22
+ "block-transfer-with-get-or-read",
23
+ "block-transfer-with-set-or-write",
24
+ "block-transfer-with-action",
25
+ "multiple-references",
26
+ "information-report",
27
+ "data-notification",
28
+ "access",
29
+ "parameterized-access",
30
+ "get",
31
+ "set",
32
+ "selective-access",
33
+ "event-notification",
34
+ "action")
35
+ if base is not None:
36
+ ELEMENTS = tuple(base[el] for el in ELEMENTS)
37
+ default = '011111111111111111111111' # zero only 1 bit
38
+
39
+ def __init__(self, value: bytes | bytearray | str | int | cdt.BitString = None):
40
+ super(Conformance, self).__init__(value)
41
+ if self.ELEMENTS is not None and len(self) != len(self.ELEMENTS):
42
+ raise ValueError(F'For {self.__class__.__name__} get {len(self)} bits, expected {len(self.ELEMENTS)}')
43
+
44
+ def __len__(self):
45
+ return 24
46
+
47
+ def from_bytes(self, value: bytes) -> bytes:
48
+ length, pdu = cdt.get_length_and_pdu(value[1:])
49
+ if length != len(self):
50
+ raise ValueError(F'Got {length=}, expected {len(self)}')
51
+ match value[:1]:
52
+ case self.TAG if len(self) <= len(pdu) * 8: return pdu[:3]
53
+ case self.TAG: raise ValueError(F'Got pdu length:{len(pdu)}, expected at least {len(self) >> 3}')
54
+ case _ as error: raise TypeError(F'Expected {self.NAME} type, got {cdt.get_common_data_type_from(error).NAME}')
55
+
56
+ def from_str(self, value: str) -> bytes:
57
+ value = value + '0' * ((8 - len(self)) % 8)
58
+ list_ = [value[count:(count + 8)] for count in range(0, len(self), 8)]
59
+ value = b''
60
+ for byte in list_:
61
+ value += int(byte, base=2).to_bytes(1, byteorder='little')
62
+ return value
63
+
64
+ def from_int(self, value: int) -> bytes:
65
+ if value < 0:
66
+ raise ValueError
67
+ res = 0
68
+ start_bit = 2 ** (len(self) - 1)
69
+ for i in range(len(self)):
70
+ if value & (1 << i):
71
+ res += start_bit >> i
72
+ return res.to_bytes(len(self) // 8, byteorder='big')
73
+
74
+ def from_bytearray(self, value: bytearray) -> bytes:
75
+ return bytes(value)
76
+
77
+ @classmethod
78
+ def get_values(cls) -> list[str]:
79
+ """ TODO: """
80
+ return cls.ELEMENTS
81
+
82
+ def validate_from(self, value: str, cursor_position: int) -> tuple[str, int]:
83
+ """ return validated value and cursor position. TODO: copypast FlagMixin """
84
+ type(self)(value=value.zfill(len(self)))
85
+ return value, cursor_position
86
+
87
+ @property
88
+ def general_protection(self) -> int:
89
+ return tuple(self)[1]
90
+
91
+ @property
92
+ def general_block_transfer(self) -> int:
93
+ return tuple(self)[2]
94
+
95
+ @property
96
+ def selective_access(self) -> int:
97
+ return tuple(self)[21]
@@ -1,35 +1,35 @@
1
- from ...types import common_data_types as cdt
2
-
3
-
4
- class DoubleLongUnsignedSecond(cdt.DoubleLongUnsigned):
5
- """for second implementation"""
6
-
7
-
8
- class IPAddress(cdt.DoubleLongUnsigned):
9
- """with string parser"""
10
-
11
- def from_str(self, value: str) -> bytes:
12
- """ create ip: integer from string type ddd.ddd.ddd.ddd, ex.: 127.0.0.1 """
13
- raw_value = bytes()
14
- for separator in '... ':
15
- try:
16
- element, value = value.split(separator, 1)
17
- except ValueError:
18
- element, value = value, ''
19
- raw_value += self.__get_attr_element(element)
20
- return raw_value
21
-
22
- @staticmethod
23
- def __get_attr_element(value: str) -> bytes:
24
- if isinstance(value, str):
25
- if value == '':
26
- return b'\x00'
27
- try:
28
- return int(value).to_bytes(1, 'big')
29
- except OverflowError:
30
- raise ValueError(F'Int too big to convert {value}')
31
- else:
32
- raise TypeError(F'Unsupported type validation from string, got {value.__class__}')
33
-
34
- def __str__(self):
35
- return F'{self.contents[0]}.{self.contents[1]}.{self.contents[2]}.{self.contents[3]}'
1
+ from ...types import common_data_types as cdt
2
+
3
+
4
+ class DoubleLongUnsignedSecond(cdt.DoubleLongUnsigned):
5
+ """for second implementation"""
6
+
7
+
8
+ class IPAddress(cdt.DoubleLongUnsigned):
9
+ """with string parser"""
10
+
11
+ def from_str(self, value: str) -> bytes:
12
+ """ create ip: integer from string type ddd.ddd.ddd.ddd, ex.: 127.0.0.1 """
13
+ raw_value = bytes()
14
+ for separator in '... ':
15
+ try:
16
+ element, value = value.split(separator, 1)
17
+ except ValueError:
18
+ element, value = value, ''
19
+ raw_value += self.__get_attr_element(element)
20
+ return raw_value
21
+
22
+ @staticmethod
23
+ def __get_attr_element(value: str) -> bytes:
24
+ if isinstance(value, str):
25
+ if value == '':
26
+ return b'\x00'
27
+ try:
28
+ return int(value).to_bytes(1, 'big')
29
+ except OverflowError:
30
+ raise ValueError(F'Int too big to convert {value}')
31
+ else:
32
+ raise TypeError(F'Unsupported type validation from string, got {value.__class__}')
33
+
34
+ def __str__(self):
35
+ return F'{self.contents[0]}.{self.contents[1]}.{self.contents[2]}.{self.contents[3]}'
@@ -1,57 +1,57 @@
1
- from ...types import common_data_types as cdt
2
-
3
-
4
- class CommSpeed(cdt.Enum, elements=tuple(range(10))):
5
- """ The communication speed supported by the corresponding port. This communication speed can be overridden if the HDLC mode of a devive is entered through a special mode
6
- of another protocol. """
7
-
8
- def to_transcript(self) -> int:
9
- """ override enum key to enum value"""
10
- match self.contents:
11
- case b'\x00': return 300
12
- case b'\x01': return 600
13
- case b'\x02': return 1200
14
- case b'\x03': return 2400
15
- case b'\x04': return 4800
16
- case b'\x05': return 9600
17
- case b'\x06': return 19200
18
- case b'\x07': return 38400
19
- case b'\x08': return 57600
20
- case b'\x09': return 115200
21
- case _ as err: raise ValueError(F'Wrong CommSpeed: {err}, expected {CommSpeed.ELEMENTS.keys()}')
22
-
23
- def from_int(self, value: int) -> bytes:
24
- """ additional cases with Speed Values"""
25
- match value:
26
- case 300: return b'\x00'
27
- case 600: return b'\x01'
28
- case 1200: return b'\x02'
29
- case 2400: return b'\x03'
30
- case 4800: return b'\x04'
31
- case 9600: return b'\x05'
32
- case 19200: return b'\x06'
33
- case 38400: return b'\x07'
34
- case 57600: return b'\x08'
35
- case 115200: return b'\x09'
36
- case other: return super(CommSpeed, self).from_int(other)
37
-
38
-
39
- class RestrictionType(cdt.Enum, elements=(0, 1, 2)):
40
- """"""
41
-
42
-
43
- class KeyInfoType(cdt.Enum, elements=(0, 1, 2)):
44
- """"""
45
-
46
-
47
-
48
- class ProtectionType(cdt.Enum, elements=(0, 1, 2, 3)):
49
- """"""
50
-
51
-
52
- class ClientSAP(cdt.Enum, elements=(0, 1, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60)): # TODO: REWRITE elements here
53
- """ IEC 62056-46 2002 6.4.2.3 Reserved special HDLC addresses p.40. IS15952ver2 """
54
- TAG = b'\x0f'
55
-
56
-
57
- configurator_client = ClientSAP(0x30)
1
+ from ...types import common_data_types as cdt
2
+
3
+
4
+ class CommSpeed(cdt.Enum, elements=tuple(range(10))):
5
+ """ The communication speed supported by the corresponding port. This communication speed can be overridden if the HDLC mode of a devive is entered through a special mode
6
+ of another protocol. """
7
+
8
+ def to_transcript(self) -> int:
9
+ """ override enum key to enum value"""
10
+ match self.contents:
11
+ case b'\x00': return 300
12
+ case b'\x01': return 600
13
+ case b'\x02': return 1200
14
+ case b'\x03': return 2400
15
+ case b'\x04': return 4800
16
+ case b'\x05': return 9600
17
+ case b'\x06': return 19200
18
+ case b'\x07': return 38400
19
+ case b'\x08': return 57600
20
+ case b'\x09': return 115200
21
+ case _ as err: raise ValueError(F'Wrong CommSpeed: {err}, expected {CommSpeed.ELEMENTS.keys()}')
22
+
23
+ def from_int(self, value: int) -> bytes:
24
+ """ additional cases with Speed Values"""
25
+ match value:
26
+ case 300: return b'\x00'
27
+ case 600: return b'\x01'
28
+ case 1200: return b'\x02'
29
+ case 2400: return b'\x03'
30
+ case 4800: return b'\x04'
31
+ case 9600: return b'\x05'
32
+ case 19200: return b'\x06'
33
+ case 38400: return b'\x07'
34
+ case 57600: return b'\x08'
35
+ case 115200: return b'\x09'
36
+ case other: return super(CommSpeed, self).from_int(other)
37
+
38
+
39
+ class RestrictionType(cdt.Enum, elements=(0, 1, 2)):
40
+ """"""
41
+
42
+
43
+ class KeyInfoType(cdt.Enum, elements=(0, 1, 2)):
44
+ """"""
45
+
46
+
47
+
48
+ class ProtectionType(cdt.Enum, elements=(0, 1, 2, 3)):
49
+ """"""
50
+
51
+
52
+ class ClientSAP(cdt.Enum, elements=(0, 1, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60)): # TODO: REWRITE elements here
53
+ """ IEC 62056-46 2002 6.4.2.3 Reserved special HDLC addresses p.40. IS15952ver2 """
54
+ TAG = b'\x0f'
55
+
56
+
57
+ configurator_client = ClientSAP(0x30)