8
8
from pymodbus.pdu import ModbusRequest
9
9
from pymodbus.pdu import ModbusResponse
10
10
from pymodbus.device import ModbusControlBlock
11
from pymodbus.exceptions import *
13
12
_MCB = ModbusControlBlock()
15
15
#---------------------------------------------------------------------------#
16
16
# TODO Make these only work on serial
17
17
#---------------------------------------------------------------------------#
101
102
# Encapsulate interface transport 43, 14
102
103
# CANopen general reference 43, 13
104
106
#---------------------------------------------------------------------------#
105
107
# TODO Make these only work on serial
106
108
#---------------------------------------------------------------------------#
107
109
class GetCommEventCounterRequest(ModbusRequest):
109
This function code is used to get a status word and an event count from the
110
remote device's communication event counter.
112
By fetching the current count before and after a series of messages, a client
113
can determine whether the messages were handled normally by the remote device.
115
The device's event counter is incremented once for each successful message
116
completion. It is not incremented for exception responses, poll commands,
117
or fetch event counter commands.
119
The event counter can be reset by means of the Diagnostics function (code 08),
120
with a subfunction of Restart Communications Option (code 00 01) or
121
Clear Counters and Diagnostic Register (code 00 0A).
111
This function code is used to get a status word and an event count from
112
the remote device's communication event counter.
114
By fetching the current count before and after a series of messages, a
115
client can determine whether the messages were handled normally by the
118
The device's event counter is incremented once for each successful
119
message completion. It is not incremented for exception responses,
120
poll commands, or fetch event counter commands.
122
The event counter can be reset by means of the Diagnostics function
123
(code 08), with a subfunction of Restart Communications Option
124
(code 00 01) or Clear Counters and Diagnostic Register (code 00 0A).
123
126
function_code = 0x0b
124
127
_rtu_frame_size = 4
156
159
return "GetCommEventCounterRequest(%d)" % (self.function_code)
158
162
class GetCommEventCounterResponse(ModbusResponse):
160
164
The normal response contains a two-byte status word, and a two-byte
161
165
event count. The status word will be all ones (FF FF hex) if a
162
previously-issued program command is still being processed by the remote
163
device (a busy condition exists). Otherwise, the status word will be
166
previously-issued program command is still being processed by the
167
remote device (a busy condition exists). Otherwise, the status word
166
170
function_code = 0x0b
167
171
_rtu_frame_size = 8
169
def __init__(self, count):
173
def __init__(self, count=0x0000):
170
174
''' Initializes a new instance
172
176
:param count: The current event counter value
174
178
ModbusResponse.__init__(self)
175
179
self.count = count
176
self.status = True # this means we are ready, not waiting
180
self.status = True # this means we are ready, not waiting
178
182
def encode(self):
179
183
''' Encodes the response
181
185
:returns: The byte encoded message
183
ready = ModbusStatus.Ready if self.status else ModbusStatus.Waiting
187
if self.status: ready = ModbusStatus.Ready
188
else: ready = ModbusStatus.Waiting
184
189
return struct.pack('>HH', ready, self.count)
186
191
def decode(self, data):
199
204
arguments = (self.function_code, self.count, self.status)
200
205
return "GetCommEventCounterResponse(%d, %d, %d)" % arguments
202
208
#---------------------------------------------------------------------------#
203
209
# TODO Make these only work on serial
204
210
#---------------------------------------------------------------------------#
205
211
class GetCommEventLogRequest(ModbusRequest):
207
This function code is used to get a status word, event count, message count,
208
and a field of event bytes from the remote device.
213
This function code is used to get a status word, event count, message
214
count, and a field of event bytes from the remote device.
210
The status word and event counts are identical to that returned by the
211
Get Communications Event Counter function (11, 0B hex).
216
The status word and event counts are identical to that returned by
217
the Get Communications Event Counter function (11, 0B hex).
213
219
The message counter contains the quantity of messages processed by the
214
remote device since its last restart, clear counters operation, or power-up.
215
This count is identical to that returned by the Diagnostic function
216
(code 08), sub-function Return Bus Message Count (code 11, 0B hex).
220
remote device since its last restart, clear counters operation, or
221
power-up. This count is identical to that returned by the Diagnostic
222
function (code 08), sub-function Return Bus Message Count (code 11,
218
The event bytes field contains 0-64 bytes, with each byte corresponding to
219
the status of one MODBUS send or receive operation for the remote device.
220
The remote device enters the events into the field in chronological order.
221
Byte 0 is the most recent event. Each new byte flushes the oldest byte
225
The event bytes field contains 0-64 bytes, with each byte corresponding
226
to the status of one MODBUS send or receive operation for the remote
227
device. The remote device enters the events into the field in
228
chronological order. Byte 0 is the most recent event. Each new byte
229
flushes the oldest byte from the field.
224
231
function_code = 0x0c
225
232
_rtu_frame_size = 4
262
269
return "GetCommEventLogRequest(%d)" % self.function_code
264
272
class GetCommEventLogResponse(ModbusResponse):
266
274
The normal response contains a two-byte status word field,
267
275
a two-byte event count field, a two-byte message count field,
268
and a field containing 0-64 bytes of events. A byte count field
269
defines the total length of the data in these four field
276
and a field containing 0-64 bytes of events. A byte count
277
field defines the total length of the data in these four field
271
279
function_code = 0x0c
272
280
_rtu_byte_count_pos = 3
291
299
:returns: The byte encoded message
293
ready = ModbusStatus.Ready if self.status else ModbusStatus.Waiting
301
if self.status: ready = ModbusStatus.Ready
302
else: ready = ModbusStatus.Waiting
294
303
packet = struct.pack('>B', 6 + len(self.events))
295
304
packet += struct.pack('>H', ready)
296
305
packet += struct.pack('>HH', self.event_count, self.message_count)
309
318
self.message_count = struct.unpack('>H', data[5:7])[0]
312
for e in xrange(7, length+1):
321
for e in xrange(7, length + 1):
313
322
self.events.append(struct.unpack('>B', data[e])[0])
315
324
def __str__(self):
320
329
arguments = (self.function_code, self.status, self.message_count, self.event_count)
321
330
return "GetCommEventLogResponse(%d, %d, %d, %d)" % arguments
323
333
#---------------------------------------------------------------------------#
324
334
# TODO Make these only work on serial
325
335
#---------------------------------------------------------------------------#
326
336
class ReportSlaveIdRequest(ModbusRequest):
328
This function code is used to read the description of the type, the current
329
status, and other information specific to a remote device.
338
This function code is used to read the description of the type, the
339
current status, and other information specific to a remote device.
331
341
function_code = 0x11
332
342
_rtu_frame_size = 4
364
374
return "ResportSlaveIdRequest(%d)" % self.function_code
366
377
class ReportSlaveIdResponse(ModbusResponse):
368
The format of a normal response is shown in the following example. The
369
data contents are specific to each type of device.
379
The format of a normal response is shown in the following example.
380
The data contents are specific to each type of device.
371
382
function_code = 0x11
372
383
_rtu_byte_count_pos = 2
374
def __init__(self, identifier, status=True):
385
def __init__(self, identifier=0x00, status=True):
375
386
''' Initializes a new instance
377
388
:param identifier: The identifier of the slave
387
398
:returns: The byte encoded message
389
status = ModbusStatus.SlaveOn if self.status else ModbusStatus.SlaveOff
400
if self.status: status = ModbusStatus.SlaveOn
401
else: status = ModbusStatus.SlaveOff
390
402
length = len(self.identifier) + 2
391
403
packet = struct.pack('>B', length)
392
packet += self.identifier # we assume it is already encoded
393
packet += struct.pack('>B', self.status)
404
packet += self.identifier # we assume it is already encoded
405
packet += struct.pack('>B', status)
396
408
def decode(self, data):
402
414
:param data: The packet data to decode
404
416
length = struct.unpack('>B', data[0])[0]
405
self.identifier = data[1:length-1]
417
self.identifier = data[1:length + 1]
406
418
status = struct.unpack('>B', data[-1])[0]
407
419
self.status = status == ModbusStatus.SlaveOn
419
431
#---------------------------------------------------------------------------#
420
432
# report device identification 43, 14
422
#---------------------------------------------------------------------------#
434
#---------------------------------------------------------------------------#
423
435
# Exported symbols
424
#---------------------------------------------------------------------------#
436
#---------------------------------------------------------------------------#
426
438
"ReadExceptionStatusRequest", "ReadExceptionStatusResponse",
427
439
"GetCommEventCounterRequest", "GetCommEventCounterResponse",