Write UDT parameter value to OPC tag value if tag value not equal to parameter value

Hello Everyone,

There is likely a simple solution to this issue, but I just can't think of the right way to do this.

I'm trying to write UDT parameter value to an OPC tag value if the tag value is not equal to parameter value. In this case, you can see in the attached image, I have multiple identical UDTs, with the instances named 701 - 730. I'd like to write the "ID" Parameter value, "703" to the value of the OPC tag "MachineNumber". What's the simplest way of doing this?

I appreciate your help!

Best regards,
Rusty

Hello again, Just bumping this message to see if anyone has an idea. Thanks!

If the result is the same, why not unconditionally write?

1 Like

That would probably work too. Here is what I came up with, I used a gateway script on tag change which watches the MachineNr Tags for value change. If a value changes, this script is executed:

# Loop through the UDT instances 
for i in range(703, 730):
    # Construct the UDT and OPC tag paths
    paramName = "Id"
    udtInstancePath = "[default]Continuity/{}_1".format(i)  # Use format method here
    paramPath = "{}/Parameters.{}".format(udtInstancePath, paramName)
    opcPath = "[default]Continuity/{}_1/MachineNumber".format(i)  # Use format method here
    
    # Get the values
    idParamValue = system.tag.read(paramPath).value
    machineNumberTagValue = system.tag.read(opcPath).value
    #print(idParamValue)
    #print(machineNumberTagValue)
    
    # Write the parameter value to the OPC tag if they differ
    if machineNumberTagValue != idParamValue:
        system.tag.write(opcPath, idParamValue)

The reason this is needed is because we have 30 identical machines. When we make changes to one of them, we download the same program to all of them. The only thing different in each program is the machine number tag value.

1 Like

Pretty sure that this is 8.1, so you should be using system.tag.read* functions and building lists of paths to read and write.

This script should produce the same results and should be more performant.

from itertools import product
def chunker(seq, size):
    return (seq[pos:pos + size] for pos in xrange(0,len(seq), size))

parentPath = "[default]Continuity"
readPaths = ["{}/{}_1/{}".format(parentPath,machId,tag) for machId, tag in product(xrange(703,730),("Parameters.Id","MachinNumber")

values = system.tag.readBlocking(readPaths)
writePaths = []
writeValues = []

for paths, (idParam,machNum) in zip(chunker(readPaths,2),chunker(values),2)):
    if machNum.value != idParam.value:
        writePaths.append(paths[1])
        writeValues.append(idParam.value)

system.tag.writeAsync(writePaths,writeValues)
1 Like

Interesting, I'm not familiar with that but I'll try it out. Thanks

Personally, this would be the easiest in my opinion. Just put a Value Changed script on the MachineNumber tag inside your UDT with this script (indent appropriately):

paramTag = tagPath.replace('MachineNumber', 'Parameters.Id')
machId = system.tag.readBlocking([paramTag])[0].value
if machId != currentValue.value:
	system.tag.writeAsync([tagPath], machId)

This will only update the value when it changes, since they won't all change at the same time. It's simple and easy to read.

Also, if you ever add more machines, you don't need to modify any scripting at all, just add the new tag with the proper parameters and it just works.

2 Likes

Thanks @michael.flagler, I like your solution.