Passing tag values to named query

I have a named query which is intended to log some batch information to a database. I have tested calling the query from a button event script using manually coded variables and it works as intended, so now I want to update it to be called from a tag change script, and to pass values from the PLC into the query.

I can do this by brute force, e.g. something like

values = system.tag.readBlocking([
    'CurrentBatch/ProductCode',
    'CurrentBatch/Description',
    'CurrentBatch/WeightSP'
    'CurrentBatch/ActualWeight'
    ])
parameters = {
    'ProductCode':values[0]
    'Description':values[1]
    'WeightSP':values[2]
    'ActualWeight':values[3]
    }
system.db.runNamedQuery(MyProjectName, MyQuery, parameters)

But it seems like there must be a more efficient way to do it. There are quite a lot of values being logged here.

Is there a way to lump all the PLC tags into a dataset (without building a table on the screen) and just pass the dataset to the query?

Is there a way to read a bunch of tags and have them assigned to each named query parameter in the order they’re defined, instead of having to specify each tag and each query parameter individually by name?

Any other creative ideas on how I can streamline this?

paths = ['ProductCode', 'Description', 'WeightSP', 'ActualWeight']

values = system.tag.readBlocking(["[default]CurrentBatch/{}".format(path) for path in paths])
parameters = dict(zip(paths, values))
system.db.runNamedQuery(MyProjectName, MyQuery, parameters)
1 Like

Neat! And I’ve learned a new python trick. I’ll give it a try!

I had to modify it slightly because system.tag.readBlocking() returns a qualified value, not just the tag value:

paths = ['ProductCode', 'Description', 'WeightSP', 'ActualWeight']

values = system.tag.readBlocking(["[default]CurrentBatch/{}".format(path) for path in paths])
values = [item.value for item in values]
parameters = dict(zip(paths, values))
system.db.runNamedQuery(MyProjectName, MyQuery, parameters)

This works, but I wondered if there’s a simpler way to use the system.tag.readBlocking function so that it only returns a list of the values, not the qualified values? Something like values = system.tag.readBlocking(["[default]CurrentBatch/{}".format(path) for path in paths]).value - though of course, that doesn’t work because the list itself has no value property, only the items in the list.

I believe all you need to do is substitute everything after values = in the line above in place of the second values in the line after it like this:

values = [x.value for x in system.tag.readBlocking(["[default]CurrentBatch/{}".format(path) for path in paths])]
2 Likes

Thanks, that worked.

Complete solution for posterity:

paths = ['ProductCode', 'Description', 'WeightSP', 'ActualWeight']
tagValues = [tag.value for tag in system.tag.readBlocking(["[default]CurrentBatch/{}".format(path) for path in paths])]
parameters = dict(zip(paths, tagValues))
system.db.runNamedQuery(MyProjectName, MyQuery, parameters)
2 Likes