Category Archives: Machine Learning

🚀 MCP Server for WinCC Unified – Powered by GraphQL and GenAI!

Just gave myself a little nightly challenge: I implemented an MCP Server for WinCC Unified, based on its GraphQL Server.

https://github.com/vogler75/winccua-mcp-server

Thanks to the GraphQL server’s built-in documentation and its clearly defined data structures, it was surprisingly straightforward to generate most of the MCP server code — with the help from Gemini! 🙌

Super excited about how well this combination works — the power of Unified, GraphQL, and GenAI all together! 💡

The prompt for the example in the picture was: “logon with username1 and password1 and then fetch the values of the Meter Input logging tag of the last 10 minutes and plot it.”

Next time I asked Claude to forecast my solar PV production to help me decide whether it’s a good time to run my dryer.

It’s fascinating how you can simply ask questions like “Should I run my dryer now?” and get intelligent – really? 🧐 – responses based on actual and historical production data.

What I like about that:
✅ Natural conversation with my process data
✅ Real-time insights from WinCC Unified data
✅ AI-powered recommendations …

👀 But can I trust it? No, you do not know how it came to this forecast…

Dockerfile for Python 3.9 with OpenCV, MediaPipe, TensorFlow Lite and Coral Edge TPU

Dockerfile

FROM python:3.9-slim
RUN apt-get update && apt -y install curl gnupg libgl1-mesa-glx libglib2.0-0 && rm -rf /var/lib/apt/lists/*
RUN echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | tee /etc/apt/sources.list.d/coral-edgetpu.list 
RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && apt-get update && apt-get install -y python3-tflite-runtime && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt /
RUN pip install -r /requirements.txt
COPY * /app/

Requirements.txt

opencv-python
mediapipe

Python and WinCC OA…

Connected Python to WinCC OA through a Websocket Manager. Python programs can connect to WinCC OA and read/write datapoints. Communication is JSON based, it’s simple to use in Python, see examples below (ws://rocworks.no-ip.org can be used for tests, but will not be available all the time).

https://github.com/vogler75/oa4j-wss

  1. dpGet
  2. dpSet
  3. dpConnect
  4. dpQueryConnect
  5. dpGetPeriod
  6. … more functions will be implemented

Required Python modules:

  • pip3 install websocket-client
  • pip3 install matplotlib

############################################################
# Open Connection
############################################################
import json
import ssl
from websocket import create_connection
url='ws://rocworks.no-ip.org/winccoa?username=demo&password=demo'
ws = create_connection(url, sslopt={"cert_reqs": ssl.CERT_NONE})

############################################################
# dpGetPeriod
############################################################
cmd={'DpGetPeriod': {
 'Dps':['ExampleDP_Trend1.'],
 'T1': '2018-02-07T18:10:00.000', 
 'T2': '2018-02-07T23:59:59.999',
 'Count': 0, # Optional (Default=0)
 'Ts': 0 # Optional (0...no ts in result, 1...ts as ms since epoch, 2...ts as ISO8601)
 }}
ws.send(json.dumps(cmd))
res=json.loads(ws.recv())
#print(res)
if "System1:ExampleDP_Trend1.:_offline.._value" in res["DpGetPeriodResult"]["Values"]:
 values=res["DpGetPeriodResult"]["Values"]["System1:ExampleDP_Trend1.:_offline.._value"]
 print(values)
else:
 print("no data found")

# Plot result of dpGetPeriod
%matplotlib inline 
import matplotlib.pyplot as plt
plt.plot(values)
plt.ylabel('ExampleDP_Trend1.')
plt.show()

############################################################
# dpGet
############################################################
cmd={'DpGet': {'Dps':['ExampleDP_Trend1.', 'ExampleDP_Trend2.']}}
ws.send(json.dumps(cmd))
res=json.loads(ws.recv())
print(json.dumps(res, indent=4, sort_keys=True))

############################################################
# dpSet
############################################################
from random import randint
cmd={'DpSet': {'Wait': True, 
 'Values':[{'Dp':'ExampleDP_Trend1.','Value': randint(0, 9)}, 
 {'Dp':'ExampleDP_Trend2.','Value': randint(0, 9)}]}}
ws.send(json.dumps(cmd))
res=json.loads(ws.recv())
print(json.dumps(res, indent=4, sort_keys=True))

############################################################
# dpConnect
############################################################
from threading import Thread

def read():
    while True:
        res=json.loads(ws.recv())
        print(res)
Thread(target=read).start()
    
cmd={"DpConnect": {"Id": 1, "Dps": ["ExampleDP_Trend1."]}}
ws.send(json.dumps(cmd))