A tagpath based template doesn't care if it is pointed a UDT instance of type A, or pointed at type B which has A as a parent, or at a tag folder that just happens to have the same structure. Or part of the structure of type A, as long as the template is only using the parts that are present. And it can be pointed at an instance of UDT type C that has no relationship to type A or B, but happens to have the named members that the template uses.
Such a template could also be designed to be pointed at a UDT type B, but gracefully degrade when given type A, type C, or some oddball tag folder. (Using overlay opt-out combined with tag qualities to detect missing tags and adjust the presence/absence of corresponding UI elements.)
Anything that uses UDT properties is stuck working strictly with tags of that data type, and without accessing the added members of any child types. Shackles.
1 Like
Let me address this one separately:
Don't create "objects" from tags. Tags are just data. Your "objects" are your configured UI components (various flavors of Java Swing JComponents) and their containers. Those are the "objects" that matter.
You're describing what I am imagining when I say "pseudo-UDT tag structures", its sort of like building an inheritable object.
Don't create "objects" from tags. Tags are just data. Your "objects" are your configured UI components (various flavors of Java Swing JComponents) and their containers. Those are the "objects" that matter.
But I have objects, and I want to treat them as such. E.g: I have a flowmeter that generates a certain datastream (say flow in gpm and temperature in Celsius), and requires certain constraints related to how to view those things (flow range, temperature range). I want a FlowMeter object that I can point at a templatized widget that is designed to accept some or all of the hooks available to the FlowMeter object. UDTs seem to me like the vector that IA has selected to represent objects. It is unfortunate that I can't build a template that accepts multiple kinds of UDTs, but I will circumvent that with generalized UDTs that are overbuilt to represent a superclass of device -- a flowmeter that doesn't have a thermometer may be put into a UDT that would accept thermometers. The opposite of how I would prefer to do it, but seems to be possible.
I can see how designing something that is folder based could work as well, although it seems like it would require functionally replicating the entire UDT system. I do like the idea of being able to have an incomplete object that a template can handle, and not being beholden to defined UDTs, but I can't justify the amount of effort it would take to do something at this low of a level when there is already the system that exists. I am not building extensions for Ignition, I am trying to build a HMI capable of handling iterations of an R&D system.
Ignition UDTs are perfect for the data stream coming from your Flowmeter. But then you will have variations of that flowmeter (totalizing, perhaps). And pressure meters. And level meters. And pH meters, et cetera ad nauseum. You will have a hugely bloated UDT to accommodate them in your UDT-based UIs, or you will have nice little efficient ones and tagpath based UIs.
You say you need flexibility, but you are dogged in your determination to go down the inflexible path.
You should bookmark this page and revisit it in a year.
1 Like
I can definitely see how this is a problem, don't get me wrong. I've been trying to build UDTs that are composed of smaller UDTs in order to be able to keep everything as modular as possible, and I have already identified that I either need more UDTs or UDTs with way too much information in them. My biggest hesitation about switching to a folder based pseudo-UDT is that it will cost me a large number of features available to me in Vision.
You say you need flexibility, but you are dogged in your determination to go down the inflexible path.
I am trying to use the product for what it has available before gutting it and rebuilding it for myself -- the main point of paying for enterprise software instead of building it from scratch like I would normally do. We're trying to do as much as we can with minimal manpower and maximum of off-the-shelf adaptation. Ignition and the HMIs developed therein are a fraction of my responsibilities.
Not following. Ignition supports both UDT based UIs that have property bindings and tag-path based UIs that have indirect tag bindings. About the same number of bindings, overall.
The only feature you are giving up is selecting templates via drop target. You will make huge gains in re-usability and efficiency that more than compensate.
You don't have to take my word for it. Ignition is a big and complex monster that takes some getting used to. You are welcome to explore your method, and I'll likely never notice if you never concede these points.
But go make a mess for give it a year.
1 Like
Not following. Ignition supports both UDT based UIs that have property bindings and tag-path based UIs that have indirect tag bindings. About the same number of bindings, overall.
I will take a pass at a folder based architecture for my next widget, and see how it works out. I really do see the advantages that you describe and the pitfalls of the current UDT system, but (beyond implementation time to get off the ground) I also worry about the ease of use for my other teammates who do not have as much scripting experience as I do. Drag-and-drop is pretty easy to use.
It really would be nice if you could drag and drop a folder onto a template to have it reference that path -- then I would be substantially more encouraged to abandon UDTs. Perhaps thats why they haven't done it? ![:slight_smile: :slight_smile:](https://emoji.discourse-cdn.com/twitter/slight_smile.png?v=12)
That's what I mean about the drop config feature for Vision. You essentially have that in Perspective.
1 Like
I haven't done much work in perspective, maybe I am making a mistake to develop our HMI in Vision -- I see that most of the development these days goes towards Perspective. The main reason I want to do it in Vision is so that it is more of a terrestrial HMI -- I am not looking to have mobile access to the HMI or access it via a webpage on arbitrary devices. I want to use the deployed Vision Clients.
I'm more than a bit biased towards Vision myself, but there's no denying that Perspective has some major advantages for flexible UIs.
I'm more than a bit biased towards Vision myself, but there's no denying that Perspective has some major advantages for flexible UIs.
All of those are concerns that I share. Especially
One other missing piece: Vision can launch local applications of any kind, monitor their operation, exchange data with them, and kill them off. Perspective cannot do this. And likely never will.
I guess I am sticking with Vision! Perspective seems great for factory monitoring and light control, but not so much for R&D. I will take a pass at the p(seudo/hil)UDT architecture tomorrow, I can live with copy pasting tag paths instead of dragging and dropping. Thank you for that clarifying edit, it will help me get started. And thank you again for your advice and assistance!
1 Like
What I normally do, is for each different variant of a device type that is different enough to warrant it, I create a variant UDT definition for each.
For example, you might have a MotorVSD and MotorDOL UDT. You might have different variations of these as well, in particular for VSDs for different brands since they might have different data you get back from them. You can have these UDTs all inherit from a parent UDT that has your base tags defined in it, along with the default parameters. In fact, I have a UDT that I use as the parent for all of my device UDT types that add the base parameters that I use for all device types.
Then, as Phil has stressed, I pass in the tag path (actually, I pass in both the DeviceName and the DeviceParentPath and combine these into the DeviceTagPath which is the tag path to the UDT instance) into my Templates (Vision) and View "Templates" (Perspective). In the template, I then use indirect bindings that use the DeviceTagPath and append onto that the tags or UDT parameters that I want to use.
The reason I pass in the DeviceName and DeviceParentPath independently, is to make populating them easier. For example, you can multi-select all of your device templates on the screen and set the DeviceParentPath all at once, assuming they all exist in the one folder, or at least aren't far from each other. Then it's simply a matter of populating the DeviceName. The other reason is so that the DeviceName is always visible. If you just passed in DevicetaGPath and this is longer than the width of the property field (more than likely it will be), then you will always have to scroll to see it.
UDTType parameters in Vision Templates, while they seem great at first, you soon learn their pitfalls and learn to avoid them like the plague (should I say COVID nowadays??)
2 Likes
One final dart to throw at UDT-based templates:
They are effectively impossible to use in the Template Repeater and Template Canvas components.
2 Likes
The actual plague was far, far worse than Covid. So, no, "avoid UDT props like Covid" doesn't have anywhere near the necessary oomph.
1 Like
We create 3 standard expression tags in every UDT
MetaTitle
Bound to {Title} which is a parameter set on the UDT instance.
MetaTagName
Bound to {InstanceName} which pulls the name of the UDT instance
MetaTagPath
Bound to {PathToParentFolder} which pulls the tag path of the UDT instance.
Then we use those throughout templates for indirect bindings, text displays, etc.
1 Like
Sounds like my core mistake was using UDT type template parameters and locked myself out of all of these capabilities, I understand now I need to be using at least the path to the UDT instead if not an entirely non-UDT data structure
Eh. Not a fan of creating a new datatype that is really just a string. Tough to integrate that with existing tagpath based templates. I'd just like to see a template property that identifies which template parameter should be filled in with a tag path upon drop. Default to empty string to not have one--backwards compatible.
Having it intelligently determine that a string should be a path would be great and totally cover it, I just figured it was more likely to get implemented if it didn't require changing the functionality of any current types.
Tough to integrate that with existing tagpath based templates.
Ideally it wouldn't make a difference to the existing ones -- strings still work. This would just be a slightly more decorated string.
Also since I hope someday they have some more object-oriented behavior with paths (so that you can do things like rename them in the Tag Browser without breaking everything), this would be compatible with that ![:crossed_fingers: :crossed_fingers:](https://emoji.discourse-cdn.com/twitter/crossed_fingers.png?v=12)