🔄 The Need for Automatic IoT Data Synchronization After Communication Loss
In modern industrial systems, IoT connectivity is vital, but even the most robust networks can experience downtime. Whether caused by network instability, device downtime, or maintenance operations, these interruptions can disrupt the data flow between shop-floor systems and higher-level applications.
Now imagine this scenario: your MES continues processing operations while IoT communication is down, and the IoT tags are managed through an OPCUA Server. Once the connection is restored, the OPCUA Server still holds outdated tag values, no longer aligned with the actual operations executed in the MES. This mismatch creates a gap that can lead to data inconsistencies, missed updates, and even operational errors.
🎯 The Challenge: Keeping IoT Data Consistent
During the implementation of a certain project using MES version 11.1, a customer in the testing phase highlighted exactly this scenario. They wanted the MES to remain fully operational even if IoT communication went down, but also needed the OPCUA Server to be automatically updated with the latest tags as soon as communication came back online.
This requirement translated into a need for IoT data synchronization upon communication failure and subsequent reconnection, essentially, an automated way to reconcile and update tags once IoT was back online.
In this particular project, I was using the OPCUA Template – DynamicTags, an automation controller previously described in another blog post (OPCUA Template - DynamicTags). As outlined there, this template aggregates customer requirements for OPCUA implementations and is continuously evolving to address common scenarios such as data collections, machine state changes, service and DEE calls, and recipe management.
As the template did not offer this type of synchronization by default, I designed and implemented the logic directly within it. In the following sections, I’ll walk you through my approach to solving this problem by extending the OPCUA Template – DynamicTags with an automatic synchronization mechanism with the update of Write Tags and Setup workflows. This ensures that OPCUA tags always catch up with the latest MES state after a communication failure, keeping workflows consistent.
📝 Write Tags Workflow
The Write Tags workflow is responsible for writing values to the tags on the OPCUA Server. It can be triggered by any other workflow, and whenever it is called, its purpose is to update one or more tags. However, if the communication is down at that moment, the request would normally fail.
To address this, I updated the code task responsible for writing tags to the OPCUA Server so that it first persists the values before attempting the write. This way, persistence always holds the most up-to-date information, regardless of the current communication state. As a result, when IoT communication is restored, the latest data can be retrieved directly from persistence and immediately synchronized with the OPCUA Server.

➡️ Here’s a snippet from the updated code task in the Write Tags workflow:
// Store in persistency the tags information
this.framework.dataStore.store("TagsInformation", propertiesToSet, "Persistent");
// Send request to driver to setPropertiesValues
let jsonReceivedSet: any = await this.framework.driver.sendRaw("connect.iot.driver.opcua.setPropertiesValues", propertiesToSet);
⚙️ Setup Workflow
The Setup workflow is responsible for managing the controller’s communication. In the original version of the controller, the onCommunicationChange output from the On Equipment Setup task was already linked to a code task. That task was designed to execute specific logic whenever the state changed to Disconnected.
Therefore, I reused the same output and code task but extended its logic: now, when the state changes to Communicating, the workflow retrieves the updated tag values from the persistence, which has been continuously maintained by the Write Tags workflow and immediately sends them to the OPCUA Server. This ensures that the server is always synchronized with the MES after a communication failure and subsequent reconnection.

➡️ Here’s a snippet from the updated code task in the Setup workflow:
if (state === "Disconnected") {
    ...
} else if (state === "Communicating") {
    let propertiesToSet: OutputProperty[] = await this.framework.dataStore.retrieve("TagsInformation", []);
            
    if (propertiesToSet?.length) {
        const deviceValues = propertiesToSet.map(p => `${p.property.deviceId} = '${p.value}'`);
        this.framework.logger.info(`Will synchronize tag values\n${deviceValues.join('\n')}`);
        // Send request to driver to setPropertiesValues
        let jsonReceivedSet: any = await this.framework.driver.sendRaw("connect.iot.driver.opcua.setPropertiesValues", propertiesToSet);
        this.framework.logger.debug(`setPropertiesValues received: ${JSON.stringify(jsonReceivedSet)}`);
    }
}
🚀 New Runtime Behavior
After the aforementioned changes, I recreated the scenario with both the Automation Manager and the OPCUA server running locally. Previously, a disconnection would cause the manager to keep attempting to reconnect, without taking further action. Currently, it also automatically retrieves the stored information and immediately updates the server tags, as shown in the figure below:

✅ Applying It in Your Project
This logic is already available in COMMON repository, within the Dynamic Tags Template. So, if you are planning to use the template and need this functionality, all you have to do is include the dependency in your project, as explained in the blog post OPCUA Template - DynamicTags.
If you do not intend to use the Dynamic Tags Template, the explanation above still provides a clear approach that can be applied to similar scenarios in other implementations.
👨💻 Author
Hi! My name is Diogo Domingues. ✌️
I’m a Software Engineer at Critical Manufacturing, working in the Solution Delivery area.
You can find me on LinkedIn.
