Skip to Content
IntegrationsPI Web API

PI Web API

Integration with the AVEVA PI System (formerly OSIsoft) through the PI Web API. It runs in process inside cms-api over HTTPS — no native SDK, no separate microservice, no binary dependency.

Although it speaks HTTP, this is not a generic HTTP integration: CMS understands the PI vocabulary (tags, time windows, sample quality) and handles the most tedious part of the product on its own — the WebId.

Why the WebId matters

Every read and write in the PI Web API addresses a tag by a WebId — an opaque identifier issued by the server that changes if the tag is deleted and recreated, or if PI is migrated.

A raw HTTP integration would store that WebId in the collector URL. The day the tag is recreated, every configuration would start returning 404 with no hint as to why, and someone would have to rewrite URL by URL.

In CMS what you configure is the tag path (\\PISRV01\FIC101.PV) — readable, stable and exportable. The WebId lives only in an internal cache; when PI reports it no longer exists, CMS re-resolves the path on its own and retries the call. The configuration does not break.

Connection

Register the server under External Connections, in the Industrial Protocols category:

  • Base URL — you may paste the site root (https://pi.company.com); the /piwebapi suffix is appended when missing.
  • Authentication — Basic (username and password), Bearer (token) or Anonymous.
  • Default Data Server — the Find servers button lists the PI Data Archives visible to the credential; clicking a name fills the field. With it set, tags can be given by name alone (FIC101.PV) instead of the full path.
  • Validate TLS certificate — keep it on. If PI uses a self-signed or internal CA certificate, prefer pasting the CA into CA certificate rather than turning validation off.

The Test Connection button validates in two steps — address/credential, then the Data Server — and rejects a non-existent server name right away, instead of letting the error surface only on the first collection.

The PI Web API requires the X-Requested-With header as CSRF protection and answers 401 without it, even with a correct credential. CMS always sends the header — this is the number one gotcha for anyone integrating with PI for the first time.

An application with PI_WEB_API Keep Alive monitors the server in the cockpit. The test also reports when the PI Web API answers but the Data Archive behind it is disconnected — a state in which no tag can be read even though HTTP keeps returning 200.

Tag catalog

The catalog icon on the connection row opens the tag browser: filter by name with PI’s own * wildcard and see descriptor, engineering units and point type.

It is cache-first — it opens instantly and works with PI offline, serving the catalog already known. The Refresh from PI button forces a round trip to the server.

The same browser reappears as a tag picker on the Collector and Delivery screens: clicking a tag adds it with a suggested alias.

Collection — PI_WEB_API

A scheduled (pull) collector, on the same scheduler as HTTP_GET/SQL_SERVER — no persistent connection —, or on demand, when it has Input Parameters. There are four read modes:

ModeWhat it does
Current valueReads the latest value of each tag. One message per run.
History (Recorded)Reads values actually stored within the window — timestamps differ per tag.
InterpolatedValues computed at regular intervals — all tags on the same time grid.
SummaryOne aggregated value per tag over the window (average, minimum, maximum, total…).

The generated payload is {alias: value} for each configured tag. With Include metadata, it gains a _meta block carrying timestamp, quality and units per tag.

{ "flow": 128.4, "temperature": 87.2, "_meta": { "flow": { "timestamp": "2026-08-21T14:03:00Z", "boa": true, "unidade": "m3/h" } } }

In Current value mode all tags are read in a single call (/streamsets/value) — twenty tags cost one request, not twenty.

Incremental history sweep

Start and End accept PI time syntax (* = now, *-1h = one hour ago) or an ISO date. They also accept {{ultimaExecucao}}, the CMS placeholder:

Start: {{ultimaExecucao}} End: *

With that, each run reads exactly the history not yet read — without repeating or skipping samples between cycles. This is the recommended way to bring continuous history from PI into a queue.

A process tag with a year of history can return millions of points. The Max samples/tag field is the per-run ceiling — keep it consistent with the scheduling interval.

Window from outside

Start, End and Interval can also come from whoever triggers the collector. The Input Parameters (API) block sits right below the read mode, before the window fields: declare the names there — for example data_inicio and data_final — and use them in the fields as {{data_inicio}} and {{data_final}}.

Start: {{data_inicio}} End: {{data_final}} Interval: {{passo}}

With at least one parameter, the collector leaves the scheduler and runs on demand: through the Dynamic Collector API, a Trigger or an AI agent.

POST /api/collect/PI_DEMO_HIST/PI_DEMO_HIST_LEITURA { "data_inicio": "*-8h", "data_final": "*" }

A parameter not sent in the call uses its default value; with no default, the field falls back to the PI default — *-1h for Start, * for End and 1h for Interval. The fields also accept Variables ({{NAME}}), like the rest of CMS.

Time assistant

Nobody needs to memorize the PI syntax. The calendar icon next to Start, End and Interval opens an assistant that builds the expression from plain-language choices:

ChoiceBecomes
Now*
2 hours before now*-2h
Today at 06:30t+6h+30m
Yesterday, 00:00y
Most recent Monday, at 08:00mon+8h
Fixed date and timethe date in ISO, in UTC
Since the last run{{ultimaExecucao}}
An Input Parameter or a Variable{{name}}
Every 15 minutes (Interval)15m

The most used shortcuts sit at the top and, when the collector has Input Parameters, one button for each of them. A preview shows the expression, what it means and the date and time it would land on if the collector ran now. The assistant opens already positioned on the field’s current value — and you can still type any expression PI accepts directly in the field.

t (today) and the weekdays are computed by PI in its server’s time zone; the preview uses your browser’s. They only differ if the two are in different time zones.

Emission

In the time-window modes the collector can produce one message with the whole series or one message per sample. The latter is meant for Interpolated mode, where all tags share the same timestamps; in Recorded, each tag has its own storage instants and the grouping rarely puts more than one tag in a message.

Quality and required tags

With Good quality only on (the default), samples PI itself flagged as bad or questionable are discarded. A tag marked required whose only sample came back bad counts as “no value” and the collection fails — instead of forwarding a number PI does not trust.

Test read

The Test read button runs the form configuration, even unsaved. While PI answers, the button shows the seconds going by; the result opens in a popup when the read finishes:

  • Query summary — the tags, the read mode, the resolved period (the expression that actually went to PI), the interval, the summary type or sample ceiling, the parameters used, how many records came back (and how many were discarded for quality), how many messages the collector would generate and how long it took. A table shows, per tag, the path and how many values arrived.
  • Records — each value read: tag, date and time, value, unit and quality, with the row total. The table shows the first 500.
  • Payload — the exact JSON the collector would put on the queue (the first five messages).

If the read worked but the collector would reject the result — a required tag with no value, for example —, the popup shows the error and the records PI returned, which is exactly what helps understand why.

There is no outside call in the test: each Input Parameter uses its default value, and {{ultimaExecucao}} means one hour ago.

Delivery — PI_WEB_API_WRITE

Writes values into PI tags from the message payload — the path back, from ERP/MES into the historian.

The message producer knows no tag paths: it sends a flat object with the configured aliases, and the screen shows the ready-to-copy model payload.

{ "setpoint": "*" }
  • Timestamp — Now stamps the moment of sending; Payload field uses a field from the message itself, for when the data was produced before reaching CMS.
  • Write mode — Replace overwrites a value already stored at the same instant, Insert writes even if another exists, No Replace only writes when nothing exists at that instant.

If the timestamp comes from a payload field and that field is missing or holds an invalid date, the delivery fails instead of stamping the current time. In a historian, data with the wrong timestamp is worse than missing data: it exists looking correct.

As in collection, writing goes in one batched call, and only tags present in the payload are written — an absent tag is not overwritten with null. Tags with a configured default value fall back to it when the message does not carry them.

Testing without a real PI

The Simulators screen ships a PI Web API tab that imitates the product’s REST contract inside CMS itself — no new port and nothing to install.

  • Tags with their own behavior (sine, ramp, square wave, noise, fixed) that vary over time on their own and serve history for any window.
  • The “PI Simulator (interno)” external connection is created and kept up to date automatically: enabling the simulator is enough to use it in a collector.
  • The Regenerate WebIds button simulates tags recreated in PI, invalidating every WebId already handed out — use it to confirm CMS re-resolves paths on its own, without editing any collector.
  • The simulator also rejects requests without the X-Requested-With header, just like real PI.
  • It understands the same time expressions the assistant builds: *, t, y, weekdays, chained offsets (t+6h+30m) and ISO dates.

Scope of this version

This version addresses the PI Data Archive (PI Points). The Asset Framework (Element/Attribute navigation) is not included — the address field is already called “path” and the cache is indexed by it, so AF fits later without a data migration.

Windows integrated authentication (NTLM/Kerberos) is also out of this version; use Basic or Bearer.