I'm creating views in Perspective for different processing systems of a plant. Each of these systems contains any number of instruments, valves, pumps, controllers etc. I want to create a tag UDT that represents the overall state of all these devices that can be accessed from anywhere else in the project, for example a process overview, menu link etc.
I could do this in the PLC but since this is really a SCADA tool and not directly related to process control I'd like to keep the programing on the ignition side.
Currently I'm achieving this by creating a UDT with a 'tags' tag that contains a dataset of all the tags that need to be monitored for that system and a periodically run script that reads the tag values and returns a status:
This works but the problem I've found is that if I move a tag within the tag provider (new tag path) there isn't a sensible way to update the tag path in the dataset. The find and replace tool doesn't pick it up.
This raise a wider question to me,
What is the best way to execute ignition side logic? Tag changes scripts, tag expressions, gateway scripts?
Where should data be stored? In tags, database, other?
Is this what sequential function charts are for?
I'd be interested to hear how others implement ignition side logic.
I use gateway events (in a project) before other methods, so gateway tag change events, gateway timer events, gateway scheduled events, and message handlers. Mostly.
I avoid using tag events (on a tag) unless it is defined in a UDT (never overridden), so it can be maintained in that spot. Tag events (on a tag) are also unsuitable for anything complex or requiring communications (so, no DB or network calls). Where needed, even in UDTs, I would have the tag event delegate to a java queue to be handled by a timer.
I despise Sequential Function Charts. I don't use them in PLCs, nor in Ignition.
Store short-term, easily reconstructed data in project library script top-level collection variables, typically dictionaries or lists.
Store data that needs to be remembered either in gateway memory tags or in your database.
Store data that needs to survive project saves, but can be reconstructed on gateway startup, in a unique key in the dictionary from system.util.getGlobals(). Store only native python or java objects, never python class instances or method or function code, unless you take care to track and replace all such upon project save (scripting restart). (Search for my posts involving getGlobals for much advice.)
Hey Phil, is this method too long to explain/get me started? I'm very interested
Also (unrelated to your post) , can you explain why it's bad to define a function within somewhere like a tag event handler? Is it just that it's inefficient to constantly define a function within a function every time the parent is called? Or are there other reasons? I assume the python garbage collector will clean up these function definitions so it's not an issue of memory, right? (I'm not saying I define functions in functions, but I don't understand the implications of doing it if I was to)
This, unless you really need a closure for a short function, but
Many event scripts have legacy scope rules that prevent def from pulling in any top level variables in that script into the function scope. Move such to project library scripts. (That's why you see import system in functions def'd in those scopes.)
Thanks for replies, I think I need to brush up on my general programing skill for some of whats been suggested. I am currently using the scripts module for the odd function but not anything major, I really just use them for centrilisation of scripts so I only have to modify them in one place.