DLMS-SPODES-client 0.19.4__tar.gz → 0.19.6__tar.gz
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_client-0.19.4/src/DLMS_SPODES_client.egg-info → dlms_spodes_client-0.19.6}/PKG-INFO +2 -2
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/pyproject.toml +2 -2
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/client.py +1 -1
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/task.py +87 -33
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6/src/DLMS_SPODES_client.egg-info}/PKG-INFO +2 -2
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client.egg-info/requires.txt +1 -1
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/client_log.txt +609 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/test_Client.py +9 -6
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/.gitignore +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/README.md +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/setup.cfg +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/FCS16.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/__init__.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_common/enums/TraceLevel.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_common/enums/__init__.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/AesGcmParameter.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/CountType.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXByteBuffer.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXCiphering.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMS.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSChippering.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSChipperingStream.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSConfirmedServiceError.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSException.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSLNParameters.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSSNParameters.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXDLMSSettings.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/GXReplyData.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/HdlcControlFrame.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/MBusCommand.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/MBusEncryptionMode.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/ResponseType.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/SetResponseType.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/_HDLCInfo.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/__init__.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Access.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/ApplicationReference.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Authentication.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/BerType.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Command.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Definition.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/ErrorCode.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/ExceptionServiceError.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/HardwareResource.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/HdlcFrameType.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Initiate.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/LoadDataSet.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/ObjectType.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Priority.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/RequestTypes.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Security.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Service.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/ServiceClass.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/ServiceError.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Standard.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/StateError.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/Task.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/VdeStateError.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/enums/__init__.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/gurux_dlms/internal/_GXCommon.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/logger.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/py.typed +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/services.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/session.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client/settings.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client.egg-info/SOURCES.txt +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client.egg-info/dependency_links.txt +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client.egg-info/entry_points.txt +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/src/DLMS_SPODES_client.egg-info/top_level.txt +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/Firmwares/firmwares.dat +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/Firmwares/firmwares_1_2_11.dat +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/Firmwares/firmwares_1_7_2.dat +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/Types/303030/0000600101ff020009054d324d5f31/0000600102ff02000906312e332e3330.xml +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/Types/313031/0000600101ff020009054d324d5f31/0000600102ff02000906312e322e3131.xml +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/config.toml +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/name2.csv +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/test_logger.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test/test_services.py +0 -0
- {dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6}/test//320/272/320/276/320/275/321/204/320/270/320/263/321/203/321/200/320/260/321/206/320/270/321/217 GSM.csv" +0 -0
{dlms_spodes_client-0.19.4/src/DLMS_SPODES_client.egg-info → dlms_spodes_client-0.19.6}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DLMS_SPODES_client
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.6
|
|
4
4
|
Summary: dlms-spodes
|
|
5
5
|
Author-email: Serj Kotilevski <youserj@outlook.com>
|
|
6
6
|
Project-URL: Source, https://github.com/youserj/SPODESclient_prj
|
|
@@ -13,7 +13,7 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
Requires-Dist: pydantic>=2.11
|
|
14
14
|
Requires-Dist: pycryptodomex>=3.22.0
|
|
15
15
|
Requires-Dist: semver>=3.0
|
|
16
|
-
Requires-Dist: StructResult<0.
|
|
16
|
+
Requires-Dist: StructResult<0.10,>=0.9.1
|
|
17
17
|
Requires-Dist: DLMS-SPODES-communications<1.5,>=1.4.9
|
|
18
18
|
Requires-Dist: DLMS_SPODES<0.88,>=0.87.6
|
|
19
19
|
Requires-Dist: DLMSadapter<0.8,>=0.7.5
|
|
@@ -15,7 +15,7 @@ exclude = ["Types"]
|
|
|
15
15
|
|
|
16
16
|
[project]
|
|
17
17
|
name = "DLMS_SPODES_client"
|
|
18
|
-
version = "0.19.
|
|
18
|
+
version = "0.19.6"
|
|
19
19
|
requires-python = ">= 3.12"
|
|
20
20
|
authors = [
|
|
21
21
|
{name="Serj Kotilevski", email="youserj@outlook.com"}
|
|
@@ -24,7 +24,7 @@ dependencies = [
|
|
|
24
24
|
"pydantic>=2.11",
|
|
25
25
|
"pycryptodomex >= 3.22.0",
|
|
26
26
|
"semver >= 3.0",
|
|
27
|
-
"StructResult >= 0.
|
|
27
|
+
"StructResult >= 0.9.1, <0.10",
|
|
28
28
|
"DLMS-SPODES-communications >= 1.4.9, <1.5",
|
|
29
29
|
"DLMS_SPODES >= 0.87.6, < 0.88",
|
|
30
30
|
"DLMSadapter >= 0.7.5, < 0.8",
|
|
@@ -970,7 +970,7 @@ class Client:
|
|
|
970
970
|
def set_params(self, field: str, value: str):
|
|
971
971
|
self.__dict__[field] = eval(value)
|
|
972
972
|
|
|
973
|
-
async def close(self):
|
|
973
|
+
async def close(self) -> None:
|
|
974
974
|
"""close , media is open"""
|
|
975
975
|
self.log(logL.DEB, "close")
|
|
976
976
|
if self.level > OSI.DATA_LINK:
|
|
@@ -5,7 +5,7 @@ import re
|
|
|
5
5
|
from typing_extensions import deprecated
|
|
6
6
|
import hashlib
|
|
7
7
|
from dataclasses import dataclass, field
|
|
8
|
-
from typing import Callable, Any, Optional, Protocol, cast, override, Self, Final
|
|
8
|
+
from typing import Callable, Any, Optional, Protocol, cast, override, Self, Final, Iterable, TypeVarTuple
|
|
9
9
|
from itertools import count
|
|
10
10
|
import datetime
|
|
11
11
|
import time
|
|
@@ -35,7 +35,8 @@ from DLMS_SPODES.firmwares import get_firmware
|
|
|
35
35
|
from DLMS_SPODES.cosem_interface_classes.image_transfer import image_transfer_status as i_t_status
|
|
36
36
|
from DLMSAdapter.main import AdapterException, Adapter, gag
|
|
37
37
|
from DLMSCommunicationProfile.osi import OSI
|
|
38
|
-
from .
|
|
38
|
+
from .logger import LogLevel as logL
|
|
39
|
+
from .client import Client, Security, Data, mechanism_id, AcseServiceUser, State
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
firm_id_pat = re.compile(b".*(?P<fid>PWRM_M2M_[^_]{1,10}_[^_]{1,10}).+")
|
|
@@ -56,7 +57,7 @@ class Base[T: result.Result](Protocol):
|
|
|
56
57
|
def copy(self) -> Self: ...
|
|
57
58
|
|
|
58
59
|
@property
|
|
59
|
-
def current(self) -> 'Base[T]':
|
|
60
|
+
def current(self) -> 'Base[T] | Self':
|
|
60
61
|
return self
|
|
61
62
|
|
|
62
63
|
async def run(self, c: Client) -> T | result.Error:
|
|
@@ -137,14 +138,14 @@ class Base[T: result.Result](Protocol):
|
|
|
137
138
|
# todo: make tile
|
|
138
139
|
return await self.application(c)
|
|
139
140
|
|
|
140
|
-
async def AA(self, c: Client):
|
|
141
|
+
async def AA(self, c: Client) -> None:
|
|
141
142
|
"""Application Associate"""
|
|
142
143
|
if c.invocationCounter and c.settings.cipher is not None and c.settings.cipher.security != Security.NONE:
|
|
143
144
|
# create IC object. TODO: remove it after close connection, maybe???
|
|
144
145
|
c.settings.proposedConformance |= Conformance.GENERAL_PROTECTION
|
|
145
146
|
|
|
146
147
|
# my block
|
|
147
|
-
IC: Data = c.
|
|
148
|
+
IC: Data = c.objects.add_if_missing(ut.CosemClassId(1),
|
|
148
149
|
logical_name=cst.LogicalName(bytearray((0, c.get_channel_index(), 43, 1,
|
|
149
150
|
c.current_association.security_setup_reference.e, 255))),
|
|
150
151
|
version=cdt.Unsigned(0))
|
|
@@ -268,12 +269,18 @@ class CDT[T: cdt.CommonDataType](Simple[T], Protocol):
|
|
|
268
269
|
async def exchange(self, c: Client) -> result.SimpleOrError[T]: ...
|
|
269
270
|
|
|
270
271
|
|
|
271
|
-
class
|
|
272
|
+
class _List[T](Base[result.List[T]], Protocol):
|
|
272
273
|
"""With List result"""
|
|
273
274
|
@override
|
|
274
275
|
async def exchange(self, c: Client) -> result.List[T] | result.Error: ...
|
|
275
276
|
|
|
276
277
|
|
|
278
|
+
class _Sequence[*Ts](Base[result.Sequence[*Ts]], Protocol):
|
|
279
|
+
"""With List result"""
|
|
280
|
+
@override
|
|
281
|
+
async def exchange(self, c: Client) -> result.Sequence[*Ts] | result.Error: ...
|
|
282
|
+
|
|
283
|
+
|
|
277
284
|
class OK(Base[result.Ok], Protocol):
|
|
278
285
|
"""Always result OK"""
|
|
279
286
|
|
|
@@ -289,12 +296,12 @@ class StrictOK(Base[result.StrictOk], Protocol):
|
|
|
289
296
|
|
|
290
297
|
|
|
291
298
|
@dataclass
|
|
292
|
-
class ClientBlocking(SimpleCopy,
|
|
299
|
+
class ClientBlocking(SimpleCopy, OK):
|
|
293
300
|
"""complete by time or abort"""
|
|
294
301
|
delay: Final[float] = field(default=99999999.0)
|
|
295
302
|
msg: str = ""
|
|
296
303
|
|
|
297
|
-
async def run(self, c: Client) -> result.Ok:
|
|
304
|
+
async def run(self, c: Client) -> result.Ok | result.Error:
|
|
298
305
|
try:
|
|
299
306
|
c.level = OSI.APPLICATION
|
|
300
307
|
c.log(logL.WARN, F"blocked for {self.delay} second")
|
|
@@ -302,8 +309,9 @@ class ClientBlocking(SimpleCopy, Base):
|
|
|
302
309
|
return result.OK
|
|
303
310
|
finally:
|
|
304
311
|
c.level = OSI.NONE
|
|
312
|
+
return result.OK
|
|
305
313
|
|
|
306
|
-
async def exchange(self, c: Client) -> result.
|
|
314
|
+
async def exchange(self, c: Client) -> result.Ok | result.Error:
|
|
307
315
|
raise RuntimeError(f"not support for {self.__class__.__name__}")
|
|
308
316
|
|
|
309
317
|
|
|
@@ -432,7 +440,7 @@ class Scheduler[T: result.Result](Base[T]):
|
|
|
432
440
|
repetition_delay_max: Final[int] = 100
|
|
433
441
|
msg: str = ""
|
|
434
442
|
|
|
435
|
-
def copy(self) ->
|
|
443
|
+
def copy(self) -> "Scheduler[T]":
|
|
436
444
|
return Scheduler(
|
|
437
445
|
task=self.task.copy(),
|
|
438
446
|
execution_datetime=self.execution_datetime,
|
|
@@ -479,37 +487,37 @@ class Scheduler[T: result.Result](Base[T]):
|
|
|
479
487
|
@dataclass
|
|
480
488
|
class Subtasks[U: Base[result.Result]](Protocol):
|
|
481
489
|
"""for register longer other tasks into task"""
|
|
482
|
-
tasks:
|
|
490
|
+
tasks: Iterable[U]
|
|
483
491
|
|
|
484
492
|
@property
|
|
485
493
|
def current(self) -> U | Self: ...
|
|
486
494
|
|
|
487
495
|
|
|
488
|
-
class
|
|
496
|
+
class List[T: result.Result, U: Base[result.Result]](Subtasks[U], _List[T]):
|
|
489
497
|
"""for exchange task sequence"""
|
|
490
498
|
__is_exchange: bool
|
|
491
499
|
msg: str
|
|
492
500
|
err_ignore: bool
|
|
493
501
|
__current: Base[T]
|
|
494
502
|
|
|
495
|
-
def __init__(self, *tasks: Base[T], msg: str =
|
|
503
|
+
def __init__(self, *tasks: Base[T], msg: str = "", err_ignore: bool = True):
|
|
496
504
|
self.tasks = list(tasks)
|
|
497
505
|
self.__current = self
|
|
498
506
|
self.__is_exchange = False
|
|
499
|
-
self.msg = self.
|
|
507
|
+
self.msg = self.__class__.__name__ if msg == "" else msg
|
|
500
508
|
self.err_ignore = err_ignore
|
|
501
509
|
|
|
502
510
|
def copy(self) -> Self:
|
|
503
511
|
if all((isinstance(t, SimpleCopy) for t in self.tasks)):
|
|
504
512
|
return self
|
|
505
|
-
return
|
|
513
|
+
return List(
|
|
506
514
|
*(t.copy() for t in self.tasks),
|
|
507
515
|
msg=self.msg,
|
|
508
516
|
err_ignore=self.err_ignore
|
|
509
517
|
)
|
|
510
518
|
|
|
511
519
|
@property
|
|
512
|
-
def current(self) -> 'Base[T]':
|
|
520
|
+
def current(self) -> 'Base[T] | Self':
|
|
513
521
|
return self.__current
|
|
514
522
|
|
|
515
523
|
def append(self, task: Base[T]):
|
|
@@ -535,6 +543,48 @@ class Sequence[T: result.Result, U: Base[result.Result]](Subtasks[U], List[T]):
|
|
|
535
543
|
return res
|
|
536
544
|
|
|
537
545
|
|
|
546
|
+
class Sequence[*Ts](Subtasks[Base[result.Result]], _Sequence[*Ts]):
|
|
547
|
+
"""for exchange task sequence"""
|
|
548
|
+
msg: str
|
|
549
|
+
err_ignore: bool
|
|
550
|
+
__current: "Base[result.Result] | Sequence[*Ts]"
|
|
551
|
+
tasks: tuple[Base[result.Result], ...]
|
|
552
|
+
|
|
553
|
+
def __init__(self, *tasks: Base[result.Result], msg: str = "", err_ignore: bool = False):
|
|
554
|
+
self.tasks = tasks
|
|
555
|
+
self.__current = self
|
|
556
|
+
self.msg = self.__class__.__name__ if msg == "" else msg
|
|
557
|
+
self.err_ignore = err_ignore
|
|
558
|
+
|
|
559
|
+
def copy(self) -> "Sequence[*Ts]":
|
|
560
|
+
if all((isinstance(t, SimpleCopy) for t in self.tasks)):
|
|
561
|
+
return self
|
|
562
|
+
return Sequence(
|
|
563
|
+
*(t.copy() for t in self.tasks),
|
|
564
|
+
msg=self.msg,
|
|
565
|
+
err_ignore=self.err_ignore
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
@property
|
|
569
|
+
def current(self) -> Base[result.Result] | Self:
|
|
570
|
+
return self.__current
|
|
571
|
+
|
|
572
|
+
async def exchange(self, c: Client) -> result.Sequence[*Ts] | result.Error:
|
|
573
|
+
res = result.Sequence()
|
|
574
|
+
for t in self.tasks:
|
|
575
|
+
self.__current = t
|
|
576
|
+
try:
|
|
577
|
+
if (
|
|
578
|
+
isinstance(res_one := await t.exchange(c), result.Error)
|
|
579
|
+
and not self.err_ignore
|
|
580
|
+
):
|
|
581
|
+
return res_one
|
|
582
|
+
res = res.add(res_one)
|
|
583
|
+
except exc.ResultError as e: # todo: make without except
|
|
584
|
+
res.add(result.Error.from_e(e).with_msg(t.msg))
|
|
585
|
+
return cast("result.Sequence[*Ts]", res)
|
|
586
|
+
|
|
587
|
+
|
|
538
588
|
class SetLocalTime(SimpleCopy, OK):
|
|
539
589
|
"""without decide time transfer"""
|
|
540
590
|
msg: str
|
|
@@ -907,7 +957,6 @@ class InitType(SimpleCopy, Simple[collection.Collection]):
|
|
|
907
957
|
FindFirmwareId(),
|
|
908
958
|
FindFirmwareVersion(),
|
|
909
959
|
msg="get collection.ID",
|
|
910
|
-
err_ignore=False
|
|
911
960
|
).exchange(c)), result.Error):
|
|
912
961
|
return res.with_msg("init type")
|
|
913
962
|
ldn, f_id, f_ver = res.value
|
|
@@ -996,7 +1045,7 @@ class Par2Data[T: cdt.CommonDataType](SimpleCopy, CDT):
|
|
|
996
1045
|
return res
|
|
997
1046
|
|
|
998
1047
|
|
|
999
|
-
class ReadSequence(
|
|
1048
|
+
class ReadSequence(List):
|
|
1000
1049
|
tasks: list[ReadAttribute]
|
|
1001
1050
|
|
|
1002
1051
|
def __post_init__(self):
|
|
@@ -1098,7 +1147,7 @@ class ActualizeAttributes(SimpleCopy, OK):
|
|
|
1098
1147
|
|
|
1099
1148
|
|
|
1100
1149
|
@dataclass
|
|
1101
|
-
class ReadAttributes(SimpleCopy,
|
|
1150
|
+
class ReadAttributes(SimpleCopy, _List[cdt.CommonDataType]):
|
|
1102
1151
|
ln: collection.LNContaining
|
|
1103
1152
|
indexes: tuple[int, ...]
|
|
1104
1153
|
msg: str = ""
|
|
@@ -1645,7 +1694,7 @@ class AccessValidate(Base[result.Ok | result.Simple[list[Parameter]]]):
|
|
|
1645
1694
|
|
|
1646
1695
|
|
|
1647
1696
|
@dataclass
|
|
1648
|
-
class WriteParDatas(SimpleCopy,
|
|
1697
|
+
class WriteParDatas(SimpleCopy, _List[result.Ok]):
|
|
1649
1698
|
"""write by ParData list"""
|
|
1650
1699
|
par_datas: list[ParData]
|
|
1651
1700
|
msg: str = ""
|
|
@@ -1664,34 +1713,39 @@ class WriteParDatas(SimpleCopy, List[result.Ok]):
|
|
|
1664
1713
|
@dataclass
|
|
1665
1714
|
class WriteParTranscript(SimpleCopy, OK):
|
|
1666
1715
|
"""write by ParValues[Transcript]"""
|
|
1667
|
-
|
|
1716
|
+
par: Parameter
|
|
1717
|
+
value: cdt.Transcript
|
|
1668
1718
|
msg: str = ""
|
|
1669
1719
|
|
|
1670
1720
|
async def exchange(self, c: Client) -> result.Ok | result.Error:
|
|
1671
|
-
|
|
1672
|
-
if isinstance((res := await Par2Data(par).exchange(c)), result.Error):
|
|
1721
|
+
if isinstance((res := await Par2Data(self.par).exchange(c)), result.Error):
|
|
1673
1722
|
return res
|
|
1674
1723
|
data = copy(res.value)
|
|
1675
1724
|
if isinstance(data, cdt.Digital):
|
|
1676
|
-
s_u = c.objects.par2su(par)
|
|
1725
|
+
s_u = c.objects.par2su(self.par)
|
|
1677
1726
|
if isinstance(s_u, cdt.ScalUnitType):
|
|
1678
|
-
value = int(float(value) * 10 ** -int(s_u.scaler))
|
|
1679
|
-
data.set(value)
|
|
1727
|
+
value = int(float(self.value) * 10 ** -int(s_u.scaler))
|
|
1728
|
+
data.set(self.value)
|
|
1680
1729
|
return await WriteAttribute(
|
|
1681
|
-
ln=self.
|
|
1682
|
-
index=self.
|
|
1730
|
+
ln=self.par.obis,
|
|
1731
|
+
index=self.par.i,
|
|
1683
1732
|
value=data.encoding
|
|
1684
1733
|
).exchange(c)
|
|
1685
1734
|
|
|
1686
1735
|
|
|
1736
|
+
Ts = TypeVarTuple("Ts")
|
|
1737
|
+
|
|
1738
|
+
|
|
1687
1739
|
@dataclass
|
|
1688
|
-
class WriteParTranscripts(SimpleCopy,
|
|
1740
|
+
class WriteParTranscripts(SimpleCopy, Sequence[*Ts]):
|
|
1689
1741
|
"""write by ParValues[Transcript] list"""
|
|
1690
|
-
par_values:
|
|
1742
|
+
par_values: list[ParValues[cdt.Transcript]]
|
|
1691
1743
|
msg: str = ""
|
|
1692
1744
|
|
|
1693
|
-
async def exchange(self, c: Client) -> result.
|
|
1694
|
-
res = result.
|
|
1745
|
+
async def exchange(self, c: Client) -> result.Sequence[*Ts] | result.Error:
|
|
1746
|
+
res = result.Sequence()
|
|
1695
1747
|
for par_value in self.par_values:
|
|
1696
|
-
WriteParTranscript(par_value)
|
|
1748
|
+
if isinstance(res_one := await WriteParTranscript(*par_value).exchange(c), result.Error):
|
|
1749
|
+
return res_one
|
|
1750
|
+
res = res.add(res_one)
|
|
1697
1751
|
return res
|
{dlms_spodes_client-0.19.4 → dlms_spodes_client-0.19.6/src/DLMS_SPODES_client.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DLMS_SPODES_client
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.6
|
|
4
4
|
Summary: dlms-spodes
|
|
5
5
|
Author-email: Serj Kotilevski <youserj@outlook.com>
|
|
6
6
|
Project-URL: Source, https://github.com/youserj/SPODESclient_prj
|
|
@@ -13,7 +13,7 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
Requires-Dist: pydantic>=2.11
|
|
14
14
|
Requires-Dist: pycryptodomex>=3.22.0
|
|
15
15
|
Requires-Dist: semver>=3.0
|
|
16
|
-
Requires-Dist: StructResult<0.
|
|
16
|
+
Requires-Dist: StructResult<0.10,>=0.9.1
|
|
17
17
|
Requires-Dist: DLMS-SPODES-communications<1.5,>=1.4.9
|
|
18
18
|
Requires-Dist: DLMS_SPODES<0.88,>=0.87.6
|
|
19
19
|
Requires-Dist: DLMSadapter<0.8,>=0.7.5
|