Architecture
A LuxReact HMI has four layers.
| Layer | Component | Job |
|---|---|---|
| UI binding | LuxReact | Connects React components to variables with hooks |
| Client | LuxConnect OpcuaMachine |
Manages the session, subscriptions, and value cache |
| Transport | HTTPS REST plus a WebSocket push channel | Carries reads, writes, and updates |
| Gateway | mapp Connect or OPC UA Proxy | Reads and writes variables on the controller over OPC UA |
flowchart TD
subgraph App["Browser or Electron"]
UI[React components] -->|useVariable / useWrite| LR[LuxReact
MachineProvider] LR -->|ICommLayer| LC[LuxConnect
OpcuaMachine] end LC -->|"REST: sessions, read, write"| GW{Gateway} GW -.->|"WebSocket push channel"| LC GW -->|B&R| MC[mapp Connect
on the controller] --> BR[(B&R PLC)] GW -->|"Other OPC UA"| P[OPC UA Proxy
on a PC or in Electron] --> OS[OPC UA server] --> PLC[(Beckhoff or other PLC)]
MachineProvider] LR -->|ICommLayer| LC[LuxConnect
OpcuaMachine] end LC -->|"REST: sessions, read, write"| GW{Gateway} GW -.->|"WebSocket push channel"| LC GW -->|B&R| MC[mapp Connect
on the controller] --> BR[(B&R PLC)] GW -->|"Other OPC UA"| P[OPC UA Proxy
on a PC or in Electron] --> OS[OPC UA server] --> PLC[(Beckhoff or other PLC)]
- LuxReact handles the React side: providers, hooks, subscription bookkeeping, and caching values across remounts. It does not know how values reach the PLC. It talks to an
ICommLayerinterface. - LuxConnect is the
ICommLayerimplementation. It opens an OPC UA session through the gateway, subscribes to variables, and receives changes over the push channel. - The gateway is mapp Connect on a B&R controller, or OPC UA Proxy for other OPC UA servers. Both offer the same API, so the HMI code is the same either way.
Because LuxReact only depends on ICommLayer, a different transport means writing a different adapter. The React code stays the same. LuxReact ships a MockCommLayer for tests and component previews.