DLMS-SPODES-client 0.19.7__py3-none-any.whl → 0.19.9__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_client/client.py +102 -29
- DLMS_SPODES_client/gurux_dlms/GXDLMSLNParameters.py +5 -5
- DLMS_SPODES_client/gurux_dlms/GXDLMSSettings.py +0 -1
- DLMS_SPODES_client/task.py +28 -24
- {dlms_spodes_client-0.19.7.dist-info → dlms_spodes_client-0.19.9.dist-info}/METADATA +1 -1
- {dlms_spodes_client-0.19.7.dist-info → dlms_spodes_client-0.19.9.dist-info}/RECORD +9 -9
- {dlms_spodes_client-0.19.7.dist-info → dlms_spodes_client-0.19.9.dist-info}/WHEEL +0 -0
- {dlms_spodes_client-0.19.7.dist-info → dlms_spodes_client-0.19.9.dist-info}/entry_points.txt +0 -0
- {dlms_spodes_client-0.19.7.dist-info → dlms_spodes_client-0.19.9.dist-info}/top_level.txt +0 -0
DLMS_SPODES_client/client.py
CHANGED
|
@@ -318,7 +318,7 @@ class Client:
|
|
|
318
318
|
self.reply.blockNumberAck = bna
|
|
319
319
|
self.settings.blockNumberAck = self.reply.blockNumber
|
|
320
320
|
self.reply.command = None
|
|
321
|
-
len_ = _GXCommon.getObjectCount(self.reply.data)
|
|
321
|
+
len_, _ = cdt.get_length_and_pdu(self.reply.data.get_data()) # _GXCommon.getObjectCount(self.reply.data)
|
|
322
322
|
if len_ > self.reply.data.size - self.reply.data.position:
|
|
323
323
|
self.reply.complete = False
|
|
324
324
|
return
|
|
@@ -369,7 +369,7 @@ class Client:
|
|
|
369
369
|
match self.reply.data.getUInt8(): # DataBlock-G.result
|
|
370
370
|
case 0:
|
|
371
371
|
if self.reply.data.position != len(self.reply.data):
|
|
372
|
-
block_length = _GXCommon.getObjectCount(self.reply.data)
|
|
372
|
+
block_length, _ = cdt.get_length_and_pdu(self.reply.data.get_data()) # _GXCommon.getObjectCount(self.reply.data)
|
|
373
373
|
if (self.reply.moreData & RequestTypes.FRAME) == 0:
|
|
374
374
|
if block_length > len(self.reply.data) - self.reply.data.position:
|
|
375
375
|
raise ValueError("Invalid block length.")
|
|
@@ -416,7 +416,7 @@ class Client:
|
|
|
416
416
|
case pdu.SetResponse.LAST_DATABLOCK_WITH_LIST:
|
|
417
417
|
raise ValueError("Not released in Client")
|
|
418
418
|
case pdu.SetResponse.WITH_LIST:
|
|
419
|
-
cnt = _GXCommon.getObjectCount(self.reply.data)
|
|
419
|
+
cnt, _ = cdt.get_length_and_pdu(self.reply.data.get_data()) # _GXCommon.getObjectCount(self.reply.data)
|
|
420
420
|
pos = 0
|
|
421
421
|
while pos != cnt:
|
|
422
422
|
self.reply.error = pdu.DataAccessResult(self.reply.data.getUInt8())
|
|
@@ -425,7 +425,7 @@ class Client:
|
|
|
425
425
|
pos += 1
|
|
426
426
|
case err: raise ValueError(F"Got Invalid Set response {err}, expect {', '.join(map(lambda it: F'{it.name} = {it.value}', pdu.SetResponse))}")
|
|
427
427
|
case XDLMSAPDU.WRITE_RESPONSE:
|
|
428
|
-
cnt = _GXCommon.getObjectCount(self.reply.data)
|
|
428
|
+
cnt, _ = cdt.get_length_and_pdu(self.reply.data.get_data()) # _GXCommon.getObjectCount(self.reply.data)
|
|
429
429
|
pos = 0
|
|
430
430
|
while pos != cnt:
|
|
431
431
|
ret = self.reply.data.getUInt8()
|
|
@@ -569,7 +569,7 @@ class Client:
|
|
|
569
569
|
pass
|
|
570
570
|
case XDLMSAPDU.GATEWAY_RESPONSE:
|
|
571
571
|
self.reply.data.getUInt8()
|
|
572
|
-
len_ = _GXCommon.getObjectCount(self.reply.data)
|
|
572
|
+
len_, _ = cdt.get_length_and_pdu(self.reply.data.get_data()) # _GXCommon.getObjectCount(self.reply.data)
|
|
573
573
|
pda = bytearray(len_)
|
|
574
574
|
self.reply.data.get(pda)
|
|
575
575
|
GXDLMS.getDataFromBlock(self.reply, index)
|
|
@@ -1144,7 +1144,7 @@ class Client:
|
|
|
1144
1144
|
else:
|
|
1145
1145
|
if tag != (BerType.APPLICATION | BerType.CONSTRUCTED | AARQapdu.APPLICATION_CONTEXT_NAME):
|
|
1146
1146
|
raise ValueError("Invalid tag.")
|
|
1147
|
-
if
|
|
1147
|
+
if cdt.get_length_and_pdu(buff)[0] > len(buff) - buff.position: # _GXCommon.getObjectCount(buff)
|
|
1148
1148
|
raise ValueError("PDU: Not enough data.")
|
|
1149
1149
|
resultComponent = AssociationResult.ACCEPTED
|
|
1150
1150
|
resultDiagnosticValue = AcseServiceUser.NULL
|
|
@@ -1583,14 +1583,25 @@ class Client:
|
|
|
1583
1583
|
reply = GXByteBuffer()
|
|
1584
1584
|
messages = list()
|
|
1585
1585
|
frame_ = 0
|
|
1586
|
-
if
|
|
1586
|
+
if (
|
|
1587
|
+
p.command == XDLMSAPDU.DATA_NOTIFICATION
|
|
1588
|
+
or p.command == XDLMSAPDU.EVENT_NOTIFICATION_REQUEST
|
|
1589
|
+
):
|
|
1587
1590
|
frame_ = 0x13
|
|
1588
1591
|
while True:
|
|
1589
1592
|
# """ Get next logical name PDU. @param p LN parameters. @param reply Generated message. """
|
|
1590
|
-
ciphering =
|
|
1593
|
+
ciphering = (
|
|
1594
|
+
p.command != ACSEAPDU.AARQ
|
|
1595
|
+
and p.command != ACSEAPDU.AARE
|
|
1596
|
+
and self.settings.cipher
|
|
1597
|
+
and self.settings.cipher.security != Security.NONE
|
|
1598
|
+
)
|
|
1591
1599
|
len_ = 0
|
|
1592
1600
|
if p.command == ACSEAPDU.AARQ:
|
|
1593
|
-
if
|
|
1601
|
+
if (
|
|
1602
|
+
self.settings.gateway
|
|
1603
|
+
and self.settings.gateway.physicalDeviceAddress
|
|
1604
|
+
):
|
|
1594
1605
|
reply.setUInt8(XDLMSAPDU.GATEWAY_REQUEST)
|
|
1595
1606
|
reply.setUInt8(self.settings.gateway.networkId)
|
|
1596
1607
|
reply.setUInt8(len(self.settings.gateway.physicalDeviceAddress))
|
|
@@ -1614,16 +1625,26 @@ class Client:
|
|
|
1614
1625
|
reply.move(pos + 1, pos, len(reply) - pos - 1)
|
|
1615
1626
|
GXDLMS.multipleBlocks(p, reply, ciphering)
|
|
1616
1627
|
elif p.command != ACSEAPDU.RLRQ:
|
|
1617
|
-
if
|
|
1628
|
+
if (
|
|
1629
|
+
p.command != XDLMSAPDU.GET_REQUEST
|
|
1630
|
+
and p.data
|
|
1631
|
+
and reply
|
|
1632
|
+
):
|
|
1618
1633
|
GXDLMS.multipleBlocks(p, reply, ciphering)
|
|
1619
1634
|
if p.command == XDLMSAPDU.SET_REQUEST:
|
|
1620
|
-
if
|
|
1635
|
+
if (
|
|
1636
|
+
p.multipleBlocks
|
|
1637
|
+
and not self.negotiated_conformance.general_block_transfer
|
|
1638
|
+
):
|
|
1621
1639
|
if p.requestType == 1:
|
|
1622
1640
|
p.requestType = SetRequest.SET_REQUEST_FIRST_DATABLOCK
|
|
1623
1641
|
elif p.requestType == 2:
|
|
1624
1642
|
p.requestType = SetRequest.SET_REQUEST_WITH_DATABLOCK
|
|
1625
1643
|
if p.command == XDLMSAPDU.GET_RESPONSE:
|
|
1626
|
-
if
|
|
1644
|
+
if (
|
|
1645
|
+
p.multipleBlocks
|
|
1646
|
+
and not self.negotiated_conformance.general_block_transfer
|
|
1647
|
+
):
|
|
1627
1648
|
if p.requestType == 1:
|
|
1628
1649
|
p.requestType = 2
|
|
1629
1650
|
if p.command != XDLMSAPDU.GENERAL_BLOCK_TRANSFER:
|
|
@@ -1633,7 +1654,10 @@ class Client:
|
|
|
1633
1654
|
else:
|
|
1634
1655
|
reply.setUInt8(GXDLMS.getInvokeIDPriority(self.settings))
|
|
1635
1656
|
reply.set(p.attributeDescriptor)
|
|
1636
|
-
if
|
|
1657
|
+
if (
|
|
1658
|
+
self.settings.is_multiple_block()
|
|
1659
|
+
and self.negotiated_conformance.general_block_transfer
|
|
1660
|
+
):
|
|
1637
1661
|
if p.lastBlock:
|
|
1638
1662
|
reply.setUInt8(1)
|
|
1639
1663
|
self.settings.setCount(0)
|
|
@@ -1643,7 +1667,10 @@ class Client:
|
|
|
1643
1667
|
reply.setUInt32(p.blockIndex)
|
|
1644
1668
|
p.blockIndex += 1
|
|
1645
1669
|
if p.status != 0xFF:
|
|
1646
|
-
if
|
|
1670
|
+
if (
|
|
1671
|
+
p.status != 0
|
|
1672
|
+
and p.command == XDLMSAPDU.GET_RESPONSE
|
|
1673
|
+
):
|
|
1647
1674
|
reply.setUInt8(1)
|
|
1648
1675
|
reply.setUInt8(p.status)
|
|
1649
1676
|
if p.data:
|
|
@@ -1661,8 +1688,14 @@ class Client:
|
|
|
1661
1688
|
_GXCommon.setObjectCount(len_, reply)
|
|
1662
1689
|
reply.set(p.data, len_)
|
|
1663
1690
|
if len_ == 0:
|
|
1664
|
-
if
|
|
1665
|
-
|
|
1691
|
+
if (
|
|
1692
|
+
p.status != 0xFF
|
|
1693
|
+
and p.command != XDLMSAPDU.GENERAL_BLOCK_TRANSFER
|
|
1694
|
+
):
|
|
1695
|
+
if (
|
|
1696
|
+
p.status != 0
|
|
1697
|
+
and p.command == XDLMSAPDU.GET_RESPONSE
|
|
1698
|
+
):
|
|
1666
1699
|
reply.setUInt8(1)
|
|
1667
1700
|
reply.setUInt8(p.status)
|
|
1668
1701
|
if p.data:
|
|
@@ -1680,7 +1713,10 @@ class Client:
|
|
|
1680
1713
|
if self.negotiated_conformance.general_block_transfer:
|
|
1681
1714
|
if 7 + len_ + len(reply) > self.settings.maxPduSize:
|
|
1682
1715
|
len_ = self.settings.maxPduSize - len(reply) - 7
|
|
1683
|
-
if
|
|
1716
|
+
if (
|
|
1717
|
+
ciphering
|
|
1718
|
+
and p.command != XDLMSAPDU.GENERAL_BLOCK_TRANSFER
|
|
1719
|
+
):
|
|
1684
1720
|
reply.set(p.data)
|
|
1685
1721
|
tmp = []
|
|
1686
1722
|
if self.settings.cipher.securitySuite == SecuritySuite.AES_GCM_128_AUT_ENCR_AND_AES_128_KEY_WRAP:
|
|
@@ -1692,11 +1728,25 @@ class Client:
|
|
|
1692
1728
|
if 7 + len_ > self.settings.maxPduSize:
|
|
1693
1729
|
len_ = self.settings.maxPduSize - 7
|
|
1694
1730
|
ciphering = False
|
|
1695
|
-
elif
|
|
1731
|
+
elif (
|
|
1732
|
+
p.command != XDLMSAPDU.GET_REQUEST
|
|
1733
|
+
and len_ + len(reply) > self.settings.maxPduSize
|
|
1734
|
+
):
|
|
1696
1735
|
len_ = self.settings.maxPduSize - len(reply)
|
|
1697
1736
|
reply.set(p.data, p.data.position, len_)
|
|
1698
|
-
elif (
|
|
1699
|
-
|
|
1737
|
+
elif (
|
|
1738
|
+
(
|
|
1739
|
+
self.settings.gateway
|
|
1740
|
+
and self.settings.gateway.physicalDeviceAddress
|
|
1741
|
+
)
|
|
1742
|
+
and not (
|
|
1743
|
+
p.command == XDLMSAPDU.GENERAL_BLOCK_TRANSFER
|
|
1744
|
+
or (
|
|
1745
|
+
p.multipleBlocks
|
|
1746
|
+
and self.negotiated_conformance.general_block_transfer
|
|
1747
|
+
)
|
|
1748
|
+
)
|
|
1749
|
+
):
|
|
1700
1750
|
if 3 + len_ + len(self.settings.gateway.physicalDeviceAddress) > self.settings.maxPduSize:
|
|
1701
1751
|
len_ -= (3 + len(self.settings.gateway.physicalDeviceAddress))
|
|
1702
1752
|
tmp = GXByteBuffer(reply)
|
|
@@ -1706,27 +1756,42 @@ class Client:
|
|
|
1706
1756
|
reply.setUInt8(len(self.settings.gateway.physicalDeviceAddress))
|
|
1707
1757
|
reply.set(self.settings.gateway.physicalDeviceAddress)
|
|
1708
1758
|
reply.set(tmp)
|
|
1709
|
-
if
|
|
1759
|
+
if (
|
|
1760
|
+
ciphering
|
|
1761
|
+
and reply
|
|
1762
|
+
and not self.negotiated_conformance.general_block_transfer
|
|
1763
|
+
and p.command != XDLMSAPDU.RELEASE_REQUEST
|
|
1764
|
+
):
|
|
1710
1765
|
tmp = []
|
|
1711
1766
|
if self.settings.cipher.securitySuite == SecuritySuite.AES_GCM_128_AUT_ENCR_AND_AES_128_KEY_WRAP:
|
|
1712
1767
|
tmp = self.cipher0(p, reply.array())
|
|
1713
1768
|
reply.size = 0
|
|
1714
1769
|
reply.set(tmp)
|
|
1715
|
-
if
|
|
1770
|
+
if (
|
|
1771
|
+
p.command == XDLMSAPDU.GENERAL_BLOCK_TRANSFER
|
|
1772
|
+
or (
|
|
1773
|
+
p.multipleBlocks
|
|
1774
|
+
and self.negotiated_conformance.general_block_transfer
|
|
1775
|
+
)
|
|
1776
|
+
):
|
|
1716
1777
|
bb = GXByteBuffer()
|
|
1717
1778
|
bb.set(reply)
|
|
1718
1779
|
reply.clear()
|
|
1719
1780
|
reply.setUInt8(XDLMSAPDU.GENERAL_BLOCK_TRANSFER)
|
|
1720
|
-
value = 0
|
|
1721
1781
|
if p.lastBlock:
|
|
1722
1782
|
value = 0x80
|
|
1723
1783
|
elif p.streaming:
|
|
1724
|
-
value
|
|
1784
|
+
value = 0x40
|
|
1785
|
+
else:
|
|
1786
|
+
value = 0
|
|
1725
1787
|
value |= p.windowSize
|
|
1726
1788
|
reply.setUInt8(value)
|
|
1727
1789
|
reply.setUInt16(p.blockIndex)
|
|
1728
1790
|
p.blockIndex += 1
|
|
1729
|
-
if
|
|
1791
|
+
if (
|
|
1792
|
+
p.command != XDLMSAPDU.DATA_NOTIFICATION
|
|
1793
|
+
and p.blockNumberAck != 0
|
|
1794
|
+
):
|
|
1730
1795
|
reply.setUInt16(p.blockNumberAck)
|
|
1731
1796
|
p.blockNumberAck += 1
|
|
1732
1797
|
else:
|
|
@@ -1737,7 +1802,10 @@ class Client:
|
|
|
1737
1802
|
if p.command != XDLMSAPDU.GENERAL_BLOCK_TRANSFER:
|
|
1738
1803
|
p.command = XDLMSAPDU.GENERAL_BLOCK_TRANSFER
|
|
1739
1804
|
p.blockNumberAck += 1
|
|
1740
|
-
if
|
|
1805
|
+
if (
|
|
1806
|
+
self.settings.gateway
|
|
1807
|
+
and self.settings.gateway.physicalDeviceAddress
|
|
1808
|
+
):
|
|
1741
1809
|
if 3 + len_ + len(self.settings.gateway.physicalDeviceAddress) > self.settings.maxPduSize:
|
|
1742
1810
|
len_ -= (3 + len(self.settings.gateway.physicalDeviceAddress))
|
|
1743
1811
|
tmp = GXByteBuffer(reply)
|
|
@@ -1747,11 +1815,13 @@ class Client:
|
|
|
1747
1815
|
reply.setUInt8(len(self.settings.gateway.physicalDeviceAddress))
|
|
1748
1816
|
reply.set(self.settings.gateway.physicalDeviceAddress)
|
|
1749
1817
|
reply.set(tmp)
|
|
1750
|
-
|
|
1751
1818
|
p.lastBlock = True
|
|
1752
1819
|
if p.attributeDescriptor is None:
|
|
1753
1820
|
self.settings.increaseBlockIndex()
|
|
1754
|
-
if
|
|
1821
|
+
if (
|
|
1822
|
+
p.command == ACSEAPDU.AARQ
|
|
1823
|
+
and p.command == XDLMSAPDU.GET_REQUEST
|
|
1824
|
+
):
|
|
1755
1825
|
assert not self.settings.maxPduSize < len(reply)
|
|
1756
1826
|
match self.com_profile:
|
|
1757
1827
|
case c_pf.TCPUDPIP():
|
|
@@ -1762,7 +1832,10 @@ class Client:
|
|
|
1762
1832
|
raise ValueError("InterfaceType")
|
|
1763
1833
|
reply.clear()
|
|
1764
1834
|
frame_ = 0
|
|
1765
|
-
if
|
|
1835
|
+
if (
|
|
1836
|
+
not p.data
|
|
1837
|
+
or p.data.position == p.data.size
|
|
1838
|
+
):
|
|
1766
1839
|
break
|
|
1767
1840
|
return messages
|
|
1768
1841
|
|
|
@@ -14,19 +14,19 @@ class GXDLMSLNParameters:
|
|
|
14
14
|
data: GXByteBuffer | None
|
|
15
15
|
# Reply status.
|
|
16
16
|
status: ErrorCode | int
|
|
17
|
+
windowSize: int = 1
|
|
18
|
+
streaming: bool = False
|
|
19
|
+
""" Is this last block in send. """
|
|
17
20
|
|
|
18
21
|
def __post_init__(self):
|
|
19
22
|
self.blockIndex = self.settings.blockIndex
|
|
20
23
|
self.blockNumberAck = self.settings.blockNumberAck
|
|
21
24
|
self.time = None
|
|
22
25
|
""" Send date and time. This is used in Data notification messages. """
|
|
23
|
-
self.multipleBlocks = self.settings.
|
|
24
|
-
""" Are there more data to send or more data to receive
|
|
26
|
+
self.multipleBlocks = self.settings.is_multiple_block()
|
|
27
|
+
""" Are there more data to send or more data to receive"""
|
|
25
28
|
self.lastBlock = self.settings.count == self.settings.index
|
|
26
29
|
""" Is this last block in send. """
|
|
27
|
-
self.windowSize = 1
|
|
28
|
-
self.streaming = False
|
|
29
|
-
""" Is this last block in send. """
|
|
30
30
|
if self.settings:
|
|
31
31
|
self.settings.command = self.command
|
|
32
32
|
if self.command == XDLMSAPDU.GET_REQUEST and self.requestType != ResponseType.WITH_DATABLOCK:
|
DLMS_SPODES_client/task.py
CHANGED
|
@@ -1030,7 +1030,7 @@ class ReadObjAttr(SimpleCopy, CDT):
|
|
|
1030
1030
|
|
|
1031
1031
|
|
|
1032
1032
|
@dataclass
|
|
1033
|
-
class Par2Data[T: cdt.CommonDataType](SimpleCopy, CDT):
|
|
1033
|
+
class Par2Data[T: cdt.CommonDataType](SimpleCopy, CDT[T]):
|
|
1034
1034
|
"""get CommonDataType by Parameter"""
|
|
1035
1035
|
par: Parameter
|
|
1036
1036
|
msg: str = "read data by Parameter"
|
|
@@ -1165,7 +1165,7 @@ class ReadAttributes(SimpleCopy, _List[cdt.CommonDataType]):
|
|
|
1165
1165
|
@deprecated("use <Write2>")
|
|
1166
1166
|
class Write(SimpleCopy, OK):
|
|
1167
1167
|
"""write with ParameterData struct"""
|
|
1168
|
-
|
|
1168
|
+
par_data: ParData
|
|
1169
1169
|
msg: str = "write attribute"
|
|
1170
1170
|
|
|
1171
1171
|
async def exchange(self, c: Client) -> result.Ok | result.Error:
|
|
@@ -1189,7 +1189,7 @@ class Write(SimpleCopy, OK):
|
|
|
1189
1189
|
return result.OK
|
|
1190
1190
|
|
|
1191
1191
|
|
|
1192
|
-
@dataclass
|
|
1192
|
+
@dataclass(frozen=True)
|
|
1193
1193
|
class Write2(SimpleCopy, OK):
|
|
1194
1194
|
"""write with ParameterData struct"""
|
|
1195
1195
|
par: Parameter
|
|
@@ -1201,10 +1201,10 @@ class Write2(SimpleCopy, OK):
|
|
|
1201
1201
|
return res_obj
|
|
1202
1202
|
if self.par.n_elements == 0:
|
|
1203
1203
|
enc = self.data.encoding
|
|
1204
|
-
elif isinstance(res_read := await
|
|
1204
|
+
elif isinstance(res_read := await Par2Data[cdt.CommonDataType](self.par.attr).exchange(c), result.Error):
|
|
1205
1205
|
return res_read
|
|
1206
1206
|
else:
|
|
1207
|
-
data =
|
|
1207
|
+
data = res_read.value
|
|
1208
1208
|
for el in self.par.elements():
|
|
1209
1209
|
data = data[el]
|
|
1210
1210
|
data.set(self.data)
|
|
@@ -1218,6 +1218,7 @@ class Write2(SimpleCopy, OK):
|
|
|
1218
1218
|
|
|
1219
1219
|
|
|
1220
1220
|
@dataclass
|
|
1221
|
+
@deprecated("use <WriteTranscript>")
|
|
1221
1222
|
class WriteParValue(SimpleCopy, OK):
|
|
1222
1223
|
"""write with ParameterValues struct"""
|
|
1223
1224
|
par_value: ParValues[cdt.Transcript]
|
|
@@ -1315,7 +1316,7 @@ class Execute(SimpleCopy, OK):
|
|
|
1315
1316
|
return result.Error.from_e(exc.DLMSException(F'Исполнение {self.desc}'))
|
|
1316
1317
|
|
|
1317
1318
|
|
|
1318
|
-
@dataclass
|
|
1319
|
+
@dataclass(frozen=True)
|
|
1319
1320
|
class Execute2(SimpleCopy, OK):
|
|
1320
1321
|
"""execute method"""
|
|
1321
1322
|
par: Parameter
|
|
@@ -1742,10 +1743,10 @@ class WriteParDatas(SimpleCopy, _List[result.Ok]):
|
|
|
1742
1743
|
|
|
1743
1744
|
class WriteList(SimpleCopy, _List[result.Ok]):
|
|
1744
1745
|
"""write by list"""
|
|
1745
|
-
par_datas: tuple[Parameter, cdt.CommonDataType]
|
|
1746
|
+
par_datas: tuple[tuple[Parameter, cdt.CommonDataType], ...]
|
|
1746
1747
|
err_ignore: bool
|
|
1747
1748
|
|
|
1748
|
-
def __init__(self, *par_datas: tuple[Parameter, cdt.CommonDataType], err_ignore: bool = False, msg = ""):
|
|
1749
|
+
def __init__(self, *par_datas: tuple[Parameter, cdt.CommonDataType], err_ignore: bool = False, msg: str = "") -> None:
|
|
1749
1750
|
self.par_datas = par_datas
|
|
1750
1751
|
self.err_ignore = err_ignore
|
|
1751
1752
|
self.msg = msg
|
|
@@ -1762,44 +1763,47 @@ class WriteList(SimpleCopy, _List[result.Ok]):
|
|
|
1762
1763
|
return res
|
|
1763
1764
|
|
|
1764
1765
|
|
|
1765
|
-
@dataclass
|
|
1766
|
-
class
|
|
1766
|
+
@dataclass(frozen=True)
|
|
1767
|
+
class WriteTranscript(SimpleCopy, OK):
|
|
1767
1768
|
"""write by ParValues[Transcript]"""
|
|
1768
1769
|
par: Parameter
|
|
1769
1770
|
value: cdt.Transcript
|
|
1770
1771
|
msg: str = ""
|
|
1771
1772
|
|
|
1772
1773
|
async def exchange(self, c: Client) -> result.Ok | result.Error:
|
|
1773
|
-
if isinstance((res := await Par2Data(self.par).exchange(c)), result.Error):
|
|
1774
|
+
if isinstance((res := await Par2Data[cdt.CommonDataType](self.par).exchange(c)), result.Error):
|
|
1774
1775
|
return res
|
|
1775
|
-
data = copy(res.value)
|
|
1776
1776
|
if isinstance(data, cdt.Digital):
|
|
1777
1777
|
s_u = c.objects.par2su(self.par)
|
|
1778
1778
|
if isinstance(s_u, cdt.ScalUnitType):
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1779
|
+
if not isinstance(self.value, str):
|
|
1780
|
+
return result.Error.from_e(TypeError(), f"for {self.par} got type: {self.value}, expected String")
|
|
1781
|
+
try:
|
|
1782
|
+
data = res.value.parse(value := str(float(self.value) * 10 ** -int(s_u.scaler)))
|
|
1783
|
+
except ValueError as e:
|
|
1784
|
+
return result.Error.from_e(e, f"for {self.par} got value: {self.value}, expected Float or Digital")
|
|
1785
|
+
else:
|
|
1786
|
+
data = res.value.parse(self.value)
|
|
1787
|
+
else:
|
|
1788
|
+
data = res.value.parse(self.value)
|
|
1789
|
+
return await Write2(self.par, data).exchange(c)
|
|
1786
1790
|
|
|
1787
1791
|
|
|
1788
|
-
class
|
|
1792
|
+
class WriteTranscripts(SimpleCopy, _List[result.Ok]):
|
|
1789
1793
|
"""write by ParValues[Transcript] list"""
|
|
1790
|
-
par_values: tuple[Parameter, cdt.Transcript]
|
|
1794
|
+
par_values: tuple[tuple[Parameter, cdt.Transcript], ...]
|
|
1791
1795
|
err_ignore: bool
|
|
1792
1796
|
|
|
1793
|
-
def __init__(self, *par_values: tuple[Parameter, cdt.Transcript], err_ignore: bool = False, msg=""):
|
|
1797
|
+
def __init__(self, *par_values: tuple[Parameter, cdt.Transcript], err_ignore: bool = False, msg: str =""):
|
|
1794
1798
|
self.par_values = par_values
|
|
1795
1799
|
self.err_ignore = err_ignore
|
|
1796
1800
|
self.msg = msg
|
|
1797
1801
|
|
|
1798
|
-
async def exchange(self, c: Client) -> result.List[
|
|
1802
|
+
async def exchange(self, c: Client) -> result.List[result.Ok] | result.Error:
|
|
1799
1803
|
res = result.List[result.Ok]()
|
|
1800
1804
|
for par, value in self.par_values:
|
|
1801
1805
|
if (
|
|
1802
|
-
isinstance(res_one := await
|
|
1806
|
+
isinstance(res_one := await WriteTranscript(par, value).exchange(c), result.Error)
|
|
1803
1807
|
and not self.err_ignore
|
|
1804
1808
|
):
|
|
1805
1809
|
return res_one
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
DLMS_SPODES_client/FCS16.py,sha256=RhoN4fX7eesKWfWCkRT_uWNfiQHqFd3T6lRwxfamUqw,2697
|
|
2
2
|
DLMS_SPODES_client/__init__.py,sha256=6wphXvqkodng7h4nKNmkfldbaxf--IDVGfT0yNbas-o,449
|
|
3
|
-
DLMS_SPODES_client/client.py,sha256=
|
|
3
|
+
DLMS_SPODES_client/client.py,sha256=9pfAhiwia47SBf3JYoJVQjQi3i1WZfdcAzsPr2-UGzg,112509
|
|
4
4
|
DLMS_SPODES_client/logger.py,sha256=zAbihLloMU99w8Sw3djQ0cwItzyGq0Fz8DI9_suazv4,1913
|
|
5
5
|
DLMS_SPODES_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
DLMS_SPODES_client/services.py,sha256=xM_-h322V1bGBcw9cJh7XOSUMTL3_E-GX89-z3YwIYw,3909
|
|
7
7
|
DLMS_SPODES_client/session.py,sha256=1sa4wJny2xwDqL3DXpfYTS7mZcabVdC5fW1H60VB5QA,12681
|
|
8
8
|
DLMS_SPODES_client/settings.py,sha256=6mitGe9UYeEgL61sf933MJ-S5N-ReoxvXqiI3agBGYE,1623
|
|
9
|
-
DLMS_SPODES_client/task.py,sha256=
|
|
9
|
+
DLMS_SPODES_client/task.py,sha256=42Tgo4eKfuh8HlguO7N1fjUosKGq7iLvhl9jo4Hcbns,76081
|
|
10
10
|
DLMS_SPODES_client/gurux_common/enums/TraceLevel.py,sha256=Ne0Rn3c9ACqQjmde_ksbiQxIUv6nXsPQRnhkGwIv3QI,521
|
|
11
11
|
DLMS_SPODES_client/gurux_common/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
DLMS_SPODES_client/gurux_dlms/AesGcmParameter.py,sha256=HJt0uvxtkqKEkvfiqXTMNsiayN15AgPJa9_iMSSFZsQ,1429
|
|
@@ -18,9 +18,9 @@ DLMS_SPODES_client/gurux_dlms/GXDLMSChippering.py,sha256=HxOtiyOUrdFreEcUHNCU8oq
|
|
|
18
18
|
DLMS_SPODES_client/gurux_dlms/GXDLMSChipperingStream.py,sha256=ix7R7h3ubsmaHy65R_9fQlZs5qpy6BNVkgz04ZCmOAQ,45717
|
|
19
19
|
DLMS_SPODES_client/gurux_dlms/GXDLMSConfirmedServiceError.py,sha256=vEUPShh5iN85yGW-YDlwbdzH2aaZvH6-AXtDfmt41Lc,3461
|
|
20
20
|
DLMS_SPODES_client/gurux_dlms/GXDLMSException.py,sha256=SME3os97MbZ-b65z2HQvU40bPbn-a4lID6i3ruAwEfs,5814
|
|
21
|
-
DLMS_SPODES_client/gurux_dlms/GXDLMSLNParameters.py,sha256=
|
|
21
|
+
DLMS_SPODES_client/gurux_dlms/GXDLMSLNParameters.py,sha256=JxFiv8Xh8VC2VcogoprKsun6iTZX_kyz3Qho8MdO-GM,1347
|
|
22
22
|
DLMS_SPODES_client/gurux_dlms/GXDLMSSNParameters.py,sha256=dKDVbtTUsG3Y_39TUVZXVvNcsyxpPVWvdNsXAFgxzGY,699
|
|
23
|
-
DLMS_SPODES_client/gurux_dlms/GXDLMSSettings.py,sha256=
|
|
23
|
+
DLMS_SPODES_client/gurux_dlms/GXDLMSSettings.py,sha256=fCXt2j1smev-r_iW-hP_PyCJzHEZzXF87_1LARse8GE,8146
|
|
24
24
|
DLMS_SPODES_client/gurux_dlms/GXReplyData.py,sha256=Aq8G5aAK__NzNzAh6YIZ-KZPeu0HtqTKi3aTJ7UfOMQ,4476
|
|
25
25
|
DLMS_SPODES_client/gurux_dlms/HdlcControlFrame.py,sha256=uB_lZfutg0xj8of7Rjhg4iYEFb08Z4BR3KLCMj0ih4g,193
|
|
26
26
|
DLMS_SPODES_client/gurux_dlms/MBusCommand.py,sha256=VlSbupvSReAb-n9QeeQcksjdQ_hFRtpwiPCOZo4k2u0,143
|
|
@@ -54,8 +54,8 @@ DLMS_SPODES_client/gurux_dlms/enums/Task.py,sha256=chuOL6-IMxBvABUZtoFcaYaQQB4GZ
|
|
|
54
54
|
DLMS_SPODES_client/gurux_dlms/enums/VdeStateError.py,sha256=qT87LMbIYEs3TYPIp3N-dR2Tcg9KhKyiELwhVl5U-tw,233
|
|
55
55
|
DLMS_SPODES_client/gurux_dlms/enums/__init__.py,sha256=F_sgGwNmmdpbKvP1klJQUNiLXxU2BtZ-LgEI9e6xP8g,1314
|
|
56
56
|
DLMS_SPODES_client/gurux_dlms/internal/_GXCommon.py,sha256=7D9EYcfiZxwbk8sfpHv7s2nYqrbmGf-Tbwv2T-gqmgk,53226
|
|
57
|
-
dlms_spodes_client-0.19.
|
|
58
|
-
dlms_spodes_client-0.19.
|
|
59
|
-
dlms_spodes_client-0.19.
|
|
60
|
-
dlms_spodes_client-0.19.
|
|
61
|
-
dlms_spodes_client-0.19.
|
|
57
|
+
dlms_spodes_client-0.19.9.dist-info/METADATA,sha256=dd2c_4HpFgr6xjOfvt19Zp4X7umrnhHVYBAnnAok0Ak,985
|
|
58
|
+
dlms_spodes_client-0.19.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
59
|
+
dlms_spodes_client-0.19.9.dist-info/entry_points.txt,sha256=Z6UTeQjjCf2k1Y3Bjs0s7yr-UYSWb-TvJMuG2K2MApw,70
|
|
60
|
+
dlms_spodes_client-0.19.9.dist-info/top_level.txt,sha256=rh_3Uig5bc6J_lKni01btol7dX_IgIJulNtGjGehmBE,19
|
|
61
|
+
dlms_spodes_client-0.19.9.dist-info/RECORD,,
|
|
File without changes
|
{dlms_spodes_client-0.19.7.dist-info → dlms_spodes_client-0.19.9.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|