Writing multiple Modbus devices triggered by a metadata or virtual source
-
I have several motorized Modbus devices, and must be able to select one as the controller and the others as followers. I can use a metadata or virtual source to select which device is the controller, and then write appropriate values to Modbus registers on all the devices to make sure all devices are set properly based on changing the selection. I have to write many different Modbus registers based on one point selection.
If I use a Scripting Data Source:
- I would be able to write all the Modbus registers without creating a point link for each register, correct?
- The selector point will have to be polled with a cron job every second or so. This seems like a lot of overhead for a change that does not occur frequently.
- The selector point could be polled once per minute, resulting in large latency and user confusion as it would take anywhere from 1-60 seconds to update the other points.
If I use a MetaData script:
- The script will execute whenever a user changes the selector point.
- I cannot write Modbus register values from a single script because MetaData scripts can only update their own script value through a
return
instruction. They cannot update other points. - I must create one MetaData point and one point link for each register
If I use event detectors:
- I could detect the first event, and use it to trigger the other write commands
- I cannot have more than one target Modbus register per event handler
- I would need a lot of event handlers
I have another Modbus device where I use event detectors and event handlers to trigger a cascade of events that update other registers. This is nice because the writes are sequential, and the order is well defined. The problem is that the cascade of events (write commands) can be triggered inadvertently by an intermediate modbus write in the middle of the event chain, when I would prefer that the event handlers only trigger the write cascade based on
It seems to me that the ideal option would be to use a Scripting data source that can write to multiple Modbus registers from within the script, and can be triggered upon the context update of whichever points I select (like the Meta data "updates context" flag. However, it seems that this is not available for Scripting data sources.
This leads to my questions:
- What is the optimal means to configure multiple Modbus writes triggered by a single virtual or meta point change?
- Is it possible to launch a Scripting data source based on a "context update?"
Thanks
-
Hi Pedro,
All of those options would work in Mango 3. Scripts can have context updates, meta points can call set() and event handlers can have scripts that call set().
In Mango 2.8, it is possible if you're using Java 8.
You could have a meta point like this one trigger your script...
var scriptDsXid = "DS_12345"; var dsvo = this.dsvo; if(!dsvo) { dsvo = this.dsvo = com.serotonin.m2m2.db.dao.DataSourceDao.instance.getDataSource(scriptDsXid); } if(com.serotonin.m2m2.Common.runtimeManager.isDataSourceRunning( dsvo.getId() )){ var dsrt = com.serotonin.m2m2.Common.runtimeManager.getRunningDataSource( dsvo.getId() ); dsrt.doPoll(new Date().getTime()); }
-
Thanks. I have Java8 on Linux. I have a Multistate virtual datapoint with the Settable attribute set to true. It now contains the script below:
// Select a VFD to be in PID mode and others in following mode switch (my.value) { case 0, 1, 2, 3: var scriptDsXid = "DS_PIDRules"; var dsvo = this.dsvo; if(!dsvo) { dsvo = this.dsvo = com.serotonin.m2m2.db.dao.DataSourceDao.instance.getDataSource(scriptDsXid); } if(com.serotonin.m2m2.Common.runtimeManager.isDataSourceRunning( dsvo.getId() )){ var dsrt = com.serotonin.m2m2.Common.runtimeManager.getRunningDataSource( dsvo.getId() ); dsrt.doPoll(new Date().getTime()); } return my.value; default: return 0; }
The above Metadata script has no context points set, but it should execute nonetheless whenever a user changes its value (since it's settable). Correct?
A Scripting datasource does the actual setting of the Modbus values. It is set to run every minute because a cron pattern is required. After debugging I may set it to run once per year, because I'd rather not use a cron schedual at all. According to the log the Scripting source is running every minute, but it is not running when the Multistate Metadata point value changes.
In your example, what exactly is this.dsvo?
How can I get the Scripting datasource to execute whenever I set a new value for the metadata point?
-
Incorrect
A meta point's script is not executed when a value is set to it; it is not a context listener for its own values.
this.dsvo was a way to avoid querying the database every time and instead only when the point runs the first time. You could use the data source's ID directly and remove dsvo
-
In that case we're back to my original question: what is the best way to set multiple Modbus points each time a user sets a virtual or metadata point?
Similarly, how can the value range of a point be restricted if the script does not run when the user changes the point value?
-
You can add your virtual point in the context of the meta point, then use the virtual point as the trigger for the meta point. The "best way" is probably only available to you in Mango 3.
-
Thank you for your advice. I got this working last week, but as you indicate, it requires tree structures in Mango 2.8.8:
- one metadata point used for creating a context change from user input
- one metadata point to detect the context change then execute the script
- one scripting datasource to set multiple points each time the context of the first point changes
I'm glad to hear this has been simplified in Mango 3.x.