Notifications
Subscribe to real-time PLC variable changes via SSE or WebSocket. Requires feature flag Notifications enabled.
Server-Sent Events (SSE)
GET /api/plcs/{plcId}/notifications/sse?symbols=MAIN.nCounter&symbols=MAIN.bRunningPolicy: ReadAccess
Simple HTTP-based streaming. Best for AI agents and lightweight clients.
Event types
event: subscribed
data: {"symbols":["MAIN.nCounter","MAIN.bRunning"]}
event: change
data: {"symbol":"MAIN.nCounter","value":42,"type":"UDINT","timestamp":"2026-03-18T14:22:01Z"}
event: heartbeat
data: {}
event: error
data: {"symbol":"MAIN.old","code":"SYMBOL_INVALIDATED","message":"Symbol no longer exists"}
event: disconnected
data: {"plcId":"Line1","code":"PLC_UNAVAILABLE"}
event: reconnected
data: {"plcId":"Line1"}Example
curl -N "http://localhost:5000/api/plcs/Line1/notifications/sse?symbols=MAIN.nCounter"WebSocket (SignalR)
WS /api/plcs/{plcId}/notifications/ws?access_token=<jwt>Policy: ReadAccess
Bidirectional communication via SignalR. Best for HMI applications needing rich interaction.
Authentication
Browser WebSocket connections cannot send Authorization headers. Pass the JWT via query string: ?access_token=<jwt>
Hub methods
| Method | Direction | Description |
|---|---|---|
Subscribe(string[] symbols) | Client -> Server | Subscribe to variable changes |
Unsubscribe(string[] symbols) | Client -> Server | Unsubscribe from variables |
SubscriptionConfirmed(string[] symbols) | Server -> Client | Confirms subscription |
VariableChanged(object event) | Server -> Client | Variable value changed |
Shared Subscriptions
Multiple clients subscribing to the same symbol on the same PLC share a single ADS notification. Reference-counted: the ADS notification is removed only when the last client unsubscribes.
Limits
- MaxSymbolsPerClient: 50 (configurable)
- Heartbeat interval: 30s (configurable)
- Default cycle time: 100ms (configurable)