gavinying / modpoll

A New Command-line Tool for Modbus and MQTT
https://gavinying.github.io/modpoll
MIT License
84 stars 17 forks source link

Add poll interval/rate for every single poll #15

Closed mr-manuel closed 1 year ago

mr-manuel commented 1 year ago

Hello,

would it be possible to add a polling interval/rate for every single poll in the CSV?

The reason is that I have some data that is rarely changing (e.g. every hour) and other data that is chaning every second. To reduce load I like to be able to add a polling interval/rate for a specific poll by adding the interval/rate in seconds to the end of the CSV line.

If nothing specified in the CSV, then the default value (specified by -r or --rate) is used. This makes the script also backward compatible without the user having to change someting.

Example

Default rate: 1.2 s Rate for poll,holding_register,10103 and ref,charger-rated-current,15216 is 3600 s

modpoll \
    --config /data/etc/must-solar-inverter/modpoll-registers.csv \
    --rate 1.200 \
    --interval 0.000 \
    --timeout 0.150 \
    --rtu /dev/ttyUSB0 \
    --rtu-baud 19200 \
    --rtu-parity none \
    --mqtt-host 127.0.0.1 \
    --mqtt-port 1883 \
    --mqtt-clientid modbus \
    --loglevel WARNING \
    --delay 0
device,must-ph18-5548-plus,4
poll,holding_register,10103,9,BE_BE,3600
ref,charger-voltage-float,10103,int16,rw,,0.1
...
ref,battery-ah,10111,int16,rw
poll,holding_register,15201,21,BE_BE
ref,charger-work-state,15201,int16,r
...
ref,charger-rated-current,15216,int16,r,,0.1
poll,holding_register,20101,44,BE_BE,3600
ref,inverter-offgrid-work,20101,int16,rw
...
ref,solar-power-balance,20144,int16,rw
poll,holding_register,25201,79,BE_BE
ref,inverter-work-state,25201,int16,r
...

Please let me know, what you think.

gavinying commented 1 year ago

Hi @mr-manuel, thank you very much for your interest and well-written proposals. Let me share my thoughts for exchange.

I understand the main purpose of this change is to minimize the communication activities and save workloads on data processing, but IMHO, I don't see much benefit from the change, because 1) Modbus is normally used in device-facing data acquisition stage, which needs reliability over performance. The firmware running on device usually has fairly constant workload and shall always work under the specs; On the other end, it is similar if we use MCU for data collector, also it shall not be a heavy load if we use linux-based CPU. 2) Modbus usually runs over local network, the communication has no addional cost. 3) Modbus RTU is master-slave network, it will occupy the whole network at runtime, the saved bandwidth seems not beneficial to others.

On the other aspect, it's about the design thinking. Generally, if we rely on a tool to reach our goal, we basically need to make two decisions, choose a right tool and decide how to use it. In my view, modpoll is that tool, and user shall be able to decide how to use it. Following this principle, I defined the tool itself (code in repo) to be simple and reusable as possible, while providing the arguments for flexible usage in various cases. Although, it is arguable that config (csv) file is on tool side or user side, my intention is to make it reusable, ideally it shall only describe the modbus spec of device (device addressing in RTU is an exception), so it can be shared and used for any new project.

Feel free to share your suggestion if you have different views. Thanks.

mr-manuel commented 1 year ago

Hi, I wanted to reduce the load on the slave, since unfortunately it's a chinese product and not very well programmed. If I request to much data at once, it crashes often and I get no reply until it recovered.

Maybe you have a better idea to solve this?

gavinying commented 1 year ago

Hi @mr-manuel , Does your device vendor state the max master polling rate or similar specs? Please check if your polling rate is within the specs. If the device cannot work properly according to their own specs, then it is obviously a quality issue.

But in case you believe reducing the load on slaves might help, you can try the following workaround, 1) seperate your fast sensors and slow sensors into 2 config(csv) files; 2) use -1 or --once argument for modpoll and schedule the polling by your self.

The following pseudo code will poll fast sensors every 3 seconds and slow sensors every 5 minutes,

i=0
while true; do
  if (( i % 3 == 0 )); then
    modpoll -1 -f fast_sensors.csv
  elif (( i % 300 == 0 )); then
    modpoll -1 -f slow_sensors.csv
  fi
  ((i++))
  sleep 1
done

Hope it helps. Gavin

mr-manuel commented 1 year ago

Perfect, thank you very much!