Skip to content

Commit

Permalink
#23 Update docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
OrangeTux committed Jan 19, 2016
1 parent 63db842 commit bf2f321
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 21 deletions.
42 changes: 36 additions & 6 deletions README.rst
Expand Up @@ -10,16 +10,17 @@
uModbus
=======

uModbus or (μModbus) is a pure Python implementation of the Modbus protcol as
described in the `MODBUS Application Protocol Specification V1.1b3`_. The "u"
or "μ" in the name comes from the the SI prefix "micro-". uModbus is very small
and lightweight. The source can be found on GitHub_. Documentation is available
at `Read the Docs`_.
uModbus or (μModbus) is a pure Python implementation of the Modbus protocol as
described in the `MODBUS Application Protocol Specification V1.1b3`_. uModbus
implements both a Modbus client (or master in Modbus language) and a Modbus
server (or slave). The "u" or "μ" in the name comes from the the SI prefix
"micro-". uModbus is very small and lightweight. The source can be found on
GitHub_. Documentation is available at `Read the Docs`_.

Quickstart
----------

Routing Modbus requests is easy:
Creating a Modbus server is easy:

..
Because GitHub doesn't support the include directive the source of
Expand All @@ -45,6 +46,7 @@ Routing Modbus requests is easy:
# Enable values to be signed (default is False).
conf.SIGNED_VALUES = True
TCPServer.allow_reuse_address = True
app = get_server(TCPServer, ('localhost', 502), RequestHandler)
Expand All @@ -66,6 +68,34 @@ Routing Modbus requests is easy:
app.shutdown()
app.server_close()
Doing a Modbus request requires even less code:

..
Because GitHub doesn't support the include directive the source of
scripts/examples/simple_data_store.py has been copied to this file.
.. code:: python
#!/usr/bin/env python
# scripts/examples/simple_client.py
import socket
from umodbus.client import tcp
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 502))
# Returns a message or Application Data Unit (ADU) specific for doing
# Modbus TCP/IP.
message = tcp.write_multiple_coils(slave_id=1, address=1, values=[1, 0, 1, 1])
# Response depends on Modbus function code. This particular returns the
# amount of coils written, in this case it isr3.
response = tcp.send_message(message, sock)
sock.close()
Features
--------

Expand Down
4 changes: 2 additions & 2 deletions docs/source/functions.rst
Expand Up @@ -38,7 +38,7 @@ The Modbus functions have been implemented.

.. autoclass:: umodbus.functions.WriteMultipleCoils

16: Write Multiple Register
===========================
16: Write Multiple Registers
============================

.. autoclass:: umodbus.functions.WriteMultipleRegisters
19 changes: 15 additions & 4 deletions docs/source/index.rst
@@ -1,14 +1,25 @@
.. include:: ../../README.rst

Contents:
---------
....

How uModus works
----------------

.. toctree::
:maxdepth: 2

installation
usage
modbus_server
modbus_client
configuration
changelog


The Modbus protocol explained
-----------------------------

.. toctree::
:maxdepth: 2

decompose_requests
functions
changelog
37 changes: 37 additions & 0 deletions docs/source/modbus_client.rst
@@ -0,0 +1,37 @@
Modbus client
---------------

Sample use
==========

Currently a client has been implemented to do Modbus TCP requests. All
functions codes for Modbus TCP/IP are supported. U can use the client like
this:


.. include:: ../../scripts/examples/simple_client.py
:code: python


API
===

.. autofunction:: umodbus.client.tcp.send_message

.. autofunction:: umodbus.client.tcp.parse_response_adu

.. autofunction:: umodbus.client.tcp.read_coils

.. autofunction:: umodbus.client.tcp.read_discrete_inputs

.. autofunction:: umodbus.client.tcp.read_holding_registers

.. autofunction:: umodbus.client.tcp.read_input_registers

.. autofunction:: umodbus.client.tcp.write_single_coil

.. autofunction:: umodbus.client.tcp.write_single_register

.. autofunction:: umodbus.client.tcp.write_multiple_coils

.. autofunction:: umodbus.client.tcp.write_multiple_registers
18 changes: 11 additions & 7 deletions docs/source/usage.rst → docs/source/modbus_server.rst
@@ -1,12 +1,13 @@
Usage
-----
Modbus server
-------------

Viewpoint
=========

uModbus is build with routing in mind. Routing (groups of) requests to a
certain callback must be easy. This is in contrast with with other Modbus
implementation which often focus on reading and writing from a data store.
The uModbus server code is build with routing in mind. Routing (groups of)
requests to a certain callback must be easy. This is in contrast with with
other Modbus implementation which often focus on reading and writing from a
data store.

Because of this difference in view point uModbus doesn't know the concepts of
Modbus' data models like discrete inputs, coils, input registers and holding
Expand All @@ -17,12 +18,15 @@ Routing

The route system was inspired by Flask_. Like Flask, uModbus requires a global
app or server. This server contains a route map. Routes can be added to this
route map.
route map.

The following code example demonstrates how to implement a very simple data
store for 10 addresses.

.. include:: ../../scripts/examples/simple_data_store.py
Sample use
==========

.. include:: ../../scripts/examples/simple_data_store.py
:code: python

.. _Flask: http://flask.pocoo.org/
19 changes: 19 additions & 0 deletions scripts/examples/simple_client.py
@@ -0,0 +1,19 @@
#!/usr/bin/env python
# scripts/examples/simple_client.py
import socket

from umodbus.client import tcp


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 502))

# Returns a message or Application Data Unit (ADU) specific for doing
# Modbus TCP/IP.
message = tcp.write_multiple_coils(slave_id=1, address=1, values=[1, 0, 1, 1])

# Response depends on Modbus function code. This particular returns the
# amount of coils written, in this case it isr3.
response = tcp.send_message(message, sock)

sock.close()
5 changes: 3 additions & 2 deletions scripts/examples/simple_data_store.py
Expand Up @@ -16,16 +16,17 @@
# Enable values to be signed (default is False).
conf.SIGNED_VALUES = True

TCPServer.allow_reuse_address = True
app = get_server(TCPServer, ('localhost', 502), RequestHandler)


@app.route(slave_ids=[1], function_codes=[3, 4], addresses=list(range(0, 10)))
@app.route(slave_ids=[1], function_codes=[1, 2], addresses=list(range(0, 10)))
def read_data_store(slave_id, address):
"""" Return value of address. """
return data_store[address]


@app.route(slave_ids=[1], function_codes=[6, 16], addresses=list(range(0, 10)))
@app.route(slave_ids=[1], function_codes=[5, 15], addresses=list(range(0, 10)))
def write_data_store(slave_id, address, value):
"""" Set value for address. """
data_store[address] = value
Expand Down
7 changes: 7 additions & 0 deletions umodbus/client/tcp.py
Expand Up @@ -211,6 +211,13 @@ def write_multiple_registers(slave_id, starting_address, values):


def parse_response_adu(resp_adu, req_adu=None):
""" Parse response ADU and return response data. Some functions require
request ADU to fully understand request ADU.
:param resp_adu: Resonse ADU.
:param req_adu: Request ADU, default None.
:return: Response data.
"""
resp_pdu = resp_adu[7:]
function = create_function_from_response_pdu(resp_pdu, req_adu)

Expand Down

0 comments on commit bf2f321

Please sign in to comment.