I have compiled the SimpleTagProviderExample from the module SDK and I have installed the module on the gateway. I launch designer and create a simple button with an action event and I try to modify the TagCount value.
I see in the source code that this has a WriteHandler so it should be writable. When I try to change it’s value I get an error:
Error writing to tag [DynamicTags]Tag Count Gateway Comm Mode is not Read/Write
Am I doing something wrong assuming I can write this value.
Here is the code from the SimpleTagProviderExample
public class SimpleProviderGatewayHook extends AbstractGatewayModuleHook {
private static final String TASK_NAME = "UpdateSampleValues";
//This pattern will be used for tag names. So, tags will be created under the "Custom Tags" folder.
private static final String TAG_NAME_PATTERN = "Custom Tags/Tag %d";
//This is the name of our "control" tag. It will be in the root folder.
private static final String CONTROL_TAG = "Tag Count";
Logger logger;
GatewayContext context;
SimpleTagProvider ourProvider;
ExtendedTagType ourTagType;
//This example adds/removes tags, so we'll track how many we currently have.
int currentTagCount = 0;
public SimpleProviderGatewayHook() {
logger = LogManager.getLogger(this.getClass());
}
@Override
public void setup(GatewayContext context) {
try {
this.context = context;
ourProvider = new SimpleTagProvider("DynamicTags");
//Set up our tag type. By doing this, we can allow our tags to use alerting, history, etc.
//The STANDARD_STATUS flag set in TagEditingFlags provides for all features, without allowing tags to be renamed or deleted.
ourTagType = TagType.Custom;
ourProvider.configureTagType(ourTagType, TagEditingFlags.STANDARD_STATUS, null);
//Set up the control tag.
//1) Register the tag, and configure it's type.
//2) Register the write handler, so the tag can be modified.
ourProvider.configureTag(CONTROL_TAG, DataType.Int4, ourTagType);
ourProvider.registerWriteHandler(CONTROL_TAG, new WriteHandler() {
@Override
public Quality write(TagPath target, Object value) {
Integer intVal = TypeUtilities.toInteger(value);
//The adjustTags function will add/remove tags, AND update the current value of the control tag.
adjustTags(intVal);
return CommonQualities.GOOD;
}
});
//Now set up our first batch of tags.
adjustTags(10);
} catch (Exception e) {
logger.fatal("Error setting up SimpleTagProvider example module.", e);
}
}
@Override
public void startup(LicenseState activationState) {
try {
ourProvider.startup(context);
//Register a task with the execution system to update values every second.
context.getExecutionManager().register(getClass().getName(), TASK_NAME, new Runnable() {
@Override
public void run() {
updateValues();
}
}, 1000);
logger.info("Example Provider module started.");
} catch (Exception e) {
logger.fatal("Error starting up SimpleTagProvider example module.", e);
}
}
@Override
public void shutdown() {
//Clean up the things we've registered with the platform- namely, our provider type.
try {
if (context != null) {
//Remove our value update task
context.getExecutionManager().unRegister(getClass().getName(), TASK_NAME);
//Shutdown our provider
ourProvider.shutdown();
}
} catch (Exception e) {
logger.error("Error stopping SimpleTagProvider example module.", e);
}
logger.info("SimpleTagProvider Example module stopped.");
}
/**
* This function adds or removes tags to/from our custom provider. Notice that it is synchronized, since we are
* updating the values asynchronously. If we weren't careful to synchronize the threading, it might happen that
* right as we remove tags, they're added again implicitly, because the value update is happening at the same time.
*
* @param newCount
*/
protected synchronized void adjustTags(int newCount) {
if (newCount > currentTagCount) {
for (int i = currentTagCount; i < newCount; i++) {
ourProvider.configureTag(String.format(TAG_NAME_PATTERN, i), DataType.Float8, ourTagType);
}
} else if (newCount < currentTagCount) {
for (int i = currentTagCount; i > newCount; i--) {
ourProvider.removeTag(String.format(TAG_NAME_PATTERN, i));
}
}
//Update current count.
currentTagCount = newCount;
//Make sure to update the control tag with the current value.
ourProvider.updateValue(CONTROL_TAG, currentTagCount, DataQuality.GOOD_DATA);
}
/**
* Update the values of the tags.
*/
protected synchronized void updateValues() {
Random r = new Random();
for (int i = 0; i < currentTagCount; i++) {
ourProvider.updateValue(String.format(TAG_NAME_PATTERN, i), r.nextFloat(), DataQuality.GOOD_DATA);
}
}
}