Project-scoped "global" variables for steering tag bindings

Right, I get that. I've tried multiple passes at self-aware tags that can be modified by adjusting where they are in a tag structure with incredibly limited success. I understand conceptually the separation, and many (surely not all) of the resulting consequences, but my understanding has evolved over time with my use of the platform so some of my older design choices are in the process of being refactored.

That said, is there any chance that there is a place where it is relatively safe to text-replace something like "MyProject1/PLC0" with "MyProject2/PLC0" in all tag bindings for a project (I assume bindings are owned by the project, if the tag system doesn't even know that this is a different project)? Or even better go all the way to script replace Tag Bindings with Indirect Bindings like {1}/PLC0 where {1}=[HMI]MyProject2/project?

I have hundreds of elements that are bound and I'd love to avoid having to manually rebinding every single element in my project. They all follow a carefully selected pattern that could be updated, but I need to be able to both fetch and update underyling bindings with a script. I know how to do this for tags, but not for bindings.

If your projects are set to use XML storage, then you can do this in the gateway filesystem. sed -i .... or similar.

1 Like

I don't know if that is how they are stored. My gateway is running in a container orchestrated by Kubernetes and is frustrating to access directly. I will try exporting the project to zip and opening it in an IDE to see what I find

Nope, the good stuff is all in a .bin. @PGriffith no way I'd be able to do this project export with a little more verbosity?

Change the storage format in the project properties. Open and re-save every window and template. Those resources will change to XML.

1 Like

Ok well that was what I needed to find the source XML, thank you. Weird behavior though, I tried changing one and then two of my text fields to be Indirect and one of them is always this massive chunk of XML. I'm guessing whichever one gets seen first gets 4000 lines (only 10000 in the whole file) of configuration jammed into its definition. I guess the rest of them refer to that first definition. Anyway, its a bit more complicated than I would feel good about trying to edit via script, which is a huge bummer. The indentation is not the same between the two components and I am not sure how these reference numbers are generated or used so I am not sure what else would break to replace the Tag binding with an Indirect Tag binding. So I guess I am SOL and need to manually redo basically every single binding in my application.

I realize that fixing things like this are not really supported, but I am disappointed that this system is less regular than the tag system. I have made a lot of thing work with the system tag configuration scirpting methods and I currently very much wish there were binding editor equivalents.

Example bindings:

normal Tag binding ("SimpleBoundTagAdapter") looks like

							<o cls="com.inductiveautomation.factorypmi.application.binding.SimpleBoundTagAdapter">
								<o-c m="setBidirectional" s="1;b"><true/></o-c>
								<o-c m="setQValue" s="1;com.inductiveautomation.ignition.common.model.values.QualifiedValue">
									<o cls="com.inductiveautomation.ignition.common.model.values.BasicQualifiedValue">
										<o-ctor s="3;O;com.inductiveautomation.ignition.common.model.values.QualityCode;date">
											<dbl>3.031247615814209</dbl>
											<qc>192</qc>
											<date>1742430748601</date>
										</o-ctor>
									</o>
								</o-c>
								<o-c m="setTagPathString" s="1;str"><str>[PROJ]TB1/L1/BP11_pressure</str></o-c>
								<o-c m="setTarget" s="1;java.awt.Component"><ref>258</ref></o-c>
								<o-c m="setTargetPropertyName" s="1;str"><ref>174</ref></o-c>
								<o-c m="setValueClass" s="1;java.lang.Class"><class>d</class></o-c>
							</o>

"normal" (not that one that has the WHOLE map for indirect actions) indirect binding looks like

							<o id="264" cls="com.inductiveautomation.factorypmi.application.binding.IndirectTagBindingAdapter">
								<o-c m="setBidirectional" s="1;b"><true/></o-c>
								<o-c m="setPathParts" s="1;[com.inductiveautomation.factorypmi.application.binding.IndirectTagBindingAdapter$IndirectTagPathNode">
									<array cls="com.inductiveautomation.factorypmi.application.binding.IndirectTagBindingAdapter$IndirectTagPathNode" len="3">
										<o cls="com.inductiveautomation.factorypmi.application.binding.IndirectTagBindingAdapter$IndirectTagPathNode">
											<o-c m="setString" s="1;str"><ref>263</ref></o-c>
										</o>
										<o cls="com.inductiveautomation.factorypmi.application.binding.IndirectTagBindingAdapter$IndirectTagPathNode">
											<o-c m="setRefIdx" s="1;i"><int>1</int></o-c>
										</o>
										<o cls="com.inductiveautomation.factorypmi.application.binding.IndirectTagBindingAdapter$IndirectTagPathNode">
											<o-c m="setString" s="1;str"><str>/L1/BP10_pressure</str></o-c>
										</o>
									</array>
								</o-c>
								<o-c m="setQValue" s="1;com.inductiveautomation.ignition.common.model.values.QualifiedValue">
									<o cls="com.inductiveautomation.ignition.common.model.values.BasicQualifiedValue">
										<o-ctor s="3;O;com.inductiveautomation.ignition.common.model.values.QualityCode;date">
											<dbl>0.11799487471580505</dbl>
											<qc>192</qc>
											<date>1742430748601</date>
										</o-ctor>
									</o>
								</o-c>
								<o-c m="setReferences" s="1;java.util.Map">
									<o cls="java.util.HashMap">
										<o-c m="put" s="2;O;O">
											<int>1</int>
											<o id="265" cls="com.inductiveautomation.factorypmi.application.binding.PropertyListenerDescriptor">
												<o-c m="setAdapter" s="1;com.inductiveautomation.factorypmi.application.binding.Adapter"><ref>264</ref></o-c>
												<o-c m="setInteractionListener" s="1;com.inductiveautomation.ignition.common.binding.InteractionListener"><ref>264</ref></o-c>
												<o-c m="setListener" s="1;java.beans.PropertyChangeListener"><ref>265</ref></o-c>
												<o-c m="setQValue" s="1;com.inductiveautomation.ignition.common.model.values.QualifiedValue"><ref>266</ref></o-c>
												<o-c m="setSource" s="1;java.awt.Component"><ref>267</ref></o-c>
												<o-c m="setSourceProperty" s="1;str"><ref>101</ref></o-c>
											</o>
										</o-c>
									</o>
								</o-c>
								<o-c m="setTarget" s="1;java.awt.Component"><ref>262</ref></o-c>
								<o-c m="setTargetPropertyName" s="1;str"><ref>174</ref></o-c>
								<o-c m="setValueClass" s="1;java.lang.Class"><class>d</class></o-c>
							</o>

The huge hashmap embedded in the other Indirect binding object is not something I can share:

Getting directed to muck around in any of the resources that are opaque-ish XML or opaque binary serialized is kind of the equivalent of getting an insanely high "go away" quote from a contractor.

It's technically possible to proceed here, but neither party really wants to.

3 Likes

Nobody directed me to do it, I just was hoping it would take me less time to take that apart and put it back together than to manually change 1000 tag bindings. Honestly, it might still, but at a higher level of risk.

TBH a sed of the bindings from tag path A to tag path B should Just Work -- and if it doesn't, it's quick to test (and you can always restore from a backup/project export if not).

Some parts of the XML here are pretty arcane but the tag binding schema is basically just strings and refs.

Probably what I'd do is write a helper script to do that SED globally across window XMLs in your case, though that's a bit risky for sure.

NOTE: I wouldn't be broadly recommending this if @pturmel hadn't suggested it first, but that makes me less concerned about it.

1 Like

Hot swapping the addresses will work as a band-aid but the real thing I need is a properly introspective system that can have a few steering tags. Will have to redo all of them as Indirect tags.

1 Like

There's an explanation, but is so arcane that it is better if you figure it out yourself. Or troll through this forum for clues.

A carefully bounded sed should get you really close in bulk.

It definitely smelt of the arcane. I will leave it to the true historians to know, I have a large task ahead of me; I can see where I might be able to pull off a swap but I have to redesign my UDTs and everything to work with this new schema anyway so I may as well get my hands dirty. Thanks for the help today.

Lol, this is the slightly nicer version of just linking the wikipedia page for pass-by-reference

2 Likes