Perspective button - write to indirect tag

I have a button which, when clicked, should write a 1 to the “Start” tag in a particular UDT. instance. The desired instance is defined by a view parameter: tagPath. As far as I can tell, at this stage we have to manually write scripts to write to tags, and I figure it should be possible to construct a tag path by accessing the view parameter, and appending ‘/Start’ to the end.

I can’t work out how to get view parameters from the script though - the documentation on perspective scripting is still a little thin, and doesn’t cover that possibility.

I’m imagining something along the lines of system.tag.write(self.view.getParam('tagPath') + '/Start', 1), but nothing I’ve tried along those lines has worked. How might I go about this?

Somehow I didn't manage to find it in my searches earlier today, but I've just found this thread asking almost the same question, which has the solution.

system.tag.writeAsync([self.view.params.tagPath + '/Start'], [1]) should do the trick, I think. I'll try it in the morning.

Still interested to hear if anyone has a simpler way of doing indirect tag addressing on a button :slightly_smiling_face:

(edited to add square brackets, as required for system.tag.writeAsync() function

It looks like the indirect binding feature seem incomplete.
Before writing to a tag indirectly I wanted to get a indirect binding working.

Here's the setup I used:

view.customer.tagPath:
image

Here's the log in the gateway console when applying this binding:

ExecutionQueue 21Feb2019 11:55:39 Uncaught Throwable during execution.
java.lang.IllegalArgumentException: Malformed path: 1
at com.inductiveautomation.ignition.common.JsonPath.parse(JsonPath.java:199)
at com.inductiveautomation.ignition.common.JsonUtilities.read(JsonUtilities.java:181)
at com.inductiveautomation.ignition.common.JsonUtilities.readString(JsonUtilities.java:59)
at com.inductiveautomation.perspective.gateway.binding.tag.TagBindingConfig.referencesFromJson(TagBindingConfig.java:48)
at com.inductiveautomation.perspective.gateway.binding.tag.TagBindingConfig.fromJson(TagBindingConfig.java:71)
at com.inductiveautomation.perspective.gateway.binding.tag.TagBindingFactory.create(TagBindingFactory.java:40)
at com.inductiveautomation.perspective.gateway.binding.tag.TagBindingFactory.create(TagBindingFactory.java:20)
at com.inductiveautomation.perspective.gateway.binding.BindingRegistryImpl.createBinding(BindingRegistryImpl.java:94)
at com.inductiveautomation.perspective.gateway.model.AbstractBindingHarness.(AbstractBindingHarness.java:63)
at com.inductiveautomation.perspective.gateway.model.DesignerPageModel$BindingPreviewSupport$PreviewBinding.(DesignerPageModel.java:160)
at com.inductiveautomation.perspective.gateway.model.DesignerPageModel$BindingPreviewSupport.start(DesignerPageModel.java:118)
at com.inductiveautomation.perspective.gateway.model.DesignerPageModel$BindingPreviewSupport.lambda$null$0(DesignerPageModel.java:113)
at java.base/java.util.Optional.ifPresent(Unknown Source)
at com.inductiveautomation.perspective.gateway.model.DesignerPageModel$BindingPreviewSupport.lambda$start$1(DesignerPageModel.java:113)
at java.base/java.util.Optional.ifPresent(Unknown Source)
at com.inductiveautomation.perspective.gateway.model.DesignerPageModel$BindingPreviewSupport.start(DesignerPageModel.java:112)
at com.inductiveautomation.perspective.gateway.model.DesignerPageModel$DesignerHandlers.lambda$null$4(DesignerPageModel.java:266)
at com.inductiveautomation.ignition.common.util.ExecutionQueue$PollAndExecute.run(ExecutionQueue.java:123)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

@code_skin: I believe the reference variable (“1” in your case) must be a String, but I’ll have to investigate further. For now, try renaming the reference variable to something like “path”, and see if that allows you to proceed.

Confirmed the cause, and the good news is that a fix is already complete - it’s just awaiting internal review. The fix for this should be in place in the next few days and at that point a number will work correctly.

In the meantime, please use a String reference variable.

1 Like

That worked. Thanks!

1 Like

Here’s what I’ve come up with; not sure if this is simpler or not for you.

I created a custom property on a button “toggleValue”
used this indirect tag binding:

Then I created a script to toggle that customProperty:

Alternatively, you could use the one-shot button or trigger and attached a bidirectional indirect tag binding.

If want to go the custom property route, your script to toggle it should just be self.custom.toggleValue = not self.custom.toggleValue for simplicity’s sake.

Alternatively, you could have done all of this with a ToggleSwitch, which removes any of the overhead of state tracking (assuming you’re only doing boolean values).

1 Like

I tried system.tag.writeAsync but it did not work, with an error about not being able to coerce my tag path into a list. I thought writeAsync was for a single tag and writeBlocking was for multiple tags, but looking at the manual pages, it looks like they’re both for multiple tags and Async is just for asynchronous writing. system.tag.write still works, but if it’s being deprecated, is there a single-tag-write equivalent that I should be using?

There is no new, dedicated single-tag-write function in 8.0 - but there’s no reason not to put your single tag path in square brackets in order to send it as a list.

2 Likes

PG, will you please provide a code snippet of system.tag.writeAsync usage including the callback as well. Thanks.