Integrating OSIsoft PI System Data into a React Front-End with a .NET Backend: A Comprehensive Guide
Learn how to integrate OSIsoft PI System data into a modern React front-end application with a .NET backend. This comprehensive guide explores efficient data retrieval methods, focusing on the PI Web API and other options.
Roshan Soni
In today's industrial landscape, the ability to access and visualize real-time operational data is crucial for informed decision-making. The OSIsoft PI System is a leading data management platform that collects, stores, and provides access to high-fidelity time-series data from various industrial sources. Integrating this data into modern web applications can unlock significant value by enabling remote monitoring, advanced analytics, and enhanced user experiences.
If you're developing a front-end application using React and have a .NET backend, you might wonder how to fetch data from the PI System efficiently. While the PI Web API is a popular choice due to its RESTful nature, it's not the only option. This comprehensive guide explores different techniques to fetch data from the PI System, helping you choose the best approach for your application's needs.
Table of Contents
- Understanding the OSIsoft PI System
- Data Access Techniques
- Choosing the Right Approach
- Security Considerations
- Best Practices
- Sample Implementation Using PI Web API
- Conclusion
Understanding the OSIsoft PI System
Before diving into data access techniques, it's essential to understand the core components of the PI System:
- PI Data Archive: A time-series database optimized for storing real-time and historical data from sensors and control systems.
- PI Asset Framework (AF): Provides a contextual layer over the PI Data Archive, organizing data according to the physical assets and processes.
- PI Interfaces and Connectors: Facilitate data collection from various sources into the PI System.
Data Access Techniques
1. PI Web API
Overview
The PI Web API is a RESTful interface to the PI System, providing cross-platform access to PI data and assets over HTTPS. It supports CRUD (Create, Read, Update, Delete) operations and is well-suited for web and mobile applications.
Advantages
- Platform Agnostic: Works with any technology stack that can make HTTP requests.
- Ease of Use: Familiar RESTful patterns simplify development.
- Asynchronous Operations: Supports modern async programming models.
Implementation Steps
Backend (.NET):
While you can call the PI Web API directly from the React front-end, routing requests through your .NET backend can enhance security and performance.
-
Set Up the PI Web API Service
Ensure that the PI Web API service is installed and configured correctly on your PI Server. Verify that you can access the service endpoints via a browser or tools like Postman.
-
Create API Endpoints in .NET Backend
Use ASP.NET Core to create API controllers that interact with the PI Web API.
[ApiController] [Route("api/pi")] public class PiDataController : ControllerBase { private readonly HttpClient _httpClient; public PiDataController(HttpClient httpClient) { _httpClient = httpClient; } [HttpGet("data/{tag}")] public async Task<IActionResult> GetPiData(string tag) { var piWebApiUrl = $"https://your-pi-web-api-server/piwebapi/streams/{tag}/value"; var response = await _httpClient.GetAsync(piWebApiUrl); var content = await response.Content.ReadAsStringAsync(); return Content(content, "application/json"); } }Note: Replace
your-pi-web-api-serverwith your actual server address. -
Handle Authentication
Configure authentication mechanisms (Basic, Kerberos, or OAuth) between your .NET backend and the PI Web API.
Front-End (React):
-
Fetch Data from Backend API
Use
fetchor libraries likeaxiosto call your .NET API endpoints.import React, { useEffect, useState } from 'react'; import axios from 'axios'; const PiDataComponent = () => { const [data, setData] = useState(null); useEffect(() => { axios.get('/api/pi/data/your-tag-name') .then(response => setData(response.data)) .catch(error => console.error(error)); }, []); return ( <div> {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : 'Loading...'} </div> ); }; export default PiDataComponent;Note: Replace
'your-tag-name'with the actual PI tag you wish to query.
Considerations
- Performance: Ensure efficient data querying to minimize latency.
- Security: Handle sensitive data carefully and secure API endpoints.
2. PI AF SDK via .NET Backend
Overview
The PI AF SDK is a rich .NET library that provides extensive functionality to interact with the PI System. It's ideal for complex data operations and when you need deep integration with PI assets and metadata.
Advantages
- Rich Functionality: Access to advanced features like event frames, asset analytics, and more.
- Performance: Efficient data retrieval and manipulation.
- Strong Typing: Compile-time checking reduces runtime errors.
Implementation Steps
Backend (.NET):
-
Install PI AF SDK
Ensure the PI AF SDK is installed on your backend server. Add references to
OSIsoft.AFSDK.dllin your project. -
Create API Endpoints Using AF SDK
using OSIsoft.AF.PI; using OSIsoft.AF.Asset; using OSIsoft.AF.Data; [ApiController] [Route("api/pi")] public class PiDataController : ControllerBase { [HttpGet("data/{tag}")] public IActionResult GetPiData(string tag) { var piServers = new PIServers(); var piServer = piServers.DefaultPIServer; var piPoint = PIPoint.FindPIPoint(piServer, tag); var value = piPoint.CurrentValue(); return Ok(value.Value); } }
Front-End (React):
Same as in the PI Web API method, fetch data from your .NET backend.
Considerations
- Deployment: AF SDK requires Windows; your backend must run on a Windows server.
- Scalability: Suitable for backend services but not directly accessible from the front-end.
3. PI OLEDB Provider or PI JDBC Driver
Overview
These drivers allow SQL-like querying of PI System data. They are typically used in conjunction with reporting tools or custom applications that require complex queries.
Advantages
- Familiar SQL Syntax: Leverage existing SQL skills.
- Complex Queries: Perform joins, aggregations, and subqueries.
Implementation Steps
Backend (.NET):
-
Install PI OLEDB Provider
Install the appropriate driver on your backend server.
-
Establish Connection and Query Data
using System.Data.OleDb; [ApiController] [Route("api/pi")] public class PiDataController : ControllerBase { [HttpGet("data/{tag}")] public IActionResult GetPiData(string tag) { string connectionString = "Provider=PIOLEDB;Data Source=YourPIServer;"; using (OleDbConnection connection = new OleDbConnection(connectionString)) { connection.Open(); string query = $"SELECT time, value FROM piarchive..piinterp WHERE tag = '{tag}'"; OleDbCommand command = new OleDbCommand(query, connection); OleDbDataReader reader = command.ExecuteReader(); // Process data } return Ok(); } }
Front-End (React):
Fetch data from your .NET backend as usual.
Considerations
- Complexity: Requires understanding of PI SQL schemas.
- Performance: May not be as performant for real-time data.
4. PI Web Services (SOAP)
Overview
PI Web Services is a SOAP-based interface to the PI System. While it's considered legacy technology, it can be used if your architecture is built around SOAP.
Advantages
- Compatibility: Works with systems that require SOAP.
- Functionality: Provides access to PI data and metadata.
Implementation Steps
Backend (.NET):
-
Add Service Reference
In your .NET project, add a service reference to the PI Web Services WSDL endpoint.
-
Consume the Service
var client = new PIWebServiceClient(); var data = client.GetPIData(...);
Front-End (React):
Since SOAP is not commonly used in JavaScript, it's best to wrap SOAP calls in your .NET backend and expose RESTful endpoints to the React app.
Considerations
- Modernization: SOAP is less common in modern web development.
- Complexity: More overhead compared to RESTful services.
5. Direct WebSocket Communication
Overview
For applications that require real-time data updates, WebSockets provide a persistent connection between the client and server, allowing instant data push.
Advantages
- Real-Time Data: Ideal for live dashboards and monitoring systems.
- Efficiency: Reduces the need for frequent polling.
Implementation Steps
Backend (.NET):
-
Implement WebSocket Server
Use libraries like SignalR for ASP.NET Core to simplify real-time communication.
public class PiDataHub : Hub { private readonly PIServer _piServer; public PiDataHub() { var piServers = new PIServers(); _piServer = piServers.DefaultPIServer; } public async Task StreamPiData(string tag) { var piPoint = PIPoint.FindPIPoint(_piServer, tag); while (true) { var value = piPoint.CurrentValue(); await Clients.Caller.SendAsync("ReceivePiData", value.Value); await Task.Delay(1000); // Adjust the interval as needed } } } -
Configure SignalR in Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddSignalR(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseEndpoints(endpoints => { endpoints.MapHub<PiDataHub>("/pidatahub"); }); }
Front-End (React):
-
Install SignalR Client
npm install @microsoft/signalr -
Connect to the Hub
import React, { useEffect, useState } from 'react'; import * as signalR from '@microsoft/signalr'; const PiDataComponent = () => { const [data, setData] = useState(null); useEffect(() => { const connection = new signalR.HubConnectionBuilder() .withUrl('/pidatahub') .build(); connection.start() .then(() => connection.invoke('StreamPiData', 'your-tag-name')) .catch(error => console.error(error)); connection.on('ReceivePiData', value => { setData(value); }); return () => { connection.stop(); }; }, []); return ( <div> {data ? <p>Current Value: {data}</p> : 'Loading...'} </div> ); }; export default PiDataComponent;
Considerations
- Scalability: Ensure your backend can handle multiple concurrent connections.
- Complexity: Adds overhead in managing persistent connections.
Choosing the Right Approach
Selecting the optimal data access technique depends on various factors:
- Application Requirements: Do you need real-time updates or periodic data fetching?
- Development Resources: What technologies are your team comfortable with?
- Performance Needs: How critical is the data latency?
- Security Policies: Are there constraints on data access methods?
Recommendation:
- Use PI Web API for most web applications due to its ease of use and compatibility.
- Consider PI AF SDK when you need advanced features and are running your backend on Windows.
- Use WebSockets for applications requiring real-time data streaming.
- Avoid legacy methods like PI Web Services unless necessary.
Security Considerations
When integrating with the PI System, security is paramount:
- Authentication and Authorization: Implement robust authentication (e.g., OAuth, JWT) and ensure users have appropriate permissions.
- Secure Communication: Use HTTPS to encrypt data in transit.
- Input Validation: Sanitize inputs to prevent injection attacks.
- Error Handling: Avoid exposing sensitive information in error messages.
Best Practices
- Caching: Implement caching strategies to reduce load and improve performance.
- Error Handling: Gracefully handle exceptions and provide user-friendly messages.
- Logging and Monitoring: Track API usage and monitor for anomalies.
- Version Control: Use API versioning to manage changes over time.
- Documentation: Maintain clear documentation for your APIs.
Sample Implementation Using PI Web API
Let's delve deeper into a sample implementation using the PI Web API, which is the most straightforward method for web applications.
Backend (.NET) Implementation
1. Setting Up the PI Web API Client
Create a service to interact with the PI Web API.
public interface IPiWebApiClient
{
Task<string> GetTagValueAsync(string tag);
}
public class PiWebApiClient : IPiWebApiClient
{
private readonly HttpClient _httpClient;
public PiWebApiClient(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<string> GetTagValueAsync(string tag)
{
var response = await _httpClient.GetAsync($"/piwebapi/streams/{tag}/value");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return content;
}
}
2. Registering the Client in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<IPiWebApiClient, PiWebApiClient>(client =>
{
client.BaseAddress = new Uri("https://your-pi-web-api-server");
// Configure authentication if needed
});
services.AddControllers();
}
3. Creating the API Controller
[ApiController]
[Route("api/pi")]
public class PiDataController : ControllerBase
{
private readonly IPiWebApiClient _piWebApiClient;
public PiDataController(IPiWebApiClient piWebApiClient)
{
_piWebApiClient = piWebApiClient;
}
[HttpGet("data/{tag}")]
public async Task<IActionResult> GetPiData(string tag)
{
var data = await _piWebApiClient.GetTagValueAsync(tag);
return Content(data, "application/json");
}
}
Front-End (React) Implementation
1. Creating a Service to Fetch Data
// piDataService.js
import axios from 'axios';
export const getPiData = (tag) => {
return axios.get(`/api/pi/data/${tag}`)
.then(response => response.data)
.catch(error => {
console.error('Error fetching PI data:', error);
throw error;
});
};
2. Using the Service in a Component
// PiDataComponent.jsx
import React, { useEffect, useState } from 'react';
import { getPiData } from './piDataService';
const PiDataComponent = () => {
const [data, setData] = useState(null);
useEffect(() => {
getPiData('your-tag-name')
.then(piData => setData(piData))
.catch(error => console.error(error));
}, []);
return (
<div>
{data ? (
<div>
<h3>PI Data for Tag: your-tag-name</h3>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
) : (
'Loading...'
)}
</div>
);
};
export default PiDataComponent;
Conclusion
Integrating OSIsoft PI System data into a modern React front-end with a .NET backend opens up a world of possibilities for real-time data visualization and analytics. While the PI Web API is a robust and straightforward method, understanding the various techniques available allows you to make informed decisions tailored to your application's requirements.
By considering factors like performance, complexity, and security, you can choose the optimal approach that not only meets your current needs but is also scalable for future enhancements. Always adhere to best practices and stay updated with the latest developments in both PI System technologies and web development frameworks.
About the Author
John Doe is a software engineer specializing in industrial data systems and web application development. With over a decade of experience integrating operational technology with modern software solutions, he is passionate about bridging the gap between legacy systems and cutting-edge applications.
References
- OSIsoft PI System Documentation
- PI Web API Developer Guide
- ASP.NET Core Documentation
- React Documentation
Disclaimer: The code samples provided are for illustrative purposes and may require additional context or configuration to work in your specific environment.
Tags
About Roshan Soni
Expert in PI System implementation, industrial automation, and data management. Passionate about helping organizations maximize the value of their process data through innovative solutions and best practices.
No comments yet
Be the first to share your thoughts on this article.
Related Articles
Enhancing PI ProcessBook Trends with Banding and Zones: User Needs, Workarounds, and the Road Ahead
A look at the user demand for trend banding/zoning in OSIsoft PI ProcessBook, current VBA workarounds, UI challenges, and how future PI Vision releases aim to address these visualization needs.
Roshan Soni
Migrating PIAdvCalcFilVal Uptime Calculations from PI DataLink to PI OLEDB
Learn how to translate PI DataLink's PIAdvCalcFilVal advanced calculations—like counting uptime based on conditions—into efficient PI OLEDB SQL queries. Explore three practical approaches using PIAVG, PIINTERP, and PICOunt tables, and get tips for validation and accuracy.
Roshan Soni
Understanding PI Web API WebID Encoding: Can You Generate WebIDs Client-Side?
Curious about how PI Web API generates WebIDs and whether you can encode them client-side using GUIDs or paths? This article explores the encoding mechanisms, current documentation, and best practices for handling WebIDs in your applications.
Roshan Soni