Changing a tag from a memory tag to an OPC tag

I have an application I'm working on that has the possibility of functioning in 2 modes.

1 mode is a local PC-only mode. the second mode is communicating with a PLC. initially, I planned on having a gateway script that would look at a configuration variable and update PLC tags if we are running in that mode (and the tags exist in the PLC). However, I've found that I can change the type of the tag from a memory to an OPC tag using the system.tag.configure function. I have it working, mostly, but I'm running into a single issue. It isn't actually updating the tag with the correct variables.

This is the code I'm using to update the tag variables. It works fine but the tag parameters don't actually seem to refresh. If I go into the tag and physically select the Value Source all of a sudden it will refresh itself and connect.

This image is of it in the memory configuration

This image is of it right after I've changed the configuration to OPC. You can see the Value Source has changed, but the properties didn't update. I'm even writing to the additional properties to get them to change... but they don't show up.
image

As soon as I physically select OPC it will activate the additional properties and take off without me having to actually change anything.
image

Do any wizards out there have any spectacular ideas on how to refresh or restart the tags? This isn't a high change system. Only on initial configuration would it ever change.

#get the configuration Type from the tag value
staID=502308102
PLCName='TestPLC'
configType=system.tag.readBlocking('[default]uAuth/U'+str(staID)+'/PCStation')[0].value
print configType
parentPath = "[default]uAuth"
plcTagList=['badgeNum','clockNum','Function','FunctionResult','LastToken','StaID','token','uFlags','uLevel','uName','uSponsorID','uSponsorName']
 
# Get the current configurations
configs = system.tag.getConfiguration(parentPath+'/U'+str(staID), True)
 
# Iterate over the results
for item in configs:
    # Through the results, search each dictionary
    for key, value in item.iteritems():
        if key == 'tags':
            for tagConfig in value:
				if tagConfig["name"] in plcTagList:
					if configType == 0: 
						# set the tags to OPC Tags
					    tagConfig['valueSource'] = 'OPC'
					    tagConfig['opcserver'] = 'Ignition OPC UA Server'
					    tagConfig['opcItemPath'] = 'ns=1;s=[TestPLC]{InstanceName}.API.'+str(tagConfig["name"])
					if configType == 1:
						# set the tags to OPC Tags
					    tagConfig['valueSource'] = 'memory'
system.tag.writeBlocking('[default]uAuth/U'+str(staID)+'/PCStationLast', configType)
#write the tag configurations to the tags
system.tag.configure(parentPath, configs, "o")

Do you need to refresh the tags from a script? If not, have you come across the 'Restart Tag' option when right-clicking on a tag in Designer? You can restart a whole folder of tags if necessary.

Alternatively, you could have two versions of your UDTs (OPC vs Memory version) and just change the UDT path on your tags. Unsure if you would run into the same issue.

Alternatively, alternatively, you could define bindings in your UDT definitions (based on a global memory/expression tag?) for the value source of your atomic tags and change between OPC and memory as necessary. The OPC server and Item path should be remembered when flicking between the two value sources.

Good luck :slight_smile:

Two different UDT's / or a separate set of tags for the PLC interface and Memory tags in a single UDT, but I was kind of annoyed by having to re-direct all my signals in Scripts. just so much extra code. The problem is that this will only get changed on the initial setup in the clients. These clients will be all over the shop floor for Machine Authentication/Documentation control. Pushing out Quality Alerts and Training Documentation... etc. Any way around it I will need a configuration parameter. I came across the system.tag.configuration item and that saves quite a bit of code... so long as it works properly...

Now, what I have found so far is that so long as I don't have the tag properties overridden, (they are in the images I posted) it actually works. So, that part works just fine when I have the PLC tags structured accordingly in the UDT. I can switch from Memory to OPC and back without any hassles. the issue with that is that now because this is going to be targeting several PLC OPC clients I will have to change the direction of the opcItemPath... From my [TestPLC] to whatever I have defined as the OPC Client. This will put the tag path into "Override"

... however now that I think about it, maybe I change the [TestPLC] to another configuration property that will just change by itself... make it a variable based on the already implied {InstanceName}... hmmm.... something to ponder this weekend as I try and prevent myself from giving my company free time lol.

Your item path syntax suggests that your PLC is a Rockwell Logix product. If so, you might find it better to simply swap PLC drivers instead of manipulating your tags. As described here:

(See the links at the bottom of that comment for other discussions of development environments.)

I'm sure that would work however making a parameter for the OPC path will also work just fine. I am going to standardize naming conventions and put them in the database so that everything will populate based on a single ID value.


Except it doesn't work for tags that aren't UDT instances.

Everything I'm working with in this particular application is all UDT so I don't have to worry about that in this particular instance.