This custom Home Assistant integration enables communication with Modbus devices via a Modbus TCP gateway. It uses YAML configuration files to define device registers and coils, mapping them to Home Assistant entities like sensors, switches, numbers, and more. It supports both monitoring (read-only) and control (read/write) operations.
The easiest way to install this integration is through the Home Assistant Community Store (HACS). After setting up HACS, you can add this integration as a custom repository:
- Go to HACS > Integrations.
- Click the three-dot menu and select "Custom repositories".
- Add repositoriy:
https://github.com/timlaing/modbus_local_gateway
- Set category to "Integration" and click "Add".
- Search for "Modbus Local Gateway" and install.
Or use these buttons (requires My Home Assistant):
Restart Home Assistant after installation.
Add devices via the Home Assistant UI:
- Go to Settings > Devices & Services.
- Click Add Integration, search for "Modbus Local Gateway".
- Or use this button:
- Host: Gateway IP/hostname (e.g.,
192.168.1.100
). - Port: TCP port (default:
502
). - Slave ID: Modbus slave ID (e.g.,
1
). - Prefix: Optional device and entity name prefix (e.g.,
Device 3
).
Choose a device type from the dropdown (e.g., Eastron SDM-230
for SDM230.yaml
).
Adjust the update frequency (default: 30 seconds) via "Configure" at the device in Devices & Services.
To add support for a new device, create a YAML file in custom_components/modbus_local_gateway/device_configs/
. Each file specifies the Modbus registers/coils for a single device, mapping them to corresponding Home Assistant entities.
device:
manufacturer: "Dimplex"
model: "Wärmepumpe SI 11TU"
read_write_word:
set_water_temp: # This key must uniquely identify the entity within the config file
address: 20
name: "Set Water Temperature"
multiplier: 0.1
control: number # Show a number input field in the Home Assistant UI
number:
min: 0
max: 100
Each file requires a device
section and optional register/coil sections:
-
device
section (required):manufacturer
(required): String.model
(required): String.max_register_read
(optional): Max registers per read (default: 8).
-
Register/Coil Sections (optional):
read_write_word
: Holding registers (read/write).read_only_word
: Input registers (read-only).read_write_boolean
: Coils (read/write).read_only_boolean
: Discrete inputs (read-only).
Each register/coil section contains entity definitions, identified by a unique key (e.g., set_water_temp
), mapping registers/coils to Home Assistant entities.
For all entity definitions:
-
address
(required): Modbus address (integer). -
name
(optional): Friendly name (default: the entity definition's key). -
size
(optional): Register count (default: 1; use 2 for raw 32-bitfloat
, or string length / 2 forstring
; not needed forsum_scale
). -
Home Assistant Properties (see HA documentation for more information):
unit_of_measurement
: E.g.,Volts
,h
.device_class
: E.g.,voltage
,power
.state_class
(only for register): E.g.,measurement
,total_increasing
.entity_category
:diagnostic
orconfig
.entity_registry_enabled_default: False
.icon: mdi:thermometer
.
-
Control Types (only for
read_write_word
): Allows the user to control the value.control: number
: Creates a number entity.- E.g.:
control: number number: # Optional min: 10.0 # float max: 100.0 # float
- E.g.:
control: select
: Creates a select entity.- E.g.:
control: select options: # Required 0: "Closed" 1: "Half-Open" 2: "Open"
- E.g.:
control: switch
: Creates a switch entity.- E.g.:
control: switch switch: # Optional "on": 1 # default: 1 "off": 0 # default: 0
- E.g.:
control: text
: Creates a text entity.
-
Data Types:
float: true
: Raw 32-bit float (requiressize: 2
).string: true
: String (requiressize:
= length / 2).- E.g.
string: true size: 5 # For a 10 byte string
- E.g.
-
Math Operations (applied in order):
sum_scale
: List of scaling factors applied to consecutive registers.- E.g.,
sum_scale: [1, 10000]
for two registers starting ataddress: 5
uses r1=5, r2=6, calculating r1 * 1 + r2 * 10000.
- E.g.,
shift_bits
: Bit shift right (integer).bits
: Bit mask length (integer).multiplier
: Scaling factor (float).offset
: Adds an offset (float).
-
Display:
precision
: Decimal places (integer). Only valid forsensor
orcontrol: number
entities.map
: Enum mapping.- E.g.
map: 0: "Enabled" 1: "Disabled" 2: "Auto"
- E.g.
flags
: Bit flags.- E.g.
flags: 1: "Pump active" 3: "Mill active" 4: "Heating active"
- E.g.
-
Behavior:
never_resets: true
: For non-resetting totals. (E.g. for sensors withstate_class: total_increasing
).
- Control Types (only for
read_write_boolean
): Allows the user to control the value.control: switch
: Creates a switch entity.- E.g.:
control: switch switch: # Optional "on": 1 # default: 1 "off": 0 # default: 0
- E.g.:
device:
manufacturer: Rekall
model: MindSync Hub 310
read_write_word:
baud_rate:
address: 28
control: select
options:
0: "2400 bps"
1: "4800 bps"
2: "9600 bps"
power_mode:
address: 30
control: switch
switch:
"on": 1
"off": 0
read_only_word:
voltage:
address: 0
precision: 2
unit_of_measurement: Volts
device_class: voltage
state_class: measurement
read_write_boolean:
power_switch:
address: 10
control: switch
read_only_boolean:
status:
address: 15
device_class: power
See custom_components/modbus_local_gateway/device_configs/
for more examples.
- Logs: Enable debug logging in
configuration.yaml
:logger: default: info logs: custom_components.modbus_local_gateway: debug
- Connection Issues: Verify gateway IP, port, and slave ID.
Tested with a WaveShare Wi-Fi to RS485 Gateway in Modbus TCP to RTU mode:
- Settings: Baud Rate: 9600, Data Bits: 8, Parity: None, Stop Bits: 1, Baudrate Adaptive: Disable, UART AutoFrame: Disable, Modbus Polling: Off, Network A TCP Time out: 5, Network A MAX TCP Num: 24.
- Tested Slaves: Eastron SDM230/SDM630, Finder 7M.38/7M.24, Growatt MIN-6000-TL-XH/MOD-6000-TL-X/MIC-2500-TL-X.
Firmware variations may affect compatibility.
MIT License. See repository for details.