SCADA Integration¶
Data Pipeline Integration¶
timeseries-qc can be integrated into SCADA data pipelines for automated quality monitoring:
- Extract data from SCADA historian (OSIsoft PI, Wonderware, Ignition, etc.)
- Transform data into the expected DataFrame format (timestamp, tag_name, value)
- Check quality with
tsqc.check() - Report via
result.export_report()or storeresult.dfback to the historian
CSV-Based Integration¶
Many SCADA systems can export data as CSV. Load and check with:
import pandas as pd
import tsqc
df = pd.read_csv("export.csv", parse_dates=["timestamp"])
result = tsqc.check(df, assume_tz="UTC")
Database Integration¶
For SCADA systems with SQL access:
import pandas as pd
import tsqc
from sqlalchemy import create_engine
engine = create_engine("postgresql://user:pass@host:5432/scada")
query = "SELECT timestamp, tag_name, value FROM measurements WHERE timestamp >= NOW() - INTERVAL '7 days'"
df = pd.read_sql(query, engine)
result = tsqc.check(df, assume_tz="UTC")
OSIsoft PI¶
For OSIsoft PI systems, use the PI Web API client to fetch data:
from piwebapi.pi_web_api_client import PIWebApiClient
client = PIWebApiClient("https://pisrvr/piwebapi", auth=("user", "pass"))
# Fetch data and convert to DataFrame
# Then pass to tsqc.check()
API Integration¶
Historical Context: Timezone Handling¶
Most industrial historians (Aspen IP21, OSIsoft PI, Wonderware, GE Historian) return timestamps as local wall-clock time with no timezone attached. When working with such data:
- Pass the source timezone via
assume_tz(e.g.,assume_tz="America/Edmonton"). - The library normalises to UTC internally for consistent rule evaluation.
- All output —
result.df,result.plot(),issue_summary(),check_timestamps()— displays timestamps in the original source timezone automatically. - If your timestamps are already tz-aware (e.g., ISO 8601 with offset),
assume_tzis optional.
API Integration¶
For custom integrations, timeseries-qc can be wrapped in an API endpoint:
from flask import Flask, request, jsonify
import tsqc
app = Flask(__name__)
@app.route("/qc/check", methods=["POST"])
def qc_check():
data = request.get_json()
df = pd.DataFrame(data["measurements"])
result = tsqc.check(df, assume_tz=data.get("timezone", "UTC"))
return jsonify(result.summary().to_dict(orient="records"))
Next Steps¶
- Industry Use Cases — applications across sectors
- YAML Configuration — configure rules per tag
- User Guide — walkthrough with examples