Gateway tag change script not executing

Good Morning, I’m writing a script for my OEE monitoring system to monitor the number of active and down machines for all the machines in the shop. I’m using a tag change script that executes when the boolean value of selected tags changes. The original script is below:

########################################################################

# Specify the paths.
paths = [
    "[default]Machines/Machine_Information_Template/Machine_Activity/Down",
    "[default]Machines/MT_Robot/Machine_Activity/Down"
    
    #^add your tag path for a new machine above
]

active = 0
down = 0

# Read tags
values = system.tag.readBlocking(paths)

# Loop through results
for i in range(len(values)):
    tagValue = values[i].value

    if tagValue == False:
        active += 1
    else:
        down += 1

print active
print down
system.tag.writeBlocking("[default]Main_Metrics/Overall/Active_Machines", active)
system.tag.writeBlocking("[default]Main_Metrics/Overall/Down_Machines", down)

########################################################################

In the first iteration, everything was working fine. I updated the code so that the paths in my machine folder associated with the "down" tag is generated automatically, eliminating the need to hardcode the tag paths for each machine.

The code still runs as expected in the Script Console, but not when triggered by the tag change event.

Here is the updated version of the code:

########################################################################

# Find all tags named "Down" under machine folder
def findTagsNamedDown(path):
    found = []
    results = system.tag.browse(path)

    for r in results.getResults():
        name = r["name"]
        fullPath = r["fullPath"]
        hasChildren = r["hasChildren"]

        if name == "Down":
            #Store string path
            found.append(str(fullPath))

        if hasChildren:
            found.extend(findTagsNamedDown(fullPath))

    return found

baseFolder = "[default]Machines"

#Find all Down tags
paths = findTagsNamedDown(baseFolder)

#Make sure every entry is a string
paths = [str(p) for p in paths]

#Count active vs down
active = 0
down = 0

values = system.tag.readBlocking(paths)

for v in values:
    tagValue = v.value

    if tagValue == False:
        active += 1
    else:
        down += 1

print active
print down

# Write machine status values to active and down machines tags
system.tag.writeBlocking("[default]Main_Metrics/Overall/Active_Machines", active)
system.tag.writeBlocking("[default]Main_Metrics/Overall/Down_Machines", down)

########################################################################

Any guidance would be greatly appreciated. I've also attached screenshots of the gateway event script configuration and script console. Thank you!

I am away from my computer, but I think you’ve made this harder than it needs to be. Tag Change events have all the information you need without browsing or reading the values.

When I get back to my desk, I’ll type something up

Yea, agreed with lrose.

Your script should look somehting like this:

activeMachines, downMachines = [qv.value for qv in system.tag.readBlocking(["default]Main_Metrics/Overall/Active_Machines","[default]Main_Metrics/Overall/Down_Machines"])]

if newValue.value == False and previousValue.value == True:
    activeMachines += 1
    downMachines -= 1

elif newValue.value == True and previousValue.value == False:
    activeMachines -= 1
    downMachines += 1

system.tag.writeBlocking(["[default]Main_Metrics/Overall/Active_Machines","[default]Main_Metrics/Overall/Down_Machines"], [activeMachines,downMachines]))

The tag event script will be triggered every time one of the tags included in the Tag Path(s) list is changing. So you would need to read the number of active and down machines first and then adjust the numbers based on the the specific down tag that is changing.

EDIT: Updated the script based on lrose comment.

This worked, thank you! I got a bit ahead of myself and didn't realize that the tag change event did that for you.

also for future reference, use the system.tag.query instead of system.tag.browse. You'll find it much faster, and you can do some nice pre-filtering with it, and also specify return values.

... And use the Tag Report Tool to generate the filtering and copy the system.tag.query()-function from there.

Except don't use multiple reads and writes.

activeMachines, downMachines = [qv.value for qv in system.tag.readBlocking(["default]Main_Metrics/Overall/Active_Machines","[default]Main_Metrics/Overall/Down_Machines"])]

if newValue.value == False and previousValue.value == True:
    activeMachines += 1
    downMachines -= 1

elif newValue.value == True and previousValue.value == False:
    activeMachines -= 1
    downMachines += 1

system.tag.writeBlocking(["[default]Main_Metrics/Overall/Active_Machines","[default]Main_Metrics/Overall/Down_Machines"], [activeMachines,downMachines]))

In my testing I actually found that browse was faster to execute, I don't recall by how much. I don't remember it being too significant though, just thought I'd mention.

Unless you need more that just the tag path, or to filter on more than just the few options supported by .browse(), or filter by complex combinations. system.tag.query() can return the current value and any desired current property values, in the one call. Avoiding the need for a followup system.tag.readBlocking().

However, system.tag.query() is always recursive.