Tracking database data in tags and resolving copy/paste conflicts

I have a need to associate complex user data to tags. The data may extend beyond the capabilities of tag "custom properties" due to various relationships and extended data structures.
I assign each tag with an ID via a database then store it in the tag via custom properties for later data lookups.

Problem is, when a designer copies/pastes tags with a custom ID assigned then that ID tracks to the pasted tag configuration. Now I have 2 or more IDs that are duplicated and need to be resolved.
I have two questions that can fix this issue:

  1. Is there a way to read the tag's UUID that's visible in the diagnostics section of the tag?
    system.tag.readBlocking(["myTag.id"]) provides an empty string. But if I got my hands on that ID then I can use that instead of my database generated ID to track the user data.
  2. Is there another way, some other tag property such as a "created timestamp", that can be used to determine the age of a tag. This could be used to identify which tag in a set of conflicts was the copied tag vs the copy.
  3. Any other ideas on how to resolve tag copy/paste conflicts by determining which tag was the original?

May I ask why do you need to copy database data to tags ?
And also why do you need to copy/paste them ?

I'm not copying database data to tags. There is user data that needs to be associated per tag for alarming
Ex. user 1 wants to receive alarm notifications from tag "High Level", but user 2 does not.

I prefer to store that data centrally in the database then link it to the tag via the database ID.
The only alternative I know about is using custom datasets per tag with all of the user data stored, but that feels a bit messy to me.

The copy/pasting is referring to within the Designer when the person creating the OPC tags copies/pastes them. Which is common when doing many instances of tags that are very similar.

I'm not sure I understand your structure here.
You have a database, that stores data about users and their preferences, then tags that do what exactly ?

UDTs might solve this.

1 Like

Isn't this exactly what the Alarm Notification Module is for? I understand that it's an additional module, but it might be worth the cost considering the headache that goes into maintaining this type of system.

I too, am a bit confused by this. Yes copy and paste is a common operation, but why would it matter which is the original? You don't copy a tag unless you intend to modify it.

I would use a custom tag property to store your DB primary key value. But also store the tagpath in the DB. A utility script could be used to browse your tags and discard values of the custom property where the tagpath doesn't match. (Or perhaps copy the DB row to a new one and update the property. Effectively extending the copy/paste to the DB.)

The source of the copy/paste problems, there are two options for associating data with a Tag:

  1. You store all of the data in the tag via a "Custom Property" such as a custom Dataset
  2. You store a customer identifier (ID) in the tag as a "Custom Property". That ID then refers to another storage location, database in this case, containing all of the associated data.

In either case, when you duplicate the tag via copy/pasting, each tag then has the exact same "Custom Properties" assigned, whether its all of the data or an ID.
In the case of an ID, a duplicate is an issue, as it's essentially the Primary Key for the Tag. A database can never have duplicate Primary Keys, as it defeats the purpose of a Primary way to identify a resource (Tag) by its Key (ID).
The copy/paste issue is referring to how an ID can effectively be duplicated, breaking the database reference structure.

@lrose That module is important and provides the framework for what I'm working on (namely pipelines), but it doesn't provide the extra layer of configuration where specific users can receive specific alarms. I have already spoken with Ignition developers directly on this matter who suggested a custom route is necessary to achieve user-specific alarm notification lists.

@pturmel I appreciate that suggestion, I think it'll take me a step closer. As long as the database records stay updated with the tags' path when it changes, then the combination of tag path + ID should be enough to identify which tag is the "original". Do you know of any "Tag configuration change" events? I have a Gateway script monitoring tag changes which does trigger off of configuration changes (implicitly, because a configuration change causes a quality change), but it will incur excess overhead on a large system where many quality changes could occur.

A custom module (SDK) can subscribe to changes to specific custom properties, IIRC. I think that is per tag provider.

If you keep the tagpath in the DB along with the ID, then you can distinguish original from duplicate (to trigger creating a new row). Moving a tag would orphan a row, so you might want a vacuum process to clean up such. Lots more possibilities in the SDK than in jython--but a heck of a learning curve. (I think you can use the UUID from the tag via the SDK, but you'd still want to drive the system with custom prop. To have something to subscribe to.)

Appreciate the input! I think the tagpath addition to the DB will get me as far as I can go with this prototype, then I'll have to consider switching to a module for proper implementation.