Multi-protocol debugging and simulation tool for Modbus RTU, suitable for both physical serial ports and network-forwarded ports. Provides both CLI and TUI interfaces.
Features
- Modbus RTU (master/slave) debugging and simulation; supports four register types: holding, input, coils, and discrete.
- Full-featured CLI: port discovery and checks (
--list-ports/--check-port), master/slave operations (--master-provide/--slave-listen) and persistent modes (--*-persist). Outputs can be JSON/JSONL, which is script/CI-friendly. - Interactive TUI: configure ports, stations, and registers via terminal UI; supports save/load (
Ctrl+Ssaves and auto-enables ports) and IPC integration with CLI for testing and automation. - Multiple data sources and protocols: physical/virtual serial ports (managed via
socat), HTTP, MQTT, IPC (Unix domain sockets / named pipes), files, and FIFOs. - Port Forwarding: configure source and target ports within the TUI for data replication, monitoring, or bridging.
- Daemon mode: run headless using a saved TUI configuration to start all configured ports/stations (suitable for embedded/CI deployments).
- Virtual port and test tooling: includes
scripts/socat_init.shfor virtual serial ports and example tests inexamples/cli_e2eandexamples/tui_e2efor local/CI testing. - Extensible integrations: forward or receive port data via HTTP/MQTT/IPC for (remote) integrations.
Note: use
--no-config-cacheto disable TUI save/load;--config-file <FILE>and--no-config-cacheare mutually exclusive.
Quick start
-
Install the Rust toolchain
-
Clone the repo and enter the directory
-
Install:
-
Build from source:
cargo install aoba -
Or install a CI-built release (if available) with
cargo-binstall:-
Example:
cargo binstall --manifest-path ./Cargo.toml --version <version> -
Use
--target <triple>to pick a platform-specific artifact (e.g.x86_64-unknown-linux-gnu).
-
-
-
Run
aobato start the TUI by default; use TUI to configure ports and save the configuration as needed.
Persistent configuration (config file)
--config-file <FILE> explicitly selects a TUI config file (daemon mode uses --daemon-config <FILE>). This conflicts with --no-config-cache, which disables loading/saving of TUI config.
Example:
# Start TUI with a specific config file; load/save enabled
# Start TUI with no config caching (default) — no load/save
Run headless with a saved configuration:
Systemd example:
[Unit]
Description=Aoba Modbus RTU Daemon
Wants=network.target
After=network.target network-service
StartLimitIntervalSec=0
[Service]
Type=simple
WorkingDirectory=/home/youruser
ExecStart=/usr/local/bin/aoba --daemon --config-file /home/youruser/config.json
Restart=always
RestartSec=1s
[Install]
WantedBy=multi-user.target
Common use cases
- Automated testing: auto-start Modbus simulators in CI/CD
- Embedded systems: run Aoba as a daemon on embedded devices (e.g., Raspberry Pi) with USB-serial adapters
Programmatic API
Aoba provides a trait-based Rust API for embedding Modbus functionality in your applications. The API supports both master (client) and slave (server) roles with customizable hooks and data sources.
Quick API Examples
Modbus Master (polling a slave):
use ;
async
Modbus Slave (responding to requests):
use ;
async
Running the API Examples
Method 1: Using the test script (recommended)
A Python test script is provided to run both master and slave examples simultaneously with colored, prefixed output:
# Run for 30 seconds
# Run indefinitely (Ctrl+C to stop)
# Custom ports
# Skip auto-build (use existing binaries)
Note: You may see "Operation timed out" warnings in the logs. This is normal behavior:
- The slave times out while waiting for master requests (1s timeout)
- The master times out while waiting for slave responses (2s timeout)
- Both automatically retry and continue operation
- Communication succeeds despite these warnings
Method 2: Manual execution
Run in separate terminals:
# Terminal 1: Start slave first
# Terminal 2: Start master
Note: On Linux/WSL, initialize virtual serial ports first:
Complete Examples
For full examples with middleware hooks and data sources, see:
examples/api_master- Master with logging hooksexamples/api_slave- Slave with request monitoring and statistics