st-one-io / node-red-contrib-s7

A Node-RED node to interact with Siemens S7 PLCs
GNU General Public License v3.0
108 stars 55 forks source link

Persistent variables #130

Open funkitup opened 4 months ago

funkitup commented 4 months ago

Problem: When restarting the Node-Red instance, all variables will be pushed again, even when set to "emit only when value changes" which I assume is due to the memory of the Node being temporary.

Has anyone built a solution for persistent variable storage that checks against stored values? I was thinking about using the file storage of NodeRed, or the MySQL Node to build it myself but was wondering if something like this already existed or could be integrated into the Node itself

Thanks!

nrbrt commented 3 months ago

Hi, I use this function extensively and the key is to use the PLC to communicate it's state to Node-RED and let that be leading. This way Node-RED knows the exact state in which the PLC is. The s7 plc's have an excellent retentive memory capability that will survive PLC reboot and Node-RED restart/deploys and communication loss. Node-RED will reinitiate contact with the PLC and will receive the actual state of things and then wait for changes.

For instance, when using a dashboard switch that is connected to a digital output on the PLC, make sure that the state of the switch shows the input and not the output, that way you know for sure that: a) your command was executed and b) that if that output changes by other means or either the PLC or Node-RED reboots, it will still show the actual state of things. The PLC uses "databases" (datablocks) to keep track of things, it is almost never a good idea to try and keep 2 databases in sync with each other when you could just use 1. I hope this helps.

funkitup commented 3 months ago

Thanks for your insight! My issue is with my database being central and connected to multiple PLCs in different networks. A NodeRed instance is running locally for each PLC, sending data via MQTT.

When a NodeRed instance loses connection to the db, all data is lost for that period. The PLCs retentive memory doesn’t solve that so I’d like data to be stored locally when a connection drop is detected.

My issue isn’t specifically with retaining memory in case of a restart. For this, PLC retentive memory is sufficient. That just led me to believe that this Node has only temporary memory since variables are emitted even though their values have not changed. Ideally I‘d like to find or build a solution for both the redundant emittance of values and data loss.

How do you deal with these issues? Do you only run NodeRed locally?

nrbrt commented 3 months ago

I understand. Why not let the PLC talk MQTT directly to the server? There is an excellent library available for the s7 that makes that easy to do. You could do some checks on the PLC to see if the last transmission was successful, store the data temporarily if it was not and re-send it when communication is restored.

I use 2 Node-RED instances to run 2 companies that share a couple of resources. I store data in a database and I communicate things that concern both companies with MQTT between the 2 instances over VPN. These companies each have a multitude of S7 PLC's, remote modules and Modbus devices that I need to keep track of. I try to push as much of the operational logic into the PLC's instead of Node-RED as I can. I use Node-RED as a kind of SCADA system and that works well for me.

I want to be able to have Node-RED crash (has not happened yet, knock on wood) or reboot without disturbing the production side of things if at all possible.

A double entry in the database does not concern me that much, since I also log loss of connection/communication and I see this as part of the restoration of communication. In my environment, a loss of connection triggers an alarm that I will respond to ASAP. The loss of data during that time is of a lesser concern. Continuity of the production process is more important. Counters, etc. will get updated in the database as soon as things are back up and running. Besides, loss of communication does not happen that often anyway.

I guess it all depends on your use case, but beware of database synchronization, that opens a whole new can of worms.