I have just started my first Ignition project and I am trying to find the best approach to create it well structured, easy to maintain and clean code. The main question is, procedural or objective?
Because my system will have different states (e.g. running, stopped, alarm etc.), many counters, flags etc. and it will make many actions on that fields, the natural choice seemed to be objective programming.
So, I have decided to create few different Python classes:
- SystemTag, which holds current tag value and is able to read and set values
- SystemCounter, which inherites from SystemTag, and has additional method for incrementing and decrementing values
- System - main class, which contains fields of type SystemTag, SystemCounter and methods for changing system state based on that fields and additional logic
I have also created UDT. One instance of UDT will corresond to one object of System class. Each tag and counter inside UDT instance will corresponds to SystemTag or SystemCounter fields inside System object.
I have put that classes into shared resources and in the shared resources, I have created an instance of System class. That way, the object is accessible from Tag events and all other Gateway scoped scripting places.
To keep consistency of values between System object and UDT, I have put into all UDT Tags value change events, System object method to update field inside taht System class object e.g. system.tag1.updateValue().
Generally this works good, but I have some questions:
- Is that approach makes sense in opinion of more expierienced Ignition programmers? I have seen few projects of quite similar systems in Ignition, and they all have been procedural. Long functions, in many different places, in my opinion not easy to read and maintain.
- About client scope. If we leave it like that, all client sessions will create new instance of that System object. Correct? So I have decided to create that object conditionally, if we have Gateway scope, return full object, if we have Client scope, return a little bit simpler object (without system logic), just with methods to increment counters etc. This Client scope methods will work a little bit different, beacuse each time we call increment() method, we need to read tag, increment and write again (with Gateway scope reading is not necessary, because actual value is stored inside System object field). Makes sense?
- What is the best approach to detect current scope via scripting? Currently I have used workaround:
try: system.gui #create Client scope object except: #create Gateway scope object
Can’t wait for you opinions. If I was not clear enough, don’t hasitate to ask for some pictures, diagrams or something