pkey
OPC UA

How to Integrate PLC with Python in a Production Line

A practical, code-first guide for industrial automation (OPC UA, data pipelines, and MES integration)


🔧 Introduction

Programmable Logic Controllers (PLCs) excel at deterministic, real-time control. They are reliable, predictable, and designed for harsh industrial environments.

But modern production lines demand more:

  • real-time analytics
  • cloud integration
  • predictive maintenance
  • MES / ERP connectivity

That’s where Python becomes extremely valuable.

Instead of replacing PLCs, Python acts as a bridge between OT (Operational Technology) and IT systems.


🧠 Core Architecture

The most common integration pattern looks like this:

https://images.openai.com/static-rsc-4/gGpg9Oc45lmXquNscdKpd9dngUKvPDUnQbZ3w6pPQznWT6GdGylqFmnMZ4n5kOSKnt26ERpZGROOhoJW4zwkj5WWNvytchBgkq4vIrXMQt90uUzxMvmm5U0iLf7yLWGRFwPX4rmou7iw74aR7N9cdtMPY5-xkEYybcVj7NFZH2YX-wKV_E0Kurh_cl_hvwwi?purpose=fullsize
https://images.openai.com/static-rsc-4/K8ovlkziiJDcAJarHoGy4qS2Bo6vE7VyO00XsXKS82mRtN1VDgnBt5rXIUdUMnn3rvTpG9PJoxu_OEc7QXUntDaBzFrRZYyjo8mhrKOuYq7WAldrD49lsU0Qm3GACIr3iwTKmSMD5cIkHVMINlhw2kEWzwr1-pg_GOgOBHRhguCMGoN0068fCSjbMFhBO4dt?purpose=fullsize
https://images.openai.com/static-rsc-4/S5vYnWwIDL7hg6H8q4PQ8JbsaaiJbWuoGfiTstvhWV7CzR5C_ulUgbXl7dwHhr5xPgbAEeLH7zi8RZ7_n0YVGOSMbTOO5r0kpssEGnFPiW_1cy8j5kAd6AkHQdFeDPeDxgFfu82ghp15RQeImN0FAhVfygwdxGhE4yTlZMJn734cMya5L4kqVZKuZTe0FZr_?purpose=fullsize

7

Flow:

PLC → OPC UA → Python → Database / Cloud / MES

⚙️ Why Python?

Python is widely used in industrial environments because:

  • fast prototyping
  • huge ecosystem (AI, data, cloud)
  • easy OPC UA integration
  • strong community support

Typical libraries:

  • opcua (PLC communication)
  • pandas (data processing)
  • numpy (analytics)
  • sqlalchemy (database)
  • requests (API integration)

🏭 Real Use Cases

1. Production Monitoring

  • machine states (RUN / STOP / ERROR)
  • cycle time tracking
  • downtime analysis

2. OEE Calculation

  • availability
  • performance
  • quality

3. Predictive Maintenance

  • vibration data
  • temperature trends
  • anomaly detection

4. MES / ERP Integration

  • production orders
  • material tracking
  • reporting

🔌 Step 1: Connecting to PLC via OPC UA

Most modern PLCs (e.g., Siemens, Beckhoff, Allen-Bradley) expose OPC UA servers.

Install dependencies

BAT (Batchfile)
pip install opcua

Python OPC UA Client Example

Python
from opcua import Client

url = "opc.tcp://192.168.0.10:4840"
client = Client(url)

try:
    client.connect()

    temperature_node = client.get_node("ns=2;i=2")
    value = temperature_node.get_value()

    print(f"Temperature: {value}")

finally:
    client.disconnect()

📡 Step 2: Subscribing to Real-Time Data

Polling is inefficient. Instead, use subscriptions.

Python
from opcua import Client, ua

class SubscriptionHandler:
    def datachange_notification(self, node, val, data):
        print(f"Data changed: {node} -> {val}")

client = Client("opc.tcp://192.168.0.10:4840")
client.connect()

handler = SubscriptionHandler()
subscription = client.create_subscription(500, handler)

node = client.get_node("ns=2;i=2")
subscription.subscribe_data_change(node)

👉 This enables event-driven processing.


🗄️ Step 3: Saving Data to Database

Example using SQLite:

Python
import sqlite3
from datetime import datetime

conn = sqlite3.connect("production.db")
cursor = conn.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS telemetry (
    timestamp TEXT,
    value REAL
)
""")

def save_value(value):
    cursor.execute(
        "INSERT INTO telemetry VALUES (?, ?)",
        (datetime.utcnow().isoformat(), value)
    )
    conn.commit()

☁️ Step 4: Sending Data to Cloud API

Python
import requests

def send_to_cloud(value):
    payload = {
        "machine": "line_1",
        "temperature": value
    }

    requests.post(
        "https://api.example.com/telemetry",
        json=payload
    )

🔄 Step 5: Full Integration Example

Putting everything together:

Python
from opcua import Client
import sqlite3
import requests
from datetime import datetime

class Handler:
    def datachange_notification(self, node, val, data):
        print(f"New value: {val}")
        save_value(val)
        send_to_cloud(val)

def save_value(value):
    conn = sqlite3.connect("production.db")
    cursor = conn.cursor()

    cursor.execute("""
    CREATE TABLE IF NOT EXISTS telemetry (
        timestamp TEXT,
        value REAL
    )
    """)

    cursor.execute(
        "INSERT INTO telemetry VALUES (?, ?)",
        (datetime.utcnow().isoformat(), value)
    )

    conn.commit()
    conn.close()

def send_to_cloud(value):
    requests.post(
        "https://api.example.com/data",
        json={"value": value}
    )

client = Client("opc.tcp://192.168.0.10:4840")
client.connect()

handler = Handler()
sub = client.create_subscription(1000, handler)

node = client.get_node("ns=2;i=2")
sub.subscribe_data_change(node)

try:
    while True:
        pass
except KeyboardInterrupt:
    client.disconnect()

🧩 Industrial Data Flow Explained

https://images.openai.com/static-rsc-4/52tImP_E35FtoM4TDGvJwMdKpn-gZB0Gqbbd2w05J1COfgWeIzFtpjVmZDL_JmD8MbPW7Z8ufq2p7KU2Lw8JkECk-3mjwJjWH27NoohBN3ycSGplHJJ4R3ZsQsajrX_k9DJmRKHZOOmNXoORf8-kr9IBoZOv6wtx2jKXfBTiNuuTSgpfyz3b6PCfyuJYO8ws?purpose=fullsize
https://images.openai.com/static-rsc-4/K8ovlkziiJDcAJarHoGy4qS2Bo6vE7VyO00XsXKS82mRtN1VDgnBt5rXIUdUMnn3rvTpG9PJoxu_OEc7QXUntDaBzFrRZYyjo8mhrKOuYq7WAldrD49lsU0Qm3GACIr3iwTKmSMD5cIkHVMINlhw2kEWzwr1-pg_GOgOBHRhguCMGoN0068fCSjbMFhBO4dt?purpose=fullsize
https://images.openai.com/static-rsc-4/n7CftNyBVAqCwmjucuqiZfjMmasviaurPZBvE_5x26aY7KxJ2FrCnWkVa9BbDd_1LMOy_Za2a7AcgEavef2btN4ix2t8SudyNdAb_HeTCTOoXpTPwO-NnKyOZ69vHY8oJ2fQJexapHMco1NO6f4nNh8i8xjVl2oI8KnKnPaTuwKDODSS1Z5tWGFpwVyarIpp?purpose=fullsize

6

Key layers:

  1. PLC Layer
    Real-time signals
  2. OPC UA Layer
    Standardized communication
  3. Python Layer
    • processing
    • enrichment
    • routing
  4. IT Systems
    • database
    • MES
    • cloud

⚠️ Common Pitfalls

❌ Polling instead of subscriptions

👉 leads to performance issues

❌ No buffering

👉 data loss during network failures

❌ Blocking code

👉 delays real-time processing

❌ Tight coupling with PLC structure

👉 hard to maintain


🛠️ Production-Ready Improvements

For real-world deployments:

  • use message brokers (Kafka / RabbitMQ)
  • implement retry policies
  • add data buffering (Redis / local queue)
  • run as Docker container
  • add monitoring (Prometheus / Grafana)

🔐 Security Considerations

  • enable OPC UA security (certificates)
  • avoid exposing PLC directly to internet
  • use VPN or gateway
  • validate incoming data

🧪 Testing Strategy

  • simulate PLC using OPC UA simulator
  • test network failures
  • load test subscriptions
  • validate data integrity

🚀 When to Use This Pattern

This architecture works best when:

  • PLC logic should remain unchanged
  • analytics is required
  • integration with IT systems is needed
  • scalability is important

🧾 Conclusion

Python does not replace PLCs.

👉 It extends their capabilities into the IT world.

References

https://akpolatcem.medium.com/getting-started-with-opc-ua-building-your-first-client-server-application-in-python-6107fb4cafec

More Info

We implement this in real production systems.
If you need help → contact us

Contact