Aveva PI

When a new asset is created in PI Asset Framework, auto-populate its metadata attributes from its supplier datasheet PDF using AAS Studio's structured extraction.

Audience: Process engineers + PI AF admins running OT analytics on top of an asset hierarchy that's missing metadata.

Topology

  1. PI AF onboarding workflow has a "datasheet" attribute that holds a path to the PDF
  2. Your PowerShell or Python integration script (running on the PI Server or a sidecar) iterates new assets
  3. For each asset, fetch the PDF, call AAS Studio /api/v1/extract
  4. Map the extracted Nameplate + TechnicalData fields onto the asset's PI AF attribute template
  5. Optionally: write the SHA-256 anchor + AAS Studio extraction id back as a custom attribute, so OT engineers can trace any anomaly back to the source datasheet

TypeScript

import { AasStudioClient } from '@aas-studio/sdk'
import { readFileSync } from 'node:fs'

const aas = new AasStudioClient({ apiKey: process.env.AAS_STUDIO_KEY! })

async function populateAssetFromDatasheet(piAssetId: string, pdfPath: string, piClient: PiAfClient) {
  const pdf = readFileSync(pdfPath)
  const { result } = await aas.extract({ file: pdf, fileName: pdfPath })

  const nameplate = result.submodels.find(sm => sm.idShort === 'Nameplate')
  const tech = result.submodels.find(sm => sm.idShort === 'TechnicalData')
  if (!nameplate || !tech) throw new Error('Required submodels missing')

  // Map onto PI AF attributes — names depend on your template
  const attrs: Record<string, string> = {
    Manufacturer: nameplate.elements.find(e => e.idShort === 'ManufacturerName')?.value ?? '',
    Model: nameplate.elements.find(e => e.idShort === 'ManufacturerProductDesignation')?.value ?? '',
    SerialNumber: nameplate.elements.find(e => e.idShort === 'SerialNumber')?.value ?? '',
    // ... iterate tech.elements onto your numeric attributes
  }
  await piClient.updateAttributes(piAssetId, attrs)
}

Install: npm install @aas-studio/sdk

Python

from aas_studio import AasStudioClient

aas = AasStudioClient(api_key=os.environ["AAS_STUDIO_KEY"])

def populate_asset_from_datasheet(pi_asset_id: str, pdf_path: str, pi_client):
    with open(pdf_path, "rb") as f:
        response = aas.extract(f.read(), file_name=pdf_path)

    submodels = {sm["idShort"]: sm for sm in response["result"]["submodels"]}
    nameplate = submodels.get("Nameplate")
    tech = submodels.get("TechnicalData")
    if not (nameplate and tech):
        raise RuntimeError("Required submodels missing")

    def find(elements, idShort):
        return next((e["value"] for e in elements if e["idShort"] == idShort), "")

    pi_client.update_attributes(pi_asset_id, {
        "Manufacturer": find(nameplate["elements"], "ManufacturerName"),
        "Model": find(nameplate["elements"], "ManufacturerProductDesignation"),
        "SerialNumber": find(nameplate["elements"], "SerialNumber"),
        # iterate tech["elements"] onto your numeric attributes
    })

Install: pip install aas-studio

Common pitfalls

  • PI AF's attribute names are usually snake_case or PascalCase per your enterprise template. AAS Studio uses IDTA-conformant idShorts (e.g. ManufacturerProductDesignation). Build a static mapping table once — don't try to fuzzy-match.
  • Range elements (operating temperature, voltage range) need two PI AF attributes — min and max — or a Composite type. Plan the attribute template with this in mind.
  • For high-volume new-asset onboarding, hit the AAS Studio Team plan (300 extractions/month, €99/mo). The Free plan's 3/month limit gets exhausted in a single afternoon of onboarding.

References

All integration guidesTry AAS Studio free

Command palette

Navigate + run actions