Skip to content

Commit 25aff40

Browse files
camtarnjaniversen
authored andcommitted
Improve docs for Read*ResponseBase and subclasses
Expose base response classes to allow doc gen Not having these base classes in the docs meant that the most important documentation (i.e. how to retrieve response items from the response) was undocumented. If exposing them as public module classes is undesired, some Sphinx directives could instead be used to cause Sphinx to document them. Add newlines to docstrings to stop docs breaking Remove automodule statement which didn\'t do anything The module name is async_io, not asyncio Add explanatory header text to pymodbus.client The subpackages TOC tree is large and messy, and the most useful sections (the client common mixin and the synchronous client) are buried well below the fold, with no TOC entries for them.
1 parent 2f92ce8 commit 25aff40

File tree

7 files changed

+80
-42
lines changed

7 files changed

+80
-42
lines changed

doc/source/library/pymodbus.client.asynchronous.asyncio.rst renamed to doc/source/library/pymodbus.client.asynchronous.async_io.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
pymodbus\.client\.asynchronous\.asyncio package
1+
pymodbus\.client\.asynchronous\.async_io package
22
===============================================
33

4-
.. automodule:: pymodbus.client.asynchronous.asyncio
4+
.. automodule:: pymodbus.client.asynchronous.async_io
55
:members:
66
:undoc-members:
77
:show-inheritance:

doc/source/library/pymodbus.client.asynchronous.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Subpackages
1111

1212
.. toctree::
1313

14-
pymodbus.client.asynchronous.asyncio
14+
pymodbus.client.asynchronous.async_io
1515
pymodbus.client.asynchronous.factory
1616
pymodbus.client.asynchronous.schedulers
1717

doc/source/library/pymodbus.client.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
pymodbus\.client package
22
========================
33

4-
.. automodule:: pymodbus.client
5-
:members:
6-
:undoc-members:
7-
:show-inheritance:
4+
Pymodbus offers a :mod:`synchronous client <pymodbus.client.sync>`, and async clients based on :mod:`asyncio <pymodbus.client.asynchronous.async_io>`, :mod:`Tornado <pymodbus.client.asynchronous.tornado>`, and :mod:`Twisted <pymodbus.client.asynchronous.Twisted>`.
5+
6+
Each client shares a :mod:`common client mixin <pymodbus.client.common>` which offers simple methods for reading and writing.
87

98
Subpackages
109
-----------

pymodbus/bit_read_message.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ def __str__(self):
5757

5858

5959
class ReadBitsResponseBase(ModbusResponse):
60-
"""Base class for Messages responding to bit-reading values."""
60+
"""Base class for Messages responding to bit-reading values.
61+
62+
The requested bits can be found in the .bits list.
63+
"""
6164

6265
_rtu_byte_count_pos = 2
6366

@@ -67,6 +70,8 @@ def __init__(self, values, **kwargs):
6770
:param values: The requested values to be returned
6871
"""
6972
ModbusResponse.__init__(self, **kwargs)
73+
74+
#: A list of booleans representing bit values
7075
self.bits = values or []
7176

7277
def encode(self):
@@ -144,9 +149,9 @@ def execute(self, context):
144149
request is valid against the current datastore.
145150
146151
:param context: The datastore to request from
147-
:returns: The initializes response message, exception message otherwise
152+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadCoilsResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
148153
"""
149-
if not 1 <= self.count <= 0x7D0:
154+
if not (1 <= self.count <= 0x7d0):
150155
return self.doException(merror.IllegalValue)
151156
if not context.validate(self.function_code, self.address, self.count):
152157
return self.doException(merror.IllegalAddress)
@@ -166,8 +171,9 @@ class ReadCoilsResponse(ReadBitsResponseBase):
166171
remaining bits in the final data byte will be padded with zeros
167172
(toward the high order end of the byte). The Byte Count field specifies
168173
the quantity of complete bytes of data.
169-
"""
170174
175+
The requested coils can be found in boolean form in the .bits list.
176+
"""
171177
function_code = 1
172178

173179
def __init__(self, values=None, **kwargs):
@@ -205,9 +211,9 @@ def execute(self, context):
205211
request is valid against the current datastore.
206212
207213
:param context: The datastore to request from
208-
:returns: The initializes response message, exception message otherwise
214+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadDiscreteInputsResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
209215
"""
210-
if not 1 <= self.count <= 0x7D0:
216+
if not (1 <= self.count <= 0x7d0):
211217
return self.doException(merror.IllegalValue)
212218
if not context.validate(self.function_code, self.address, self.count):
213219
return self.doException(merror.IllegalAddress)
@@ -227,8 +233,9 @@ class ReadDiscreteInputsResponse(ReadBitsResponseBase):
227233
remaining bits in the final data byte will be padded with zeros
228234
(toward the high order end of the byte). The Byte Count field specifies
229235
the quantity of complete bytes of data.
230-
"""
231236
237+
The requested coils can be found in boolean form in the .bits list.
238+
"""
232239
function_code = 2
233240

234241
def __init__(self, values=None, **kwargs):
@@ -243,6 +250,7 @@ def __init__(self, values=None, **kwargs):
243250
# Exported symbols
244251
# ---------------------------------------------------------------------------#
245252
__all__ = [
253+
"ReadBitsResponseBase",
246254
"ReadCoilsRequest",
247255
"ReadCoilsResponse",
248256
"ReadDiscreteInputsRequest",

pymodbus/client/asynchronous/async_io/__init__.py

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def connection_made(self, transport):
4343
"""Call when a connection is made.
4444
4545
The transport argument is the transport representing the connection.
46+
4647
:param transport:
4748
:return:
4849
"""
@@ -56,6 +57,7 @@ def connection_lost(self, reason):
5657
"""Call when the connection is lost or closed.
5758
5859
The argument is either an exception object or None
60+
5961
:param reason:
6062
:return:
6163
"""
@@ -69,24 +71,34 @@ def data_received(self, data):
6971
"""Call when some data is received.
7072
7173
data is a non-empty bytes object containing the incoming data.
74+
7275
:param data:
7376
:return:
7477
"""
7578
self._data_received(data)
7679

77-
def create_future(self): # pylint: disable=no-self-use
78-
"""Create asyncio Future object."""
80+
def create_future(self):
81+
"""Helper function to create asyncio Future object
82+
83+
:return:
84+
"""
7985
return asyncio.Future()
8086

81-
def resolve_future(self, my_future, result): # pylint: disable=no-self-use
82-
"""Resolve future."""
87+
def resolve_future(self, my_future, result):
88+
"""Resolves the completed future and sets the result
89+
90+
:param my_future:
91+
:param result:
92+
:return:
93+
"""
8394
if not my_future.done():
8495
my_future.set_result(result)
8596

86-
def raise_future(self, my_future, exc): # pylint: disable=no-self-use
87-
"""Set exception of a future if not done
97+
def raise_future(self, my_future, exc):
98+
"""
99+
Sets exception of a future if not done
88100
89-
:param f:
101+
:param my_future:
90102
:param exc:
91103
:return:
92104
"""
@@ -183,6 +195,7 @@ def data_received(self, data):
183195
"""Call when some data is received.
184196
185197
data is a non-empty bytes object containing the incoming data.
198+
186199
:param data:
187200
:return:
188201
"""
@@ -219,7 +232,7 @@ class ReconnectingAsyncioModbusTcpClient:
219232
DELAY_MAX_MS = 1000 * 60 * 5
220233

221234
def __init__(self, protocol_class=None, loop=None, **kwargs):
222-
"""Initialize ReconnectingAsyncioModbusTcpClient
235+
"""Initialize ReconnectingAsyncioModbusTcpClient.
223236
224237
:param protocol_class: Protocol used to talk to modbus device.
225238
:param loop: Event loop to use
@@ -258,7 +271,10 @@ async def start(self, host, port=502):
258271
return await self._connect()
259272

260273
def stop(self):
261-
"""Stop client."""
274+
"""Stop client.
275+
276+
:return:
277+
"""
262278
# prevent reconnect:
263279
self.host = None
264280

@@ -606,7 +622,7 @@ class AsyncioModbusUdpClient:
606622
"""Client to connect to modbus device over UDP."""
607623

608624
def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs):
609-
"""Initialize Asyncio Modbus UDP Client
625+
"""Initialize Asyncio Modbus UDP Client.
610626
611627
:param host: Host IP address
612628
:param port: Port to connect
@@ -627,7 +643,10 @@ def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs
627643
self._proto_args = kwargs
628644

629645
def stop(self):
630-
"""Stop connection."""
646+
"""Stop connection.
647+
648+
:return:
649+
"""
631650
# prevent reconnect:
632651
# self.host = None
633652

@@ -753,7 +772,10 @@ def _connected(self):
753772
return self._connected_event.is_set()
754773

755774
async def connect(self):
756-
"""Connect Async client."""
775+
"""Connect Async client.
776+
777+
:return:
778+
"""
757779
_logger.debug(TEXT_CONNECTING)
758780
try:
759781
await create_serial_connection(

pymodbus/client/sync.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
class BaseModbusClient(ModbusClientMixin):
3232
"""Interface for a modbus synchronous client.
3333
34-
Defined here are all the methods for performing the related request
35-
methods. Derived classes simply need to implement the transport
36-
methods and set the correct framer.
34+
Defined here are all the methods for performing the related
35+
request methods.
36+
Derived classes simply need to implement the transport methods and set the correct
37+
framer.
3738
"""
38-
3939
def __init__(self, framer, **kwargs):
4040
"""Initialize a client instance.
4141
@@ -128,7 +128,7 @@ def __exit__(self, klass, value, traceback):
128128
self.close()
129129

130130
def idle_time(self):
131-
"""Return bus Idle Time to initiate next transaction.
131+
"""Bus Idle Time to initiate next transaction
132132
133133
:return: time stamp
134134
"""
@@ -160,7 +160,7 @@ def _dump(self, data):
160160
_logger.exception(exc)
161161

162162
def register(self, function):
163-
"""Register a function and sub function class with the decoder.
163+
"""Registers a function and sub function class with the decoder
164164
165165
:param function: Custom function class to register
166166
:return:

pymodbus/register_read_message.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ def __str__(self):
5050

5151

5252
class ReadRegistersResponseBase(ModbusResponse):
53-
"""Base class for responding to a modbus register read."""
53+
"""Base class for responding to a modbus register read.
54+
55+
The requested registers can be found in the .registers list.
56+
"""
5457

5558
_rtu_byte_count_pos = 2
5659

@@ -60,6 +63,8 @@ def __init__(self, values, **kwargs):
6063
:param values: The values to write to
6164
"""
6265
ModbusResponse.__init__(self, **kwargs)
66+
67+
#: A list of register values
6368
self.registers = values or []
6469

6570
def encode(self):
@@ -122,9 +127,9 @@ def execute(self, context):
122127
"""Run a read holding request against a datastore.
123128
124129
:param context: The datastore to request from
125-
:returns: An initialized response, exception message otherwise
130+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadHoldingRegistersResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
126131
"""
127-
if not 1 <= self.count <= 0x7D:
132+
if not (1 <= self.count <= 0x7d):
128133
return self.doException(merror.IllegalValue)
129134
if not context.validate(self.function_code, self.address, self.count):
130135
return self.doException(merror.IllegalAddress)
@@ -140,8 +145,9 @@ class ReadHoldingRegistersResponse(ReadRegistersResponseBase):
140145
starting register address and the number of registers. In the PDU
141146
Registers are addressed starting at zero. Therefore registers numbered
142147
1-16 are addressed as 0-15.
143-
"""
144148
149+
The requested registers can be found in the .registers list.
150+
"""
145151
function_code = 3
146152

147153
def __init__(self, values=None, **kwargs):
@@ -176,9 +182,9 @@ def execute(self, context):
176182
"""Run a read input request against a datastore.
177183
178184
:param context: The datastore to request from
179-
:returns: An initialized response, exception message otherwise
185+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadInputRegistersResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
180186
"""
181-
if not 1 <= self.count <= 0x7D:
187+
if not (1 <= self.count <= 0x7d):
182188
return self.doException(merror.IllegalValue)
183189
if not context.validate(self.function_code, self.address, self.count):
184190
return self.doException(merror.IllegalAddress)
@@ -194,8 +200,9 @@ class ReadInputRegistersResponse(ReadRegistersResponseBase):
194200
starting register address and the number of registers. In the PDU
195201
Registers are addressed starting at zero. Therefore input registers
196202
numbered 1-16 are addressed as 0-15.
197-
"""
198203
204+
The requested registers can be found in the .registers list.
205+
"""
199206
function_code = 4
200207

201208
def __init__(self, values=None, **kwargs):
@@ -281,9 +288,9 @@ def execute(self, context):
281288
"""Run a write single register request against a datastore.
282289
283290
:param context: The datastore to request from
284-
:returns: An initialized response, exception message otherwise
291+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadWriteMultipleRegistersResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
285292
"""
286-
if not 1 <= self.read_count <= 0x07D:
293+
if not (1 <= self.read_count <= 0x07d):
287294
return self.doException(merror.IllegalValue)
288295
if not 1 <= self.write_count <= 0x079:
289296
return self.doException(merror.IllegalValue)
@@ -331,8 +338,9 @@ class ReadWriteMultipleRegistersResponse(ModbusResponse):
331338
The normal response contains the data from the group of registers that
332339
were read. The byte count field specifies the quantity of bytes to
333340
follow in the read data field.
334-
"""
335341
342+
The requested registers can be found in the .registers list.
343+
"""
336344
function_code = 23
337345
_rtu_byte_count_pos = 2
338346

@@ -379,6 +387,7 @@ def __str__(self):
379387
"ReadHoldingRegistersResponse",
380388
"ReadInputRegistersRequest",
381389
"ReadInputRegistersResponse",
390+
"ReadRegistersResponseBase",
382391
"ReadWriteMultipleRegistersRequest",
383392
"ReadWriteMultipleRegistersResponse",
384393
]

0 commit comments

Comments
 (0)