Main Content

Update Invalid Data of Tag in AVEVA PI Data Archive

This example shows you how to manage invalid data present in a tag in the AVEVA® PI Data Archive by updating data with the correct values from the OPC UA server.

For this example, consider any data with status bad as invalid. You fetch the correct data for the invalid data instances from the backup data stored in an OPC UA server. You then write the correct values in the AVEVA PI Data Archive at the required time instances.

The write capability of Industrial Communication Toolbox™ for PI provides a variety of options and flexible ways to update data to an existing tag in PI Data Archive. Running this example assumes a PI Data Archive is available for connection and Prosys OPC UA Simulation Server is installed and running. The demo tags used in this example were provided by AVEVA and can be downloaded from AVEVA sharefile.

Create Client/Server Connection and Retrieve Required Tags

Connect to the PI Data Archive using the piclient function. This example uses the name of the Windows® computer name as the PI Data Archive name, which might vary depending on the PI System configuration.

host = getenv("COMPUTERNAME");
client = piclient(host);

Find a list of tag names that start with "Flynn I" using the tags function. For more information, see Get Started Accessing a PI Data Archive.

tagsFlynnI = tags(client, Name="Flynn I.*")
tagsFlynnI=3×1 table
                                         Tags                                     
    ______________________________________________________________________________

    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"         
    "Flynn I.Hydro Unit Attention Percentage.fb72102e-7bae-5b4d-0c63-1a95b1062dab"
    "Flynn I.Hydro Unit Condition.eabe7033-cd1c-5fe8-36cc-3d172e7ca0dd"           

Read Value of Tag

Read the data recorded in a tag using the read function. To read data of a tag over a period of time, first define the period. For example, to read the data from 09-Dec-2023 in UTC timezone, use the DateRange name-value argument to specify a starting datetime and ending datetime.

startDate=datetime("09-12-2023", InputFormat="dd-MM-uuuu", TimeZone="UTC");
endDate = startDate + days(1);
activePowerGenFlynnI = read(client, tagsFlynnI.Tags(1), DateRange=[startDate endDate])
activePowerGenFlynnI=8×3 timetable
              Time                                               Tag                                     Value     Status
    ________________________    _____________________________________________________________________    ______    ______

    09-Dec-2023 04:40:00 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"       NaN     Bad  
    09-Dec-2023 05:35:00 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"       NaN     Bad  
    09-Dec-2023 06:09:00 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"       NaN     Bad  
    09-Dec-2023 13:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"     95.14     Good 
    09-Dec-2023 14:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"     96.22     Good 
    09-Dec-2023 15:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"    98.236     Good 
    09-Dec-2023 16:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"     99.11     Good 
    09-Dec-2023 17:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"      95.3     Good 

In this example, the data in rows 1, 2 and 3 is considered as invalid because of the Bad status.

Retrieve Correct Value from OPC UA Server

Create a client object using the endpoint URL of the OPC UA server that you are connecting to and the opcua function. Connect the client to the server using the connect function. For more information, see Access Data from OPC UA Servers.

uaClient = opcua("opc.tcp://BGL-SSAHA.dhcp.mathworks.com:53530/OPCUA/SimulationServer");
connect(uaClient);

Get the handle to the node containing the backup data using the findNodeById function.

nodeOfInterest = findNodeById(uaClient.Namespace, 3, 1005);

Retrieve the time instances where invalid data is present in the PI tag.

invalidDataTimestamp = activePowerGenFlynnI.Time(activePowerGenFlynnI.Status == "Bad")
invalidDataTimestamp = 3×1 datetime
   09-Dec-2023 04:40:00 UTC
   09-Dec-2023 05:35:00 UTC
   09-Dec-2023 06:09:00 UTC

Retrieve the values of the node at the specific time instances from the OPC UA server using the readAtTime function.

correctValue = readAtTime(uaClient, nodeOfInterest, invalidDataTimestamp)
correctValue = 
1-by-1 OPC UA Data object array:

           Timestamp                  Sinusoid           
    -----------------------  --------------------------  
    2023-12-09 10:10:00.000       88.535900 [Good (Raw)]  
    2023-12-09 11:05:00.000       90.000000 [Good (Raw)]  
    2023-12-09 11:39:00.000       95.236070 [Good (Raw)]  

Update Invalid Value of Tag

Update the invalid data using the write function. You can overwrite the invalid data with correct data by setting the Overwrite name-value argument to true. You can write data to a tag at a specific timestamp by setting the TimeInstance name-value argument to the required datetime.

write(client, tagsFlynnI.Tags(1), correctValue.Value, TimeInstance=invalidDataTimestamp, Overwrite=true)

Verify updated values by waiting for one second before using the read function.

pause(1);
activePowerGenFlynnI = read(client, tagsFlynnI.Tags(1), DateRange=[startDate endDate])
activePowerGenFlynnI=8×3 timetable
              Time                                               Tag                                     Value     Status
    ________________________    _____________________________________________________________________    ______    ______

    09-Dec-2023 04:40:00 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"    88.536     Good 
    09-Dec-2023 05:35:00 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"        90     Good 
    09-Dec-2023 06:09:00 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"    95.236     Good 
    09-Dec-2023 13:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"     95.14     Good 
    09-Dec-2023 14:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"     96.22     Good 
    09-Dec-2023 15:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"    98.236     Good 
    09-Dec-2023 16:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"     99.11     Good 
    09-Dec-2023 17:23:22 UTC    "Flynn I.Active Power Generated.4780df36-9354-5eda-28b0-f7a67582c48f"      95.3     Good 

You can see that the invalid data in rows 1, 2, and 3 is replaced with the correct data from the OPC UA server.