Hi very excited about the KNOT but looking at the Docs/Application examples it appears that modbus functions as an RTU to IP client/server.
So it looks like we can't route modbus to/from MQTT/HTTPs REST ?
Thanks
Lawrence
I'm thinking on switching from generic ModBus RTU->TCP gateways to the new KNOT. RouterOS can be a great tool to protect plain ModBus/TCP traffic over public channels.modbus works partially. read holding register only. there is no way to get a response in high-low. answers in integer only. export data to file only.
I understand this limitation if you are scripting within RouterOS. However, can RouterOS pass function code 4 requests/responses using the RS485-TCP bridge?Currently, MODBUS in RouterOS can display only the response/reply to function code 3 (Modbus) request (that is if Modbus "slave" device that is connected to KNOT supports "function code 3"):
https://help.mikrotik.com/docs/pages/vi ... ngRouterOS
So as long as it can be "printed" in CLI, it can be scripted and posted via MQTT.
2. RouterOS can act as a MODBUS RS485-TCP bridge. This allows external software to connect to your modbus network over TCP/IP via the KNOT. This is enabled from the IOT/modbus menu, this menu is available in v7, and only in the CLI for v6. You should firewall access appropriately since Modbus-TCP has no security on its own.Known Bug RouterOS v6, and versions including v7.2.3 (current stable version at the time of this post) where the parity setting of even or odd continues to behave as parity=none. If your MODBUS network uses parity=even or odd, then connectivity won't work as expected. This issue is resolved as of v7.3beta33
Hope this helps.Limitation the versions of RouterOS available at the time of this post only supports Function Code 3 querying from within RouterOS. If you need other function codes you need to enable the MODBUS RS485-TCP bridge and use external software
There is scripting "tips and tricks", that discuss "once":1) what is the meaning of " as-value once " , it's in the official docs but got no description:
https://help.mikrotik.com/docs/pages/vi ... d=61046813
/iot modbus read-holding-registers slave-id=0x03 num-regs=0x1 reg-addr=0x0 once
{:local output [/iot modbus read-holding-registers slave-id=0x03 num-regs=0x1 reg-addr=0x0 as-value once];:put [($output->"values")]}
That's the granularity of the schedule, so 1 sec.2) Anyway all of this should be put in a script and then system>scheduled, so the minimum time between each poll is 1 second?
Docs say KNOT only support function 3, which is the read registers.3) is it supported only read-holding-registers or exist also a write-holding-registers?
# wcs, copyright © 2010. all rights reserved
# script version : 1.0
:local errors 0
#
:global gostatusXscript
:while ($gostatusXscript = "no" ) do={
:delay 5s;
}
:set gostatusXscript "no"
#
:do {
:global modbusregisters {
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=154 as-value once]";"0";"154";"grid_voltage"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=192 as-value once]";"0";"192";"grid_frequency"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=167 as-value once]";"0";"167";"grid_power"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=183 as-value once]";"0";"183";"battery_voltage"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=184 as-value once]";"0";"184";"battery_state_of_charge"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=190 as-value once]";"0";"190";"battery_power"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=175 as-value once]";"0";"175";"inverter_power"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=164 as-value once]";"0";"164";"inverter_current"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=186 as-value once]";"0";"186";"mppt_1"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=187 as-value once]";"0";"187";"mppt_2"};
{":set tmp [/iot modbus read-holding-registers slave-id=0x01 num-regs=0x1 reg-addr=172 as-value once]";"0";"172";"172?"};
}
:global tmp
#
:log info "[ starting - modbus mqtt ]"
#
:foreach register in=$modbusregisters do={
:log info ($register->3)
#
:log info (" register:")
:log info (" " . ($register->2))
#
:log info (" command:")
:log info (" " . ($register->0))
:execute ($register->0)
:delay 2.5s
#
:set ($register->1) [($tmp->"values")]
:log info (" reading:")
:log info (" " . ($register->1))
#
:log info ""
#
/iot mqtt publish broker="x x x x " topic=("feeds/thing-x/process-power-x/outgoing/sunsynk/" . $register->2) message=($register->1) qos=2
}
#
:log info "[ ending - modbus mqtt ]"
#
} on-error={
:set gostatusXscript "yes"
:log error "script failure [ modbus mqtt ]"
}
#
:log info "script completed with $errors errors"
:set gostatusXscript "yes"
:log info " "
#