Discuss and solve problems in energy management and automation. Join conversations and share insights on products and solutions. Co-innovate and collaborate with a global network of peers.Register Now
>>Message imported from previous forum - Category:ClearSCADA Software<<
User: nminchin, originally posted: 2018-12-04 02:01:24 Id:330
All of the ClearSCADA projects that I've seen in my 9 years working with it off and on, have all used the same cumbersome approach to mimic parameters. That is, all symbols have defined parameter groups, and each group contains every conceivable object property that might be needed for each object in the parameter hierarchy that will come from a database object.
This can be replaced with a far more simple approach:
Then in animation expressions, you can indirectly bind to the object properties you need using:
["Parameter:Group.Value.FullName" + '.CurrentValueFormatted']
Using this method has several advantages:
- Far simpler parameter creation
- No reliance on the initial list of properties being correct. It's not a major event if you need to reference another tag property in the future.
- Far far simpler to dynamically exchange out the tags being passed into the symbol. For example, if you want an analogue display to show one tag on condition, and another tag on another condition, then this logic is done once to swap out the FullName passed in, rather than an expression to swap out every single property. Seen this lots of time and it's so frustrating to work with and work out what's going on...
The only potential downside to this approach that I can see might be a performance hit due to using indirect bindings. I've tested this however with 50 symbols embedded on a page using this approach, and haven't seen any noticeable lag.
I'm curious, is it just the projects that I've worked on, or is this parameter-per-property approach how most other projects have been done as well? Does anyone use the FullName/Indirect binding approach, and have they had any issues with performance?
Attached file: (editor/3a/kxnfzqsci17d.png), image.png File size: 28935
Attached file: (editor/dy/j8shj3xvv8ld.png), new symbol.png File size: 12324
Reply User: dmercer, posted: 2018-12-04 03:23:31
I've used this in the past.
Indirect references do cause a performance hit, but I've only seen it cause real problems when there was some latency between the client and the server.
I like to try to put in all of the parameters that I am likely to use, and then also include FullName and Id as backups in case I need to add more functionality later and don't want to go back over every place that it's been embedded.
In your example above you can go further if the folder structure is always the same, by removing the limits group, and using ["Parameter:Group.Value.FullName" + '.Limits.High.CurrentValueFormatted']
A similar trick is that mimic scripts can read parameters and read and write to animation values. You can use this to get properties from other tags which are referenced by the tag that passed to the embedded mimic. If you want it to continually update then you have to put a loop inside the Mimic_Load() function.
Reply User: adamwoodland, posted: 2018-12-04 03:27:40
The issue with indirect tags is scaling. On a single mimic/head you probably won't notice anything, but multi-user systems with multiple mimics open on each head expect to see a significant load start to appear on the server the clients are connected to.
This trips up a number of customers I work with causing performance issues. Defining animation using the 'cumbersome' approach may mean a quicker development but means less efficient server processing over the many years the system is in use.
If anyone chooses the path of indirect tags make sure to fully read the help, for example "Core Reference Coding Expressions Indirect Tags", for the impact and the actions to take to minimise the problems.
Reply User: dmercer, posted: 2018-12-04 03:28:05
Another similar thing, which does cause a performance hit, is to do queries inside an expression. eg:
['?SELECT TOP(1) Id FROM CDBObject']
This should definitely be used sparingly, because I have seen it bring a system with a very powerful server and extremely low latency to its knees by having maybe a few hundred of these in a mimic.
Reply User: nminchin, posted: 2018-12-04 03:45:17
+1 for the very noticeable effect of a select query inside of animations - I've already experimented with those and put them on my no-fly list!
Point taken RE performance hit. I did suspect that this would be the main reason this approach wasn't overly used, and why it isn't viable in the long term.
I guess I'll continue to use the ~~cumbersome~~ most server-efficient method
Reply User: sbeadle, posted: 2018-12-04 08:37:16
With great power comes great responsibility ...
Reply User: sbeadle, posted: 2018-12-04 08:45:39
Also note that indirect tags have different impact levels on embedded mimics when choosing either 'shared with embedded' or 'non-shared' property.
Reply User: JesseChamberlain, posted: 2018-12-07 00:55:09
These are some of the most common causes of poor mimic performance that I've come across, so I'll write some explanations for anyone that comes across the thread.
**Indirect animations** [square bracket syntax] causes multiple round trips each mimic refresh and is very inefficient if the 'shared with other embedded mimics' option is left ticked.
You can identify this problem from DB logs if you use [CS File Analyser](https://tprojects.schneider-electric.com/telemetry/display/CS/CS+File+Analyser "CS File Analyser"). The analysis will come back with something along the lines of "multiple add/remove single items".
**SQL animations** should be used **very** carefully. They are not cached in any way and do not time out, so for one such animation that is on the header of every mimic (for example) the load on your server becomes: SQL execute time * mimic refresh rate (default 1s) * client count.
If SQL execute time mimic refresh rate, they will keep backing up which will lock the server. I've seen this result in mimics not updating at all. The calling card in DB logs is [QueryTagManager], which isn't currently picked up by CS file analyser but in default logs will be pretty easy to find manually.
The workaround is to use SQL vars in ST logic, which should be declared as VAR NOCACHE, and run at a reasonable interval (does it really need to be quicker than 10s?). This will cache the SQL result, and logic can time out. The load is now: SQL execute * Logic execute interval; ie independent of client count.
**Alarm summary tags** are the built in tags like AlarmAcceptedCount or AlarmState when used on a group or instance. These are calculated at the subscription rate, so if you use them in an animation, again they are calculated at mimic refresh rate. For an object, this is fine, but when they are summarising a lot of objects in a group, the server load: mimic refresh rate * calculation time * client count - can get problematic. I've seen $Root.AlarmAcceptedCount bring systems to their knees.
If you have them parameterised for every embedded mimic as seen in Nick's screenshot, you might even have subscriptions you're not using.
If the calculation time of the alarm summary tag mimc refresh rate, again they get backed up and don't time out. We call this OPC thrashing. In DB logs this can be identified by OPCDA refreshes that you would expect to be periodic (ie at mimic refresh rate) all being executed at once as fast as the server can do it.
Again the solution is to cache the tag in ST logic.
And please - the simpler you make your mimics, with minimal scripting and less levels of embedded mimics, not only the better they will run, but the easier they will be to troubleshoot, and the less time the poor support engineer will have to spend pulling apart your mimics looking for the above. Not everything has to be crammed into the one mimic using pretty layer visibility and six levels of embedded mimics to create tabbed interfaces.
Reply User: sbeadle, posted: 2018-12-07 08:57:42
Thanks Jesse - plenty of wisdom there.