Setting read/write permissions when creating tags

As discussed in other topics, I'm using the ManagedTagProvider to set up tags and am writing to those tags in the gateway context. I am now having trouble setting those tags I am creating to read/write instead of read only. My current implementation doesn't set any tag permissions, so I tried to include code based on the following code from Create Tags | Ignition SDK Programmer's Guide.

// Tag permissions
Map<ZoneRole, Boolean> permissionsMap = new HashMap<>(); 
TagPermissionsModel.ZoneRole zoneRole = new TagPermissionsModel.ZoneRole();
zoneRole.setRole("Administrator");    
zoneRole.setZone("default");    
permissionsMap.put(zoneRole, true);    
BasicTagPermissions permissions = new BasicTagPermissions(permissionsMap);
tagConfig.set(WellKnownTagProps.PermissionModel, permissions);

It looks like a lot of these commands come from the deprecated com.inductiveautomation.ignition.common.sqltags.model package. Since yesterday the solution to my problem was that I wasn't importing the newer package that had an identical class (in that case TagPathParser), I double checked a couple of these in the javadocs to see if they were in a newer package but couldn't find one.

Two questions:

  1. Is this the right approach to setting my tags to read/write for the Administrator role?
  2. If so, what packages should I be using?

The update to the Ignition SDK Programmer's Guide is still in progress, so a lot of the old code snippets and examples haven't been updated.

I would recommend that you take a look at the example modules here:

I think you can probably get a better grasp on what's going on then.

Thanks for the reply. I had looked at that example and it doesn't look like it shows how to set tag permissions as far as I could tell...

Have you registered a writeHandler?

Note from the JavaDocs on ManagedTagProvider

Registers a callback that will be used when a write is attempted against the specified path. Only one write handler is allowed per path. If a write handler is not registered for a path, any attempted writes will result in "ReadOnly" errors. Note that other tag settings, such as Permissions, might still prevent writes.

I did have a writeHandler, but it looks like it wasn't set up for my path. I fixed that and now per the Gateway log output, the tags appear to be writing, but when I view their values in the Tag Browser in Designer, the values are still empty.

Here is the command I am using to try to write to tags:

        List<QualityCode> results;
        try {
            results = provider.writeAsync(tagPaths, newValues, SecurityContext.emptyContext()).get(30, TimeUnit.SECONDS);
        } catch (Exception e) {
            // Log exception during write operation
            logger.error("writeTagValues: Exception during tag write operation - " + e.getMessage());
            throw e;
        }
    
        for (int i = 0; i < results.size(); i++) {
            QualityCode qc = results.get(i);
            logger.info("Quality Code: " + qc.toString());
            if (qc.isNotGood()) {
                String errorMessage = String.format("Write operation for tag '%s' returned bad result '%s'",
                                                    tagPaths.get(i).toString(), qc.toString());
                // Log the error for each tag
                logger.error("writeTagValues: " + errorMessage);
                throw new Exception(errorMessage);
            }
        }
    
        // Log successful completion
        logger.info("writeTagValues: Completed tag write operation successfully");
    }
    

}

It looks like this is working when I look at the Ignition Gateway log (no errors are thrown). tagPaths and newValues are both lists of the paths and values, respectively. provider is an object of the TagProvider class. This seems like it should work, so I'm not sure why it appears that the tags are not getting updated when I view them in Designer.

Edit: I have done some more troubleshooting and for some reason the tags that I am automatically creating in Ignition with my SDK module have no "Value" category when I right click on the tag and select Edit Tag. They appear to be memory tags (based on the icon), and I am setting the initial value of each tag to 0 when I generate it with the module. Not only can I not update the tag values programmatically, but I also can't update a tag manually in Ignition by entering a new value in the Value field (I enter the new value, hit enter, and the new value disappears while the old value remains). Any thoughts on what I need to fix?

Hello,

Posting again because I am still having issues writing to tags, per my last post. Any insights on how I can make my tags writeable?

Are you able to post your entire module somewhere publicly?

The Venn diagram of devs who are active on the forum and devs who are particularly well versed in this area of the tag system is basically two circles. If you post your code, I can try to tag someone who knows the tag system well enough in. Otherwise, you're going to have to muddle through it yourself.

Our Sales Engineering department may also be able to help, but probably not for free :man_shrugging:.

Thanks for the offer! Here is the code where I create the tags. Let me know if this isn't detailed enough and I can post more.

Here is the code for setting up the tag provider:

    public void setup(GatewayContext context) {
        try {
            GatewayHook.context = context;
            ProviderConfiguration configuration = new ProviderConfiguration("tagProvider");

            // Needed to allow tag configuration to be editable. Comment this out to disable tag configuration editing.
            configuration.setAllowTagCustomization(true);
            configuration.setPersistTags(false);
            configuration.setPersistValues(false);
            configuration.setAttribute(TagProviderMeta.FLAG_HAS_OPCBROWSE, false);
            configuration.setAllowDefaultWriteHandling(true);

            ourProvider = context.getTagManager().getOrCreateManagedProvider(configuration);

            // Register the write handler, so the tags can be modified.
            ourProvider.registerWriteHandler("", (TagPath target, Object value) -> {
                return QualityCode.Good;
            });

            //Now set up our first batch of tags.
            parseAndCreateTagsFromXml();
        } catch (Exception e) {
            logger.error("Error setting up ManagedTagProvider example module.", e);
        }
    }

Here is the code for creating the tags:

private void createTagsForType(String typeName, Map<String, Element> structElementMap, String tagPath) {
        Element typeElement = structElementMap.get(typeName);
        if (typeElement != null) {
            NodeList memberNodes = typeElement.getElementsByTagName("member");
            for (int i = 0; i < memberNodes.getLength(); i++) {
                Element member = (Element) memberNodes.item(i);
                String memberName = member.getAttribute("name");
                String memberType = member.getAttribute("type");
                if (memberType.equals("nonBasic")) {
                    String newTypeName = member.getAttribute("nonBasicTypeName");
                    String newTagPath = tagPath + "/" + memberName;
                    logger.info("New Type Name: " + newTypeName);
                    logger.info("New Tag Path: " + newTagPath);
                    createTagsForType(newTypeName, structElementMap, newTagPath);
                } else {
                    DataType dataType = mapXmlTypeToIgnitionType(memberType);
                    ourProvider.configureTag(tagPath + "/" + memberName, dataType);
                    Object initialValue = determineInitialValue(dataType);
                    ourProvider.updateValue(tagPath + "/" + memberName, initialValue, QualityCode.Good);
                }
            }
        }

        else {
            logger.error("Error creating tags.");
        }
    }

When the tags get created, they are missing the following section (screenshot from the "Writeable" section in "Sample_Tags"):

image

The module basically works at this point minus writing to tags. I can work around it by creating a script that updates the tag value (see code below) instead of updating the tag directly, but that isn't ideal.

GatewayHook.ourProvider.updateValue(tagPathString, value, QualityCode.Good);

Take this with a grain of salt, as I haven't ever used the Managed Tag Provider, but you are registering a write handler that doesn't actually write. Should there not be a call to updateValue in that handler?

2 Likes

I do have a call to updateValue..

ourProvider.updateValue(tagPath + "/" + memberName, initialValue, QualityCode.Good);

Are you saying that I should be using a command such as writeAsync instead of updateValue?

No, I'm saying your write handler is doing nothing but returning success. It isn't actually writing.

Well, it looks like that was it. I fixed the write handler and I can write to the tags now. I still don't see the "Value" section I included a screenshot of above when I select "Edit Tag", but at least I can write to the tag. Thanks for the help!