DLMS-SPODES 0.86.8__py3-none-any.whl → 0.86.10__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.
@@ -522,8 +522,6 @@ __func_map_for_create.update({
522
522
  (1, 0, 148, 136, 0): RegisterMap,
523
523
  (1, 94, 7, 0): ProfileGenericMap.renew(1, impl.profile_generic.SPODES3CurrentProfile),
524
524
  (1, 94, 7, (1, 2, 3, 4, 5, 6)): ProfileGenericMap.renew(1, impl.profile_generic.SPODES3ScalesProfile), # Todo: RU. Scaler-profile With 1 entry and more
525
- # KPZ
526
- (128, 0, tuple(range(20)), 0, 0): RegisterMap
527
525
  })
528
526
 
529
527
  func_maps["SPODES_3"] = get_func_map(__func_map_for_create)
@@ -533,9 +531,11 @@ __func_map_for_create.update({
533
531
  (0, 96, 11, 4): ClassMap({0: impl.data.KPZSPODES3ExternalEvent}),
534
532
  (0, 0, 97, 98, (0, 10, 20)): ClassMap({0: impl.data.KPZAlarm1}),
535
533
  (0, 128, 25, 6, 0): ClassMap({0: impl.data.DataStatic}),
534
+ (0, 128, 96, 2, (0, 1, 2)): ClassMap({0: impl.data.KPZAFEOffsets}),
536
535
  (0, 128, 96, 13, 1): ClassMap({0: impl.data.ITEBitMap}),
537
536
  (0, 128, 154, 0, 0): ClassMap({0: impl.data.KPZGSMPingIP}),
538
537
  (0, 0, 128, (100, 101, 102, 103, 150, 151, 152, 170)): DataMap,
538
+ (128, 0, tuple(range(20)), 0, 0): RegisterMap
539
539
  })
540
540
  func_maps["KPZ"]: FUNC_MAP = get_func_map(__func_map_for_create)
541
541
  # KPZ1 with bag in log event profiles
@@ -606,7 +606,7 @@ def get_filtered(objects: Iterable[InterfaceClass],
606
606
  keys: ObjFilteredKey) -> list[InterfaceClass]:
607
607
  c_ids: list[ut.CosemClassId] = list()
608
608
  patterns: list[LNPattern] = list()
609
- ch: Channel | None = None
609
+ ch: Optional[Channel] = None
610
610
  for k in keys:
611
611
  if isinstance(k, ut.CosemClassId):
612
612
  c_ids.append(k)
@@ -679,7 +679,7 @@ class Collection:
679
679
  self.__country_ver = cntr_ver
680
680
  """country version specification"""
681
681
  self.spec_map = "DLMS_6"
682
- self.__objs = dict()
682
+ self.__objs = {}
683
683
  """ all DLMS objects container with obis key """
684
684
 
685
685
  @property
@@ -1127,6 +1127,19 @@ class Collection:
1127
1127
  res.append_err(e)
1128
1128
  return res
1129
1129
 
1130
+ def iter_classID_objects(self,
1131
+ class_id: ut.CosemClassId) -> Iterator[InterfaceClass]:
1132
+ return (obj for obj in self.__objs.values() if obj.CLASS_ID == value)
1133
+
1134
+ def LNPattern2objects(self,
1135
+ pat: LNPattern) -> list[InterfaceClass]:
1136
+ ret = []
1137
+ for obj in self.__objs.values():
1138
+ if obj.logical_name in pat:
1139
+ ret.append(obj)
1140
+ return ret
1141
+
1142
+
1130
1143
  def get_attr(self, value: ut.CosemAttributeDescriptor) -> cdt.CommonDataTypes:
1131
1144
  """attribute value from descriptor"""
1132
1145
  return self.__get_object(value.instance_id.contents).get_attr(int(value.attribute_id))
@@ -1141,17 +1154,14 @@ class Collection:
1141
1154
  else:
1142
1155
  raise exc.NoObject(F"not found at least one DLMS Objects from collection with {values=}")
1143
1156
 
1157
+ @deprecated("use <iter_classID_objects>")
1144
1158
  def get_objects_by_class_id(self, value: ut.CosemClassId) -> list[InterfaceClass]:
1145
1159
  return list(filter(lambda obj: obj.CLASS_ID == value, self.__objs.values()))
1146
1160
 
1147
- def get_objects_descriptions(self) -> list[tuple[cst.LogicalName, cdt.LongUnsigned, cdt.Unsigned]]:
1148
- """ return container of objects for get device clone """
1149
- return list(map(lambda obj: (obj.logical_name, obj.CLASS_ID, obj.VERSION), self.__objs.values()))
1150
-
1151
1161
  def get_writable_attr(self) -> UsedAttributes:
1152
1162
  """return all writable {obj.ln: {attribute_index}}"""
1153
1163
  ret: UsedAttributes = dict()
1154
- for ass in self.get_objects_by_class_id(ClassID.ASSOCIATION_LN):
1164
+ for ass in self.iter_classID_objects(ClassID.ASSOCIATION_LN):
1155
1165
  if (
1156
1166
  ass.logical_name.e == 0
1157
1167
  or ass.object_list is None
@@ -1351,7 +1361,7 @@ class Collection:
1351
1361
  raise ValueError(F"absent association with {client_sap}")
1352
1362
 
1353
1363
  def sap2association(self, sap: enums.ClientSAP) -> AssociationLN:
1354
- for ass in get_filtered(self, (ClassID.ASSOCIATION_LN,)):
1364
+ for ass in self.iter_classID_objects(ClassID.ASSOCIATION_LN):
1355
1365
  if (
1356
1366
  ass.associated_partners_id is not None
1357
1367
  and ass.associated_partners_id.client_SAP == sap
@@ -456,3 +456,22 @@ class KPZGSMPingIPValue(cdt.Structure):
456
456
  class KPZGSMPingIP(DataStatic):
457
457
  """Проприетарный объект"""
458
458
  A_ELEMENTS = DataStatic.get_attr_element(2).get_change(data_type=KPZGSMPingIPValue),
459
+
460
+
461
+ class AFERegister(cdt.Structure):
462
+ name: cdt.VisibleString
463
+ value: choices.common_dt
464
+
465
+
466
+ class AFERegisters(cdt.Array):
467
+ TYPE = AFERegister
468
+ values: list[AFERegister]
469
+
470
+
471
+ class AFEOffsets(cdt.Structure):
472
+ identifier: cdt.VisibleString
473
+ register_list: AFERegisters
474
+
475
+
476
+ class KPZAFEOffsets(DataDynamic):
477
+ A_ELEMENTS = DataStatic.get_attr_element(2).get_change(data_type=AFEOffsets),
@@ -1,48 +1,87 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Self, Literal
3
3
  from ..types import cst
4
+ from copy import copy
4
5
 
5
- SKIP = bytes(range(256))
6
- RANGE64 = bytes(range(65))
7
- type ObisGroup = int | set[int]
8
- type GroupLiteral = Literal['a', 'b', 'c', 'd', 'e', 'f']
6
+ SKIP: int = 0
7
+ RANGE256 = set(range(256))
8
+ RANGE64 = bytes(range(64))
9
+ RANGE64_WITH_LENGTH = b'\x40' + RANGE64
9
10
 
10
11
 
11
- @dataclass
12
+ @dataclass(frozen=True, slots=True)
12
13
  class LNPattern:
13
- """pattern for use in get_filtered.
14
- value "x.x.x.x.x.x" where x is:
15
- 0..255 - simple value
16
- a,b,c,d,e,f - for skip value in each group
17
- (y, z, ...) - set of simple values(y or z)
18
- ((y-z), ...) - set of simple values with range(from y to z)
19
- !() - as () but, set of exclude values
20
- example: "a.0.(1,2,3).(0-64).0.f"
21
14
  """
22
- __values: tuple[bytes, ...]
15
+ LNPattern ::= SEQUENCE (SIZE (6)) OF GroupPattern
16
+
17
+ GroupPattern ::= CHOICE {
18
+ skip [0] NULL, -- SKIP marker
19
+ single [1] INTEGER (0..255), -- single value
20
+ multiple [2] SEQUENCE OF INTEGER (0..255) -- set of values
21
+ }
22
+ LNPattern Binary Encoding Specification:
23
+ ---------------------------------------
24
+ A compact tag-less binary format for storing 6 OBIS-like groups.
25
+
26
+ Structure:
27
+ [L1][V1][L2][V2]...[L6][V6]
28
+ where:
29
+ - Ln: 1-byte length prefix for group n (0-255)
30
+ - Vn: Value bytes (interpretation depends on Ln)
23
31
 
24
- def __post_init__(self):
25
- if len(self.__values) != 6:
26
- raise ValueError(F"for {self.__class__.__name__} got values with length={len(self.__values)}, expected 6")
32
+ Length Semantics:
33
+ - L=0 : SKIP group (no value bytes follow)
34
+ - L=1 : Single value (V is 1-byte integer 0-255)
35
+ - L=2..255 : Value set (V contains L bytes as possible values)
36
+
37
+ Special Cases:
38
+ - Group 'b' (index 1) when marked SKIP uses predefined RANGE64 (0-64)
39
+ - Empty exclusion sets "!()" are prohibited
40
+
41
+ Example:
42
+ Pattern "a.1.(2-5).!().0.f" encodes as:
43
+ [00][01][01][04][02][03][04][05][00][01][00][00]
44
+ (SKIP|1|{2,3,4,5}|SKIP|0|SKIP)
45
+
46
+ Properties:
47
+ - Fixed overhead: 6 bytes (1 length byte per group)
48
+ - Max size: 6 + 255*6 = 1536 bytes
49
+ - Order-preserving
50
+ - Comparison-friendly memory layout
51
+ """
52
+ buffer: bytes
27
53
 
28
54
  @classmethod
29
55
  def parse(cls, value: str) -> Self:
30
- values: list[bytes] = [SKIP, SKIP, SKIP, SKIP, SKIP, SKIP]
31
- for i, val in enumerate(value.split('.', maxsplit=5)):
32
- if (
33
- len(val) == 1
34
- and (ord(val) == 97+i)
35
- ):
36
- if val == 'b':
37
- values[i] = RANGE64
38
- else:
56
+ buffer = bytearray()
57
+ parts = value.split('.', maxsplit=5)
58
+ if len(parts) != 6:
59
+ raise ValueError(f"got {len(parts)} elements, expected 6")
60
+ for i, val in enumerate(parts):
61
+ if val.isdigit():
62
+ num = int(val)
63
+ if 0 <= num <= 255:
64
+ buffer.extend((1, num))
65
+ continue
66
+ raise ValueError(f"Value {val} out of range 0-255")
67
+ if len(val) == 1:
68
+ if val == "x":
69
+ buffer.append(SKIP)
70
+ continue
71
+ elif (
72
+ i == 1
73
+ and val == "b"
74
+ ):
75
+ buffer.extend(RANGE64_WITH_LENGTH)
39
76
  continue
40
- elif val.isdigit():
41
- values[i] = int(val)
42
- if not (0 <= values[i] <= 255):
43
- raise ValueError(F"in {value=} got element {val=}, expected 0..255")
44
- elif val.startswith('(') and val.endswith(')'):
45
- el: set[int] = set()
77
+ elif ord(val) == i + 97:
78
+ buffer.append(SKIP)
79
+ continue
80
+ if val == "":
81
+ buffer.append(SKIP)
82
+ continue
83
+ if val[0]=='(' and val[-1]==')':
84
+ el = set()
46
85
  val = val.replace('(', "").replace(')', "")
47
86
  for j in val.split(","):
48
87
  j = j.replace(" ", '')
@@ -53,12 +92,16 @@ class LNPattern:
53
92
  start, end = j.split("-")
54
93
  el.update(range(
55
94
  cls.__simple_validate(start),
56
- cls.__simple_validate(end)+1))
95
+ cls.__simple_validate(end) + 1))
57
96
  case err:
58
97
  raise ValueError(F"got a lot of <-> in pattern: {value}, expected one")
59
- values[i] = bytes(el)
60
- elif val.startswith('!(') and val.endswith(')'):
61
- el: set[int] = set(range(256))
98
+ # values = bytes(el)
99
+ # buffer.extend([len(values)] + list(values))
100
+ buffer.append(len(el))
101
+ buffer.extend(el)
102
+ continue
103
+ if val.startswith('!(') and val.endswith(')'):
104
+ el = copy(RANGE256)
62
105
  val = val.replace('!(', "").replace(')', "")
63
106
  for j in val.split(","):
64
107
  j = j.replace(" ", '')
@@ -69,15 +112,18 @@ class LNPattern:
69
112
  start, end = j.split("-")
70
113
  el.difference_update(range(
71
114
  cls.__simple_validate(start),
72
- cls.__simple_validate(end)+1))
115
+ cls.__simple_validate(end) + 1))
73
116
  case err:
74
117
  raise ValueError(F"got a lot of <-> in pattern: {value}, expected one")
75
- if len(el) == 0:
76
- raise ValueError(F"no one element in group: {chr(97+i)}")
77
- values[i] = bytes(el)
78
- else:
79
- raise ValueError(F"got wrong symbol: {val} in pattern")
80
- return cls(tuple(values))
118
+ if len(el)==0:
119
+ raise ValueError(F"no one element in group: {chr(97 + i)}")
120
+ # values = bytes(el)
121
+ # buffer.extend([len(values)] + list(values))
122
+ buffer.append(len(el))
123
+ buffer.extend(el)
124
+ continue
125
+ raise ValueError(f"Invalid pattern: {val}")
126
+ return cls(bytes(buffer))
81
127
 
82
128
  @staticmethod
83
129
  def __simple_validate(value: str) -> int:
@@ -86,26 +132,66 @@ class LNPattern:
86
132
  else:
87
133
  raise ValueError(F"got not valid element: {value} in pattern, expected 0..255")
88
134
 
89
- def get_update(self, group: GroupLiteral, value: str) -> Self:
90
- """get new instance with updated group value"""
91
- # todo: make this
92
- raise RuntimeError("no implement now")
93
-
94
- def __eq__(self, other: cst.LogicalName):
95
- for i, j in zip(self.__values, other):
96
- if i == j or (i == -1):
97
- continue
98
- elif isinstance(i, set) and j in i:
135
+ def __eq__(self, other: "LNPattern") -> bool:
136
+ ptr = 0
137
+ for i in range(6):
138
+ length = self.buffer[ptr]
139
+ ptr += 1
140
+ if length == 0: # SKIP
99
141
  continue
100
- else:
101
- return False
142
+ other_byte = other.contents[i]
143
+ if length == 1: # Single byte
144
+ if self.buffer[ptr]!=other_byte:
145
+ return False
146
+ else: # Multiple bytes
147
+ if other_byte not in self.buffer[ptr:ptr + length]:
148
+ return False
149
+ ptr += length
102
150
  return True
103
151
 
104
- def __repr__(self) -> str:
105
- return F"{self.__class__.__name__}(\"{".".join(map(lambda it: str(it) if isinstance(it, int) else str(tuple(it)), self.__values))}\")"
152
+ @staticmethod
153
+ def _format_ranges(values: list[int]) -> str:
154
+ if not values:
155
+ return "!()"
156
+ ranges = []
157
+ start = end = values[0]
158
+ for num in values[1:]:
159
+ if num==end + 1:
160
+ end = num
161
+ else:
162
+ ranges.append((start, end))
163
+ start = end = num
164
+ ranges.append((start, end))
165
+ parts = []
166
+ for start, end in ranges:
167
+ if start==end:
168
+ parts.append(str(start))
169
+ elif end==start + 1: # Диапазон из 2 чисел
170
+ parts.extend([str(start), str(end)])
171
+ else:
172
+ parts.append(f"{start}-{end}")
173
+ if len(parts) > 3 and len(values) > 128: # Эмпирический порог
174
+ all_values = set(range(256))
175
+ excluded = sorted(all_values - set(values))
176
+ if len(excluded) < len(values):
177
+ return f"!({','.join(self._format_ranges(excluded))})"
178
+ return f"({','.join(parts)})"
106
179
 
107
- def __hash__(self) -> int:
108
- return hash(self.__values)
180
+ def __str__(self) -> str:
181
+ parts = []
182
+ ptr = 0
183
+ for _ in range(6):
184
+ length = self.buffer[ptr]
185
+ ptr += 1
186
+ if length == 0:
187
+ parts.append("x")
188
+ elif length == 1:
189
+ parts.append(str(self.buffer[ptr]))
190
+ else:
191
+ values = sorted(set(self.buffer[ptr:ptr + length]))
192
+ parts.append(self._format_ranges(values))
193
+ ptr += length
194
+ return ".".join(parts)
109
195
 
110
196
 
111
197
  @dataclass
@@ -115,14 +201,17 @@ class LNPatterns:
115
201
  def __iter__(self):
116
202
  return iter(self.value)
117
203
 
204
+ def __str__(self) -> str:
205
+ return f"[{" | ".join(map(str, self.value))}]"
206
+
118
207
 
119
- ABSTRACT = LNPattern.parse("0")
120
- ELECTRICITY = LNPattern.parse("1")
121
- HCA = LNPattern.parse("4")
122
- THERMAL = LNPattern.parse("(5,6)")
123
- GAS = LNPattern.parse("7")
124
- WATER = LNPattern.parse("(8,9)")
125
- OTHER_MEDIA = LNPattern.parse("15")
208
+ ABSTRACT = LNPattern.parse("0.....")
209
+ ELECTRICITY = LNPattern.parse("1.....")
210
+ HCA = LNPattern.parse("4.....")
211
+ THERMAL = LNPattern.parse("(5,6).....")
212
+ GAS = LNPattern.parse("7.....")
213
+ WATER = LNPattern.parse("(8,9).....")
214
+ OTHER_MEDIA = LNPattern.parse("15.....")
126
215
 
127
216
 
128
217
  BILLING_PERIOD_VALUES_RESET_COUNTER_ENTRIES = LNPatterns((
@@ -1,6 +1,5 @@
1
1
  from typing_extensions import deprecated
2
2
  from dataclasses import dataclass
3
- import functools
4
3
  import numpy as np
5
4
  from struct import Struct, pack, unpack_from
6
5
  from typing import Optional, cast, Iterator
DLMS_SPODES/pardata.py CHANGED
@@ -25,5 +25,5 @@ class ParValues[T]:
25
25
 
26
26
 
27
27
  @dataclass(frozen=True)
28
- class ParData(ParValues):
28
+ class ParData(ParValues[cdt.CommonDataType]):
29
29
  data: Optional[cdt.CommonDataType]
@@ -620,10 +620,10 @@ class Float(SimpleDataType, ABC):
620
620
  case None: self.clear()
621
621
  case bytes() as encoding:
622
622
  length_and_contents = encoding[1:]
623
- match encoding[:1], len(self):
624
- case self.TAG, int() if len(self) <= len(length_and_contents): self.contents = length_and_contents[:len(self)]
623
+ match encoding[:1], self.SIZE:
624
+ case self.TAG, int() if self.SIZE <= len(length_and_contents): self.contents = length_and_contents[:self.SIZE]
625
625
  case self.TAG, _: raise ValueError(F'Length of contents for {self.TAG} must be at least '
626
- F'{len(self)}, but got {len(length_and_contents)}')
626
+ F'{self.SIZE}, but got {len(length_and_contents)}')
627
627
  case _ as wrong_tag, _: raise ValueError(F'Expected {self.TAG} type, got {get_common_data_type_from(wrong_tag).TAG}')
628
628
  case bytearray(): self.contents = bytes(value) # Attention!!! changed method content getting from bytearray
629
629
  case str(): self.contents = self.from_str(value)
@@ -668,13 +668,13 @@ class Float(SimpleDataType, ABC):
668
668
 
669
669
  def __float__(self):
670
670
  """ return the build in float type IEEE 60559"""
671
- return unpack(cls.FORMAT, value)[0]
671
+ return unpack(self.FORMAT, self.contents)[0]
672
672
 
673
673
  def __str__(self):
674
674
  return str(float(self))
675
675
 
676
676
  def clear(self): # todo: remove this
677
- self.contents = bytes(len(self))
677
+ self.contents = bytes(self.SIZE)
678
678
 
679
679
 
680
680
  class LIST(ABC):
@@ -1903,12 +1903,13 @@ class Float32(Float, SimpleDataType):
1903
1903
  """float32. ISO/IEC/IEEE 60559:2011"""
1904
1904
  TAG = TAG(b'\x17')
1905
1905
  FORMAT = ">f"
1906
-
1906
+ SIZE = 4
1907
1907
 
1908
1908
  class Float64(Float, SimpleDataType):
1909
1909
  """float64. ISO/IEC/IEEE 60559:2011"""
1910
1910
  TAG = TAG(b'\x18')
1911
1911
  FORMAT = ">d"
1912
+ SIZE = 8
1912
1913
 
1913
1914
 
1914
1915
  _SHORT_MONTHS = (4, 6, 9, 11)
@@ -1,8 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DLMS_SPODES
3
- Version: 0.86.8
3
+ Version: 0.86.10
4
4
  Summary: dlms-spodes
5
5
  Author-email: Serj Kotilevski <youserj@outlook.com>
6
+ Project-URL: Source, https://github.com/youserj/DlmsSPODES-project
6
7
  Keywords: dlms
7
8
  Classifier: Programming Language :: Python :: 3
8
9
  Classifier: License :: OSI Approved :: MIT License
@@ -13,7 +14,7 @@ Requires-Dist: pydantic>=2.11
13
14
  Requires-Dist: cryptography>=45.0
14
15
  Requires-Dist: semver>=3.0
15
16
  Requires-Dist: typing-extensions>=4.12.2
16
- Requires-Dist: StructResult>=0.7.3
17
+ Requires-Dist: StructResult>=0.8.0
17
18
  Provides-Extra: dev
18
19
  Requires-Dist: mypy>=1.5.0; extra == "dev"
19
20
  Requires-Dist: ruff>=0.11; extra == "dev"
@@ -6,7 +6,7 @@ DLMS_SPODES/enums.py,sha256=13BE0owOyJBNlOI4NY1d-kpqVoHF7JPR9brkPKHLERE,17789
6
6
  DLMS_SPODES/exceptions.py,sha256=UBZRQlQIRi1CzRxWTeqX5PVNuFS770f77BAizQ99IDU,3006
7
7
  DLMS_SPODES/firmwares.py,sha256=lFRnxtq4joYhpZPxHD8Pv30-GvgcEfZCDZUYo_pIeQU,3850
8
8
  DLMS_SPODES/literals.py,sha256=5u6hreLSXgmN7Z_5pXchyBKsuPYJ5deqxKHqewQEFoI,1632
9
- DLMS_SPODES/pardata.py,sha256=bCVkylaJiZqfXcQ83YZ5RhimHsRn3cl4k-6p-dLSfJU,685
9
+ DLMS_SPODES/pardata.py,sha256=8Pl2Bq-hGrsmH9sajqCf1kxSzpzPsySeq_MYRrRyWFk,705
10
10
  DLMS_SPODES/pdu_enums.py,sha256=5xiV-tZTPXOcHT8XQcHWrwAMKTOmCH09Sk4iL1N7I3c,2276
11
11
  DLMS_SPODES/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  DLMS_SPODES/relation_to_OBIS.py,sha256=KcSMIQ_5amjeT0Lya3HbYoaDdz_BjZC2JLVhl2nffwo,32761
@@ -25,7 +25,7 @@ DLMS_SPODES/cosem_interface_classes/activity_calendar.py,sha256=1kKRxBmMRKaKRYpR
25
25
  DLMS_SPODES/cosem_interface_classes/arbitrator.py,sha256=CvrYknl6xfg8hZR5RijzWsMh34XBQKsQ0nQp_Jtm__E,3208
26
26
  DLMS_SPODES/cosem_interface_classes/attr_indexes.py,sha256=aUSnT-dKoBsDbwLhlgtLIHGRl7PZrT-ld2ThCEUjUeA,328
27
27
  DLMS_SPODES/cosem_interface_classes/clock.py,sha256=AQiMtW13_Y74M2kYYfhZsKGPWtHqOkBNvEPX2QCfXfg,4493
28
- DLMS_SPODES/cosem_interface_classes/collection.py,sha256=AR_RpS22igMpKUHrNEQtXt41eAtcCuvzyVXtwlgA4DU,96057
28
+ DLMS_SPODES/cosem_interface_classes/collection.py,sha256=daTqYyMfdGHC5upqVrIJARsMLPs0JQP-b5DPlwUREw8,96343
29
29
  DLMS_SPODES/cosem_interface_classes/cosem_interface_class.py,sha256=k-eMPkFK2myfII2sRH8JdwoE7bxtBep-gHE-tqMR71I,22929
30
30
  DLMS_SPODES/cosem_interface_classes/data.py,sha256=ELFfBX_VFsKRpAB7SVUp1sBnhjDgttGXa96jSYYLOH8,734
31
31
  DLMS_SPODES/cosem_interface_classes/disconnect_control.py,sha256=21qKu4cpOEeiuhQAk4tGcfsm32ibCgQv8W3vVdOO4Wo,2894
@@ -34,10 +34,10 @@ DLMS_SPODES/cosem_interface_classes/gprs_modem_setup.py,sha256=TM0PcTNOmk0GApHwp
34
34
  DLMS_SPODES/cosem_interface_classes/iec_local_port_setup.py,sha256=Tu6WB8S7gT-9X7IWYuFFIdtNnbkHM_prG_f-Ock8jUM,410
35
35
  DLMS_SPODES/cosem_interface_classes/ipv4_setup.py,sha256=kFixHUH8D7_hVRvOWAQPdcUjCcJT5QtjincOQew2vDU,2823
36
36
  DLMS_SPODES/cosem_interface_classes/limiter.py,sha256=a4vyTbglRUPRxP9dGhyrcyYwO5bjy0r-KfG6Kim5sek,5249
37
- DLMS_SPODES/cosem_interface_classes/ln_pattern.py,sha256=9abQ_KMkHXw0ogl-rrlUe_2qpfhEGI6LmixFQjpuI_4,10916
37
+ DLMS_SPODES/cosem_interface_classes/ln_pattern.py,sha256=IPluhyGWJQLBEUjOjdfEMct8JP_4orUwF92c3sQfSNM,13921
38
38
  DLMS_SPODES/cosem_interface_classes/obis.py,sha256=yEwYm5CshJx8X8uSy3QH8XIbdVPg8Tt6zPUjFgkAB0M,575
39
39
  DLMS_SPODES/cosem_interface_classes/overview.py,sha256=4RjE6_5x_dDGv4M5J2rjT8MZDF-Q4nFE8JSOUA7OD84,6973
40
- DLMS_SPODES/cosem_interface_classes/parameter.py,sha256=AX3t67iLJNtGhIPq2GavOSCilwGVypkOLXPfQxLMHVs,18270
40
+ DLMS_SPODES/cosem_interface_classes/parameter.py,sha256=ukoDSqGutYV4K4QSaM7i9zKYm8eyqQ8gnOWvqqAeDCo,18252
41
41
  DLMS_SPODES/cosem_interface_classes/register.py,sha256=ClnkQ9-lg9NCxxCtFLR0soQ7VuNdigHia9qx1suGVZE,1854
42
42
  DLMS_SPODES/cosem_interface_classes/register_monitor.py,sha256=CrcFqas157kGaaDDwy8a0DKy5wK1Jm-tzCOBGBLuIKM,1760
43
43
  DLMS_SPODES/cosem_interface_classes/reports.py,sha256=9kOt9Ztyp5D59j3k3x5URy7WD1qlFNMa8xFlMu7nUmA,3320
@@ -71,7 +71,7 @@ DLMS_SPODES/cosem_interface_classes/image_transfer/image_transfer_status.py,sha2
71
71
  DLMS_SPODES/cosem_interface_classes/image_transfer/ver0.py,sha256=YD1Col7297zKt2HcjgZZ4EkahSvSuC0DruX07-hk2uo,5338
72
72
  DLMS_SPODES/cosem_interface_classes/implementations/__init__.py,sha256=z4OfnPPyYr6f94rj-PU3---Wk05ddduf9MkmWxhczXA,77
73
73
  DLMS_SPODES/cosem_interface_classes/implementations/arbitrator.py,sha256=cMhYLi9ZFqfJ0yxjONHq9JZZJ3QuzrF0jtPjk4nf0eo,573
74
- DLMS_SPODES/cosem_interface_classes/implementations/data.py,sha256=jzxWIuJkWIH3vjOc8d6q7g5WKMX8fhcysg-xYtXoK2M,18144
74
+ DLMS_SPODES/cosem_interface_classes/implementations/data.py,sha256=g-3SZCSodet9gILK7SsrTPc72Fsq87YDtaZTb0Vucdc,18561
75
75
  DLMS_SPODES/cosem_interface_classes/implementations/profile_generic.py,sha256=oibO3EV9fRHxxaBdMQqz436GrMMqo1BlT6lgVtzUKU0,4318
76
76
  DLMS_SPODES/cosem_interface_classes/modem_configuration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  DLMS_SPODES/cosem_interface_classes/modem_configuration/ver0.py,sha256=6fzbsID_cOmYsl3alLHHcMM1zpD7NjsK77NzTViQOmo,3038
@@ -99,7 +99,7 @@ DLMS_SPODES/obis/abstract_objects.py,sha256=0ZoJKRQ_7FoChC2rNSgNV573hso8JYZQKdLF
99
99
  DLMS_SPODES/obis/media_id.py,sha256=GRiwHPe9-3iCg4u_J6qf2rMc3Wjw0aJHKiSnBtNYD3o,22339
100
100
  DLMS_SPODES/types/__init__.py,sha256=UFiP4suA72o_kvaqUnHLGK-cedDXLl8kVHYsjXHYUDw,116
101
101
  DLMS_SPODES/types/choices.py,sha256=z7IasrlRaagOYNfRvgbpojDxf1jgYUc9cz59PH2PMi0,6350
102
- DLMS_SPODES/types/common_data_types.py,sha256=d5-D0Hp3uzc5PijuK6ZLQZ4hB9RHgNmpBXVXJ0MJ4_s,96901
102
+ DLMS_SPODES/types/common_data_types.py,sha256=IzFFsCWAEORh82aUTg41InfTsXym1i2lynWd5gGWfyc,96936
103
103
  DLMS_SPODES/types/cosem_service_types.py,sha256=XLWPDfdSxyYpr_3NwAxICRgxjPJdHf7EgQ4694M-erQ,4360
104
104
  DLMS_SPODES/types/useful_types.py,sha256=sRboTj7ZUjEHF9ypCgdXNOk_uOLXL6pjdbqKuPZrtEE,27426
105
105
  DLMS_SPODES/types/implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -111,7 +111,7 @@ DLMS_SPODES/types/implementations/integers.py,sha256=KAcaTY8ZwhBaJThbLSr39Oh_-9h
111
111
  DLMS_SPODES/types/implementations/long_unsigneds.py,sha256=SxmFvD2moQ03p-KZSBYK1Rv7bQSaywlHVXBfkTZG1OQ,8761
112
112
  DLMS_SPODES/types/implementations/octet_string.py,sha256=Jo_sfWcsfstiP4O6mXfBOOQlksx1c2qJMI-vbAOV-yM,294
113
113
  DLMS_SPODES/types/implementations/structs.py,sha256=GMOo6Jy8jA9d6KTLs0D-j5t0oSRvxUIwtBr_4UePwbA,2059
114
- dlms_spodes-0.86.8.dist-info/METADATA,sha256=EtdXZQj5lPd7SMKDWQ-0G0DQT7AmVIUcEiOpE9YpuNc,930
115
- dlms_spodes-0.86.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
116
- dlms_spodes-0.86.8.dist-info/top_level.txt,sha256=k26SRuRdwBZrSM3NgNZECAUNIDZREbJuLCnPbWtTNak,12
117
- dlms_spodes-0.86.8.dist-info/RECORD,,
114
+ dlms_spodes-0.86.10.dist-info/METADATA,sha256=TIED87Nv6wSzhQegjcQTg-_5uFsI5aQJIzoLb9CqeA8,999
115
+ dlms_spodes-0.86.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
116
+ dlms_spodes-0.86.10.dist-info/top_level.txt,sha256=k26SRuRdwBZrSM3NgNZECAUNIDZREbJuLCnPbWtTNak,12
117
+ dlms_spodes-0.86.10.dist-info/RECORD,,