Files
opcua_fastapi_backend/routers/websocket.py
2025-11-08 13:56:28 +01:00

62 lines
2.0 KiB
Python

from fastapi import WebSocket, APIRouter
import msgpack
import globalData as gd
from asyncua import ua
from models import WriteNodeCommand
router = APIRouter()
@router.websocket("/ws")
async def websocket_endpoint(ws: WebSocket):
global clients
await ws.accept()
gd.clients[ws] = set()
try:
while True:
# empfange binäre Daten vom Client
raw = await ws.receive_bytes()
data = msgpack.unpackb(raw, raw=False)
# Subscription handling
if "subscribe" in data:
gd.clients[ws].update(data["subscribe"])
diff_set = gd.subscribed_nodes.symmetric_difference(data["subscribe"])
nodes = [gd.opc_ua_client.get_node(f"{nid}") for nid in diff_set]
#await gd.subscription_handler.subscribe_data_change(nodes)
initial_values = {
nid: val
for nid in gd.node_storage
if (val := gd.node_storage.get(nid)) is not None
}
initial_events = {
nid: val
for nid in gd.event_storage
if (val := gd.event_storage.get(nid)) is not None
}
#if initial_values:
await ws.send_bytes(msgpack.packb({"initial": {"values": initial_values, "events": initial_events}}))
elif "unsubscribe" in data:
gd.clients[ws].pop(data["unsubscribe"])
elif "command" in data:
await handle_command(data["command"])
except Exception:
if ws in gd.clients:
del gd.clients[ws]
async def handle_command(cmd):
#print(f"Received command: {cmd}")
try:
wnc = WriteNodeCommand.model_validate(cmd)
node = gd.opc_ua_client.get_node(cmd["nodeId"])
dv = ua.DataValue(ua.Variant(wnc.nodeValue, wnc.nodeType))
await node.write_value(dv)
except Exception as e:
print(e)