Set/Configure tag binding with script in Perspective

Hello,
From my research online it might not be possible (yet). However, I have seen some people claiming it has been possible in Vision.

I want to configure tag bindings via script in Perspective.
Let's say I have a onStartup script that populates a map with multiple markers where each marker represents a vehicle in a fleet of vehicles. The markers latitude and longitude are dynamic and the data comes from vehicle specific tags. Is there a way to configure the tag binding with a script.

I can set the value for Lat and Lng manually by "self.props.layers.ui.marker[0].lat = Value" however, this does not configure a binding to a tag and would require me to run a while loop continously to update the value dynamically like a tag binding would do.

You cannot. You can directly edit the view definition in the gateway filesystem and wait five minutes for Ignition to notice. That would be a project-wide change. There is no solution for per-session binding creation.

There is limited ability to programmatically create bindings for Vision in the designer. All undocumented, unsupported, and cryptically intricate. The options for creating bindings in runtime in a Vision client are more limited than that.

So there is no way to automate configuring tag bindings?

Is it then acceptable to update values that would normally be read directly off a tag by having a script read the tag value and update the value in a continous while loop?

No, there is no way to do it in perspective.

What exactly are you trying to accomplish? I would always recommend against a continuous while loop. What is preventing you from using embedded views and indirect tag bindings? There are other mechanisms for periodically updating if needed. Look into Gateway Events, specifically Scheduled, Timer, and Tag Change.

1 Like

Never use a continuous while loop. You probably want a polling binding that will call a script that does all of the tag reads and property writes at once. Consider runScript() with a non-zero poll time. (A view custom prop would be most appropriate.) Presumably the script can dynamically determine the tag/property relationship from the rest of the view's properties.

What I am trying to achieve is to update the position of units on our fleet on a map component with the Latitude and Longitude values for a marker. Our units move around and therefore the locations change at random times. Therefore I would be interested in updating these values on tag change.

However, since we have so many units i am trying to automate adding them to the map with a script that populates markers on the map, and this is where I wanted to automate the configuration of tag bindings to avoid manually configuring them.

Consider using a gateway tag change script subscribed to all of the relevant tags. That event script can then re-package the important parts of the event into a payload for system.perspective.sendMessage() at session scope. That relays these events into your GUI. The map would have a message handler listening for these broadcasts and checking if it contains a marker matching the incoming event, and updating the appropriate property. Probably worth only writing to the prop if it is actually different, minimizing browser churn.

The only manual part would be adding each vehicle's tags to the gateway tag change event's list. You can use a designer script that browses for relevant tags and spits out a list of tag paths. That minimizes the chances for mistakes.

4 Likes

Thank you for this! You are truly an expert user.
Could you provide a simple example of configuring one tag on a component using this approach?

I am getting "No perspective session attached to this thread." when trying to use system.perspective.sendMessage(messageType, payload) in a gateway event timer script.

Trying to use system.util.sendMessage(project ='name of project',messageHandler,myDict ='payload',scope ='CG') but no component seems to be listening for these messages

Have you configured the message handler on the component? Is it set to listen on the correct scope?

Ah, right. You need to use system.util.sendMessage() to cross from plain gateway scope to Perspective sessions. Use scope='S'.

I am still not able to communicate to a component within a view in perspective with this approach.
Do you see anything obvious that I am doing wrong?

The gateway script is has success status in the gateway, but the message handler of the component is for sure listning for a system.perspective.sendMessage(messageType, payload) and not a util as I can see it.

So, to get this to work I had to make a handler in the project's "Session Events" to receive from system.util.sendMessage(..., scope='S'). It then just calls system.perspective.sendMessage(..., scope='session') with the same payload. The component can receive this latter broadcast.

This is a nuance that should be put in the documentation. (That messages broadcast to Perspective via system.util.sendMessage(..., scope='S') can only be received in "Session Events".)

1 Like

You could probably use system.perspective.getSessionInfo() to get a list of session IDs to broadcast out with system.perspective.sendMessage from a 'regular' gateway thread. Might or might not be worth the effort compared to the indirect solution.

Meh. Not. The intermediate handler is trivial and only needs to be in one spot.

1 Like