# DM-aiomodbus
### Asynchronous Modbus clients for Python with TCP and Serial connection support.
## Links
* [PyPI](https://pypi.org/project/dm-aiomodbus)
* [GitHub](https://github.com/MykhLibs/dm-aiomodbus)
---
| Section | Description |
|-----------------------------------------------|--------------------------------------------|
| [Installation](#installation) | How to install the package |
| [Usage](#usage) | How to use the package |
| [Types](#types) | Types and classes used in the package |
| [Inner Client Methods](#inner-client-methods) | List of methods available for inner client |
---
## Installation
Check if you have Python 3.12.6 or higher installed:
```bash
python3 --version
```
Install the package using pip:
```bash
pip install dm-aiomodbus
```
---
## Usage
### Windows Setup
```python
import asyncio
import sys
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
```
### Code Example
```python
import asyncio
from dm_aiomodbus import (
DMAioModbusSerialClient, DMAioModbusSerialClientConfig,
DMAioModbusTcpClient, DMAioModbusTcpClientConfig,
DMAioModbusInnerClient
)
async def main():
# Initialize Serial client
serial_modbus_client = DMAioModbusSerialClient(
config=DMAioModbusSerialClientConfig(
port="/dev/ttyUSB0",
baudrate=9600, # default value
bytesize=8, # default value
stopbits=2, # default value
parity="N", # default value
disconnect_timeout_s=20, # default value
error_logging=False # default value
)
)
# Initialize TCP client
tcp_modbus_client = DMAioModbusTcpClient(
config=DMAioModbusTcpClientConfig(
host="129.168.1.5",
port=502, # default value
disconnect_timeout_s=20, # default value
error_logging=False # default value
)
)
# Read/write register(s)
async def callback(client: DMAioModbusInnerClient):
await client.write_register(256, 1)
result = await client.read_holding_registers(256, count=3)
print(result)
# Execute callback
await serial_modbus_client.execute(callback)
# or
await tcp_modbus_client.execute(callback)
if __name__ == "__main__":
asyncio.run(main())
```
**Note:** All read/write methods should be called inside your callback function
---
## Types
### Serial Client Config
```python
class DMAioModbusSerialClientConfig:
port: str # Serial port name. Example: "/dev/ttyS0" - Linux UART, "/dev/ttyUSB0" - linux USB, "COM1" - Windows USB
baudrate: int = 9600 # Baudrate in bits per second
bytesize: Literal[7, 8] = 8 # Number of data bits
stopbits: Literal[1, 2] = 2 # Number of stop bits
parity: Literal["N", "E", "O"] = "N" # Parity mode. N - None, E - Even, O - Odd
disconnect_timeout_s: int = 20 # Timeout in seconds
error_logging: bool = False # Enable error logging
```
### TCP Client Config
```python
class DMAioModbusTcpClientConfig:
host: str # IP address of the device
port: int = 502 # Port number
disconnect_timeout_s: int = 20 # Timeout in seconds
error_logging: bool = False # Enable error logging
```
### Read Response
```python
class DMAioModbusReadResponse:
data: list[int] # List of values read from device
error: str # Error message if operation failed
```
**Note:** This class has `to_dict()` method that returns a dictionary
**Warning:** If the operation failed, the `data` field will be an empty list
### Write Response
```python
class DMAioModbusWriteResponse:
status: bool # Boolean indicating success or failure
error: str # Error message if operation failed
```
**Note:** This class has `to_dict()` method that returns a dictionary
**Warning:** The status is considered True, if the operation did not result in an error.
---
## Inner Client Methods
| Method | Arguments | Response Type |
|--------------------------|--------------------------------------------------------------------------|----------------------------------|
| `read_coils` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |
| `read_discrete_inputs` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |
| `read_holding_registers` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |
| `read_input_registers` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |
| `write_coil` | - *address* `int`<br>- *value* `int`<br>- *slave* `int` = 1 | [WriteResponse](#write-response) |
| `write_register` | - *address* `int`<br>- *value* `int`<br>- *slave* `int` = 1 | [WriteResponse](#write-response) |
| `write_coils` | - *address* `int`<br>- *values* `list[int] \| int`<br>- *slave* `int`= 1 | [WriteResponse](#write-response) |
| `write_registers` | - *address* `int`<br>- *values* `list[int] \| int`<br>- *slave* `int`= 1 | [WriteResponse](#write-response) |
### Parameters Description
- `address`: Register address _(single integer)_
- `count`: Number of items to read _(default: 1)_
- `value`/`values`: Value(s) to write _(single integer or list of integers)_
- `slave`: Slave unit address _(default: 1)_
Raw data
{
"_id": null,
"home_page": "https://pypi.org/project/dm-aiomodbus",
"name": "dm-aiomodbus",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "dm aiomodbus",
"author": "dimka4621",
"author_email": "mismartconfig@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/87/ea/9bf46322d6f0d4fdab38fd44ac94c5071f9f103990f903439d0b630ffaae/dm_aiomodbus-0.3.2.tar.gz",
"platform": null,
"description": "# DM-aiomodbus\n\n### Asynchronous Modbus clients for Python with TCP and Serial connection support.\n\n## Links\n\n* [PyPI](https://pypi.org/project/dm-aiomodbus)\n* [GitHub](https://github.com/MykhLibs/dm-aiomodbus)\n\n---\n\n| Section | Description |\n|-----------------------------------------------|--------------------------------------------|\n| [Installation](#installation) | How to install the package |\n| [Usage](#usage) | How to use the package |\n| [Types](#types) | Types and classes used in the package |\n| [Inner Client Methods](#inner-client-methods) | List of methods available for inner client |\n\n---\n\n## Installation\n\nCheck if you have Python 3.12.6 or higher installed:\n\n```bash\npython3 --version\n```\n\nInstall the package using pip:\n\n```bash\npip install dm-aiomodbus\n```\n\n---\n\n## Usage\n\n### Windows Setup\n\n```python\nimport asyncio\nimport sys\n\nif sys.platform == \"win32\":\n asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())\n```\n\n### Code Example\n\n```python\nimport asyncio\nfrom dm_aiomodbus import (\n DMAioModbusSerialClient, DMAioModbusSerialClientConfig,\n DMAioModbusTcpClient, DMAioModbusTcpClientConfig,\n DMAioModbusInnerClient\n)\n\n\nasync def main():\n # Initialize Serial client\n serial_modbus_client = DMAioModbusSerialClient(\n config=DMAioModbusSerialClientConfig(\n port=\"/dev/ttyUSB0\",\n baudrate=9600, # default value\n bytesize=8, # default value\n stopbits=2, # default value\n parity=\"N\", # default value\n disconnect_timeout_s=20, # default value\n error_logging=False # default value\n )\n )\n\n # Initialize TCP client\n tcp_modbus_client = DMAioModbusTcpClient(\n config=DMAioModbusTcpClientConfig(\n host=\"129.168.1.5\",\n port=502, # default value\n disconnect_timeout_s=20, # default value\n error_logging=False # default value\n )\n )\n\n # Read/write register(s)\n async def callback(client: DMAioModbusInnerClient):\n await client.write_register(256, 1)\n result = await client.read_holding_registers(256, count=3)\n print(result)\n\n # Execute callback\n await serial_modbus_client.execute(callback)\n # or\n await tcp_modbus_client.execute(callback)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n**Note:** All read/write methods should be called inside your callback function\n\n---\n\n## Types\n\n### Serial Client Config\n\n```python\nclass DMAioModbusSerialClientConfig:\n port: str # Serial port name. Example: \"/dev/ttyS0\" - Linux UART, \"/dev/ttyUSB0\" - linux USB, \"COM1\" - Windows USB\n baudrate: int = 9600 # Baudrate in bits per second\n bytesize: Literal[7, 8] = 8 # Number of data bits\n stopbits: Literal[1, 2] = 2 # Number of stop bits\n parity: Literal[\"N\", \"E\", \"O\"] = \"N\" # Parity mode. N - None, E - Even, O - Odd\n disconnect_timeout_s: int = 20 # Timeout in seconds\n error_logging: bool = False # Enable error logging\n```\n\n### TCP Client Config\n\n```python\nclass DMAioModbusTcpClientConfig:\n host: str # IP address of the device\n port: int = 502 # Port number\n disconnect_timeout_s: int = 20 # Timeout in seconds\n error_logging: bool = False # Enable error logging\n```\n\n### Read Response\n\n```python\nclass DMAioModbusReadResponse:\n data: list[int] # List of values read from device\n error: str # Error message if operation failed\n```\n\n**Note:** This class has `to_dict()` method that returns a dictionary\n\n**Warning:** If the operation failed, the `data` field will be an empty list\n\n### Write Response\n\n```python\n\nclass DMAioModbusWriteResponse:\n status: bool # Boolean indicating success or failure\n error: str # Error message if operation failed\n```\n\n**Note:** This class has `to_dict()` method that returns a dictionary\n\n**Warning:** The status is considered True, if the operation did not result in an error.\n\n---\n\n## Inner Client Methods\n\n| Method | Arguments | Response Type |\n|--------------------------|--------------------------------------------------------------------------|----------------------------------|\n| `read_coils` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |\n| `read_discrete_inputs` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |\n| `read_holding_registers` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |\n| `read_input_registers` | - *address* `int`<br>- *count* `int` = 1<br>- *slave* `int`= 1 | [ReadResponse](#read-response) |\n| `write_coil` | - *address* `int`<br>- *value* `int`<br>- *slave* `int` = 1 | [WriteResponse](#write-response) |\n| `write_register` | - *address* `int`<br>- *value* `int`<br>- *slave* `int` = 1 | [WriteResponse](#write-response) |\n| `write_coils` | - *address* `int`<br>- *values* `list[int] \\| int`<br>- *slave* `int`= 1 | [WriteResponse](#write-response) |\n| `write_registers` | - *address* `int`<br>- *values* `list[int] \\| int`<br>- *slave* `int`= 1 | [WriteResponse](#write-response) |\n\n### Parameters Description\n\n- `address`: Register address _(single integer)_\n- `count`: Number of items to read _(default: 1)_\n- `value`/`values`: Value(s) to write _(single integer or list of integers)_\n- `slave`: Slave unit address _(default: 1)_\n",
"bugtrack_url": null,
"license": null,
"summary": "This is my custom aiomodbus client",
"version": "0.3.2",
"project_urls": {
"GitHub": "https://github.com/MykhLibs/dm-aiomodbus",
"Homepage": "https://pypi.org/project/dm-aiomodbus"
},
"split_keywords": [
"dm",
"aiomodbus"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7b2cf503064647c77d296a64b52da6d3756e53d61a62f7f91744ccf267e2fd2c",
"md5": "c957cf5200e65d9c8bd4c4ee2fff40b0",
"sha256": "f5c583fdfb1703a62fefbc1c62ebe71e08f8a65004fabab2f8ee59f5465b4d4b"
},
"downloads": -1,
"filename": "dm_aiomodbus-0.3.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c957cf5200e65d9c8bd4c4ee2fff40b0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 6706,
"upload_time": "2025-02-22T13:28:01",
"upload_time_iso_8601": "2025-02-22T13:28:01.203410Z",
"url": "https://files.pythonhosted.org/packages/7b/2c/f503064647c77d296a64b52da6d3756e53d61a62f7f91744ccf267e2fd2c/dm_aiomodbus-0.3.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "87ea9bf46322d6f0d4fdab38fd44ac94c5071f9f103990f903439d0b630ffaae",
"md5": "73b4875302e38dd2713aea4fe9180fe2",
"sha256": "23c55d0eb6048398191bece2ea7a499c3652b9d94157bd4e464974f68c9ddc1a"
},
"downloads": -1,
"filename": "dm_aiomodbus-0.3.2.tar.gz",
"has_sig": false,
"md5_digest": "73b4875302e38dd2713aea4fe9180fe2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 5633,
"upload_time": "2025-02-22T13:28:03",
"upload_time_iso_8601": "2025-02-22T13:28:03.195113Z",
"url": "https://files.pythonhosted.org/packages/87/ea/9bf46322d6f0d4fdab38fd44ac94c5071f9f103990f903439d0b630ffaae/dm_aiomodbus-0.3.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-22 13:28:03",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MykhLibs",
"github_project": "dm-aiomodbus",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "dm-logger",
"specs": [
[
"~=",
"0.5.3"
]
]
},
{
"name": "pyserial",
"specs": [
[
"==",
"3.5"
]
]
},
{
"name": "pymodbus",
"specs": [
[
"==",
"3.8.6"
]
]
}
],
"lcname": "dm-aiomodbus"
}