I have a system that controls heating of metal through temperature sensors and a PID controller in Node-red.
I use context too file for the controlling and storing of setpoints, temperature, statuses and so forth.
I have a :1881/ui with textfields, buttons and what not for setting what needs to be set.
This system needs to support Modbus TCP.
Now, writing locally from the context to the local modbus server is not a problem. That works fine, and the remote client is able to read the data. It is writing from a remote client to the local server that the problem arises. Since the system uses the context data for control, the new data from the remote client is not used. And I'd hate to start using the modbus server data for control, since that is a lot more complicated procedure than to just write out global.get("someKey", "file") in a function node or using a change node.
Now, I have a solution that I think will work, but I wanted to ask here before I embark on some rewrite quests.
The delay node here is the window where the remote modbus client and the local ui can do changes.
The problem here is that when a local change through the ui is done and stored in context, that data will be overridden by the data in the modbus server. The solution here is to store new data from ui in the modbus server instead, and let the loop depicted over do the writing to context.
In my opinion MQTT rather than context is the best solution for this type of problem. It easily allows all your systems to have access to the data. Use retained topics where appropriate and it will remember the data over restarts and automatically inject the current values on restart.
I don't have control over the client system. I'm forced to use Modbus TCP for interacting with remote system.
I'm not sure how MQTT would solve my problem though. When remote client modbus writes to my local modbus server I would still need to update the MQTT data somehow.
Ideally, there would be perfect to have a modbus node that could intercept a write to the local modubs server so you could manipulate the data or do whatever you want with it. A node that simulates modbus server or something. Like the http in node.
I know that the modbus "flex server" have function on "set coil" and "set registers", but it seems that you don't have access to context. When writing too the local modbus server while accessing global context in the "setFlexCoil" function, the remote client doing the writing gets back a modbus exception.
I didn't mean that you should change the the TCP comms. Setup an mqtt server on your system and use that to store your settings instead of context. So the UI gets data from mqtt and makes changes through it, for example.
I am at my computer now and have read your question more carefully,
On the modbus side, do you mean you have a modbus server running locally on your system, and the client writes/reads to that in order to do stuff? If so then what server are you using? The ideal would be if it told you when data changes.
Exactly Colin. It should tel me what data changed. I'm using node-red-contrib-modbus's modbus flex server.
I am in the process to test node-red-contrib-modbus-api which has a "modbus in" node which does exactly what I'm looking for (in its description). I have not been able to test it fully yet. Will come back when I have.
For that I suggest making the modbus interface effectively a comms translation layer between the modbus protocol and MQTT. So any time the client writes to modbus it goes through the server and writes to MQTT, and any time the client reads from modbus it will be sent the current value from MQTT. Node red can forget about the modbus server and just directly use MQTT.
So, after some testing (not enough though) I must say that it does what it says.
You have a "modbus in" node that can be a write or a read (even though it says that it only do reads in the readme). You do what ever you want with the data and you return your result in a "modbus out" node.
Unfortunately, it doesn’t look like it is maintained much.
It says that it can only do 128 registers at a time, or node-red will crash. Whatever that means.
The biggest drawback is that you must make a pair of "modbus in" and "modbus out" with your process in between for each register you want to use. I have not been able to do a range of registers and respond to that. Only one address at a time. I have not tested the client side, if it can read a range of registers if the register addresses are present.
I will try it out though since it does exactly what I need.