DLMS-SPODES-client 0.19.35__py3-none-any.whl → 0.19.37__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 (60) hide show
  1. DLMS_SPODES_client/FCS16.py +39 -39
  2. DLMS_SPODES_client/__init__.py +12 -12
  3. DLMS_SPODES_client/client.py +2093 -2093
  4. DLMS_SPODES_client/gurux_common/enums/TraceLevel.py +21 -21
  5. DLMS_SPODES_client/gurux_dlms/AesGcmParameter.py +37 -37
  6. DLMS_SPODES_client/gurux_dlms/CountType.py +16 -16
  7. DLMS_SPODES_client/gurux_dlms/GXByteBuffer.py +545 -545
  8. DLMS_SPODES_client/gurux_dlms/GXCiphering.py +196 -196
  9. DLMS_SPODES_client/gurux_dlms/GXDLMS.py +426 -426
  10. DLMS_SPODES_client/gurux_dlms/GXDLMSChippering.py +237 -237
  11. DLMS_SPODES_client/gurux_dlms/GXDLMSChipperingStream.py +977 -977
  12. DLMS_SPODES_client/gurux_dlms/GXDLMSConfirmedServiceError.py +90 -90
  13. DLMS_SPODES_client/gurux_dlms/GXDLMSException.py +139 -139
  14. DLMS_SPODES_client/gurux_dlms/GXDLMSLNParameters.py +33 -33
  15. DLMS_SPODES_client/gurux_dlms/GXDLMSSNParameters.py +21 -21
  16. DLMS_SPODES_client/gurux_dlms/GXDLMSSettings.py +254 -254
  17. DLMS_SPODES_client/gurux_dlms/GXReplyData.py +87 -87
  18. DLMS_SPODES_client/gurux_dlms/HdlcControlFrame.py +9 -9
  19. DLMS_SPODES_client/gurux_dlms/MBusCommand.py +8 -8
  20. DLMS_SPODES_client/gurux_dlms/MBusEncryptionMode.py +27 -27
  21. DLMS_SPODES_client/gurux_dlms/ResponseType.py +8 -8
  22. DLMS_SPODES_client/gurux_dlms/SetResponseType.py +29 -29
  23. DLMS_SPODES_client/gurux_dlms/_HDLCInfo.py +9 -9
  24. DLMS_SPODES_client/gurux_dlms/__init__.py +75 -75
  25. DLMS_SPODES_client/gurux_dlms/enums/Access.py +12 -12
  26. DLMS_SPODES_client/gurux_dlms/enums/ApplicationReference.py +14 -14
  27. DLMS_SPODES_client/gurux_dlms/enums/Authentication.py +41 -41
  28. DLMS_SPODES_client/gurux_dlms/enums/BerType.py +35 -35
  29. DLMS_SPODES_client/gurux_dlms/enums/Command.py +285 -285
  30. DLMS_SPODES_client/gurux_dlms/enums/Definition.py +9 -9
  31. DLMS_SPODES_client/gurux_dlms/enums/ErrorCode.py +46 -46
  32. DLMS_SPODES_client/gurux_dlms/enums/ExceptionServiceError.py +12 -12
  33. DLMS_SPODES_client/gurux_dlms/enums/HardwareResource.py +10 -10
  34. DLMS_SPODES_client/gurux_dlms/enums/HdlcFrameType.py +9 -9
  35. DLMS_SPODES_client/gurux_dlms/enums/Initiate.py +10 -10
  36. DLMS_SPODES_client/gurux_dlms/enums/LoadDataSet.py +13 -13
  37. DLMS_SPODES_client/gurux_dlms/enums/ObjectType.py +306 -306
  38. DLMS_SPODES_client/gurux_dlms/enums/Priority.py +7 -7
  39. DLMS_SPODES_client/gurux_dlms/enums/RequestTypes.py +9 -9
  40. DLMS_SPODES_client/gurux_dlms/enums/Security.py +14 -14
  41. DLMS_SPODES_client/gurux_dlms/enums/Service.py +16 -16
  42. DLMS_SPODES_client/gurux_dlms/enums/ServiceClass.py +9 -9
  43. DLMS_SPODES_client/gurux_dlms/enums/ServiceError.py +8 -8
  44. DLMS_SPODES_client/gurux_dlms/enums/Standard.py +18 -18
  45. DLMS_SPODES_client/gurux_dlms/enums/StateError.py +7 -7
  46. DLMS_SPODES_client/gurux_dlms/enums/Task.py +10 -10
  47. DLMS_SPODES_client/gurux_dlms/enums/VdeStateError.py +10 -10
  48. DLMS_SPODES_client/gurux_dlms/enums/__init__.py +33 -33
  49. DLMS_SPODES_client/gurux_dlms/internal/_GXCommon.py +1673 -1673
  50. DLMS_SPODES_client/logger.py +56 -56
  51. DLMS_SPODES_client/services.py +90 -90
  52. DLMS_SPODES_client/session.py +363 -363
  53. DLMS_SPODES_client/settings.py +48 -48
  54. DLMS_SPODES_client/task.py +1884 -1884
  55. {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/METADATA +29 -29
  56. dlms_spodes_client-0.19.37.dist-info/RECORD +61 -0
  57. {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/WHEEL +1 -1
  58. dlms_spodes_client-0.19.35.dist-info/RECORD +0 -61
  59. {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/entry_points.txt +0 -0
  60. {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/top_level.txt +0 -0
@@ -1,254 +1,254 @@
1
- from __future__ import print_function
2
- from ..gurux_dlms.GXCiphering import GXCiphering
3
- from .enums import Priority, ServiceClass, Authentication, Standard
4
- from DLMS_SPODES.hdlc.frame import Control
5
- from DLMS_SPODES.enums import Conformance
6
-
7
-
8
- class GXDLMSSettings:
9
- """ This class includes DLMS communication settings. """
10
- ctoSChallenge: bytes | None
11
-
12
- @classmethod
13
- def getInitialConformance(cls, useLN):
14
- if useLN:
15
- return Conformance.BLOCK_TRANSFER_WITH_ACTION | Conformance.BLOCK_TRANSFER_WITH_SET_OR_WRITE | Conformance.BLOCK_TRANSFER_WITH_GET_OR_READ | Conformance.SET | Conformance.SELECTIVE_ACCESS | Conformance.ACTION | Conformance.MULTIPLE_REFERENCES | Conformance.GET
16
- return Conformance.INFORMATION_REPORT | Conformance.READ | Conformance.UN_CONFIRMED_WRITE | Conformance.WRITE | Conformance.PARAMETERIZED_ACCESS | Conformance.MULTIPLE_REFERENCES
17
-
18
- def __init__(self, isServer: bool):
19
- self.customChallenges = False
20
- self.ctoSChallenge = None
21
- self.stoCChallenge = None
22
- self.sourceSystemTitle = None
23
- self.invokeId = 1
24
- self.longInvokeID = 0x1
25
- self.priority = Priority.HIGH
26
- self.serviceClass = ServiceClass.CONFIRMED
27
- self.clientAddress = 0
28
- self.serverAddress = 0
29
- self.pushClientAddress = 0
30
- self.serverAddressSize = 0
31
- self.__useLogicalNameReferencing = True
32
- self.authentication = Authentication.NONE
33
- self.password = None
34
- self.kek = None
35
- self.count = 0
36
- self.index = 0
37
- self.targetEphemeralKey = None
38
- self.dlmsVersion = 6
39
- """ deprecated """
40
- self.allowAnonymousAccess = False
41
- self.maxPduSize = 0xFFFF
42
- self.maxServerPDUSize = 0xFFFF
43
- self.startingPacketIndex = 1
44
- # Gets current block index.
45
- self.blockIndex = 1
46
- self.cipher = GXCiphering("ABCDEFGH".encode())
47
- self.blockNumberAck = 0
48
- self.protocolVersion = None
49
- self.isServer = isServer
50
- self.gateway = None
51
- self.proposedConformance = GXDLMSSettings.getInitialConformance(self.__useLogicalNameReferencing)
52
- self.resetFrameSequence()
53
- self.windowSize = 1
54
- self.userId = -1
55
- self.qualityOfService = 0
56
- """ deprecated """
57
- self.useUtc2NormalTime = False
58
- self.standard = Standard.DLMS
59
- self.negotiatedConformance = Conformance.NONE
60
- self.receiverFrame = Control.S0_R0 # 0
61
- self.senderFrame = Control.S0_R0 # 0
62
- self.command = 0
63
- self.commandType = 0
64
- self.useUtc2NormalTime = False
65
-
66
- def setCtoSChallenge(self, value):
67
- """ Client to Server challenge setter """
68
- if not self.customChallenges or self.ctoSChallenge is None:
69
- self.ctoSChallenge = value
70
-
71
- def getStoCChallenge(self):
72
- """ Server to Client challenge getter """
73
- return self.stoCChallenge
74
-
75
- def setStoCChallenge(self, value):
76
- """ Server to Client challenge setter """
77
- if not self.customChallenges or self.stoCChallenge is None:
78
- self.stoCChallenge = value
79
-
80
- def resetFrameSequence(self):
81
- if self.isServer:
82
- self.senderFrame = Control.S7_R0_PF
83
- self.receiverFrame = Control.S7_R7_PF
84
- else:
85
- self.senderFrame = Control.S7_R7_PF
86
- self.receiverFrame = Control.S7_R0_PF
87
-
88
- def getNextSend(self, is_first: bool) -> int:
89
- """ Generates I-frame. Is this first packet. """
90
- if is_first:
91
- self.senderFrame = Control.next_receiver_sequence(Control.next_send_sequence(self.senderFrame))
92
- else:
93
- self.senderFrame = Control.next_send_sequence(self.senderFrame)
94
- return self.senderFrame
95
-
96
- def getReceiverReady(self):
97
- """ Generates Receiver Ready S-frame """
98
- self.senderFrame = Control.next_receiver_sequence(self.senderFrame | 1)
99
- return self.senderFrame & 0xF1
100
-
101
- def getKeepAlive(self):
102
- """ Generates Keep Alive S-frame """
103
- self.senderFrame = (self.senderFrame | 1)
104
- return self.senderFrame & 0xF1
105
-
106
- #
107
- # Gets starting block index in HDLC framing. Default is One based,
108
- # but some
109
- # meters use Zero based value. Usually this is not used.
110
- #
111
- # Current block index.
112
- #
113
- def getStartingPacketIndex(self):
114
- return self.startingPacketIndex
115
-
116
- #
117
- # Set starting block index in HDLC framing. Default is One based,
118
- # but some
119
- # meters use Zero based value. Usually this is not used.
120
- #
121
- # @param value
122
- # Zero based starting index.
123
- #
124
- def setStartingPacketIndex(self, value):
125
- self.startingPacketIndex = value
126
- self.resetBlockIndex()
127
-
128
- #
129
- # Sets current block index.
130
- #
131
- # @param value
132
- # Block index.
133
- #
134
- def setBlockIndex(self, value):
135
- self.blockIndex = value
136
-
137
- #
138
- # Block number acknowledged in GBT.
139
- #
140
- def getBlockNumberAck(self):
141
- return self.blockNumberAck
142
-
143
- #
144
- # @param value
145
- # Block number acknowledged in GBT.
146
- #
147
- def setBlockNumberAck(self, value):
148
- self.blockNumberAck = value
149
-
150
- #
151
- # Resets block index to default value.
152
- #
153
- def resetBlockIndex(self):
154
- self.blockIndex = self.startingPacketIndex
155
- self.blockNumberAck = 0
156
-
157
- #
158
- # Increases block index.
159
- #
160
- def increaseBlockIndex(self):
161
- self.blockIndex += 1
162
-
163
- # Is Logical Name Referencing used.
164
- # Don't use property. For some reason Python 2.7 doesn't call it in Rasbperry PI.
165
- def getUseLogicalNameReferencing(self):
166
- return self.__useLogicalNameReferencing
167
-
168
- # Is Logical Name Referencing used.
169
- def setUseLogicalNameReferencing(self, value):
170
- if self.__useLogicalNameReferencing != value:
171
- self.__useLogicalNameReferencing = value
172
- self.proposedConformance = GXDLMSSettings.getInitialConformance(self.__useLogicalNameReferencing)
173
-
174
- #
175
- # @param value
176
- # update invoke ID.
177
- #
178
- def updateInvokeId(self, value):
179
- if (value & 0x80) != 0:
180
- self.priority = Priority.HIGH
181
- else:
182
- self.priority = Priority.NORMAL
183
- if (value & 0x40) != 0:
184
- self.serviceClass = ServiceClass.CONFIRMED
185
- else:
186
- self.serviceClass = ServiceClass.UN_CONFIRMED
187
- self.invokeId = int((value & 0xF))
188
-
189
- #
190
- # @param value
191
- # Invoke ID.
192
- #
193
- def setInvokeID(self, value):
194
- if value > 0xF:
195
- raise ValueError("Invalid InvokeID")
196
- self.invokeId = int(value)
197
-
198
- #
199
- # Invoke ID.
200
- #
201
- def getLongInvokeID(self):
202
- return self.longInvokeID
203
-
204
- #
205
- # @param value
206
- # Invoke ID.
207
- #
208
- def setLongInvokeID(self, value):
209
- if value > 0xFFFFFFFF:
210
- raise ValueError("Invalid InvokeID")
211
- self.longInvokeID = value
212
-
213
- #
214
- # Source system title.
215
- #
216
- def getSourceSystemTitle(self):
217
- return self.sourceSystemTitle
218
-
219
- #
220
- # @param value
221
- # Source system title.
222
- #
223
- def setSourceSystemTitle(self, value):
224
- if not value or len(value) != 8:
225
- raise ValueError("Invalid client system title.")
226
- self.sourceSystemTitle = value
227
-
228
- #
229
- # Long data count.
230
- #
231
- def getCount(self):
232
- return self.count
233
-
234
- #
235
- # @param value
236
- # Data count.
237
- #
238
- def setCount(self, value):
239
- if value < 0:
240
- raise ValueError("Invalid count.")
241
- self.count = value
242
-
243
- #
244
- # @param value
245
- # Long data index
246
- #
247
- def setIndex(self, value):
248
- if value < 0:
249
- raise ValueError("Invalid Index.")
250
- self.index = value
251
-
252
- def is_multiple_block(self) -> bool:
253
- """ Are there more data to send or more data to receive. !!! instead GXDLMSLNParameters.multipleBlocks """
254
- return self.count != self.index
1
+ from __future__ import print_function
2
+ from ..gurux_dlms.GXCiphering import GXCiphering
3
+ from .enums import Priority, ServiceClass, Authentication, Standard
4
+ from DLMS_SPODES.hdlc.frame import Control
5
+ from DLMS_SPODES.enums import Conformance
6
+
7
+
8
+ class GXDLMSSettings:
9
+ """ This class includes DLMS communication settings. """
10
+ ctoSChallenge: bytes | None
11
+
12
+ @classmethod
13
+ def getInitialConformance(cls, useLN):
14
+ if useLN:
15
+ return Conformance.BLOCK_TRANSFER_WITH_ACTION | Conformance.BLOCK_TRANSFER_WITH_SET_OR_WRITE | Conformance.BLOCK_TRANSFER_WITH_GET_OR_READ | Conformance.SET | Conformance.SELECTIVE_ACCESS | Conformance.ACTION | Conformance.MULTIPLE_REFERENCES | Conformance.GET
16
+ return Conformance.INFORMATION_REPORT | Conformance.READ | Conformance.UN_CONFIRMED_WRITE | Conformance.WRITE | Conformance.PARAMETERIZED_ACCESS | Conformance.MULTIPLE_REFERENCES
17
+
18
+ def __init__(self, isServer: bool):
19
+ self.customChallenges = False
20
+ self.ctoSChallenge = None
21
+ self.stoCChallenge = None
22
+ self.sourceSystemTitle = None
23
+ self.invokeId = 1
24
+ self.longInvokeID = 0x1
25
+ self.priority = Priority.HIGH
26
+ self.serviceClass = ServiceClass.CONFIRMED
27
+ self.clientAddress = 0
28
+ self.serverAddress = 0
29
+ self.pushClientAddress = 0
30
+ self.serverAddressSize = 0
31
+ self.__useLogicalNameReferencing = True
32
+ self.authentication = Authentication.NONE
33
+ self.password = None
34
+ self.kek = None
35
+ self.count = 0
36
+ self.index = 0
37
+ self.targetEphemeralKey = None
38
+ self.dlmsVersion = 6
39
+ """ deprecated """
40
+ self.allowAnonymousAccess = False
41
+ self.maxPduSize = 0xFFFF
42
+ self.maxServerPDUSize = 0xFFFF
43
+ self.startingPacketIndex = 1
44
+ # Gets current block index.
45
+ self.blockIndex = 1
46
+ self.cipher = GXCiphering("ABCDEFGH".encode())
47
+ self.blockNumberAck = 0
48
+ self.protocolVersion = None
49
+ self.isServer = isServer
50
+ self.gateway = None
51
+ self.proposedConformance = GXDLMSSettings.getInitialConformance(self.__useLogicalNameReferencing)
52
+ self.resetFrameSequence()
53
+ self.windowSize = 1
54
+ self.userId = -1
55
+ self.qualityOfService = 0
56
+ """ deprecated """
57
+ self.useUtc2NormalTime = False
58
+ self.standard = Standard.DLMS
59
+ self.negotiatedConformance = Conformance.NONE
60
+ self.receiverFrame = Control.S0_R0 # 0
61
+ self.senderFrame = Control.S0_R0 # 0
62
+ self.command = 0
63
+ self.commandType = 0
64
+ self.useUtc2NormalTime = False
65
+
66
+ def setCtoSChallenge(self, value):
67
+ """ Client to Server challenge setter """
68
+ if not self.customChallenges or self.ctoSChallenge is None:
69
+ self.ctoSChallenge = value
70
+
71
+ def getStoCChallenge(self):
72
+ """ Server to Client challenge getter """
73
+ return self.stoCChallenge
74
+
75
+ def setStoCChallenge(self, value):
76
+ """ Server to Client challenge setter """
77
+ if not self.customChallenges or self.stoCChallenge is None:
78
+ self.stoCChallenge = value
79
+
80
+ def resetFrameSequence(self):
81
+ if self.isServer:
82
+ self.senderFrame = Control.S7_R0_PF
83
+ self.receiverFrame = Control.S7_R7_PF
84
+ else:
85
+ self.senderFrame = Control.S7_R7_PF
86
+ self.receiverFrame = Control.S7_R0_PF
87
+
88
+ def getNextSend(self, is_first: bool) -> int:
89
+ """ Generates I-frame. Is this first packet. """
90
+ if is_first:
91
+ self.senderFrame = Control.next_receiver_sequence(Control.next_send_sequence(self.senderFrame))
92
+ else:
93
+ self.senderFrame = Control.next_send_sequence(self.senderFrame)
94
+ return self.senderFrame
95
+
96
+ def getReceiverReady(self):
97
+ """ Generates Receiver Ready S-frame """
98
+ self.senderFrame = Control.next_receiver_sequence(self.senderFrame | 1)
99
+ return self.senderFrame & 0xF1
100
+
101
+ def getKeepAlive(self):
102
+ """ Generates Keep Alive S-frame """
103
+ self.senderFrame = (self.senderFrame | 1)
104
+ return self.senderFrame & 0xF1
105
+
106
+ #
107
+ # Gets starting block index in HDLC framing. Default is One based,
108
+ # but some
109
+ # meters use Zero based value. Usually this is not used.
110
+ #
111
+ # Current block index.
112
+ #
113
+ def getStartingPacketIndex(self):
114
+ return self.startingPacketIndex
115
+
116
+ #
117
+ # Set starting block index in HDLC framing. Default is One based,
118
+ # but some
119
+ # meters use Zero based value. Usually this is not used.
120
+ #
121
+ # @param value
122
+ # Zero based starting index.
123
+ #
124
+ def setStartingPacketIndex(self, value):
125
+ self.startingPacketIndex = value
126
+ self.resetBlockIndex()
127
+
128
+ #
129
+ # Sets current block index.
130
+ #
131
+ # @param value
132
+ # Block index.
133
+ #
134
+ def setBlockIndex(self, value):
135
+ self.blockIndex = value
136
+
137
+ #
138
+ # Block number acknowledged in GBT.
139
+ #
140
+ def getBlockNumberAck(self):
141
+ return self.blockNumberAck
142
+
143
+ #
144
+ # @param value
145
+ # Block number acknowledged in GBT.
146
+ #
147
+ def setBlockNumberAck(self, value):
148
+ self.blockNumberAck = value
149
+
150
+ #
151
+ # Resets block index to default value.
152
+ #
153
+ def resetBlockIndex(self):
154
+ self.blockIndex = self.startingPacketIndex
155
+ self.blockNumberAck = 0
156
+
157
+ #
158
+ # Increases block index.
159
+ #
160
+ def increaseBlockIndex(self):
161
+ self.blockIndex += 1
162
+
163
+ # Is Logical Name Referencing used.
164
+ # Don't use property. For some reason Python 2.7 doesn't call it in Rasbperry PI.
165
+ def getUseLogicalNameReferencing(self):
166
+ return self.__useLogicalNameReferencing
167
+
168
+ # Is Logical Name Referencing used.
169
+ def setUseLogicalNameReferencing(self, value):
170
+ if self.__useLogicalNameReferencing != value:
171
+ self.__useLogicalNameReferencing = value
172
+ self.proposedConformance = GXDLMSSettings.getInitialConformance(self.__useLogicalNameReferencing)
173
+
174
+ #
175
+ # @param value
176
+ # update invoke ID.
177
+ #
178
+ def updateInvokeId(self, value):
179
+ if (value & 0x80) != 0:
180
+ self.priority = Priority.HIGH
181
+ else:
182
+ self.priority = Priority.NORMAL
183
+ if (value & 0x40) != 0:
184
+ self.serviceClass = ServiceClass.CONFIRMED
185
+ else:
186
+ self.serviceClass = ServiceClass.UN_CONFIRMED
187
+ self.invokeId = int((value & 0xF))
188
+
189
+ #
190
+ # @param value
191
+ # Invoke ID.
192
+ #
193
+ def setInvokeID(self, value):
194
+ if value > 0xF:
195
+ raise ValueError("Invalid InvokeID")
196
+ self.invokeId = int(value)
197
+
198
+ #
199
+ # Invoke ID.
200
+ #
201
+ def getLongInvokeID(self):
202
+ return self.longInvokeID
203
+
204
+ #
205
+ # @param value
206
+ # Invoke ID.
207
+ #
208
+ def setLongInvokeID(self, value):
209
+ if value > 0xFFFFFFFF:
210
+ raise ValueError("Invalid InvokeID")
211
+ self.longInvokeID = value
212
+
213
+ #
214
+ # Source system title.
215
+ #
216
+ def getSourceSystemTitle(self):
217
+ return self.sourceSystemTitle
218
+
219
+ #
220
+ # @param value
221
+ # Source system title.
222
+ #
223
+ def setSourceSystemTitle(self, value):
224
+ if not value or len(value) != 8:
225
+ raise ValueError("Invalid client system title.")
226
+ self.sourceSystemTitle = value
227
+
228
+ #
229
+ # Long data count.
230
+ #
231
+ def getCount(self):
232
+ return self.count
233
+
234
+ #
235
+ # @param value
236
+ # Data count.
237
+ #
238
+ def setCount(self, value):
239
+ if value < 0:
240
+ raise ValueError("Invalid count.")
241
+ self.count = value
242
+
243
+ #
244
+ # @param value
245
+ # Long data index
246
+ #
247
+ def setIndex(self, value):
248
+ if value < 0:
249
+ raise ValueError("Invalid Index.")
250
+ self.index = value
251
+
252
+ def is_multiple_block(self) -> bool:
253
+ """ Are there more data to send or more data to receive. !!! instead GXDLMSLNParameters.multipleBlocks """
254
+ return self.count != self.index