2
Modbus Payload Builders
3
------------------------
5
A collection of utilities for building and decoding
6
modbus messages payloads.
8
from struct import pack, unpack
9
from pymodbus.constants import Endian
12
class PayloadBuilder(object):
14
A utility that helps build payload messages to be
15
written with the various modbus messages. It really is just
16
a simple wrapper around the struct module, however it saves
17
time looking up the format strings. What follows is a simple
20
builder = PayloadBuilder(endian=Endian.Little)
21
builder.add_8bit_uint(1)
22
builder.add_16bit_uint(2)
23
payload = builder.tostring()
26
def __init__(self, payload=None, endian=Endian.Little):
27
''' Initialize a new instance of the payload builder
29
:param payload: Raw payload data to initialize with
30
:param endian: The endianess of the payload
32
self._payload = payload or []
36
''' Reset the payload buffer
41
''' Return the payload buffer as a string
43
:returns: The payload buffer as a string
45
return ''.join(self._payload)
48
''' Return the payload buffer as a list
50
:returns: The payload buffer as a list
54
def add_8bit_uint(self, value):
55
''' Adds a 8 bit unsigned int to the buffer
57
:param value: The value to add to the buffer
59
fstring = self._endian + 'B'
60
self._payload.append(pack(fstring, value))
62
def add_16bit_uint(self, value):
63
''' Adds a 16 bit unsigned int to the buffer
65
:param value: The value to add to the buffer
67
fstring = self._endian + 'H'
68
self._payload.append(pack(fstring, value))
70
def add_32bit_uint(self, value):
71
''' Adds a 32 bit unsigned int to the buffer
73
:param value: The value to add to the buffer
75
fstring = self._endian + 'I'
76
self._payload.append(pack(fstring, value))
78
def add_64bit_uint(self, value):
79
''' Adds a 64 bit unsigned int to the buffer
81
:param value: The value to add to the buffer
83
fstring = self._endian + 'Q'
84
self._payload.append(pack(fstring, value))
86
def add_8bit_int(self, value):
87
''' Adds a 8 bit signed int to the buffer
89
:param value: The value to add to the buffer
91
fstring = self._endian + 'b'
92
self._payload.append(pack(fstring, value))
94
def add_16bit_int(self, value):
95
''' Adds a 16 bit signed int to the buffer
97
:param value: The value to add to the buffer
99
fstring = self._endian + 'h'
100
self._payload.append(pack(fstring, value))
102
def add_32bit_int(self, value):
103
''' Adds a 32 bit signed int to the buffer
105
:param value: The value to add to the buffer
107
fstring = self._endian + 'i'
108
self._payload.append(pack(fstring, value))
110
def add_64bit_int(self, value):
111
''' Adds a 64 bit signed int to the buffer
113
:param value: The value to add to the buffer
115
fstring = self._endian + 'q'
116
self._payload.append(pack(fstring, value))
118
def add_32bit_float(self, value):
119
''' Adds a 32 bit float to the buffer
121
:param value: The value to add to the buffer
123
fstring = self._endian + 'f'
124
self._payload.append(pack(fstring, value))
126
def add_64bit_float(self, value):
127
''' Adds a 64 bit float(double) to the buffer
129
:param value: The value to add to the buffer
131
fstring = self._endian + 'd'
132
self._payload.append(pack(fstring, value))
134
def add_string(self, value):
135
''' Adds a string to the buffer
137
:param value: The value to add to the buffer
139
fstring = self._endian + 's'
141
self._payload.append(pack(fstring, c))
144
class PayloadDecoder(object):
146
A utility that helps decode payload messages from a modbus
147
reponse message. It really is just a simple wrapper around
148
the struct module, however it saves time looking up the format
149
strings. What follows is a simple example::
151
decoder = PayloadDecoder(self.little_endian_payload)
152
first = decoder.decode_8bit_uint()
153
second = decoder.decode_16bit_uint()
156
def __init__(self, payload, endian=Endian.Little):
157
''' Initialize a new payload decoder
159
:param payload: The payload to decode with
160
:param endian: The endianess of the payload
162
self._payload = payload
164
self._endian = endian
167
''' Reset the decoder pointer back to the start
171
def decode_8bit_uint(self):
172
''' Decodes a 8 bit unsigned int from the buffer
175
fstring = self._endian + 'B'
176
handle = self._payload[self._pointer - 1:self._pointer]
177
return unpack('B', handle)[0]
179
def decode_16bit_uint(self):
180
''' Decodes a 16 bit unsigned int from the buffer
183
fstring = self._endian + 'H'
184
handle = self._payload[self._pointer - 2:self._pointer]
185
return unpack(fstring, handle)[0]
187
def decode_32bit_uint(self):
188
''' Decodes a 32 bit unsigned int from the buffer
191
fstring = self._endian + 'I'
192
handle = self._payload[self._pointer - 4:self._pointer]
193
return unpack(fstring, handle)[0]
195
def decode_64bit_uint(self):
196
''' Decodes a 64 bit unsigned int from the buffer
199
fstring = self._endian + 'Q'
200
handle = self._payload[self._pointer - 8:self._pointer]
201
return unpack(fstring, handle)[0]
203
def decode_8bit_int(self):
204
''' Decodes a 8 bit signed int from the buffer
207
fstring = self._endian + 'b'
208
handle = self._payload[self._pointer - 1:self._pointer]
209
return unpack(fstring, handle)[0]
211
def decode_16bit_int(self):
212
''' Decodes a 16 bit signed int from the buffer
215
fstring = self._endian + 'h'
216
handle = self._payload[self._pointer - 2:self._pointer]
217
return unpack(fstring, handle)[0]
219
def decode_32bit_int(self):
220
''' Decodes a 32 bit signed int from the buffer
223
fstring = self._endian + 'i'
224
handle = self._payload[self._pointer - 4:self._pointer]
225
return unpack(fstring, handle)[0]
227
def decode_64bit_int(self):
228
''' Decodes a 64 bit signed int from the buffer
231
fstring = self._endian + 'q'
232
handle = self._payload[self._pointer - 8:self._pointer]
233
return unpack(fstring, handle)[0]
235
def decode_32bit_float(self):
236
''' Decodes a 32 bit float from the buffer
239
fstring = self._endian + 'f'
240
handle = self._payload[self._pointer - 4:self._pointer]
241
return unpack(fstring, handle)[0]
243
def decode_64bit_float(self):
244
''' Decodes a 64 bit float(double) from the buffer
247
fstring = self._endian + 'd'
248
handle = self._payload[self._pointer - 8:self._pointer]
249
return unpack(fstring, handle)[0]
251
def decode_string(self, size=1):
252
''' Decodes a string from the buffer
254
:param size: The size of the string to decode
256
self._pointer += size
257
return self._payload[self._pointer - size:self._pointer]
259
#---------------------------------------------------------------------------#
260
# Exported Identifiers
261
#---------------------------------------------------------------------------#
262
__all__ = ["PayloadBuilder", "PayloadDecoder"]