tiagocoutinho / modbus-proxy

Connect multiple clients to modbus devices
Other
71 stars 13 forks source link

Alternatives to this project #31

Open IngmarStein opened 9 months ago

IngmarStein commented 9 months ago

The last commit for this project has been one year ago and there has been little activity in the issue tracker as well. Assuming this project is paused, it might be worth looking for alternatives.

Personally, I had good success with HAProxy. Yes, it's not as lightweight but it's rock-solid, extremely scalable, well documented, and supported.

Here's my configuration to proxy a modbus server (port mapping: 5020 -> 1502) with a maximum connection count of 1:

haproxy.cfg

global
    daemon
    maxconn 256

listen modbus-in
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    bind *:5020
    server server1 $IP:1502 maxconn 1 check

Docker Compose

services:
  haproxy:
    image: haproxy:latest
    container_name: haproxy
    ports:
      - "5020:5020"
    volumes:
      - type: bind
        source: /my/path/haproxy.cfg
        target: /usr/local/etc/haproxy/haproxy.cfg
    restart: unless-stopped                                                                                                                                                                                                                                 

Maybe this helps someone.

rucksman commented 9 months ago

Thanks for pointing out to this other solution, @IngmarStein . I tried to get this version (Python) as well as the Rust version to run with no success (timeout, no matter what configs I try) since some days. Tried installing this version and also tried Docker, but everything failed. As there was no reaction from @tiagocoutinho in the last issues, I didn't even attempt to seek some help here. That's why I am glad that you @IngmarStein posted this message.

rucksman commented 9 months ago

Just a short feedback @IngmarStein : worked perfectly! One question, although this is out of scope here: what does " with a maximum connection count of 1" mean in this context? Only one connection to the server allowed, or only one connection to haproxy?

IngmarStein commented 9 months ago

Glad to hear that it's been useful for you! I had reliability issues with the Rust version and I'm not sure whether https://github.com/tiagocoutinho/modbus-proxy-rs/pull/4 would have fully resolved those.

The maxconn 1 is next to server so that it applies to the connection between haproxy and the modbus server. The other maxconn 256 applies to the connections from clients to haproxy.

IngmarStein commented 8 months ago

Addendum: the haproxy solution does not do TCP-level multiplexing. That means: long-living TCP connections from one client will block other clients for as long as they keep the TCP connection alive. haproxy queues other clients and eventually drops them when timeout queue (same as timeout connect by default) is reached. So the solution is essentially just a better queuing mechanism and allows for better observability (when using the stats handler), but doesn't allow for multiple simultaneously active clients.

sunnysingh-84 commented 7 months ago

haproxy solution does not do TCP-level multiplexing

Firstly thanks for sharing the alternative, I have been testing modbus-proxy for over a week to allow my victron system (1 sec polling) and home assistant (30 sec polling) to read my huawei inverter/meter stats and all seems to be working well so far.

I am however interested in understanding if there is any DIY software/hardware solution that would allow multiple simultaneously active clients/cache the results and share to clients without having to do multiple reads similar to what is advertised for the following hardware:

7bit Modbus Proxy - Modbus RTU to Modbus TCP caching gateway 2 x RS-485, 2 х Ethernet, Wi-Fi

_Unlike most gateways, which only re-transmit packets from one network to another, while introducing additional delay, Modbus Proxy works at its pace all along, reading the requested registers into the internal memory and responds to requests with values stored in memory. Thus, the requested registers are read from the gateway’s cache without delay over Modbus TCP, while the gateway cyclically reads them from the Modbus RTU devices and put data into cache.__

EvoSems commented 7 months ago

The last commit for this project has been one year ago and there has been little activity in the issue tracker as well. Assuming this project is paused, it might be worth looking for alternatives.

Personally, I had good success with HAProxy. Yes, it's not as lightweight but it's rock-solid, extremely scalable, well documented, and supported.

Here's my configuration to proxy a modbus server (port mapping: 5020 -> 1502) with a maximum connection count of 1:

haproxy.cfg

global
    daemon
    maxconn 256

listen modbus-in
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    bind *:5020
    server server1 $IP:1502 maxconn 1 check

Docker Compose

services:
  haproxy:
    image: haproxy:latest
    container_name: haproxy
    ports:
      - "5020:5020"
    volumes:
      - type: bind
        source: /my/path/haproxy.cfg
        target: /usr/local/etc/haproxy/haproxy.cfg
    restart: unless-stopped                                                                                                                                                                                                                                 

Maybe this helps someone.

Wow! life saver. I have been struggling for days to try to get my sun grow inverter to communicate with my rpi and Hass.

I am not very code efficient.

could you explain what I need to change in the config file?

using yours I get.

evo@rpi:~/haproxy $ docker compose up [+] Running 1/1 ✔ Container haproxy Created 0.2s Attaching to haproxy haproxy | [NOTICE] (1) : New worker (8) forked haproxy | [NOTICE] (1) : Loading success. haproxy | [WARNING] (8) : Server modbus-in/server1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. haproxy | [ALERT] (8) : proxy 'modbus-in' has no server available! haproxy exited with code 137

my inverter is runing on 193.168.31.148 port 502

using server server1 192.168.31.148:502 maxconn 1 check

gives me. $ docker compose up [+] Running 1/1 ✔ Container haproxy Created 0.1s Attaching to haproxy haproxy | [NOTICE] (1) : New worker (8) forked haproxy | [NOTICE] (1) : Loading success.

so do I know connect my my other program. inverter to mqtt to port 192.168.31.148:0502?

what do I need to change? many thanks.. Jim

IngmarStein commented 7 months ago

Did you change server server1 $IP:1502 maxconn 1 check to server server1 193.168.31.148:502 maxconn 1 check?

blastik commented 4 months ago

in case somebody find this useful. i wanted to connect two devices to the modbus (huawei SUN2000L inverter): 1 being home assistant and the other being my EV charger. in my case i picked v2c trydan because its API is open and it has many integrations (geek!) i tried this approach and it worked but then i thought... wait a sec. if the v2c trydan supports MQTT why i just publish a couple of topics from HAOS? and thats what i did:

alias: V2C MQTT - Publish grid power
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.power_meter_active_power
condition: []
action:
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: v2c/trydan_v2c_grid_power
      payload: "{{ trigger.to_state.state }}"
mode: single
alias: V2C MQTT - Publish inverter input power
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.inverter_input_power
condition: []
action:
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: v2c/trydan_v2c_sun_power
      payload: "{{ trigger.to_state.state }}"
mode: single

problem solved.

IngmarStein commented 3 months ago

So I rolled my own: http://github.com/ingmarStein/tcp-multiplexer If you pass -p modbus, it can multiplex modbus-tcp and I've been running it for a number of days in a container without the issues I had with modbus-proxy. Give this a try if you want.