- Application Guide
- FlowFuse Guide
- Overview
- Foundations
- App delivery methods
- Hardware apps
- Software apps
- Data plane
- Architectures
- IT architectures
- OT architectures
- IIoT architectures
- Worked examples
- OEE, end to end
- Node-RED Guide
- Overview
- Foundations
- Patterns
- Design patterns
- Handling data
- Good form
- Worked examples
- OEE - Edge Aggregator
- OEE - Central Dashboard
OEE - Edge Aggregator
The edge app from the FlowFuse OEE worked example — it reads a line's machine signals and publishes its state, one Remote Instance per line. The flow logic is a simple straight line; the choices that matter are packaging it for reuse and treating the data as a stream.
Definition
- The app — reads a line's machine signals and publishes its state.
- Design pattern — subflow, applied to the whole flow (not to extract an internal seam): the straight-line flow is packaged as one subflow and dropped onto every line, each configured with its own line's PLC tags as per-instance config — the Node-RED side of the Configurable App pattern.
- Data handling — classify (the signals are a telemetry stream, read at the poll cadence) → hold the running run/stop counts in context.
- Runs on — a Remote Instance, one per line.
- Why this shape — the same complete job runs identically on every line, right next to the equipment, and keeps working if the link drops.
The flow
Why these choices
- Subflow, applied whole-flow — the flow itself is a straight line with no seams to extract, so there's no internal pattern to reach for. But because the same complete flow runs on every line, it's packaged as a subflow — reuse across instances is exactly the subflow rung. The pattern is applied to the whole flow, not to a piece inside it.
- Configured per line — why it's a Configurable App — a config UI node sets this line's PLC tag names into context; a get config node in front of the PLC read loads them, so the one subflow reads different tags on every line without changing the build. That per-line configuration is exactly what makes it a Configurable App.
- Classify: it's a stream — the signals are telemetry read at the poll cadence, so the latest value matters more than any single earlier one. One read → one compute → one publish per tick; the poll interval already paces it, so there's no fast-in / slow-out to rate-limit.
- Context for the counts — running run/stop counts live in flow context, not threaded through the wires.
- Catch the read — a PLC read can time out; a Catch scoped to the read handles a dropped read so it doesn't stall the publish. A Catch node isn't wired from the read — it registers to catch errors in its scope, so the dashed line shows that scope, not a connection. Catching errors is good form, not a per-flow choice.
In one line — a subflow per line: set the tags in a config UI, load them, then poll → read → compute → publish (with a scoped catch); the data call is treating it as a stream and holding the counts in context.