diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 16b515b6..4d7624d2 100755 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -11,7 +11,6 @@ "extensions": [ "ms-python.python", "charliermarsh.ruff", - "ms-python.black-formatter", "ms-python.vscode-pylance", "github.vscode-pull-request-github", "ryanluker.vscode-coverage-gutters", diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7da91946..70a5d49c 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,14 +6,6 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - repo: local - hooks: - - id: black - name: black - entry: black - language: system - types: [python] - require_serial: true - repo: https://github.com/pre-commit/mirrors-prettier rev: v2.2.1 hooks: diff --git a/.prettierignore b/.prettierignore index bd3739de..c76fb396 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,2 @@ tests/__snapshots__ +custom_components/foxess_modbus/vendor diff --git a/.vscode/settings.json b/.vscode/settings.json index d9035590..a7538c3f 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,5 +27,8 @@ "source.fixAll": "explicit" }, "editor.defaultFormatter": "ms-python.black-formatter" - } + }, + "python.analysis.extraPaths": [ + "./custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4" + ] } diff --git a/custom_components/foxess_modbus/client/custom_modbus_tcp_client.py b/custom_components/foxess_modbus/client/custom_modbus_tcp_client.py index 95f3be77..ef6bdf4a 100644 --- a/custom_components/foxess_modbus/client/custom_modbus_tcp_client.py +++ b/custom_components/foxess_modbus/client/custom_modbus_tcp_client.py @@ -5,8 +5,8 @@ from typing import Any from typing import cast -from pymodbus.client import ModbusTcpClient -from pymodbus.exceptions import ConnectionException +from ..vendor.pymodbus import ConnectionException +from ..vendor.pymodbus import ModbusTcpClient _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/foxess_modbus/client/modbus_client.py b/custom_components/foxess_modbus/client/modbus_client.py index 8b6f01ee..2752f69c 100644 --- a/custom_components/foxess_modbus/client/modbus_client.py +++ b/custom_components/foxess_modbus/client/modbus_client.py @@ -11,14 +11,6 @@ import serial from homeassistant.core import HomeAssistant -from pymodbus.client import ModbusSerialClient -from pymodbus.client import ModbusUdpClient -from pymodbus.framer import FramerType -from pymodbus.pdu import ModbusPDU -from pymodbus.pdu.register_read_message import ReadHoldingRegistersResponse -from pymodbus.pdu.register_read_message import ReadInputRegistersResponse -from pymodbus.pdu.register_write_message import WriteMultipleRegistersResponse -from pymodbus.pdu.register_write_message import WriteSingleRegisterResponse from .. import client from ..common.types import ConnectionType @@ -28,6 +20,14 @@ from ..const import TCP from ..const import UDP from ..inverter_adapters import InverterAdapter +from ..vendor.pymodbus import FramerType +from ..vendor.pymodbus import ModbusPDU +from ..vendor.pymodbus import ModbusSerialClient +from ..vendor.pymodbus import ModbusUdpClient +from ..vendor.pymodbus import ReadHoldingRegistersResponse +from ..vendor.pymodbus import ReadInputRegistersResponse +from ..vendor.pymodbus import WriteMultipleRegistersResponse +from ..vendor.pymodbus import WriteSingleRegisterResponse from .custom_modbus_tcp_client import CustomModbusTcpClient _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/foxess_modbus/flow/adapter_flow_segment.py b/custom_components/foxess_modbus/flow/adapter_flow_segment.py index f038b7a2..523793b1 100644 --- a/custom_components/foxess_modbus/flow/adapter_flow_segment.py +++ b/custom_components/foxess_modbus/flow/adapter_flow_segment.py @@ -7,8 +7,6 @@ from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import config_validation as cv from homeassistant.helpers.selector import selector -from pymodbus.exceptions import ConnectionException -from pymodbus.exceptions import ModbusIOException from ..client.modbus_client import ModbusClient from ..client.modbus_client import ModbusClientFailedError @@ -23,6 +21,8 @@ from ..inverter_adapters import InverterAdapter from ..inverter_adapters import InverterAdapterType from ..modbus_controller import ModbusController +from ..vendor.pymodbus import ConnectionException +from ..vendor.pymodbus import ModbusIOException from .flow_handler_mixin import FlowHandlerMixin from .flow_handler_mixin import ValidationFailedError from .inverter_data import InverterData diff --git a/custom_components/foxess_modbus/manifest.json b/custom_components/foxess_modbus/manifest.json index 9d774a57..dcbc111e 100755 --- a/custom_components/foxess_modbus/manifest.json +++ b/custom_components/foxess_modbus/manifest.json @@ -8,6 +8,5 @@ "integration_type": "service", "iot_class": "local_push", "issue_tracker": "https://github.com/nathanmarlor/foxess_modbus/issues", - "requirements": ["pymodbus>=3.7.4"], "version": "1.0.0" } diff --git a/custom_components/foxess_modbus/modbus_controller.py b/custom_components/foxess_modbus/modbus_controller.py index abceb8a2..5d29381e 100644 --- a/custom_components/foxess_modbus/modbus_controller.py +++ b/custom_components/foxess_modbus/modbus_controller.py @@ -18,7 +18,6 @@ from homeassistant.helpers import issue_registry from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.issue_registry import IssueSeverity -from pymodbus.exceptions import ConnectionException from .client.modbus_client import ModbusClient from .client.modbus_client import ModbusClientFailedError @@ -38,6 +37,7 @@ from .inverter_profiles import INVERTER_PROFILES from .inverter_profiles import InverterModelConnectionTypeProfile from .remote_control_manager import RemoteControlManager +from .vendor.pymodbus import ConnectionException _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/foxess_modbus/services/update_charge_period_service.py b/custom_components/foxess_modbus/services/update_charge_period_service.py index 9f28d161..e3d967bb 100644 --- a/custom_components/foxess_modbus/services/update_charge_period_service.py +++ b/custom_components/foxess_modbus/services/update_charge_period_service.py @@ -10,13 +10,13 @@ from homeassistant.core import ServiceCall from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv -from pymodbus.exceptions import ModbusIOException from ..const import DOMAIN from ..entities.modbus_charge_period_sensors import is_time_value_valid from ..entities.modbus_charge_period_sensors import parse_time_value from ..entities.modbus_charge_period_sensors import serialize_time_to_value from ..modbus_controller import ModbusController +from ..vendor.pymodbus import ModbusIOException from .utils import get_controller_from_friendly_name_or_device_id _LOGGER: logging.Logger = logging.getLogger(__package__) diff --git a/custom_components/foxess_modbus/services/write_registers_service.py b/custom_components/foxess_modbus/services/write_registers_service.py index 3b3fa659..c42b821a 100644 --- a/custom_components/foxess_modbus/services/write_registers_service.py +++ b/custom_components/foxess_modbus/services/write_registers_service.py @@ -8,10 +8,10 @@ from homeassistant.core import ServiceCall from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv -from pymodbus.exceptions import ModbusIOException from ..const import DOMAIN from ..modbus_controller import ModbusController +from ..vendor.pymodbus import ModbusIOException from .utils import get_controller_from_friendly_name_or_device_id _LOGGER: logging.Logger = logging.getLogger(__package__) diff --git a/custom_components/foxess_modbus/vendor/pymodbus/__init__.py b/custom_components/foxess_modbus/vendor/pymodbus/__init__.py new file mode 100644 index 00000000..9107a25c --- /dev/null +++ b/custom_components/foxess_modbus/vendor/pymodbus/__init__.py @@ -0,0 +1,34 @@ +import sys +from pathlib import Path + +# Update python.analysis.extraPaths in .vscode/settings.json if you change this. +# If changed, make sure subclasses in modbus_client are still valid! +sys.path.insert(0, str((Path(__file__).parent / "pymodbus-3.7.4").absolute())) + +from pymodbus.client import ModbusSerialClient +from pymodbus.client import ModbusTcpClient +from pymodbus.client import ModbusUdpClient +from pymodbus.exceptions import ConnectionException +from pymodbus.exceptions import ModbusIOException +from pymodbus.framer import FramerType +from pymodbus.pdu import ModbusPDU +from pymodbus.pdu.register_read_message import ReadHoldingRegistersResponse +from pymodbus.pdu.register_read_message import ReadInputRegistersResponse +from pymodbus.pdu.register_write_message import WriteMultipleRegistersResponse +from pymodbus.pdu.register_write_message import WriteSingleRegisterResponse + +sys.path.pop(0) + +__all__ = [ + "ModbusSerialClient", + "ModbusTcpClient", + "ModbusUdpClient", + "ConnectionException", + "ModbusIOException", + "FramerType", + "ModbusPDU", + "ReadHoldingRegistersResponse", + "ReadInputRegistersResponse", + "WriteMultipleRegistersResponse", + "WriteSingleRegisterResponse", +] diff --git a/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/bin/pymodbus.simulator.exe b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/bin/pymodbus.simulator.exe new file mode 100644 index 00000000..51aa2318 Binary files /dev/null and b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/bin/pymodbus.simulator.exe differ diff --git a/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/AUTHORS.rst b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/AUTHORS.rst new file mode 100644 index 00000000..9f1a8e91 --- /dev/null +++ b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/AUTHORS.rst @@ -0,0 +1,185 @@ +Authors +======= +All these versions would not be possible without volunteers! + +This is a complete list for each major version. + +A big "thank you" to everybody who helped out. + +Pymodbus version 3 family +------------------------- +Thanks to + +- ahcm-dev +- AKJ7 +- Alex +- Alex Ruddick +- Alexander Lanin +- Alexandre CUER +- Alois Hockenschlohe +- Andy Walker +- Arjan +- André Srinivasan +- andrew-harness +- banana-sun +- Blaise Thompson +- CapraTheBest +- cgernert +- corollaries +- Chandler Riehm +- Chris Hung +- Christian Krause +- Daniel Rauber +- dhoomakethu +- doelki +- DominicDataP +- Dominique Martinet +- Dries +- duc996 +- efdx +- Esco441-91 +- Farzad Panahi +- Fredo70 +- Gao Fang +- Ghostkeeper +- Hangyu Fan +- Hayden Roche +- Iktek +- Ilkka Ollakka +- Jakob Ruhe +- Jakob Schlyter +- James Braza +- James Cameron +- James Hilliard +- jan iversen +- Jerome Velociter +- Joe Burmeister +- John Miko +- Jonathan Reichelt Gjertsen +- julian +- Justin Standring +- Kenny Johansson +- Kürşat Aktaş +- laund +- Logan Gunthorpe +- Marko Luther +- Martyy +- Máté Szabó +- Matthias Straka +- Matthias Urlichs +- Michel F +- Mickaël Schoentgen +- Pavel Kostromitinov +- peufeu2 +- Philip Couling +- Qi Li +- Sebastian Machuca +- Sefa Keleş +- Steffen Beyer +- sumguytho +- Thijs W +- Totally a booplicate +- WouterTuinstra +- wriswith +- Yash Jani +- Yohrog +- yyokusa + + +Pymodbus version 2 family +------------------------- +Thanks to + +- alecjohanson +- Alexey Andreyev +- Andrea Canidio +- Carlos Gomez +- Cougar +- Christian Sandberg +- dhoomakethu +- dices +- Dmitri Zimine +- Emil Vanherp +- er888kh +- Eric Duminil +- Erlend Egeberg Aasland +- hackerboygn +- Jian-Hong Pan +- Jose J Rodriguez +- Justin Searle +- Karl Palsson +- Kim Hansen +- Kristoffer Sjöberg +- Kyle Altendorf +- Lars Kruse +- Malte Kliemann +- Memet Bilgin +- Michael Corcoran +- Mike +- sanjay +- Sekenre +- Siarhei Farbotka +- Steffen Vogel +- tcplomp +- Thor Michael Støre +- Tim Gates +- Ville Skyttä +- Wild Stray +- Yegor Yefremov + + +Pymodbus version 1 family +------------------------- +Thanks to + +- Antoine Pitrou +- Bart de Waal +- bashwork +- bje- +- Claudio Catterina +- Chintalagiri Shashank +- dhoomakethu +- dragoshenron +- Elvis Stansvik +- Eren Inan Canpolat +- Everley +- Fabio Bonelli +- fleimgruber +- francozappa +- Galen Collins +- Gordon Broom +- Hamilton Kibbe +- Hynek Petrak +- idahogray +- Ingo van Lil +- Jack +- jbiswas +- jon mills +- Josh Kelley +- Karl Palsson +- Matheus Frata +- Patrick Fuller +- Perry Kundert +- Philippe Gauthier +- Rahul Raghunath +- sanjay +- schubduese42 +- semyont +- Semyon Teplitsky +- Stuart Longland +- Yegor Yefremov + + +Pymodbus version 0 family +------------------------- +Thanks to + +- Albert Brandl +- Galen Collins + +Import to github was based on code from: + +- S.W.A.C. GmbH, Germany. +- S.W.A.C. Bohemia s.r.o., Czech Republic. +- Hynek Petrak +- Galen Collins diff --git a/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/INSTALLER b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/LICENSE b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/LICENSE new file mode 100644 index 00000000..d3dda3d9 --- /dev/null +++ b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/LICENSE @@ -0,0 +1,23 @@ +Copyright 2008-2023 Pymodbus + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/METADATA b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/METADATA new file mode 100644 index 00000000..5e895905 --- /dev/null +++ b/custom_components/foxess_modbus/vendor/pymodbus/pymodbus-3.7.4/pymodbus-3.7.4.dist-info/METADATA @@ -0,0 +1,423 @@ +Metadata-Version: 2.1 +Name: pymodbus +Version: 3.7.4 +Summary: A fully featured modbus protocol stack in python +Author: Galen Collins, Jan Iversen +Maintainer: dhoomakethu, janiversen +License: BSD-3-Clause +Project-URL: Homepage, https://github.com/pymodbus-dev/pymodbus/ +Project-URL: Source Code, https://github.com/pymodbus-dev/pymodbus +Project-URL: Bug Reports, https://github.com/pymodbus-dev/pymodbus/issues +Project-URL: Docs: Dev, https://pymodbus.readthedocs.io/en/latest/?badge=latest +Project-URL: Discord, https://discord.gg/vcP8qAz2 +Keywords: modbus,asyncio,scada,client,server,simulator +Platform: 'Linux' +Platform: 'Mac OS X' +Platform: 'Win' +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Framework :: AsyncIO +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: Unix +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: OS Independent +Classifier: Operating System :: Microsoft +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Topic :: System :: Networking +Classifier: Topic :: Utilities +Requires-Python: >=3.9.0 +Description-Content-Type: text/x-rst +License-File: LICENSE +License-File: AUTHORS.rst +Provides-Extra: all +Requires-Dist: pymodbus[development,documentation,repl,serial,simulator] ; extra == 'all' +Provides-Extra: development +Requires-Dist: build >=1.2.2 ; extra == 'development' +Requires-Dist: codespell >=2.3.0 ; extra == 'development' +Requires-Dist: coverage >=7.6.1 ; extra == 'development' +Requires-Dist: mypy >=1.11.2 ; extra == 'development' +Requires-Dist: pylint >=3.3.0 ; extra == 'development' +Requires-Dist: pytest >=8.3.3 ; extra == 'development' +Requires-Dist: pytest-asyncio >=0.24.0 ; extra == 'development' +Requires-Dist: pytest-cov >=5.0.0 ; extra == 'development' +Requires-Dist: pytest-timeout >=2.3.1 ; extra == 'development' +Requires-Dist: pytest-xdist >=3.6.1 ; extra == 'development' +Requires-Dist: pytest-aiohttp >=1.0.5 ; extra == 'development' +Requires-Dist: ruff >=0.5.3 ; extra == 'development' +Requires-Dist: twine >=5.1.1 ; extra == 'development' +Requires-Dist: types-Pygments ; extra == 'development' +Requires-Dist: types-pyserial ; extra == 'development' +Requires-Dist: pytest-profiling >=1.7.0 ; (python_version < "3.13") and extra == 'development' +Provides-Extra: documentation +Requires-Dist: recommonmark >=0.7.1 ; extra == 'documentation' +Requires-Dist: Sphinx >=7.3.7 ; extra == 'documentation' +Requires-Dist: sphinx-rtd-theme >=2.0.0 ; extra == 'documentation' +Provides-Extra: repl +Requires-Dist: pymodbus-repl >=2.0.4 ; extra == 'repl' +Provides-Extra: serial +Requires-Dist: pyserial >=3.5 ; extra == 'serial' +Provides-Extra: simulator +Requires-Dist: aiohttp >=3.8.6 ; (python_version < "3.12") and extra == 'simulator' +Requires-Dist: aiohttp >=3.10.5 ; (python_version >= "3.12") and extra == 'simulator' + +PyModbus - A Python Modbus Stack +================================ +.. image:: https://github.com/pymodbus-dev/pymodbus/actions/workflows/ci.yml/badge.svg?branch=dev + :target: https://github.com/pymodbus-dev/pymodbus/actions/workflows/ci.yml +.. image:: https://readthedocs.org/projects/pymodbus/badge/?version=latest + :target: https://pymodbus.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status +.. image:: https://pepy.tech/badge/pymodbus + :target: https://pepy.tech/project/pymodbus + :alt: Downloads +.. image:: https://img.shields.io/badge/Gurubase-Ask%20PyModbus%20Guru-006BFF + :target: https://gurubase.io/g/pymodbus + :alt: PyModbus Guru + +Pymodbus is a full Modbus protocol implementation offering client/server with synchronous/asynchronous API and simulators. + +Our releases is defined as X.Y.Z, and we have strict rules what to release when: + +- **Z**, No API changes! bug fixes and smaller enhancements. +- **Y**, API changes, bug fixes and bigger enhancements. +- **X**, Major changes in API and/or method to use pymodbus + +Upgrade examples: + +- 3.6.1 -> 3.6.9: just plugin the new version, no changes needed. +- 3.6.1 -> 3.7.0: Smaller changes to the pymodbus calls might be needed +- 2.5.4 -> 3.0.0: Major changes in the application might be needed + +Current release is `3.7.4 `_. + +Bleeding edge (not released) is `dev `_. + +Waiting for v3.8.0 (not released) is `wait_next_API `_. This contains +dev + merged pull requests that have API changes, and thus have to wait. + +All changes are described in `release notes `_ +and all API changes are `documented `_ + +A big thanks to all the `volunteers `_ that helps make pymodbus a great project. + +Source code on `github `_ + +Pymodbus in a nutshell +---------------------- +Pymodbus consist of 5 parts: + +- **client**, connect to your favorite device(s) +- **server**, simulate your favorite device(s) +- **repl**, a commandline text based client/server simulator +- **simulator**, an html based server simulator +- **examples**, showing both simple and advances usage + +Common features +^^^^^^^^^^^^^^^ +* Full modbus standard protocol implementation +* Support for custom function codes +* support serial (rs-485), tcp, tls and udp communication +* support all standard frames: socket, rtu, rtu-over-tcp, tcp and ascii +* does not have third party dependencies, apart from pyserial (optional) +* very lightweight project +* requires Python >= 3.9 +* thorough test suite, that test all corners of the library +* automatically tested on Windows, Linux and MacOS combined with python 3.9 - 3.13 +* strongly typed API (py.typed present) + +The modbus protocol specification: Modbus_Application_Protocol_V1_1b3.pdf can be found on +`modbus org `_ + + +Client Features +^^^^^^^^^^^^^^^ +* asynchronous API and synchronous API for applications +* very simple setup and call sequence (just 6 lines of code) +* utilities to convert int/float to/from multiple registers +* payload builder/decoder to help with complex data + +`Client documentation `_ + + +Server Features +^^^^^^^^^^^^^^^ +* asynchronous implementation for high performance +* synchronous API classes for convenience +* simulate real life devices +* full server control context (device information, counters, etc) +* different backend datastores to manage register values +* callback to intercept requests/responses +* work on RS485 in parallel with other devices + +`Server documentation `_ + + +REPL Features +^^^^^^^^^^^^^ +- server/client commandline emulator +- easy test of real device (client) +- easy test of client app (server) +- simulation of broken requests/responses +- simulation of error responses (hard to provoke in real devices) + +`REPL documentation `_ + + +Simulator Features +^^^^^^^^^^^^^^^^^^ +- server simulator with WEB interface +- configure the structure of a real device +- monitor traffic online +- allow distributed team members to work on a virtual device using internet +- simulation of broken requests/responses +- simulation of error responses (hard to provoke in real devices) + +`Simulator documentation `_ + +Use Cases +--------- +The client is the most typically used. It is embedded into applications, +where it abstract the modbus protocol from the application by providing an +easy to use API. The client is integrated into some well known projects like +`home-assistant `_. + +Although most system administrators will find little need for a Modbus +server, the server is handy to verify the functionality of an application. + +The simulator and/or server is often used to simulate real life devices testing +applications. The server is excellent to perform high volume testing (e.g. +houndreds of devices connected to the application). The advantage of the server is +that it runs not only a "normal" computers but also on small ones like Raspberry PI. + +Since the library is written in python, it allows for easy scripting and/or integration into their existing +solutions. + +For more information please browse the project documentation: + +https://readthedocs.org/docs/pymodbus/en/latest/index.html + + + +Install +------- +The library is available on pypi.org and github.com to install with + +- :code:`pip` for those who just want to use the library +- :code:`git clone` for those who wants to help or just are curious + +Be aware that there are a number of project, who have forked pymodbus and + +- seems just to provide a version frozen in time +- extended pymodbus with extra functionality + +The latter is not because we rejected the extra functionality (we welcome all changes), +but because the codeowners made that decision. + +In both cases, please understand, we cannot offer support to users of these projects as we do not known +what have been changed nor what status the forked code have. + +A growing number of Linux distributions include pymodbus in their standard installation. + +You need to have python3 installed, preferable 3.11. + +Install with pip +^^^^^^^^^^^^^^^^ +You can install using pip by issuing the following +commands in a terminal window:: + + pip install pymodbus + +If you want to use the serial interface:: + + pip install pymodbus[serial] + +This will install pymodbus with the pyserial dependency. + +Pymodbus offers a number of extra options: + +- **repl**, needed by pymodbus.repl +- **serial**, needed for serial communication +- **simulator**, needed by pymodbus.simulator +- **documentation**, needed to generate documentation +- **development**, needed for development +- **all**, installs all of the above + +which can be installed as:: + + pip install pymodbus[