2
2
Modbus Request/Response Decoder Factories
3
3
-------------------------------------------
5
The following factories make it easy to decode request/response messages.
6
To add a new request/response pair to be decodeable by the library, simply
7
add them to the respective function lookup table (order doesn't matter, but
8
it does help keep things organized).
10
Regardless of how many functions are added to the lookup, O(1) behavior is
11
kept as a result of a pre-computed lookup dictionary.
7
14
from pymodbus.pdu import IllegalFunctionRequest
14
21
from pymodbus.diag_message import *
15
22
from pymodbus.file_message import *
16
23
from pymodbus.other_message import *
24
from pymodbus.mei_message import *
17
25
from pymodbus.register_read_message import *
18
26
from pymodbus.register_write_message import *
24
32
_logger = logging.getLogger(__name__)
26
35
#---------------------------------------------------------------------------#
28
37
#---------------------------------------------------------------------------#
30
38
class ServerDecoder(IModbusDecoder):
31
39
''' Request Message Factory (Server)
41
49
WriteMultipleRegistersRequest,
42
50
WriteSingleRegisterRequest,
43
51
WriteSingleCoilRequest,
44
ReadWriteMultipleRegistersRequest
52
ReadWriteMultipleRegistersRequest,
54
ReturnQueryDataRequest,
55
RestartCommunicationsOptionRequest,
56
ReturnDiagnosticRegisterRequest,
57
ChangeAsciiInputDelimiterRequest,
58
ForceListenOnlyModeRequest,
60
ReturnBusMessageCountRequest,
61
ReturnBusCommunicationErrorCountRequest,
62
ReturnBusExceptionErrorCountRequest,
63
ReturnSlaveMessageCountRequest,
64
ReturnSlaveNoResponseCountRequest,
65
ReturnSlaveNAKCountRequest,
66
ReturnSlaveBusyCountRequest,
67
ReturnSlaveBusCharacterOverrunCountRequest,
68
ReturnIopOverrunCountRequest,
69
ClearOverrunCountRequest,
70
GetClearModbusPlusRequest,
72
ReadExceptionStatusRequest,
73
GetCommEventCounterRequest,
74
GetCommEventLogRequest,
77
ReadFileRecordRequest,
78
WriteFileRecordRequest,
79
MaskWriteRegisterRequest,
82
ReadDeviceInformationRequest,
46
84
__lookup = dict([(f.function_code, f) for f in __function_table])
82
120
request.decode(data[1:])
85
#---------------------------------------------------------------------------#
124
#---------------------------------------------------------------------------#
87
#---------------------------------------------------------------------------#
126
#---------------------------------------------------------------------------#
89
127
class ClientDecoder(IModbusDecoder):
90
128
''' Response Message Factory (Client)
100
138
WriteMultipleRegistersResponse,
101
139
WriteSingleRegisterResponse,
102
140
WriteSingleCoilResponse,
103
ReadWriteMultipleRegistersResponse
141
ReadWriteMultipleRegistersResponse,
143
ReturnQueryDataResponse,
144
RestartCommunicationsOptionResponse,
145
ReturnDiagnosticRegisterResponse,
146
ChangeAsciiInputDelimiterResponse,
147
ForceListenOnlyModeResponse,
148
ClearCountersResponse,
149
ReturnBusMessageCountResponse,
150
ReturnBusCommunicationErrorCountResponse,
151
ReturnBusExceptionErrorCountResponse,
152
ReturnSlaveMessageCountResponse,
153
ReturnSlaveNoReponseCountResponse,
154
ReturnSlaveNAKCountResponse,
155
ReturnSlaveBusyCountResponse,
156
ReturnSlaveBusCharacterOverrunCountResponse,
157
ReturnIopOverrunCountResponse,
158
ClearOverrunCountResponse,
159
GetClearModbusPlusResponse,
161
ReadExceptionStatusResponse,
162
GetCommEventCounterResponse,
163
GetCommEventLogResponse,
164
ReportSlaveIdResponse,
166
ReadFileRecordResponse,
167
WriteFileRecordResponse,
168
MaskWriteRegisterResponse,
169
ReadFifoQueueResponse,
171
ReadDeviceInformationResponse,
105
173
__lookup = dict([(f.function_code, f) for f in __function_table])
137
205
_logger.debug("Factory Response[%d]" % function_code)
138
206
response = self.__lookup.get(function_code, lambda: None)()
139
207
if function_code > 0x80:
140
code = function_code & 0x7f # strip error portion
208
code = function_code & 0x7f # strip error portion
141
209
response = ExceptionResponse(code, ecode.IllegalFunction)
143
211
raise ModbusException("Unknown response %d" % function_code)
144
212
response.decode(data[1:])
147
#---------------------------------------------------------------------------#
215
#---------------------------------------------------------------------------#
148
216
# Exported symbols
149
#---------------------------------------------------------------------------#
217
#---------------------------------------------------------------------------#
150
218
__all__ = ['ServerDecoder', 'ClientDecoder']