feature-requests icon indicating copy to clipboard operation
feature-requests copied to clipboard

Add Modbus slave support (RTU and TCP)

Open tuxmartin opened this issue 5 years ago • 13 comments

Describe the problem you have/What new integration you would like

It would be great to be able to use ESPhome on ESP32 as a Modbus slave.

I would like to use Modbus RTU via RS-485, but Modbus TCP would also suffice.

Please describe your use case for this integration and alternatives you've tried:

I asked at Discord and ESPhome can only use Modbus master.

Additional context

/

tuxmartin avatar Apr 28 '20 20:04 tuxmartin

actually I'm interested in modbus slave RTU too. Any hints how it can be implemented?

bademux avatar May 05 '20 15:05 bademux

I have also been wanting Modbus RTU on esphome. Y have many devices that are far away and y don't want wire a long cable to a PLC to monitor these devices. Is Modbus RTU master already possible? I couldn't find that anywhere.

Nicomagno avatar Oct 16 '20 21:10 Nicomagno

Hello:

I'm interested in this question, does anyone already have the solution?

Thank you.

vtb77 avatar Dec 26 '21 12:12 vtb77

If anybody does start this, i suggest you base yourself on a real library instead of doing some partial solution in esphome. Using for example m-bus or libmodbus.

elupus avatar Dec 26 '21 14:12 elupus

It has recently been integrated into the main ESPhome repository. https://esphome.io/components/modbus_controller.html We have to thank https://github.com/martgras. He did the integration, many people tested it and now it works with a lot of devices.

Nicomagno avatar Dec 26 '21 14:12 Nicomagno

Version 2021.10.0 of ESPHome (see https://github.com/esphome/esphome/pull/1779) introduced Modbus client support (props to @martgras) for talking to Modbus servers (previously known as slaves) but support for making ESPHome itself act as a Modbus slave/server is still not available.

What are the complexities with creating a generic server device support? From the outside it seems like mapping sensors/state to coil/registry values might be the most complicated part due to the different ways these values could be represented in the Modbus payload. Are there other things I'm missing?

kasparsd avatar Apr 23 '22 19:04 kasparsd

Just to reinforce the request for modbus slave functionality.

jgracio avatar Aug 25 '22 10:08 jgracio

+1 for this...

grob6000 avatar Aug 29 '22 10:08 grob6000

@kasparsd: It depends. I would say some people want to just use any commercially available modbus controller and hook an esp32 in slave mode to it. But in some cases it would be nice to have some auto-mapping, if you want to use modbus instead of api/mqtt (still dreaming that it would be possible to use Zigbee, LoRa,ESP-Now,... instead of WiFi). All esp32's could be wired, only in case of OTA you will need to enable WiFi.

randybb avatar Sep 05 '22 17:09 randybb

Hello all,

I just wrote a component that allows you to expose your ESPHome as a RTU modbus slave. The documentation is pending, but it is straightforward to use with the example provided.

https://github.com/epiclabs-io/esphome-modbus-server

Please let me know your feedback.

jpeletier avatar Sep 20 '22 12:09 jpeletier

@jpeletier sorry for stupid question, is it possible to expose your modbus slave implementation with RS485 (serial).

bademux avatar Sep 20 '22 13:09 bademux

Hello @bademux.

This implementation already and actually only works over RS485.

In the example you will see that first a serial uart has to be defined by specifying gpio pins where your RS485 serial adapter is connected:

uart:
  - id: my_uart
    tx_pin: 13
    rx_pin: 16
    baud_rate: 9600
    stop_bits: 1
    data_bits: 8
    parity: NONE
    debug:
      direction: BOTH

Then, you instantiate modbus_server linking to the above defined uart:

modbus_server:
  - id: modbuserver
    uart_id: my_uart
   # [...]

Let me know if this clarifies. Cheers

jpeletier avatar Sep 20 '22 13:09 jpeletier

Excellent!!! We need thorough documentation, please. Let's not just point people towards MODBus standards literature, let's explain in a few words how it works and how registers build up, and provide examples for each type of registers (Coil, Discrete Input, Input Register, Holding Register).

Moreover it would be nice to show an example where two ESPHome nodes talk to each other via MODBus.

nagyrobi avatar Sep 20 '22 18:09 nagyrobi

Excellent!!! We need thorough documentation, please. Let's not just point people towards MODBus standards literature, let's explain in a few words how it works and how registers build up, and provide examples for each type of registers (Coil, Discrete Input, Input Register, Holding Register).

Moreover it would be nice to show an example where two ESPHome nodes talk to each other via MODBus.

Nagyrobi, i actually have an implementation of 2 esp32 talking in modbus with @jpeletier component, basically works but master and slave codes need some tweak in order to avoid crc errors ( i think that the esphome master sends too many requests to the slve), i will buy some rs485-ttl adapters to rule out hardware malfunctioning

btw, thank you @jpeletier :)

fdepalo avatar Nov 06 '22 11:11 fdepalo

@fdepalo what do you mean by master and slave code tweaks? Is that in the library of just in the yaml config?

grantstephens avatar Jan 25 '23 12:01 grantstephens

Sorry if my question seems stupid.....but how can I acces the registers (fill in new values from the side of home assistant)? I want to fill the registers from some point within home assistant to allow a client that is connected on the RS485 side to read that values from the registers.

usernamephoenix avatar Jan 25 '23 15:01 usernamephoenix

@usernamephoenix Let's take the discussion to https://github.com/epiclabs-io/esphome-modbus-server in an issue so we don't clutter this thread. Open an issue there so we can discuss.

In essence, you will have to create a template number so HomeAssistant can write to it. Then, you write an on_read lambda in modbus server that picks the value from the template number when the client attempts to read a register. You can also use a template switch if your data is on/off type, or a template select if your data is within a discrete set of possible values.

jpeletier avatar Jan 26 '23 08:01 jpeletier

@usernamephoenix Let's take the discussion to https://github.com/epiclabs-io/esphome-modbus-server in an issue so we don't clutter this thread. Open an issue there so we can discuss.

I have tried this, but you don't reply in the project :/

StarChildDK avatar Apr 12 '23 18:04 StarChildDK

Some work is being done on this: https://github.com/esphome/esphome/pull/4761

JeroenVanOort avatar May 18 '23 16:05 JeroenVanOort

Good morning , since I am struggling with 1 d1mini to configure as a slave to communicate with HA , I saw the jpeletier code , to allow Esphome to work in slave mode , but to add it to Home assistant give me some suggestions to understand how to integrate it .... Thank you

minixium avatar May 30 '23 12:05 minixium

How can i use touch switch wifi by flash firmware ESPhome and i need to make touch switch connect V-box by modbus TCP How can I code to modbus TCP?

pK4n avatar Jul 12 '23 04:07 pK4n

How can i use touch switch wifi by flash firmware ESPhome and i need to make touch switch connect V-box by modbus TCP How can I code to modbus TCP?

What you are asking for is ESPHome as a Modbus TCP Client to another Modbus TCP Server, correct? If so, here's your correct FR: https://github.com/esphome/feature-requests/issues/1992

makuser avatar Oct 05 '23 14:10 makuser

Say someone was willing to work on this, how do you see the configuration working?

There is already a modbus controller that has this kind of config:

uart:
  id: mod_uart
  ...

modbus:
  send_wait_time: 200ms
  uart_id: mod_uart
  id: mod_bus

modbus_controller:
- id: sdm
  address: 2
  modbus_id: mod_bus
  ...

Say that instead of modbus_controller we could add a modbus_server with register -> sensor/actuator mappings, an example could be (present sensors from a BME280 environmental sensor in Modbus registers):

sensor:
  - platform: bme280_i2c
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x77
    update_interval: 15s

uart:
  id: mod_uart
  ...

modbus:
  uart_id: mod_uart
  id: mod_bus

modbus_server:
- id: ms1
  address: 2
  modbus_id: mod_bus
  entities:
    - address: 0x4001
      register_type: holding
      value_type: S_WORD
      id: bme280_temperature
    - address: 0x4002
      register_type: holding
      value_type: U_WORD
      id: bme280_pressure
    - address: 0x4003
      register_type: holding
      value_type: U_WORD
      id: bme280_humidity

Or at least that's how I imagine it could work. Each address could probably do with a filter for sensor value manipulation before presenting to the Modbus master. Eg. for bme280_temperature filter could be of * 100 (ie. multiple the sensor value by 100 before presenting as an unsigned integer).

I'm not actually convinced register_type is required as it could be derived from the actual address but seems very open to interpretation.

Does this sound feasible to anyone here?

raintonr avatar Apr 07 '24 18:04 raintonr

Say someone was willing to work on this, how do you see the configuration working?

This is already functional in one of the referenced PR's: https://github.com/esphome/esphome/pull/4874

You can currently define a modbus slave aka server, define a number of entities mapped to registers, and have a modbus client query the modbus server for values.

One additional feature I'd love to see would be a modbus TCP server implementation. I believe that this could be easily implemented as a feature in the existing modbus_controller:, such that a client on the network could connect to the modbus_controller:'s socket, and send modbus TCP-formatted messages. The modbus_controller: would then either respond directly to the messages, by looking up the defined entities for the requested registers, or potentially by translating them to modbus RTU messages and forwarding them to a UART, then translating the responses from modbus RTU to modbus TCP and sending them to the network client.

RoganDawes avatar Apr 08 '24 17:04 RoganDawes

Should we create a new issue for TCP support?

RoganDawes avatar May 22 '24 05:05 RoganDawes

Yes, please.

nagyrobi avatar May 22 '24 06:05 nagyrobi