Hi everyone, hopefully this question will be easy for you guys!
In a tag script I am trying to add an amount of time(as an integer) to the current time, when a process starts. See my code above. This code works as intended when the highlighted code is replaced with a hardcoded integer. It does not work when I try to use a tag value.
To recap, When the "lift raised" tag goes from 0 to 1, I want to write the current system time to CycleStartTime and I also want to add StationCycleTime to current system time and write the sum to CycleEndTime.
I have been stuck on this for a while and am wondering if it is even possible. maybe I can't reference other tags inside of a tag script?
Any help would be greatly appreciated!
Luke M. Smith
This is how it shows up when I click the "insert tag" icon. Also it seems to work with that syntax for the other tags in the script. How would I do it then? {} ?
system.tag.writeBlocking's syntax is system.tag.writeBlocking([list-of-tag-paths], [list-of-values])
It runs through the list of tag paths and does a write to each of those using the corresponding value from the list of values. You need to get that value using system.tag.readBlocking([list-of-tag-paths]) first.
if previousValue.value != currentValue.value and initialChange == False and currentValue.value == 1:
system.tag.writeBlocking(["[default]Station/ACell_15/Stations/Unload/CycleStartTime"], [system.date.now()])
system.tag.writeBlocking(["[default]Station/ACell_15/Stations/Unload/CycleEndTime"], [system.date.addSeconds(system.date.now(), '[.]../StationCycleTime.value')])
So you're saying to do system.tag.writeBlocking(["[default]Station/ACell_15/Stations/Unload/CycleEndTime"], [system.tag.readBlocking(system.date.addSeconds(system.date.now(), '[.]../StationCycleTime.value'))])
if current.value and not initialChange:
cycleTime = system.tag.readBlocking(['[default]Station/ACell_15/Stations/Unload/StationCycleTime'])[0].value
start = system.date.now()
end = system.date.addSeconds(start, cycleTime)
system.tag.writeBlocking(['[default]Station/ACell_15/Stations/Unload/CycleStartTime', '[default]Station/ACell_15/Stations/Unload/CycleEndTime'], [start, end])
Jordan beat me to it (and did a better job). Note that there is only one writeBlocking call for both tags. This will be more efficient.
Yours wouldn't work because you are trying to read a tag called system.date.addSeconds(system.date.now(), '[.]../StationCycleTime.value')
which is not a valid tag path.
@JordanCClark , seeing it written that way brought me joy. so much more beautiful than what I had. @Transistor , that makes sense. Thank you! I put Jordan's code in and it is not working. Neither CycleStartTime or CycleEndTime are being changed. Can you explain the [0] portion of this line? cycleTime = system.tag.readBlocking(['[default]Station/ACell_15/Stations/Unload/StationCycleTime'])[0].value
You've only read one tag but the function still returns a list so you need the first tag qualified value. So, system.tag.readBlocking(['.../StationCycleTime'])[0]
will give you that.
Inside that you want the value so, system.tag.readBlocking(['.../StationCycleTime'])[0].value
You could also retrieve system.tag.readBlocking(['.../StationCycleTime'])[0].timestamp system.tag.readBlocking(['.../StationCycleTime'])[0].quality
Error I am getting
Error executing script.
Traceback (most recent call last):
File "tagevent:valueChanged", line 6, in valueChanged
AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'WriteBlocking'
Just thought of something here. A few cups of coffee will do that to a person. This script is on a tag. You should be doing an asynchronous write instead of a blocking one, as there is only-- by default-- three threads dedicated to those types of scripts. So, you want it to be as speedy as possible.
Also, you should do the check for initial change prior to any check of previous value. And, it should be currentValue.value not current.value
if not initialChange and currentValue.value:
cycleTime = system.tag.readBlocking(['[default]Station/ACell_15/Stations/Unload/StationCycleTime'])[0].value
start = system.date.now()
end = system.date.addSeconds(start, cycleTime)
system.tag.writeAsync(['[default]Station/ACell_15/Stations/Unload/CycleStartTime', '[default]Station/ACell_15/Stations/Unload/CycleEndTime'], [start, end])
Honestly though, this should most likely be done in a Gateway Tag Change Event, rather than a Tag Value Change event, for performance reasons. Generally, you want any ValueChange script like this to execute in single digit ms.
You may also want to consider that it is possible that the value in the PLC/Device may not be updated when this event triggers so you could be reading stale data. Unless you have done something in the device to insure that this trigger tag is not updated until all needed data is ready. This is because readBlocking() reads the value of the tag in Ignition, not the value of the tag in the device. They are not always equivalent. There is potential for a race condition here.
Thank you for the input, this is my first ignition project in years so I am relearning everything as I go. Where and how to script to be the most efficient is where I am struggling the most, so your comment is very helpful. Thank you! I will try to switch it over to a Gateway Tag Change Event.