A powerful multi-device Modbus TCP proxy for Home Assistant with enhanced logging and client tracking. Allows multiple clients to connect to Modbus servers that typically only support a single connection.
This is version 2.2.6 with comprehensive TCP-to-RTU device support and full serial device access.
✅ Key Features:
- Protocol Auto-Detection: Automatically handles TCP and RTU over TCP from Home Assistant
- Universal Support: All protocol combinations supported (TCP ↔ RTU ↔ RTU over TCP)
- IPv6 Compatibility: Full dual-stack IPv4 and IPv6 support
- Enhanced Debugging: Detailed protocol transformation logging
Installation:
- Add the repository:
https://github.com/TCzerny/ha-modbusproxy - Install via Home Assistant Supervisor
- Configure your Modbus devices
Note: Home Assistant Supervisor automatically installs the latest stable version.
Critical Serial Device Access Fix:
- 🔓 absolute/relative Path issue fixed - Fixed an issue in
modbus_proxy.pyto resolve FileNotFoundError error for/dev/serial/by-id/*
Critical Serial Device Access Fix:
- 🔓 UART & udev Support - Added
uart: trueandudev: trueto resolve FileNotFoundError for/dev/serial/by-id/*symlinks - 🔍 Startup Diagnostics - Now shows all available serial devices at startup for easier troubleshooting
Enhanced USB-to-RTU Device Support:
- 🔌 Comprehensive Device Coverage: Added support for all major USB-to-Serial chipsets
- 📡 Extended Serial Ports: Support for ttyAMA3-5, ttyS4-7 for newer hardware
- 🛡️ Stable Device Identifiers: Enhanced by-id symlink support for reliable device mapping
- ⚡ Plug & Play: Automatic detection of CH340, CH341, FTDI, Silicon Labs, Prolific chipsets
- 🔧 Hot-Swappable: Better support for multiple USB-Serial adapters
Supported USB-to-RTU Chipsets:
- ✅ CH340/CH341 - Most common USB-Serial adapters
- ✅ FTDI FT232/FT2232 - Professional-grade adapters
- ✅ Silicon Labs CP2102/CP2104 - High-quality converters
- ✅ Prolific PL2303 - Widely used adapters
- ✅ Onboard UARTs - Raspberry Pi GPIO, ttyAMA0-5
- ✅ Classic Serial - ttyS0-7 for legacy hardware
RTU over TCP Communication Fix:
- 🔧 Fixed RTU over TCP Issue: Resolved communication problem where RTU over TCP → RTU over TCP didn't work
- 🎯 Smart Format Detection: Eliminated duplicate format detection for better performance
- 🔄 Intelligent Response Handling: Now properly detects client format and responds accordingly
- ⚡ Optimized Processing: Reduced redundant format detection calls
Enhanced Protocol Support:
- 📡 Complete RTU over TCP Support: All RTU over TCP communication scenarios now work correctly
- 🔍 Consistent Format Handling: Both request and reply transformations use unified format detection
- 🛡️ Backward Compatibility: All existing functionality remains unchanged
IPv6 & Connectivity:
- 🌐 IPv6 Support: Fixed dual-stack IPv4/IPv6 binding for all client types
- 🔗 Universal Connectivity: Clients can connect via IPv4 or IPv6
- 🔧 Network Compatibility: Resolves connection issues with IPv6-enabled Home Assistant instances
Protocol Features (2.2.1):
- 🔍 Auto-Detection: Client automatically detects TCP vs RTU over TCP from Home Assistant
- 🔄 Smart Transformation: Automatic conversion between all protocol formats (TCP ↔ RTU ↔ RTU over TCP)
- 📊 Enhanced Debug Logging: Shows exact protocol transformations (
TCP → RTU Serial, etc.)
Device Support:
- 🔌 RTU Protocol Support: Connect to Modbus RTU devices via serial ports
- 📡 RTU over TCP Support: Support for RTU over TCP connections
- ⚙️ Configurable Serial Parameters: Baudrate, databits, stopbits, parity
- 🔍 Auto-Detection: Automatically detect serial devices for plug & play setup
Enhanced Logging & Debug Features:
- 🔍 Client IP Tracking: Every log entry shows the client's IP address and port
- 📊 Debug Value Parsing: At DEBUG level, see actual Modbus register values and coil states
- 🎯 Detailed Request/Response Logging: Transaction IDs, Unit IDs, Function Codes
- ⚡ Performance Monitoring: Response times and connection statistics
- 🔍 Enhanced INFO Messages: Clear Client ↔ Proxy ↔ Device tracking
- 📈 Request Counting: Track number of requests per client connection
Example Debug Output (TCP → TCP):
2024-12-19 10:30:16 DEBUG Client(192.168.1.50:45231): ← TCP Request #1: 12 bytes
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.100:502): TRANSFORM: TCP → TCP (TCP passthrough)
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.100:502): Registers: [12345, 67890, 11111, 22222]
Example Debug Output (TCP → RTU Serial):
2024-12-19 10:30:16 DEBUG Client(192.168.1.50:45231): ← TCP Request #1: 12 bytes
2024-12-19 10:30:16 DEBUG ModBus(RTU:/dev/ttyUSB0): TRANSFORM: TCP → RTU Serial (TCP → RTU conversion)
2024-12-19 10:30:16 DEBUG ModBus(RTU:/dev/ttyUSB0): TRANSFORM REPLY: RTU Serial → TCP (RTU → TCP conversion)
2024-12-19 10:30:16 DEBUG ModBus(RTU:/dev/ttyUSB0): RTU Registers: [12345]
Example Debug Output (RTU over TCP → RTU over TCP):
2024-12-19 10:30:16 DEBUG Client(192.168.1.50:45231): ← RTU over TCP Request #1: 8 bytes
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.200:502): TRANSFORM: RTU over TCP → RTU over TCP (RTU passthrough)
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.200:502): TRANSFORM REPLY: RTU over TCP → RTU over TCP (RTU passthrough)
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.200:502): RTU Registers: [12345, 67890]
Most Modbus TCP servers only allow a single client connection and reject additional clients. This add-on creates a proxy that can handle multiple client connections simultaneously while maintaining a single connection to each Modbus server.
Key Features:
- 🔄 Multiple client connections to single Modbus server
- 🌐 Support for multiple Modbus devices (TCP and RTU)
- ⚙️ Easy configuration through Home Assistant UI
- 🔧 Configurable timeouts and connection parameters
- 📊 Enhanced logging with client tracking and debug value parsing
- 🚀 Host network mode for optimal performance
- 🔍 Real-time client IP monitoring and request tracking
- 🔌 RTU/Serial Modbus support with configurable serial parameters
- 🔍 Auto-Detection: Plug & play serial device detection
- ⚡ Asyncio Serial: Non-blocking serial communication
- 🛡️ Udev Integration: Automatic device permissions
- 📈 Request Counting: Track requests per client connection
- Navigate to Settings → Addons → Add-on Store in your Home Assistant
- Click the ⋮ menu in the top right corner
- Select Repositories
- Add this repository URL:
https://github.com/TCzerny/ha-modbusproxy - Find Modbus Proxy in the add-on store
- Click Install
- name: "Solar Inverter"
host: "192.168.1.100"
bind_port: 502| Parameter | Required | Default | Description |
|---|---|---|---|
name |
No | Device X |
Friendly name for the device |
host |
Yes (for TCP) | - | IP address of the Modbus server |
port |
No | 502 |
Modbus TCP port of the server |
bind_port |
Yes | - | Local port where proxy will listen |
unit_id_remapping |
No | - | Map incoming unit ID to target unit ID (e.g., 1: 10) |
connection_time |
No | 0.1 |
Time to establish connection in seconds |
log_level |
No | info |
Logging level: debug, info, warning, error |
| Parameter | Required | Default | Description |
|---|---|---|---|
name |
No | Device X |
Friendly name for the device |
protocol |
No | Auto-detected | Protocol type: tcp, rtu, or rtutcp |
device |
No* | - | Serial device path (e.g., /dev/ttyUSB0) |
baudrate |
No | 9600 |
Serial baudrate |
databits |
No | 8 |
Number of data bits |
stopbits |
No | 1 |
Number of stop bits |
parity |
No | N |
Parity: N (None), E (Even), O (Odd) |
bind_port |
Yes | - | Local port where proxy will listen |
unit_id_remapping |
No | - | Map incoming unit ID to target unit ID |
timeout |
No | 5.0 |
Connection timeout in seconds |
connection_time |
No | 0.1 |
Time to establish connection in seconds |
log_level |
No | info |
Logging level: debug, info, warning, error |
*device is optional when auto_detect_device: true is enabled
The add-on can automatically detect serial devices for plug & play setup:
# Enable auto-detection
auto_detect_device: true
modbus_devices:
- name: "Auto-Detected Solar Inverter"
protocol: "rtu"
baudrate: 9600
databits: 8
stopbits: 1
parity: "N"
bind_port: 502
timeout: 5.0
connection_time: 0.1Auto-Detection Priority:
/dev/serial/by-id/*- Stable device identifiers (CH340, CH341, FTDI, Silicon Labs, Prolific)/dev/ttyUSB0-9- USB-to-Serial adapters (CH340, FTDI, etc.)/dev/ttyACM0-4- CDC-ACM devices (Arduino, CH340/CP210x)/dev/ttyAMA0-5- Onboard UARTs (Raspberry Pi GPIO)/dev/ttyS0-7- Classic serial ports- Any
/dev/ttyUSB*,/dev/ttyACM*,/dev/ttyAMA*, or/dev/ttyS*device
Benefits:
- 🔌 Plug & Play: No manual device path configuration
- 🔄 Hot-Swappable: Automatically adapts to device changes
- 🛡️ Error Prevention: Reduces configuration mistakes
- ⚡ Quick Setup: Faster initial configuration
The unit_id_remapping feature allows you to map incoming unit IDs to different target unit IDs on the Modbus server. This is useful when:
- Your Modbus client expects a specific unit ID (e.g., 1)
- The actual Modbus server has the device on a different unit ID (e.g., 10)
- You want to virtualize unit IDs for different clients
Syntax: unit_id_remapping: "1<>10" means:
- When a client sends a request to unit ID 1, it gets forwarded to unit ID 10 on the server
- All responses from unit ID 10 appear as if they came from unit ID 1
Multiple Mappings: unit_id_remapping: "1<>10,2<>20,3<>30" for multiple unit ID mappings
JSON Syntax (Legacy): unit_id_remapping: "{\"1\": 10}" - still supported for backward compatibility
Note: Each device can only have one remapping configuration.
modbus_devices:
- name: "Inverter 1"
host: "192.168.1.100"
port: 502
bind_port: 503
unit_id_remapping: "{\"1\": 10}"
timeout: 10.0
connection_time: 2.0
- name: "Inverter 2"
host: "192.168.1.101"
bind_port: 504
timeout: 10.0
connection_time: 2.0
- name: "Inverter 3"
host: "192.168.1.102"
bind_port: 505
log_level: "info"modbus_devices:
- name: "TCP Solar Inverter"
host: "192.168.1.100"
port: 502
bind_port: 502
timeout: 10.0
connection_time: 2.0
- name: "RTU Energy Meter"
device: "/dev/ttyUSB0"
baudrate: 9600
databits: 8
stopbits: 1
parity: "N"
bind_port: 503
timeout: 5.0
connection_time: 1.0
- name: "RTU over TCP Gateway"
host: "192.168.1.200"
port: 502
protocol: "rtutcp"
bind_port: 504
timeout: 5.0
connection_time: 1.0
- name: "RTU Temperature Sensor"
device: "/dev/ttyACM0"
baudrate: 115200
databits: 8
stopbits: 1
parity: "E"
bind_port: 505
timeout: 3.0
connection_time: 0.5
log_level: "debug"
Before starting the proxy, stop all clients currently connected to your Modbus servers. The server needs time to release existing connections.
- Go to Settings → Addons → Modbus Proxy
- Click the Configuration tab
- Add your Modbus devices using the examples above
- Click Save
- Click the Info tab
- Click Start
- Monitor the logs for successful connections
Configure your Modbus clients to connect to:
- Host: Your Home Assistant IP address
- Port: The
bind_portyou configured for each device
OSError: [Errno 98] error while attempting to bind on address ('0.0.0.0', 502): address in use
Solution: Change the bind_port to an unused port (e.g., 505, 506, etc.)
Connection refused to 192.168.1.100:502
Solutions:
- Verify the Modbus server IP address and port
- Ensure the Modbus server is running and accessible
- Check firewall settings on both devices
- Stop other clients connected to the Modbus server
Solutions:
- Increase the
timeoutvalue in configuration - Increase the
connection_timevalue - Check network connectivity and latency
Problem: Second inverter (slave) connection fails in Master-Slave setups (e.g., Sungrow hybrid inverters)
Related Issue: #4 - Connection to second inverter fails
Symptoms:
- First inverter connects successfully
- Second inverter shows connection errors
- Timeout or connection refused errors
Solutions:
- Reduce
connection_time- Set to0.1or0.0for faster connection establishment - Increase
timeout- Set to15.0or higher for slower responding devices - Check inverter settings - Ensure both inverters are properly configured for Master-Slave mode
- Network delays - Some inverters need time between connection attempts
Recommended Configuration for Master-Slave:
modbus_devices:
- name: "Master Inverter"
host: "192.168.1.100"
port: 502
bind_port: 502
timeout: 15.0
connection_time: 0.1 # Reduced for faster connection
- name: "Slave Inverter"
host: "192.168.1.101"
port: 502
bind_port: 503
timeout: 15.0
connection_time: 0.1 # Reduced for faster connectionThe add-on provides multiple logging levels for different monitoring needs:
| Level | Description | Use Case |
|---|---|---|
debug |
Detailed Modbus parsing | See actual register values and function codes |
info |
Connection status | Basic connection and error information |
warning |
Warnings only | Important issues that don't break functionality |
error |
Errors only | Critical problems only |
Perfect for monitoring which devices connect to your proxy and their status:
log_level: "info"Example INFO Output:
2024-12-19 10:30:15 INFO modbus-proxy.ModBus - Ready to accept requests on 0:502 for Device(192.168.1.100:502)
2024-12-19 10:30:16 INFO modbus-proxy.Client - new client connection from 192.168.1.50:45231 -> to Proxy
2024-12-19 10:30:16 INFO modbus-proxy.ModBus - connecting Proxy to Modbus Device(192.168.1.100:502)...
2024-12-19 10:30:16 INFO modbus-proxy.ModBus - connected to Device(192.168.1.100:502)!
Example INFO Output (RTU):
2024-12-19 10:30:15 INFO modbus-proxy.ModBus - Ready to accept requests on 0:503 for Device(/dev/ttyUSB0)
2024-12-19 10:30:16 INFO modbus-proxy.Client - new client connection from 192.168.1.51:45232 -> to Proxy
2024-12-19 10:30:16 INFO modbus-proxy.ModBus - connecting to RTU device /dev/ttyUSB0...
2024-12-19 10:30:16 INFO modbus-proxy.ModBus - connected to RTU device /dev/ttyUSB0!
For detailed analysis of Modbus messages and values:
log_level: "debug"What you'll see in DEBUG mode:
- Client Connections:
Client(192.168.1.50:45231): new client connection from 192.168.1.50:45231 - Request Details:
received_from_client: TxID=1, Unit=1, FC=03(Transaction ID, Unit ID, Function Code) - Response Values:
Registers: [12345, 67890, 11111, 22222]orValues: [1, 0, 1, 1, 0, 1] - Performance: Response times and connection statistics
Check the add-on logs:
- Go to Settings → Addons → Modbus Proxy
- Click the Log tab
- Look for detailed client tracking and modbus value information
Example Debug Session:
2024-12-19 10:30:15 INFO Client(192.168.1.50:45231): new client connection from 192.168.1.50:45231
2024-12-19 10:30:16 DEBUG Client(192.168.1.50:45231): received request from 192.168.1.50:45231 - 12 bytes
2024-12-19 10:30:16 DEBUG Client(192.168.1.50:45231): received_from_client: TxID=1, Unit=1, FC=03
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.100:502): sent_to_device: TxID=1, Unit=1, FC=03
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.100:502): received: TxID=1, Unit=1, FC=03
2024-12-19 10:30:16 DEBUG ModBus(192.168.1.100:502): Registers: [12345, 67890, 11111, 22222]
2024-12-19 10:30:16 INFO Client(192.168.1.50:45231): Response: 15 bytes, 45.2ms
Important Notes for RTU Devices:
- 🔌 Serial Port Access: The add-on needs access to serial ports on the host
- 🔓 UART & udev Support: The add-on uses
uart: trueandudev: truefor proper serial device access (following HA best practices) - 📁 Device Paths: Comprehensive support for all common paths:
/dev/ttyUSB0-9- USB-to-Serial adapters/dev/ttyACM0-4- CDC-ACM devices/dev/ttyAMA0-5- Onboard UARTs (Raspberry Pi)/dev/ttyS0-7- Classic serial ports/dev/serial/by-id/*- Stable device identifiers (recommended!)
- 🔧 Permissions: Automatic permission handling with UART and udev integration
- 📊 Baudrate: Must match your device's communication speed
- 🔄 Parity: Common values are
N(None),E(Even),O(Odd) - ⚡ Asyncio Support: Non-blocking serial communication for better performance
Supported USB-to-RTU Chipsets:
- ✅ CH340/CH341 - Most common USB-Serial adapters (1a86)
- ✅ FTDI FT232/FT2232 - Professional-grade adapters
- ✅ Silicon Labs CP2102/CP2104 - High-quality converters
- ✅ Prolific PL2303 - Widely used adapters
- ✅ Onboard UARTs - Raspberry Pi GPIO, ttyAMA0-5
- ✅ Classic Serial - ttyS0-7 for legacy hardware
Enhanced Features:
- 🔍 Auto-Detection: Automatically find and configure serial devices
- 🛡️ Udev Rules: Automatic permission setting for USB-Serial adapters
- ⚡ Asyncio Serial: Improved performance with non-blocking I/O
- 🔄 Hot-Plug: Support for device hot-swapping
- 📈 Request Tracking: Monitor serial communication activity
Troubleshooting RTU Connections:
- Check if the serial device exists:
ls -la /dev/tty* - Check stable device identifiers:
ls -la /dev/serial/by-id/ - Verify device permissions:
ls -la /dev/ttyUSB0 - Test serial communication:
stty -F /dev/ttyUSB0 9600 - Check for device conflicts:
dmesg | grep tty - Monitor auto-detection: Check logs for "Auto-detecting serial device"
- Review device list in logs: The add-on shows all available devices at startup
Common Issue: FileNotFoundError for Serial Devices
If you get a FileNotFoundError when trying to access serial devices:
- Check Add-on Logs: The add-on lists all available devices at startup
- Use Stable Paths: Prefer
/dev/serial/by-id/*over/dev/ttyUSB*for reliability - Verify Device Exists: On the host, run
ls -la /dev/serial/by-id/to see available devices
Enhanced Serial Communication:
- ⚡ Asyncio Serial: Non-blocking serial I/O using
pyserial-asyncio - 🔄 Fallback Support: Graceful fallback to synchronous serial if needed
- 🛡️ Permission Management: Automatic device permission handling
- 🔍 Device Validation: Comprehensive device existence and permission checks
Udev Integration:
- 🔧 Automatic Permissions: udev rules for common USB-Serial adapters
- 🔌 Hot-Plug Support: Automatic device detection and configuration
- 🛡️ Permission Fixing: Attempts to fix device permissions automatically
- 📋 Device Mapping: Support for
/dev/serial/by-id/stable identifiers
Enhanced Error Handling:
- 🔍 Device Validation: Checks device existence and permissions
- 🛡️ Graceful Degradation: Fallback mechanisms for various scenarios
- 📊 Detailed Logging: Comprehensive error reporting and debugging
- 🔄 Connection Recovery: Automatic reconnection attempts
This add-on uses host_network: true which means:
- ✅ Direct access to host network interfaces
- ✅ No need to configure port mappings in add-on settings
- ✅ Optimal performance with minimal network overhead
⚠️ Ports must be unique across all services on your host
This add-on uses uart: true and udev: true to enable access to all serial devices including symlinks in /dev/serial/by-id/, following Home Assistant Add-on security best practices.
What uart: true and udev: true mean:
- ✅ Access to UART/serial devices in
/dev/* - ✅ Access to udev system for dynamic device detection
- ✅ Proper permissions following Home Assistant security guidelines
Is this safe?
- ✅ Uses recommended HA add-on permissions for serial device access
- ✅ The add-on only accesses serial devices for Modbus communication
- ✅ No unnecessary system access beyond serial devices
- ✅ Open-source code - you can review all operations
- Check the logs first for error messages
- Review this README for configuration examples
- Search existing issues on GitHub
- Create a new issue with:
- Your configuration (remove sensitive data)
- Complete log output
- Description of the problem
When reporting issues, please include:
# Your anonymized configuration
modbus_devices:
- name: "Device 1"
host: "192.168.1.XXX" # Replace with XXX
port: 502
bind_port: 5020
# ... rest of configAnd the complete log output from the add-on.
This add-on is based on:
- Original add-on: Akulatraxas/ha-modbusproxy
- Modbus Proxy Library: tiagocoutinho/modbus-proxy
See the LICENSE file for details.
