# uModbus

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 (both TCP and RTU) and a Modbus server (both TCP and RTU). 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

Creating a Modbus TCP server is easy:

    #!/usr/bin/env python
    # scripts/examples/simple_tcp_server.py
    import logging
    from socketserver import TCPServer
    from collections import defaultdict

    from umodbus import conf
    from umodbus.server.tcp import RequestHandler, get_server
    from umodbus.utils import log_to_stream

    # Add stream handler to logger 'uModbus'.
    log_to_stream(level=logging.DEBUG)

    # A very simple data store which maps addresss against their values.
    data_store = defaultdict(int)

    # 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)))
    def read_data_store(slave_id, function_code, address):
        """" Return value of address. """
        return data_store[address]

    @app.route(slave_ids=[1], function_codes=[6, 16], addresses=list(range(0, 10)))
    def write_data_store(slave_id, function_code, address, value):
        """" Set value for address. """
        data_store[address] = value

    if __name__ == '__main__':
        try:
            app.serve_forever()
        finally:
            app.shutdown()
            app.server_close()

Doing a Modbus request requires even less code:

    #!/usr/bin/env python
    # scripts/examples/simple_tcp_client.py
    import socket

    from umodbus import conf
    from umodbus.client import tcp

    # Enable values to be signed (default is False).
    conf.SIGNED_VALUES = True

    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, starting_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 is.
    response = tcp.send_message(message, sock)

    sock.close()

## Features

The following functions have been implemented for Modbus TCP and Modbus RTU:

- 01: Read Coils

- 02: Read Discrete Inputs

- 03: Read Holding Registers

- 04: Read Input Registers

- 05: Write Single Coil

- 06: Write Single Register

- 15: Write Multiple Coils

- 16: Write Multiple Registers

Other featues:

- Support for signed and unsigned register values.

## License

uModbus software is licensed under Mozilla Public License. © 2018 Advanced Climate Systems.

## How uModus works

- Installation
  - As package
  - For development, debugging and testing
- Modbus Server
  - Viewpoint
  - Routing
  - Modbus TCP example
  - Modbus RTU example
- Modbus Client
  - Modbus TCP
  - Modbus RTU
- Configuration
  - `Config`
- Changelog
  - 1.0.4 (2020-08-27)
  - 1.0.3 (2019-12-04)
  - 1.0.2 (2018-05-22)
  - 1.0.1 (2018-05-22)
  - 1.0.0 (2018-01-06)
  - 0.8.2 (2016-11-11)
  - 0.8.1 (2016-11-02)
  - 0.8.0 (2016-10-31)
  - 0.7.2 (2016-09-27)
  - 0.7.1 (01-09-2016)
  - 0.7.0 (29-07-2016)
  - 0.6.0 (2016-05-08)
  - 0.5.0 (2016-05-03)
  - 0.4.2 (2016-04-07)
  - 0.4.1 (2016-01-22)
  - 0.4.0 (2016-01-22)
  - 0.3.1 (2015-12-12)
  - 0.3.0 (2015-12-05)
  - 0.2.0 (2015-11-19)
  - 0.1.2 (2015-11-16)
  - 0.1.1 (2015-11-12)
  - 0.1.0 (2015-11-10)

## The Modbus protocol explained

- Decompose requests
  - PDU
  - ADU for TCP/IP requests and responses
  - ADU for RTU requests and responses
- Modbus Functions
  - 01: Read Coils
  - 02: Read Discrete Inputs
  - 03: Read Holding Registers
  - 04: Read Input Registers
  - 05: Write Single Coil
  - 06: Write Single Register
  - 15: Write Multiple Coils
  - 16: Write Multiple Registers