Skip to content

Commit 67126da

Browse files
camtarnjaniversen
andauthored
Documentation cleanup and clarification (#689)
* 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. * Clean. Co-authored-by: jan Iversen <jancasacondor@gmail.com>
1 parent c77a65e commit 67126da

File tree

6 files changed

+73
-30
lines changed

6 files changed

+73
-30
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pymodbus\.client\.asynchronous\.asyncio package
1+
pymodbus\.client\.asynchronous\.async_io package
22
===============================================
33

44
.. automodule:: pymodbus.client.asynchronous.async_io

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 & 5 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,6 +171,8 @@ 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.
174+
175+
The requested coils can be found in boolean form in the .bits list.
169176
"""
170177

171178
function_code = 1
@@ -205,9 +212,9 @@ def execute(self, context):
205212
request is valid against the current datastore.
206213
207214
:param context: The datastore to request from
208-
:returns: The initializes response message, exception message otherwise
215+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadDiscreteInputsResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
209216
"""
210-
if not 1 <= self.count <= 0x7D0:
217+
if not (1 <= self.count <= 0x7d0):
211218
return self.doException(merror.IllegalValue)
212219
if not context.validate(self.function_code, self.address, self.count):
213220
return self.doException(merror.IllegalAddress)
@@ -227,6 +234,8 @@ class ReadDiscreteInputsResponse(ReadBitsResponseBase):
227234
remaining bits in the final data byte will be padded with zeros
228235
(toward the high order end of the byte). The Byte Count field specifies
229236
the quantity of complete bytes of data.
237+
238+
The requested coils can be found in boolean form in the .bits list.
230239
"""
231240

232241
function_code = 2
@@ -243,6 +252,7 @@ def __init__(self, values=None, **kwargs):
243252
# Exported symbols
244253
# ---------------------------------------------------------------------------#
245254
__all__ = [
255+
"ReadBitsResponseBase",
246256
"ReadCoilsRequest",
247257
"ReadCoilsResponse",
248258
"ReadDiscreteInputsRequest",

pymodbus/client/asynchronous/async_io/__init__.py

Lines changed: 30 additions & 9 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,33 @@ 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

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

8187
def resolve_future(self, my_future, result): # pylint: disable=no-self-use
82-
"""Resolve future."""
88+
"""Resolve 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

8697
def raise_future(self, my_future, exc): # pylint: disable=no-self-use
87-
"""Set exception of a future if not done
98+
"""Set exception of a future if not done.
8899
89-
:param f:
100+
:param my_future:
90101
:param exc:
91102
:return:
92103
"""
@@ -183,6 +194,7 @@ def data_received(self, data):
183194
"""Call when some data is received.
184195
185196
data is a non-empty bytes object containing the incoming data.
197+
186198
:param data:
187199
:return:
188200
"""
@@ -219,7 +231,7 @@ class ReconnectingAsyncioModbusTcpClient:
219231
DELAY_MAX_MS = 1000 * 60 * 5
220232

221233
def __init__(self, protocol_class=None, loop=None, **kwargs):
222-
"""Initialize ReconnectingAsyncioModbusTcpClient
234+
"""Initialize ReconnectingAsyncioModbusTcpClient.
223235
224236
:param protocol_class: Protocol used to talk to modbus device.
225237
:param loop: Event loop to use
@@ -258,7 +270,10 @@ async def start(self, host, port=502):
258270
return await self._connect()
259271

260272
def stop(self):
261-
"""Stop client."""
273+
"""Stop client.
274+
275+
:return:
276+
"""
262277
# prevent reconnect:
263278
self.host = None
264279

@@ -606,7 +621,7 @@ class AsyncioModbusUdpClient:
606621
"""Client to connect to modbus device over UDP."""
607622

608623
def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs):
609-
"""Initialize Asyncio Modbus UDP Client
624+
"""Initialize Asyncio Modbus UDP Client.
610625
611626
:param host: Host IP address
612627
:param port: Port to connect
@@ -627,7 +642,10 @@ def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs
627642
self._proto_args = kwargs
628643

629644
def stop(self):
630-
"""Stop connection."""
645+
"""Stop connection.
646+
647+
:return:
648+
"""
631649
# prevent reconnect:
632650
# self.host = None
633651

@@ -753,7 +771,10 @@ def _connected(self):
753771
return self._connected_event.is_set()
754772

755773
async def connect(self):
756-
"""Connect Async client."""
774+
"""Connect Async client.
775+
776+
:return:
777+
"""
757778
_logger.debug(TEXT_CONNECTING)
758779
try:
759780
await create_serial_connection(

pymodbus/client/sync.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@
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
"""
3839

3940
def __init__(self, framer, **kwargs):
@@ -128,7 +129,7 @@ def __exit__(self, klass, value, traceback):
128129
self.close()
129130

130131
def idle_time(self):
131-
"""Return bus Idle Time to initiate next transaction.
132+
"""Bus Idle Time to initiate next transaction
132133
133134
:return: time stamp
134135
"""

pymodbus/register_read_message.py

Lines changed: 19 additions & 7 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,6 +145,8 @@ 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.
148+
149+
The requested registers can be found in the .registers list.
143150
"""
144151

145152
function_code = 3
@@ -176,9 +183,9 @@ def execute(self, context):
176183
"""Run a read input request against a datastore.
177184
178185
:param context: The datastore to request from
179-
:returns: An initialized response, exception message otherwise
186+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadInputRegistersResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
180187
"""
181-
if not 1 <= self.count <= 0x7D:
188+
if not (1 <= self.count <= 0x7d):
182189
return self.doException(merror.IllegalValue)
183190
if not context.validate(self.function_code, self.address, self.count):
184191
return self.doException(merror.IllegalAddress)
@@ -194,6 +201,8 @@ class ReadInputRegistersResponse(ReadRegistersResponseBase):
194201
starting register address and the number of registers. In the PDU
195202
Registers are addressed starting at zero. Therefore input registers
196203
numbered 1-16 are addressed as 0-15.
204+
205+
The requested registers can be found in the .registers list.
197206
"""
198207

199208
function_code = 4
@@ -281,9 +290,9 @@ def execute(self, context):
281290
"""Run a write single register request against a datastore.
282291
283292
:param context: The datastore to request from
284-
:returns: An initialized response, exception message otherwise
293+
:returns: An initialized :py:class:`~pymodbus.register_read_message.ReadWriteMultipleRegistersResponse`, or an :py:class:`~pymodbus.pdu.ExceptionResponse` if an error occurred
285294
"""
286-
if not 1 <= self.read_count <= 0x07D:
295+
if not (1 <= self.read_count <= 0x07d):
287296
return self.doException(merror.IllegalValue)
288297
if not 1 <= self.write_count <= 0x079:
289298
return self.doException(merror.IllegalValue)
@@ -331,6 +340,8 @@ class ReadWriteMultipleRegistersResponse(ModbusResponse):
331340
The normal response contains the data from the group of registers that
332341
were read. The byte count field specifies the quantity of bytes to
333342
follow in the read data field.
343+
344+
The requested registers can be found in the .registers list.
334345
"""
335346

336347
function_code = 23
@@ -379,6 +390,7 @@ def __str__(self):
379390
"ReadHoldingRegistersResponse",
380391
"ReadInputRegistersRequest",
381392
"ReadInputRegistersResponse",
393+
"ReadRegistersResponseBase",
382394
"ReadWriteMultipleRegistersRequest",
383395
"ReadWriteMultipleRegistersResponse",
384396
]

0 commit comments

Comments
 (0)