Hello All,
I am developing a perspective application that makes use of UDTs and embedded views to enable drag-and-drop development using the dropConfig feature. This is working well but I am running into an issue I am hoping the community can help me with.
When developing a graphic like a pump I create several custom properties stored in the CP object see Original Parameters screenshot. This is fine until I need to add another property like “MyNewProperty” shown in the Updated Parameter screenshot. The problem is existing embedded views do not automatically update forcing me to find each pump embedded view and update the CP object manually.
So on to my question is there a better way to manage parameters on embedded views? Can it be done dynamically somehow? Ideally, I would be able to update the base/template embedded view and have the rest update automatically somehow.
Original Parameters:
Updated Parameters:
Original Object:
Updated Object:
Thanks!
You can Sync Params manually, if that's what you meant.
As of release 8.1.4, the view parameters available from the embedded view, will appear on a dropdown list of parameters in the Property Editor. You can select any or all of the parameters to add. Two additional operations are available:
- Sync Params - Adds all the embedded view's parameters and removes any parameters that don't exist on the embedded view.
- Sync & Reset - Resets the parameter values to their default.
Embedded Views - Ignition User Manual 8.1 - Ignition Documentation (inductiveautomation.com)
This works for new root param keys, but not for changes to root param keys. i.e. if you add a new param into view.params
, you have the option to add that new parameter via the props.params
context menu in the embedded view, but if you add a new key to a params object like view.params.CP.newParam
, then you're out of luck; the only option you get then is to reset and sync in the embedded view.
@James.Sletten I'm interested however how you're using the dropConfig with your current params?
(also what does CP stand for?)
It looks like some of those params could be taken from the UDT instance itself, well, specifically the "Desc".
I'll give you an idea of how I create my templates for food for thought.
For all devices, I have a single popup that has a header (title/subtitle/tabs) and a footer (exit button), and a content area in the middle.
I pass in some of these params:
- enablePopup
- deviceName
- deviceParentPath
where the deviceParentPath + '/' + deviceName
makes up the deviceTagPath
, the path to the UDT instance.
All but the content area is fixed for all devices. The content area uses a dynamic path which is looked up in a dataset tag which contains a lookup which links tag TypeId to content View to display. So for every device UDT type I have, I add this into the dataset lookup and associate a content View with it to display in the popup.
Using this, I don't have to pass anything into my symbol templates (for example, your PopupPath), and I have a single central list of UDT types and what View content they display.
@andrew.budaiev thanks for your comment. I am aware of the sync params feature but it is not what I meant. Instead of manually going to each instance of the embedded view and syncing parameters I would like any changes to the base/template embedded view to be automatically synced by all embedded views.
As an example in this application if have 50+ motors and finding them all and syncing parameters is time-consuming each time I need to make a change.
Thank you for taking the time to comment. I appreciate it!
@nminchin Currently I have the dropConfig object linked to my UDT param you can see in the first screenshot using a path binding. This allows me to locate my UDT tag in the tag browser then drag and drop it onto the screen where i can select one of my embedded views. Path binding also allows me to access additional metadata like engUnit, documentation, formatString, etc.
CP stands for Custom Properties and is just a naming convention I adopted.
The thought behind the CP object was to expose some embedded view parameters I would like to change when embedding a motor UDT on a screen in the designer. For instance the popup path. If I have a pump that needs a special faceplate for some reason I simply update PopupPath and the view will open the correct popup. Additionally ShowAutoTxt and ShowDesc control visibility animations for some text on my motor graphic. This allows me to have one motor graphic that I can change as needed when dropped on a screen without editing the base embedded view.
I think your popup comment is a little outside the scope of my original question but is interesting. Assuming I understand your comment. You use a data set tag to hold all the views for a specific UDT type and then look up the desired view and pass it to the popup. How are you specifying the content to show? Are you storing it in the UDT or doing some scripting to open a specific view? If you need to pass additional information to the popup how are you accomplishing this at runtime? Are you modifying the dataset tag and then opening the popup?
Thank you for taking the time to comment. I appreciate it!
1 Like
Granted, it was a bit of a reach from what you were asking, haha.
Regarding your issue though, you really only have 1 decent option, and that's to not use an object to store your CPs and instead move them out into the root params
. You'll still have to sync these in all of your templates already embedded, but at least you'll be able to just sync in the new parameters without clearing any configuration.
This is an example of my dataset contents:
TypeId |
P_ContentViewPath |
PopupHeightOverride |
Devices/Analogue Devices/Analogue Input 01 |
_Templates/Devices/Control/Analogue_01 |
650 |
Devices/Digital Devices/Digital Switch 1 |
_Templates/Devices/Control/DigitalInput_01 |
0 |
Devices/Motors/DOL-DOL_RemOS |
_Templates/Devices/Control/Pump_DOL_01 |
0 |
Devices/Motors/DOL-DOL_SS |
_Templates/Devices/Control/Pump_DOL_01 |
0 |
I don't pass anything to the popup apart from the deviceParentPath
and the deviceName
. The popup does all the work:
- combining the two parameters into
deviceTagPath
- reading the typeId of the UDT instance (e.g. reading tag
{view.custom.deviceTagPath} + '.TypeId'
)
- using that to lookup the content View path from the dataset. E.g. lookup
Devices/Analogue Devices/Analogue Input 01
and return _Templates/Devices/Control/Analogue_01
The content View placeholder is just a regular Embedded View component (just drag on any View to get the container in there), and its View path prop is bound to the result of the lookup.
I have some other things in the popup as well so it's not quite that simple, for example I have tabs for Status (that uses the above content View), Details (some UDTs need extra details displayed that don't belong in the Status tab - the View path of this appends " Detail" onto the status view and if found, makes this tab visible), Alarms, PID (if relevant), Settings, can't remember if there are any more..
If there are three things that I would recommend when creating a project, it's
- doing this above (i.e. one device popup with dataset lookup), and
- adding a Status and a Mode descriptive tag into your device UDTs that converts the device status/mode into a descriptive label (Stopped/Running/Faulted, Manual/Auto/Off etc.) and then use the descriptive tag in all your bindings.
- create Perspective Styles for all of your device states/modes, and using a dataset tag to store device descriptive states/modes against the P style to use, then using a lookup in your device symbol bindings to lookup the device state/mode and return the P Style to use => "templated" map transform for your device symbol colours
2 Likes
Very interesting; I use a very similar system, but per UDT-instance instead of globally defined.
Each device UDT contains a FaceplateConfig UDT that controls its faceplate contents.
Example: TT1040/FaceplateConfig/Tabs = memory dataset tag containing:
ViewPath |
Icon |
ExtraParams |
Faceplates/Devices/Analog/Display |
material/home |
|
Faceplates/Devices/Alarms/Default |
material/alarm |
|
UDT inheritance keeps things linked, but you can always override the tabs for a specific instance if needed.
Interesting! I can definitely see where that has its benefits. For overriding, at the moment, I'm able to override the view content in via the device symbol which is very average.. (although I've never actually had to do this before).
Not sure if this issue has been resolved.
I'm going to make one template and 100 instances from it. Lets say months later I add more attributes to the template does all the children from the template get the Update?
I will be using perspective view, dropconfig, and UDTs to build this template similar to what the author of this post is doing.
Yes, however the new params will not be automatically added to all of the instances; they will use the default saved values in the template. You can add them in using the context menu on the props.params on the instances to sync them in.
1 Like