Modbus


Modbus is a serial communication protocol to control PLCs (Programmable Logic Controller) and RTUs (Remote Terminal Unit). The integration adheres strictly to the protocol specification. Modbus supports all devices adhering to the Modbus standard. The communication between the device(s) can be serial (rs-485), TCP, or UDP connections. The Modbus integration allows multiple communications e.g. serial combined with TCP or different TCP connected devices.

Configuring Modbus

First, you define how to communicate with your Modbus devices and after that you define the information being exchanged. The Modbus integration allows you to use multiple connections.

Configuring Modbus common parameters

Part of the configuration is common for all types of communication. Add the following to your configuration.yaml file:

modbus:
  - name: "hub1"
    close_comm_on_error: true
    delay: 5
    timeout: 5
    type: tcp

Configuration Variables

close_comm_on_error boolean (Optional, default: true)

Determines if the device connection is closed when an error occurs, default is true. Some serial-rs485 adapters deliver garble when opened, this leads to a disconnect and a new connect, which can continue. If in a running communication the debug log contains a message from pymodbus, with the text “cleaning….”, then try this parameter.

delay integer (Optional, default: 0)

Time to delay sending messages in seconds after connecting. Some Modbus devices need a delay of typically 1-2 seconds after established connection to prepare the communication. If a device does not respond to messages after connecting, this parameter might help. Remark: the delay is solely between connect and the first message.

message_wait_milliseconds integer (Optional)

Time to wait in milliseconds between requests.

Default:

30 for serial connection, 0 for everything else.

name string (Optional, default: modbus_hub)

Name for this hub. Must be unique, so it is required when setting up multiple instances.

retries integer (Optional, default: 3)

Number of times to retry a request.

retry_on_empty boolean (Optional, default: false)

Retry request, when receiving and empty message.

timeout integer (Optional, default: 5)

Timeout while waiting for a response in seconds.

type string Required

Type of communication. Possible values are tcp Modbus messages with Modbus TCP frame on TCP/IP, udp Modbus messages with Modbus TCP frame on UDP, rtuovertcp Modbus messages with a wrapper TCP/IP simulating a serial line, serial Modbus serial (RS485).

Configuring network connection

For a network (type: tcp/udp/rtuovertcp) connection, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry for a TCP connection
modbus:
  - name: "hub1"
    type: tcp
    host: IP_ADDRESS
    port: 502

Configuration Variables

host string Required

The IP address of your Modbus device, e.g., 192.168.1.1.

port integer Required

The network port for the communication.

type string Required

Type of the connection to Modbus, needs to be tcp or udp or rtuovertcp for this setup.

Configuring serial connection

For a serial connection, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry for a serial connection
modbus:
  - name: hub1
    type: serial
    baudrate: 9600
    bytesize: 8
    method: rtu
    parity: E
    port: /dev/ttyUSB0
    stopbits: 1

Configuration Variables

baudrate integer Required

The speed for the serial connection.

bytesize integer Required

The bytesize for the serial connection; can be 5, 6, 7 or 8.

method string Required

Method of the connection to Modbus, either rtu or ascii.

parity string Required

The parity for the serial connection; can be E, O or N.

port string Required

The port where your Modbus device is connected to your Home Assistant host.

stopbits integer Required

The stopbits for the serial connection, either 1 or 2.

type string Required

Type of the connection to Modbus, needs to be serial for this setup.

Configuring multiple connections

Multiple connections are possible with identical/different type:.

# Example configuration.yaml entry for multiple TCP connections
modbus:
  - type: tcp
    host: IP_ADDRESS_1
    port: 2020
    name: "hub1"

  - type: udp
    host: IP_ADDRESS_2
    port: 501
    name: hub2

Remark: name:is required for multiple connections, because it needs to be unique.

Modbus services

The Modbus integration provides two generic write services in addition to the platform-specific services.

Service Description
modbus.write_register Write register or registers
modbus.write_coil Write coil or coils

Description:

Attribute Description
hub Hub name (defaults to ‘modbus_hub’ when omitted)
unit Slave address (0-255), alternative to slave
slave Slave address (0-255), alternative to unit
address Address of the Register (e.g. 138)
value (write_register) A single value or an array of 16-bit values. Single value will call modbus function code 0x06. Array will call modbus function code 0x10. Values might need reverse ordering. E.g., to set 0x0004 you might need to set [4,0], this depend on the byte order of your CPU
state (write_coil) A single boolean or an array of booleans. Single boolean will call modbus function code 0x05. Array will call modbus function code 0x0F

The Modbus integration also provides communication stop/restart services. These services will not do any reconfiguring, but simply stop/start the modbus communication layer.

Service Description
modbus.stop Stop communication
modbus.restart Restart communication (Stop first if running)

Description:

Attribute Description
hub Hub name (defaults to ‘modbus_hub’ when omitted)

Example: writing a float32 type register

To write a float32 datatype register use network format like 10.0 == 0x41200000 (network order float hexadecimal).

service: modbus.write_register
data:
  address: <target register address>
  unit: <target slave address>
  hub: <hub name>
  value: [0x4120, 0x0000]

configure Modbus platforms

Modbus platform entities are configured within the Modbus configuration.

Configuring platform common parameters

All modbus platforms share a set of common parameters.

# Example configuration.yaml entry for platform common parameters
modbus:
  - type: tcp
    host: IP_ADDRESS_1
    port: 2020
    name: "hub1"
    sensors:
      - name: sensor1
        scan_interval: 999
        slave: 0

Configuration Variables

lazy_error_count integer (Optional, default: 0)

Number of messages with error received before setting entity to unavailable. This parameter can be used to prevent spontaneous errors to ruin statistic graphs.

name string Required

Name for the platform entity which must be unique within the platform.

scan_interval integer (Optional, default: 15)

Defines the update interval of the entity in seconds, if scan_interval = 0 polling is stopped. Entities are unavailable until the first response is received, except for entities with scan_interval = 0, these entities are available from startup.

slave integer (Optional, default: 0)

The number of the slave.

unique_id string (Optional)

An ID that uniquely identifies this sensor. Slaves will be given a unique_id of <<unique_id>>_<<slave_index>>. If two sensors have the same unique ID, Home Assistant will raise an exception.

Configuring data_type and struct

Climate and Sensor share setup of data_type and struct.

# Example configuration.yaml entry for platform common parameters
modbus:
  - type: tcp
    host: IP_ADDRESS_1
    port: 2020
    name: "hub1"
    sensors:
      - name: sensor1
        data_type: int

Configuration Variables

data_type string (Optional, default: int16)

Response representation (int8, int16, int32, int64, uint8, uint16, uint32, uint64, float16, float32, float64, string). int/uintare silently converted to int16/uint16.

offset float (Optional, default: 0)

Final offset (output = scale * value + offset).

precision integer (Optional, default: 0)

Number of valid decimals.

scale float (Optional, default: 1)

Scale factor (output = scale * value + offset).

structure string (Optional)

If data_type is custom specified a double-quoted Python struct is expected here, to format the string to unpack the value. See Python documentation for details. Example: >i.

Default:

f

swap string (Optional, default: none)

Swap the order of bytes/words, options are none, byte, word, word_byte.

unique_id string (Optional)

An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception.

Configuring platform binary sensor

The Modbus binary sensor allows you to gather data from coils which as per standard have state ON/OFF.

To use your Modbus binary sensors in your installation, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry for binary_sensor configuration
modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    binary_sensors:
      - name: "binary_sensor1"
        address: 100
        scan_interval: 20
        slave: 1
      - name: "binary_sensor2"
        address: 110
        device_class: door
        input_type: discrete_input
      - name: "binary_sensor3"
        address: 120
        slave: 2
        device_class: running
        scan_interval: 10
        input_type: input

Configuration Variables

binary_sensors map (Optional)

A list of all binary_sensors available in this modbus instance, omit if there are no binary_sensors.

address integer Required

Address of the Register.

device_class string (Optional)

The type/class to be used for the UI (e.g. “door”).

input_type string (Optional, default: coil)

type of address (discrete_input/coil/holding/input)

unique_id string (Optional)

An ID that uniquely identifies this sensor. Slaves will be given a unique_id of <<unique_id>>_<<slave_index>>. If two sensors have the same unique ID, Home Assistant will raise an exception.

slave_count integer (Optional)

Generates x+1 binary sensors (master + slaves), allowing read of multiple coils with a single read messsage.

Configuring platform climate

The Modbus climate platform allows you to monitor your thermostat as well as set a target temperature.

To use your Modbus thermostat in your installation, add the following to your configuration.yaml file, in addition to the common parameters and response regresentation:

# Example configuration.yaml entry
modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    climates:
      - name: "Watlow F4T"
        address: 27586
        input_type: holding
        count: 1
        data_type: custom
        max_temp: 35
        min_temp: 15
        offset: 0
        precision: 1
        scale: 0.1
        max_temp: 30
        structure: ">f"
        target_temp_register: 2782
        temp_step: 1
        temperature_unit: C
      - name: "Bedroom Air Condition"
        address: 10
        target_temp_register: 10
        hvac_mode_register:
          address: 11
          values:
            state_auto: 0
            state_cool: 1
            state_heat: 2
            state_fan_only: 3
            state_dry: 4
            state_off: 5
          write_registers: true
        hvac_onoff_register: 11
        write_registers: true

Configuration Variables

climates map (Optional)

A list of all climates available in this modbus instance.

address integer Required

Register address for current temperature (process value).

count integer (Optional)

Number of registers to read.

Default:

1 or calculated if data_type is not struct.

input_type string (Optional, default: holding)

Modbus register type (holding, input) for current temperature.

max_temp integer (Optional, default: 35)

Maximum setpoint temperature.

min_temp integer (Optional, default: 5)

Minimum setpoint temperature.

target_temp_register integer Required

Register address for target temperature (Setpoint).

temp_step float (Optional, default: 0.5)

The supported step size a target temperature can be increased/decreased.

temperature_unit string (Optional, default: C)

Temperature unit reported by the current_temp_register. C or F

hvac_mode_register map (Optional)

Definition of a register holding and controlling an HVAC mode

address integer Required

The address of the HVAC mode register.

write_registers boolean (Optional, default: false)

if true use write_registers

values map Required

A mapping between the register values and HVAC modes

state_off integer (Optional)

The register value corresponding to HVAC Off mode.

state_heat integer (Optional)

The register value corresponding to HVAC Heat mode.

state_cool integer (Optional)

The register value corresponding to HVAC Cool mode.

state_auto integer (Optional)

The register value corresponding to HVAC Auto mode.

state_dry integer (Optional)

The register value corresponding to HVAC Dry mode.

state_fan_only integer (Optional)

The register value corresponding to HVAC Fan only mode.

state_heat_cool integer (Optional)

The register value corresponding to HVAC Heat/Cool mode.

hvac_onoff_register integer (Optional)

Address of a register holding and controlling the On/Off state of the climate device. When zero is read from this register, the HVAC state is set to Off, otherwise the hvac_mode_register dictates the state of the HVAC. If no such register is defined, it defaults to Auto. When the HVAC mode is set to Off, the value 0 is written to the register, otherwise the value 1 is written.

write_registers boolean (Optional, default: false)

if true use write_registers for hvac_onoff.

unique_id string (Optional)

An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception.

Service modbus.set-temperature

Service Description
set_temperature Set Temperature. Requires value to be passed in, which is the desired target temperature. value should be in the same type as data_type

Service modbus.set_hvac_mode

Service Description
set_hvac_mode Set HVAC mode. Requires value to be passed in, which is the desired mode. value should be a valid HVAC mode. A mapping between the desired state and the value to be written to the HVAC mode register must exist. Calling this service will also set the On/Off register to an appropriate value, if such a register is defined.

Configuring platform cover

The modbus cover platform allows you to control covers (such as blinds, a roller shutter, or a garage door).

At the moment, platform cover support the opening and closing of a cover. You can control your covers either using coils or holding registers.

Cover that uses input_type: coil is not able to determine intermediary states such as opening and closing. Coil stores only two states — “0” means cover closed, and “1” implies cover open. To allow detecting intermediary states, there is an optional status_register attribute. It will enable you to write your command (e.g., to open a cover) into a coil, and read current cover status back through the register. Additionally, you can specify values for state_open, state_opening, state_closed, and state_closing attributes. These will be matched with the value read from the status_register.

If your cover uses ìnput_type: holding(default) to send commands, it can also read the intermediary states. To adjust which value represents what state, you can fine-tune the optional state attributes, likestate_open`. These optional state values are also used for specifying values written into the register. If you specify an optional status_register attribute, cover states will be read from status_register instead of the register used for sending commands.

To use Modbus covers in your installation, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry
modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    covers:
      - name: Door1
        device_class: door
        input_type: coil
        address: 117
        state_open: 1
        state_opening: 2
        state_closed: 0
        state_closing: 3
        status_register: 119
        status_register_type: holding
      - name: "Door2"
        address: 118

Configuration Variables

covers map Required

The array contains a list of all your Modbus covers.

address integer Required

Address of coil / register.

device_class device_class (Optional, default: None)

The type/class of the cover to set the icon in the frontend.

input_type string (Optional, default: holding)

Modbus register type (holding, input), default holding.

state_open integer (Optional, default: 1)

A value in status_register or register representing an open cover. If your configuration uses the register attribute, this value will be written into the holding register to open the cover.

state_closed integer (Optional, default: 0)

A value in status_register or register representing a closed cover. If your configuration uses the register attribute, this value will be written into the holding register to close the cover.

state_opening integer (Optional, default: 2)

A value in status_register or register representing an opening cover. Note that this state should be also supported on your connected Modbus cover. If it won’t report the state, this state won’t be detected.

state_closing integer (Optional, default: 3)

A value in status_register or register representing a closing cover. Note that this state should be also supported on your connected Modbus cover. If it won’t reeport the state, this state won’t be detected.

status_register integer (Optional)

An address of a register, from which all the cover states will be read. If you specified register attribute, and not status_register attribute, your main register will also be used as a status register.

status_register_type string (Optional)

Modbus register type (holding, input), default holding.

unique_id string (Optional)

An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception.

Example: Modbus cover controlled by a coil

This example shows a configuration for a Modbus cover controlled using a coil. Intermediary states like opening/closing are not supported. The cover state is polled from Modbus every 10 seconds.

modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    covers:
      - name: Door1
        slave: 1
        coil: 1
        device_class: door
        scan_interval: 10
      - name: Door2
        slave: 2
        coil: 2
        device_class: door
        scan_interval: 10

Example: Modbus cover controlled by a coil, its state is read from the register

This example shows a configuration for a Modbus cover controlled using a coil. Actual cover state is read from the status_register. We’ve also specified register values to match with the states open/opening/closed/closing. The cover state is polled from Modbus every 10 seconds.

modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    covers:
      - name: Door1
        slave: 1
        device_class: door
        scan_interval: 10
        coil: 1
        status_register: 1
        status_register_type: input
        state_opening: 1
        state_open: 2
        state_closing: 3
        state_closed: 4

Example: Modbus cover controlled by a holding register

This example shows a configuration for a Modbus cover controlled using a holding register, from which we also read current cover state. We’ve also specified register values to match with the states open/opening/closed/closing. The cover state is polled from Modbus every 10 seconds.

modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    covers:
      - name: Door1
        slave: 1
        device_class: door
        scan_interval: 10
        register: 1
        state_opening: 1
        state_open: 2
        state_closing: 3
        state_closed: 4

Example: Modbus cover controlled by a holding register, its state is read from the status register

This example shows a configuration for a Modbus cover controlled using a holding register. However, cover state is read from a status_register. In this case, we’ve specified only values for state_open and state_closed, for the rest, default values are used. The cover state is polled from Modbus every 10 seconds.

modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502

    covers:
      - name: Door1
        slave: 1
        device_class: door
        scan_interval: 10
        register: 1
        status_register: 2
        register_type: holding
        state_open: 1
        state_closed: 0

Configuring platform fan

The modbus fan platform allows you to control Modbus coils or registers.

To use your Modbus fans in your installation, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry
modbus:
  - type: tcp
    host: IP_ADDRESS
    port: 502
    fans:
      - name: "Fan1"
        address: 13
        write_type: coil
      - name: "Fan2"
        slave: 2
        address: 14
        write_type: coil
        verify:
      - name: "Register1"
        address: 11
        command_on: 1
        command_off: 0
        verify:
            input_type: holding
            address: 127
            state_on: 25
            state_off: 1

Configuration Variables

fans map Required

The array contains a list of all your Modbus fans.

address integer Required

Coil number or register.

command_on integer (Optional, default: 1)

Value to write to turn on the fan.

command_off integer (Optional, default: 0)

Value to write to turn off the fan.

write_type string (Optional, default: holding)

Type of address (holding/coil or holdings/coils for array call).

name string Required

Name of the fan.

verify map (Optional)

Read from Modbus device to verify fan. If used without attributes it uses the toggle register configuration. If omitted no verification is done, but the state of the fan is set with each toggle.

address integer (Optional, default: write address)

Address to read from.

delay integer (Optional, default: 0)

delay between write and verify.

input_type integer (Optional, default: write_type)

Type of address (holding/coil/discrete/input).

state_on integer (Optional, default: same as command_on)

Value when the fan is on.

state_off integer (Optional, default: same as command_off)

Value when the fan is off.

unique_id string (Optional)

An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception.

Configuring platform light

The modbus light platform allows you to control Modbus coils or registers.

To use your Modbus lights in your installation, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry
modbus:
  - type: tcp
    host: IP_ADDRESS
    port: 502
    lights:
      - name: "light1"
        address: 13
        write_type: coil
      - name: "light2"
        slave: 2
        address: 14
        write_type: coil
        verify:
      - name: "Register1"
        address: 11
        command_on: 1
        command_off: 0
        verify:
            input_type: holding
            address: 127
            state_on: 25
            state_off: 1

Configuration Variables

lights map Required

The array contains a list of all your Modbus lights.

address integer Required

Coil number or register.

command_on integer (Optional, default: 1)

Value to write to turn on the fan.

command_off integer (Optional, default: 0)

Value to write to turn off the light.

write_type string (Optional, default: holding)

Type of address (holding/coil or holdings/coils for array call).

verify map (Optional)

Read from Modbus device to verify the light. If used without attributes it uses the toggle register configuration. If omitted no verification is done, but the state of the light is set with each toggle.

address integer (Optional, default: write address)

Address to read from.

delay integer (Optional, default: 0)

delay between write and verify.

input_type integer (Optional, default: write_type)

Type of address (holding/coil/discrete/input).

state_on integer (Optional, default: same as command_on)

Value when the light is on.

state_off integer (Optional, default: same as command_off)

Value when the light is off.

unique_id string (Optional)

An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception.

Configuring platform sensor

The modbus sensor allows you to gather data from Modbus registers.

To use your Modbus sensors in your installation, add the following to your configuration.yaml file, in addition to the common parameters and response regresentation:

# Example configuration.yaml entry
modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    sensors:
      - name: Sensor1
        unit_of_measurement: °C
        slave: 1
        address: 100
      - name: Sensor2
        unit_of_measurement: mg
        address: 110
        count: 2
      - name: Sensor3
        unit_of_measurement: °C
        slave: 1
        address: 120
        input_type: input
        data_type: float
        scale: 0.01
        offset: -273.16
        precision: 2

Configuration Variables

sensors map Required

The array contains a list of all your Modbus sensors.

address integer Required

Register number.

count integer (Optional)

Number of registers to read.

Default:

1 or calculated if data_type is not struct.

device_class device_class (Optional, default: None)

The type/class of the sensor to set the icon in the frontend.

input_type string (Optional)

Modbus register type (holding, input), default holding.

name string Required

Name of the sensor.

scan_interval integer (Optional, default: 15)

Defines the update interval of the sensor in seconds.

slave integer Required

The number of the slave (Optional for tcp and upd Modbus).

unit_of_measurement string (Optional)

Unit to attach to value.

min_value float (Optional)

The minimum allowed value of a sensor. If value < min_value –> min_value. Can be float or integer

max_value float (Optional)

The maximum allowed value of a sensor. If value > max_value –> max_value. Can be float or integer

zero_suppress float (Optional)

Suppress values close to zero. If -zero_suppress <= value <= +zero_suppress –> 0. Can be float or integer

state_class string (Optional)

The state_class of the sensor.

unique_id string (Optional)

An ID that uniquely identifies this sensor. Slaves will be given a unique_id of <<unique_id>>_<<slave_index>>. If two sensors have the same unique ID, Home Assistant will raise an exception.

slave_count integer (Optional)

Generates x+1 sensors (master + slaves), allowing read of multiple registers with a single read messsage.

If you specify scale or offset as floating point values, double precision floating point arithmetic will be used to calculate final value. This can cause loss of precision for values that are larger than 2^53.

Full example

Example temperature sensor with a default scan interval:

modbus:
  - name: hub1
    type: tcp
    host: IP_ADDRESS
    port: 502
    sensors:
      - name: Room_1
        slave: 10
        address: 0
        input_type: holding
        unit_of_measurement: °C
        state_class: measurement
        count: 1
        scale: 0.1
        offset: 0
        precision: 1
        data_type: integer

Configuring platform switch

The modbus switch platform allows you to control Modbus coils or registers.

To use your Modbus switches in your installation, add the following to your configuration.yaml file, in addition to the common parameters:

# Example configuration.yaml entry
modbus:
  - type: tcp
    host: IP_ADDRESS
    port: 502
    switches:
      - name: Switch1
        address: 13
        write_type: coil
      - name: Switch2
        slave: 2
        address: 14
        write_type: coil
        verify:
      - name: Register1
        address: 11
        command_on: 1
        command_off: 0
        verify:
            input_type: holding
            address: 127
            state_on: 25
            state_off: 1

Configuration Variables

switches map Required

The array contains a list of all your Modbus switches.

address integer Required

Coil number or register

command_on integer (Optional, default: 1)

Value to write to turn on the switch.

command_off integer (Optional, default: 0)

Value to write to turn off the switch.

write_type string (Optional, default: holding)

type of address (holding/coil or holdings/coils for array call)

verify map (Optional)

Read from modbus device to verify switch. If used without attributes it uses the toggle register configuration. If omitted no verification is done, but the state of the switch is set with each toggle.

address integer (Optional, default: write address)

Address to read from.

delay integer (Optional, default: 0)

delay between write and verify.

input_type integer (Optional, default: write_type)

type of address (holding/coil/discrete/input or holdings/coils for array call)

state_on integer (Optional, default: same as command_on)

value when switch is on.

state_off integer (Optional, default: same as command_off)

value when switch is off.

unique_id string (Optional)

An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception.

Opening an issue

When opening an issue, please add your current configuration (or a scaled down version), with at least:

  • the Modbus configuration lines
  • the entity (sensor, etc.) lines

In order for the developers better to identify the problem, please add the following lines to configuration.yaml:

logger:
  default: warning
  logs:
    homeassistant.components.modbus: debug
    pymodbus: debug

and restart Home Assistant, reproduce the problem, and include the log in the issue.

Building on top of Modbus