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 repository:
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.
For support and discussions, join our Discord community: Join our Discord community
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). - Device ID: Modbus device 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 /config/modbus_local_gateway/. Each file specifies the Modbus registers/coils for a single device, mapping them to corresponding Home Assistant entities.
Any files in /config/modbus_local_gateway/ will override those as part of this repo (custom_components/modbus_local_gateway/device_configs/).
Once you are happy with your configuration, please consider sharing with others by creating a pull request with your config file.
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: 100Each file requires a device section and optional register/coil sections:
-
devicesection (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). -
scan_interval(optional): Override the default update interval for this entity. Used to increase or decrease the frequency of polling. -
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:diagnosticorconfig.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 step: 5 # optional (defaults to modbus multiplier or 1.0) mode: slider # optional: slider or box (default)
- 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:
signed: true: Signed integer values rather than the default of unsigned (requiressize: 1,size: 2orsize: 4).float: true: Raw 32-bit float (requiressize: 2orsize: 4).string: true: String (requiressize:= length / 2).- E.g.
string: true size: 5 # For a 10 byte string
- E.g.
-
Math Operations (applied in order):
swap: updates the byte ordering of the registers (byte,wordorword_byte)sum_scale: List of scaling factors applied to consecutive registers.- E.g.,
sum_scale: [1, 10000]for two registers starting ataddress: 5uses 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 forsensororcontrol: numberentities.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.:
control: binary_sensor: Creates a binary_sensor entity.- E.g.:
control: binary_sensor "on": False # Optional - default: True "off": True # Optional - default: False
- 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
register_1:
name: "Boolean Register"
address: 0x0004
bits: 1
shift_bits: 4
device_class: running
control: binary_sensor
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: powerSee 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 device 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.
We welcome contributions! Please open an issue to discuss your ideas or submit a PR against the main branch. Ensure your code follows the existing style, passes the test suite, and update this README with any new instructions.
MIT License. See repository for details.