Files
zihluwang d781d2fadc
Build and Push Docker Image / build (push) Canceled after 0s
fix(docker): multi-stage build and publish tags
- Split Dockerfile into builder and runtime stages
- Put .venv on PATH so pymodbus resolves in the container
- Push image to Docker Hub and GHCR with latest and 7-char SHA tags
- Use real repo/image names in README
2026-08-31 11:59:37 +08:00

101 lines
2.5 KiB
Markdown

# Modbus Slave Simulator
A configurable Modbus slave simulator for testing Modbus TCP, RTU, and TLS connections.
## Features
- **Multiple Protocols**: TCP, RTU (serial), and TLS support
- **Configurable Data Store**: Customisable sizes for coils, discrete inputs, holding registers, and input registers
- **Initial Values**: Set default values for all data types
- **Device Identity**: Configurable vendor name, product code, model, and version
- **Docker Support**: Ready-to-use Docker image
## Installation
### From Source
```bash
git clone https://github.com/zihluwang/modbus-slave
cd modbus-slave
pip install -r requirements.txt
```
### With Docker
```bash
docker pull zihluwang/modbus-slave
```
## Usage
### Command Line
```bash
# TCP server (default: 127.0.0.1:5020)
python main.py
# Custom port
python main.py --port 5020
# RTU mode
python main.py --type rtu --serial-port /dev/ttyUSB0 --slave-id 2
# Custom data store sizes
python main.py --holding-registers-size 1000 --input-registers-size 500
# Set initial values
python main.py --holding-registers-default 100 --coils-default true
```
### Docker
```bash
# Run with defaults
docker run -p 5020:5020 zihluwang/modbus-slave
# Run with custom arguments
docker run -p 5020:5020 zihluwang/modbus-slave --holding-registers-size 1000
```
## Command Line Options
| Option | Description | Default |
|--------|-------------|---------|
| `-t, --type` | Server type (tcp, rtu, tls) | tcp |
| `-h, --host` | TCP bind host | 127.0.0.1 |
| `-p, --port` | TCP/TLS port | 5020 |
| `-s, --slave-id` | Modbus slave ID | 1 |
| `--serial-port` | Serial port (RTU) | /dev/ttyUSB0 |
| `--baudrate` | Serial baudrate | 9600 |
| `--coils-size` | Number of coils | 100 |
| `--holding-registers-size` | Number of holding registers | 100 |
| `--input-registers-size` | Number of input registers | 100 |
| `--holding-registers-default` | Default value for holding registers | 0 |
| `-v, --verbose` | Increase verbosity | - |
## Modbus Data Model
| Function Code | Data Type | Access |
|--------------|-----------|--------|
| 0x01/0x05/0x0F | Coil | Read/Write |
| 0x02 | Discrete Input | Read Only |
| 0x03/0x06/0x10 | Holding Register | Read/Write |
| 0x04 | Input Register | Read Only |
## Testing
Test with `pymodbus` client:
```python
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('127.0.0.1', port=5020)
result = client.read_holding_registers(0, 10)
print(result.registers)
client.close()
```
## Licence
See [LICENCE](LICENCE) file.