Hey all. I've been trying my hand at utilizing tag change scripts to write values from query tags down into the OPC tags from the controller. I very quickly ran into an issue, though, as none of my scripts will fire. I tried multiple iterations of my real script before deciding to make a simple testing setup to diagnose the issue. The testing script and setup is as follows:
if newValue.value:
read = system.tag.readBlocking("[default]R300/test/Read")
arg = read.value
system.tag.writeBlocking("[default]R300/test/Write",arg)
I created 3 dummy tags to go with the script:
Trigger: (boolean memory tag)
Read: (integer query tag)
Write: (integer memory tag)
The script runs upon a change in Trigger, and obviously my goal is to read the value from the Read tag and write it to the Write tag. However, nothing seems to allow me to do this. I have tried removing the line:
if newValue.value:
as well as try a completely explicit write script with nothing else:
Additionally, I tried using system.tag.writeSynchronus, as I saw it recommended in a similar thread.
I have a handful of tags that I want to read from and write to at once, but I cannot manage to get even this simple case to work. Any advice on this issue would be greatly appreciated!
You need to extract the qualifiedValue as system.tag.readBlocking returns a list of qualified values. Heres an example:
read = system.tag.readBlocking("[default]R300/test/Read")
arg = read[0] # extract the qualified value from this list, there should only be 1 because we are reading a single tag value`
print arg.value
you can also just do: arg = system.tag.readBlocking("[default]R300/test/Read")[0].value
For your system.tag.writeBlocking you should be passing a list of tag paths and list of values, like this:
if newValue.value:
arg = system.tag.readBlocking("[default]R300/test/Read")[0].value
print arg
system.tag.writeBlocking(["[default]R300/test/Write"],[arg])
Unfortunately, I still see no updates to the tag. Additionally, I do not see the 'arg' value printed or any errors thrown in the console. The only indication in the console that I'm doing anything at all is the wall of project saves.
Neither one of you should be using print. That isn't captured by the gateway log, only the wrapper log. I say gateway log because gateway events don't run in your designer, so they aren't going to write to the designer's console.
There's very likely some subtle error in your event code that is throwing an error (once) in the gateway log. Look there.
Aside from that, consider your architecture. Your goals sound suspiciously like some kind of recipe load operation. If so, you should not be using query tags, but scripting your queries after the trigger fires. Then writing to your tags (in one single big system.tag.writeBlocking()) from the result.
Thank you for the insight, I was able to find an error in the gateway log that can be condensed down as follows:
"Cannot coerce value '[default]R300/test/Read' into type: interface java.util.List"
because I was missing a pair of brackets around my readBlocking argument. Fixing the bracket issue allowed me to write to the tag as initially intended, but I take your meaning regarding the query tags. The script seems functional now but I'll be sure to rewrite to include the queries directly in the script instead of using an intermediate tag for them.
This is exactly the type of process that Transaction Groups are made for, if you do not have the SQL Bridge module, then you should definitely be running the query in the script. I would recommend system.db.runNamedQuery().
system.tag.readBlocking() takes a list of tag paths. It returns a list of QualifiedValues maintaining the order the tag paths were passed in.
You can the. Reference the value of those tags by index in the list.