Expression Tag that Writes to OPC Address (PLC)

The answer is probably obvious, but…

I need to create an expression tag that writes to an OPC location, which is a bit on a PLC connected via OPC UA. I’ve been reading OPC tags (Allen Bradley PLCs) and even writing to them, but not running an expression and writing to it both.

In the expression tag (Boolean), I’m watching a pressure differential and if it crosses a threshold, it returns a TRUE. If not, it returns a FALSE. Simple. Now I want to write that true or false to a bit on a PLC so it turns on a stack light?

Any help would be appreciated.

Take a look at Gateway Tags Change Scripts: https://docs.inductiveautomation.com/display/DOC81/Gateway+Event+Scripts

Your script will look something like this:

if newValue.getValue() > diffSetpoint:
    system.tag.writeBlocking([tagToWrite],[1])
else:
    system.tag.writeBlocking([tagToWrite],[0)

where tagToWrite is the tagpath that you want to write. This is just pseudocode so you will have to adjust to fit your system.

Thank you for the quick response. I’ll try this. I’m wondering if there’s a way to do this other than scripting.

Not in a way that will be reliable.

Expressions are basically only available for use when a client is running.

Your best bet will be to use the Tag Change Event to trigger that.

1 Like

Expressions on regular tags run all the time, you must be thinking about expressions on client tags.

But there's still no way to make an expression go and write to another tag without using the change script.

1 Like

In 7.9 there was an option on expression tags to write the value back to an OPC item. If this functionality was removed how is it handled during conversion?

Turned into a tag change script on upgrade.

See [13069] - Write value to Opc item feature for Expression Tags is no longer available in 8.0

2 Likes

If you are still on v7.9, there are OPC write-back settings available for Expression Tags:

https://docs.inductiveautomation.com/display/DOC79/Types+of+Tags#TypesofTags-ExpressionTags

This feature has since been dropped. /:

Edit: ninja’d by @lrose. (:

1 Like

That’s pretty much what I meant I just didn’t expound like ya’ll did. :smiley:

So, here’s what I have. I’m not used to scripting, so I’m not sure about the syntax concerning the tags.


When I trigger the expression tag ([default]Rkn031_900/Atomizer/Atomizer_Open_Check),
the tag it’s supposed to write to (…Atomizer_Open) doesn’t change.

You need brackets around the tag paths in the writeBlocking calls. Both parameters are lists.

1 Like

Also, diffSetpoint is not defined, so you’ll need to either assign a value, or hard code a value

diffSetpoint = 100
if newValue.getValue() > diffSetpoint:

or

if newValue.getValue() > 100:

Edit: just thinking through this a bit. If the tag that is triggering this event is an expression tag which results in a bool value then your script can be simplified

if you only want to write to the tag on a true value:

if newValue.getValue():
    system.tag.writeBlocking(['[default]_Rkn031_900_/Atomizer/Atomizer_Open'],[newValue.getValue()])

if you want it to write for both then omit the if statement

system.tag.writeBlocking(['[default]_Rkn031_900_/Atomizer/Atomizer_Open'],[newValue.getValue()])

If the tag is a numeric value then you’ll need what you have.

1 Like

GOT IT !!!

Thank you everyone. :grin: New skill learned that can be applied elsewhere.

Here’s the final (before I saw lrose’s simplified version):

if newValue.getValue() > 0:
system.tag.writeBlocking(["[default]Rkn031_900/Atomizer/Atomizer_Open"],[1])
else:
system.tag.writeBlocking(["[default]Rkn031_900/Atomizer/Atomizer_Open"],[0])

This works, but I will simplify it.

" A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." ~ Antoine de Saint-Exupery.

1 Like

Just to note, you can also have on change scripts directly on individual tags if it’s more appropriate there. For example for tags within a udt that require it, it’s far easier to use a tag’s on change event than have to add each instance tag into the gateway tag change event

Is it possible to write a tag with another tag, for example: system.tag.writeBlocking([tagToWrite],[another_Tag])? To send a expression tag to OPC tag

Yes, although I don’t know what kind of performance impact this might have if doing this quickly and with many tags. Keep in mind that you can use relative tag path references within tag change scripts. e.g. use [.]../../Tag to refer to a tag 2 folder parent folders down

I am trying to use this script as a template for a similar situation (if we lose comms with server, write a 1 to this bool opc tag) but am getting an error saying

Traceback (most recent call last):
File "", line 1, in
NameError: name 'newValue' is not defined

How would I define newValue?

newValue is defined as part of the gateway tag change event. It is a special QualifiedValue that represents the QualifiedValue that has just been written to the tag which triggered the change.

This error makes me wonder if you are attempting to use this script in a Tag Value Change script which is not the same thing as a Gateway Tag Change event.

Yes I was trying to use a tag value change script, should I be applying this script in a gateway tag change event script?

For a script of this nature, it probably doesn't matter much. Though for a value change script it should be modified.

Something like this would be used in a Value Change Script:

if currentValue.value:
    system.tag.writeAsync(['Path to tag'],[currentValue])

Notice the use of writeAsync here. It is important becuase of how value change scripts work that they execute as quickly as possible (in single digit ms).

Gateway Tag Change Events do not have this restriction. They are also a project resource and so have access to project specific information where Value Change scripts do not. Which you use depends on execution time and the need for project specific information.

Never touch a DB in a value change script. (Never is maybe a heavy word, but generally this is a good rule).