Jump to content

Re-naming OSIsoft PI AF Asset Tree root node Name in Seeq


Kjell Raemdonck

Recommended Posts

  • Seeq Team

If you have many different OSIsoft AF databases connected to Seeq, you will see all those Asset Trees show up in your Data Tab. As you can imagine, some customers have 50+ AF databases connecting to Seeq, which could lead to 50+ Asset Trees, making navigation to the desired tree difficult. Prior to R52, there was no alternative but to live with a messy Data Tab. 

Now, starting with R52, you can add a Property Transform to your OSIsoft AF Connector.json config file to rename the root Asset Tree name of each data source with multiple databases.

Example:

I have 2 PI AF data sources connected to Seeq, and each data source has 2 data bases with identical naming - see OSIsoft AF Connector.json original configuration file below.

{
  "Version": "Seeq.Link.Connector.AF.Config.AFConnectorConfigV3",
  "Connections": [
    {
      "Name": "piAFserverONE",
      "Id": "570974a9-d38f-4445-ad0d-3aac24fa88da",
      "Enabled": true,
      "Indexing": {
        "Frequency": "1w",
        "OnStartupAndConfigChange": false,
        "Next": "2021-07-05T01:00:00-05[America/Chicago]"
      },
      "Transforms": null,
      "MaxConcurrentRequests": null,
      "MaxResultsPerRequest": null,
      "IncrementalIndexingFrequency": "300d",
      "AFServerID": "46abe034-1602-484f-b142-d8a667356e9f",
      "Username": '***',
      "Password": '***',
      "IncrementalIndexingMaxChangedPerDatabase": 10000,
      "IgnoreHiddenAttributes": true,
      "IgnoreExcludedAttributes": true,
      "NestChildAttributes": false,
      "SyncElementReferences": false,
      "RegisterSeeqDataReference": null,
      "AFServerName": "PIAFONE",
      "Databases": [
        {
          "Name": "Database One",
          "ID": "af79d0c8-4afb-43ed-a7b2-115844f1ad29",
          "Enabled": true
        },
        {
          "Name": "Database Two",
          "ID": "dee1a62d-9eac-4945-82e1-4a1e9baa9d8e",
          "Enabled": true
        }
      ],
      "AdditionalProperties": null,
      "PISecuritySynchronization": {
        "PointSecurity": false,
        "PIWorldMapping": null
      },
      "AFSecuritySynchronization": {
        "IdentityMappingsDatasourceClass": "Windows Auth",
        "IdentityMappingsStopRegex": "^(BUILTIN\\\\.*)$",
        "Identities": false,
        "ElementsSecurity": false,
        "IdentityMappingsDatasourceId": null,
        "WorldMapping": null
      }
    },
    {
      "Name": "piAFserverTWO",
      "Id": "68a9bccc-a421-4e0e-b06d-0586867decca",
      "Enabled": true,
      "Indexing": {
        "Frequency": "1w",
        "OnStartupAndConfigChange": false,
        "Next": "2021-07-05T03:00:00-05[America/Chicago]"
      },
      "Transforms": null,
      "MaxConcurrentRequests": null,
      "MaxResultsPerRequest": null,
      "IncrementalIndexingFrequency": "300d",
      "AFServerID": "57abc41f-8822-4d0d-a668-8607db1c1445",
      "Username": '***',
      "Password": '***',
      "IncrementalIndexingMaxChangedPerDatabase": 10000,
      "IgnoreHiddenAttributes": true,
      "IgnoreExcludedAttributes": true,
      "NestChildAttributes": false,
      "SyncElementReferences": false,
      "RegisterSeeqDataReference": null,
      "AFServerName": "PIAFTWO",
      "Databases": [
        {
          "Name": "Database One",
          "ID": "dee1a62d-9eac-4945-82e1-4a1e9baa9d8e",
          "Enabled": true
        },
        {
          "Name": "Database Two",
          "ID": "8e05153b-a249-4165-a6cf-fa3e13fd6f4c",
          "Enabled": true
        }
      ],
      "AdditionalProperties": null,
      "PISecuritySynchronization": {
        "PointSecurity": false,
        "PIWorldMapping": null
      },
      "AFSecuritySynchronization": {
        "IdentityMappingsDatasourceClass": "Windows Auth",
        "IdentityMappingsStopRegex": "^(BUILTIN\\\\.*)$",
        "Identities": false,
        "ElementsSecurity": false,
        "IdentityMappingsDatasourceId": null,
        "WorldMapping": null
      }
    }
  ],
  "ApplicationIdentity": null,
  "RestartAgentAfterErrorTimeout": null
}

In Seeq, my Data Tab would look like this:

image.png

This is confusing, because I have no way to distinguish which data source each Database One is coming from, without diving into the Item Properties to get more information. Ideally, I could visually identify which is which. Hence, thanks to R52, I will rename the Asset Trees I see here via a Property Transform in my connector config file. See updated config below, with Transform:

{
  "Version": "Seeq.Link.Connector.AF.Config.AFConnectorConfigV3",
  "Connections": [
    {
      "Name": "piAFserverONE",
      "Id": "570974a9-d38f-4445-ad0d-3aac24fa88da",
      "Enabled": true,
      "Indexing": {
        "Frequency": "1w",
        "OnStartupAndConfigChange": false,
        "Next": "2021-07-05T01:00:00-05[America/Chicago]"
      },
      "Transforms": [
		  {
			"Inputs": [
			  {
				"Property": "AF Path",
				"Value": "\\\\\\\\[^\\\\]+\\\\(?<path>[^\\\\]+?)$"
			  }
			],
			"Outputs": [
			  {
				"Property": "Name",
				"Value": "ONE.${path}"
			  }
			],
			"Enabled": true,
			"Log": false
		  }
		],
      "MaxConcurrentRequests": null,
      "MaxResultsPerRequest": null,
      "IncrementalIndexingFrequency": "300d",
      "AFServerID": "46abe034-1602-484f-b142-d8a667356e9f",
      "Username": '***',
      "Password": '***',
      "IncrementalIndexingMaxChangedPerDatabase": 10000,
      "IgnoreHiddenAttributes": true,
      "IgnoreExcludedAttributes": true,
      "NestChildAttributes": false,
      "SyncElementReferences": false,
      "RegisterSeeqDataReference": null,
      "AFServerName": "PIAFONE",
      "Databases": [
        {
          "Name": "Database One",
          "ID": "af79d0c8-4afb-43ed-a7b2-115844f1ad29",
          "Enabled": true
        },
        {
          "Name": "Database Two",
          "ID": "dee1a62d-9eac-4945-82e1-4a1e9baa9d8e",
          "Enabled": true
        }
      ],
      "AdditionalProperties": null,
      "PISecuritySynchronization": {
        "PointSecurity": false,
        "PIWorldMapping": null
      },
      "AFSecuritySynchronization": {
        "IdentityMappingsDatasourceClass": "Windows Auth",
        "IdentityMappingsStopRegex": "^(BUILTIN\\\\.*)$",
        "Identities": false,
        "ElementsSecurity": false,
        "IdentityMappingsDatasourceId": null,
        "WorldMapping": null
      }
    },
    {
      "Name": "piAFserverTWO",
      "Id": "68a9bccc-a421-4e0e-b06d-0586867decca",
      "Enabled": true,
      "Indexing": {
        "Frequency": "1w",
        "OnStartupAndConfigChange": false,
        "Next": "2021-07-05T03:00:00-05[America/Chicago]"
      },
      "Transforms": [
		  {
			"Inputs": [
			  {
				"Property": "AF Path",
				"Value": "\\\\\\\\[^\\\\]+\\\\(?<path>[^\\\\]+?)$"
			  }
			],
			"Outputs": [
			  {
				"Property": "Name",
				"Value": "TWO.${path}"
			  }
			],
			"Enabled": true,
			"Log": false
		  }
		],
      "MaxConcurrentRequests": null,
      "MaxResultsPerRequest": null,
      "IncrementalIndexingFrequency": "300d",
      "AFServerID": "57abc41f-8822-4d0d-a668-8607db1c1445",
      "Username": '***',
      "Password": '***',
      "IncrementalIndexingMaxChangedPerDatabase": 10000,
      "IgnoreHiddenAttributes": true,
      "IgnoreExcludedAttributes": true,
      "NestChildAttributes": false,
      "SyncElementReferences": false,
      "RegisterSeeqDataReference": null,
      "AFServerName": "PIAFTWO",
      "Databases": [
        {
          "Name": "Database One",
          "ID": "dee1a62d-9eac-4945-82e1-4a1e9baa9d8e",
          "Enabled": true
        },
        {
          "Name": "Database Two",
          "ID": "8e05153b-a249-4165-a6cf-fa3e13fd6f4c",
          "Enabled": true
        }
      ],
      "AdditionalProperties": null,
      "PISecuritySynchronization": {
        "PointSecurity": false,
        "PIWorldMapping": null
      },
      "AFSecuritySynchronization": {
        "IdentityMappingsDatasourceClass": "Windows Auth",
        "IdentityMappingsStopRegex": "^(BUILTIN\\\\.*)$",
        "Identities": false,
        "ElementsSecurity": false,
        "IdentityMappingsDatasourceId": null,
        "WorldMapping": null
      }
    }
  ],
  "ApplicationIdentity": null,
  "RestartAgentAfterErrorTimeout": null
}

After a fresh re-index of my 2 data sources, I can now see my Asset Trees are renamed in Seeq's Data Tab, and can clearly distinguish which Database belongs to which data source. 

image.png

You can use this to add data source information as I have done above, or simply use another method to order them in a different way - they will always populate alphabetically.

 

Link to comment
Share on other sites

  • Seeq Team

One question you may have - why so many backslashes in the Property Transform?

Well, we need to escape backslashes, twice in this case, once because we are working in JSON language in the config file, and another time for regular expressions. The expression below will match PI AF paths like "\\AFServerName\AFDatabaseName" but will not match, e.g., "\\AFServerName\AFDatabaseName\AnyElement|SomeAttribute".

For the curious, after removing the JSON escaping, the regular expression used to match the AF path looks like this:

\\\\[^\\]+\\(?<path>[^\\]+?)$

This expression can be tested at a site like regextester.com, which will explain what each part of the regular expression does.

 Note, you should be able to use this transform as is in your config file, by only editing the prefix 'ONE' in "Outputs" to your desired Asset Tree name prefix.

Transform:

"Transforms": [
		  {
			"Inputs": [
			  {
				"Property": "AF Path",
				"Value": "\\\\\\\\[^\\\\]+\\\\(?<path>[^\\\\]+?)$"
			  }
			],
			"Outputs": [
			  {
				"Property": "Name",
				"Value": "ONE.${path}"
			  }
			],
			"Enabled": true,
			"Log": false
		  }
		],

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...