[{"data":1,"prerenderedAt":353},["ShallowReactive",2],{"agmd-flowfuse-hardware-apps":3,"application-guide-nav":245},{"id":4,"title":5,"blurb":6,"body":7,"description":20,"extension":235,"guide":236,"meta":237,"navOrder":238,"navTitle":5,"navigation":239,"parent":240,"path":241,"seo":242,"slug":13,"stem":243,"__hash__":244},"applicationGuideDoc\u002Fapplication-guide\u002Fflowfuse\u002Fhardware-apps.md","Hardware apps","The three shapes a FlowFuse app takes when it runs on a device. Pick by how much varies per site: nothing (Packaged App), a few settings (Configurable App), or you assemble it yourself (Edge Building Block).",{"type":8,"value":9,"toc":231},"minimark",[10,14,21,23],[11,12,5],"h1",{"id":13},"hardware-apps",[15,16,17],"p",{},[18,19,20],"strong",{},"Hardware apps — start here",[15,22,6],{},[24,25,26,102,167],"guide-tabs",{},[27,28,30,35,38,44,50,55,83,88],"guide-tab",{"label":29},"Packaged App",[31,32],"flow-diagram",{":edges":33,":nodes":34},"[{\"from\":\"snap\",\"to\":\"inst\",\"label\":\"deploy · sealed\",\"accent\":\"slate\"}]","[{\"id\":\"snap\",\"label\":\"Pipeline snapshot\",\"sub\":\"sealed · built once\",\"accent\":\"indigo\"},{\"id\":\"inst\",\"label\":\"Remote Instance\",\"sub\":\"identical\",\"accent\":\"indigo\",\"many\":true}]",[15,36,37],{},"A sealed product that ships on a piece of hardware and is identical everywhere — buy it, it runs on its device, nothing to configure.",[15,39,40,43],{},[18,41,42],{},"Use it when"," — The app ships with a known partner device and the data it reads is fixed by that hardware.",[15,45,46,49],{},[18,47,48],{},"How it works"," — Built and promoted through a pipeline (dev → staging → prod), then deployed to a Remote Instance as a snapshot. Everything is baked in; only fixed env vars vary at deploy.",[15,51,52],{},[18,53,54],{},"Major components",[56,57,58,65,71,77],"ul",{},[59,60,61,64],"li",{},[18,62,63],{},"Pipeline snapshot"," — the app built once, promoted to the device",[59,66,67,70],{},[18,68,69],{},"Remote Instance (edge device)"," — FlowFuse-managed Node-RED running the sealed app",[59,72,73,76],{},[18,74,75],{},"Team Broker (MQTT)"," — carries the app's events to subscribers",[59,78,79,82],{},[18,80,81],{},"FlowFuse Tables"," — stores the rows the app writes",[15,84,85],{},[18,86,87],{},"Where config & data live",[56,89,90,96],{},[59,91,92,95],{},[18,93,94],{},"Config"," — baked into the snapshot; only fixed env vars at deploy, nothing per-site.",[59,97,98,101],{},[18,99,100],{},"Data"," — events to the Team Broker, records to FlowFuse Tables.",[27,103,105,110,113,118,123,127,151,155],{"label":104},"Configurable App",[31,106],{":edges":107,":nodes":108,":legend":109},"[{\"from\":\"snap\",\"to\":\"inst\",\"label\":\"same build\",\"accent\":\"slate\"},{\"from\":\"cfg\",\"to\":\"inst\",\"label\":\"loads its own config\",\"accent\":\"red\",\"dashed\":true}]","[{\"id\":\"snap\",\"label\":\"Pipeline snapshot\",\"sub\":\"same build\",\"accent\":\"indigo\",\"col\":1,\"row\":1},{\"id\":\"cfg\",\"label\":\"Per-site config\",\"sub\":\"tags · broker · site\",\"accent\":\"slate\",\"col\":1,\"row\":2},{\"id\":\"inst\",\"label\":\"Remote Instance\",\"sub\":\"per site\",\"accent\":\"indigo\",\"many\":true,\"col\":2,\"row\":1}]","[{\"line\":\"slate\",\"label\":\"same build\"},{\"line\":\"red\",\"dashed\":true,\"label\":\"loads its own config\"}]",[15,111,112],{},"The same shelf product, plus a few knobs — tag names, broker address, site name — that differ per site and live on the Remote Instance.",[15,114,115,117],{},[18,116,42],{}," — The flows are the same everywhere but the values they use differ per install and may change over time.",[15,119,120,122],{},[18,121,48],{}," — Same pipeline delivery to a Remote Instance; the runtime loads a per-site config from a file on the device. Back that file up to the database, so a device swap restores the config — the device is the source of truth, the DB is the safety net.",[15,124,125],{},[18,126,54],{},[56,128,129,134,139,145],{},[59,130,131,133],{},[18,132,63],{}," — the same build promoted to every device",[59,135,136,138],{},[18,137,69],{}," — runs the app and loads its own per-site config",[59,140,141,144],{},[18,142,143],{},"Per-site config (tags · broker · site)"," — a file on the device, backed up to the DB",[59,146,147,150],{},[18,148,149],{},"Team Broker \u002F FlowFuse Tables"," — event egress + records",[15,152,153],{},[18,154,87],{},[56,156,157,162],{},[59,158,159,161],{},[18,160,94],{}," — a per-site file on the device (tags, broker address, site name), backed up to FlowFuse Tables so a swap restores it.",[59,163,164,166],{},[18,165,100],{}," — Team Broker + FlowFuse Tables.",[27,168,170,174,177,182,187,191,215,219],{"label":169},"Edge Building Block",[31,171],{":edges":172,":nodes":173},"[{\"from\":\"eq\",\"to\":\"inst\",\"label\":\"reads\"},{\"from\":\"inst\",\"to\":\"broker\",\"label\":\"publishes\",\"accent\":\"slate\"}]","[{\"id\":\"eq\",\"label\":\"Equipment\",\"sub\":\"signals \u002F PLC\",\"accent\":\"slate\"},{\"id\":\"inst\",\"label\":\"Remote Instance\",\"sub\":\"edge building block\",\"accent\":\"indigo\"},{\"id\":\"broker\",\"label\":\"Team Broker\",\"sub\":\"MQTT\",\"accent\":\"indigo\"}]",[15,175,176],{},"Not a finished app — one hardware-facing block plus example flows, running on a Remote Instance. You assemble everything upstream of it yourself.",[15,178,179,181],{},[18,180,42],{}," — The hardware-facing piece is reusable, but everything before it differs so much per site that no finished app would fit.",[15,183,184,186],{},[18,185,48],{}," — Blocks are published as subflows to the Team Library with an example flow. Consumers drop them onto a Remote Instance and wire them up.",[15,188,189],{},[18,190,54],{},[56,192,193,199,204,209],{},[59,194,195,198],{},[18,196,197],{},"Equipment (signals \u002F PLC)"," — the source hardware the block reads",[59,200,201,203],{},[18,202,69],{}," — runs the edge building block at the line",[59,205,206,208],{},[18,207,75],{}," — publishes the normalized data upstream",[59,210,211,214],{},[18,212,213],{},"Team Library"," — where the block is published as an installable subflow",[15,216,217],{},[18,218,87],{},[56,220,221,226],{},[59,222,223,225],{},[18,224,94],{}," — lives in the consuming flow you build around the block (env \u002F context).",[59,227,228,230],{},[18,229,100],{}," — Team Broker (normalized, upstream).",{"title":232,"searchDepth":233,"depth":233,"links":234},"",4,[],"md","flowfuse",{},3.1,true,"app-delivery-methods","\u002Fapplication-guide\u002Fflowfuse\u002Fhardware-apps",{"title":5,"description":20},"application-guide\u002Fflowfuse\u002Fhardware-apps","FFkzfpAW4Jgn6CD1bZb4-90kNzSetNbm4UtDnLivoFg",[246,253,257,263,266,271,276,278,283,289,294,300,305,310,316,322,328,333,338,343,347],{"guide":236,"slug":247,"title":248,"navOrder":249,"parent":250,"blurb":251,"path":252},"overview","Overview",1,null,"The map of the FlowFuse guide — apps, architectures, and a worked example.","\u002Fapplication-guide\u002Fflowfuse\u002Foverview\u002F",{"guide":254,"slug":247,"title":248,"navOrder":249,"parent":250,"blurb":255,"path":256},"node-red","The map of the Node-RED guide — the pattern families that turn an app into a clean flow.","\u002Fapplication-guide\u002Fnode-red\u002Foverview\u002F",{"guide":236,"slug":258,"title":259,"navOrder":260,"parent":250,"blurb":261,"path":262},"foundations","Foundations",2,"The foundation to build on: what FlowFuse is, its core pieces, and how code is shared across teams.","\u002Fapplication-guide\u002Fflowfuse\u002Ffoundations\u002F",{"guide":254,"slug":258,"title":259,"navOrder":260,"parent":250,"blurb":264,"path":265},"The handful of concepts you need to build with Node-RED, and how they fit together.","\u002Fapplication-guide\u002Fnode-red\u002Ffoundations\u002F",{"guide":236,"slug":240,"title":267,"navOrder":268,"parent":250,"blurb":269,"path":270},"App delivery methods",3,"Two different units of code, delivered two ways. Ship the whole app — a complete, versioned project promoted through environments — or publish one reusable piece — a package the whole team installs and upgrades in one place. Pick by what you're shipping: the app, or a part of it.","\u002Fapplication-guide\u002Fflowfuse\u002Fapp-delivery-methods\u002F",{"guide":254,"slug":272,"title":273,"navOrder":268,"parent":250,"blurb":274,"path":275},"patterns","Patterns","The moves that turn an architecture into a clean, reusable flow — find the seams and reuse well, then handle data on the right paths.","\u002Fapplication-guide\u002Fnode-red\u002Fpatterns\u002F",{"guide":236,"slug":13,"title":5,"navOrder":238,"parent":240,"blurb":6,"path":277},"\u002Fapplication-guide\u002Fflowfuse\u002Fhardware-apps\u002F",{"guide":254,"slug":279,"title":280,"navOrder":238,"parent":272,"blurb":281,"path":282},"design-patterns","Design patterns","The structural choices you select for a flow: find the seams it breaks into, then reuse each piece at the lightest level that solves it — link in\u002Fout, link call, subflow, or packaged node.","\u002Fapplication-guide\u002Fnode-red\u002Fdesign-patterns\u002F",{"guide":236,"slug":284,"title":285,"navOrder":286,"parent":240,"blurb":287,"path":288},"software-apps","Software apps",3.2,"The three shapes a FlowFuse app takes when it runs on the platform. Pick by what it needs: a headless job (Packaged App), a user-facing app driven by data (Data-Driven App), or a reusable piece other apps embed (Shared Building Block).","\u002Fapplication-guide\u002Fflowfuse\u002Fsoftware-apps\u002F",{"guide":254,"slug":290,"title":291,"navOrder":286,"parent":272,"blurb":292,"path":293},"handling-data","Handling data","Classify each signal by shape, purpose and direction, then pick the methods it needs — separate the paths, pace the flow, hold state in context, and manage config. The methods you select to move a flow's data.","\u002Fapplication-guide\u002Fnode-red\u002Fhandling-data\u002F",{"guide":254,"slug":295,"title":296,"navOrder":297,"parent":272,"blurb":298,"path":299},"good-form","Good form",3.3,"A clean flow isn't luck — it's a handful of habits. Wire for reading, lay it out on a grid, decouple UI from logic, catch errors where you can see them, and keep data on a stable contract. Follow these and a flow stays readable, reusable, and out of spaghetti.","\u002Fapplication-guide\u002Fnode-red\u002Fgood-form\u002F",{"guide":236,"slug":301,"title":302,"navOrder":233,"parent":250,"blurb":303,"path":304},"data-plane","Data plane","Before you pick where things run, decide how data is handled. Two stores come built into every FlowFuse server install — the Team Broker and relational Tables — exposed to every instance with nothing extra to stand up. Everything else you bring your own: run it (a time-series DB, an existing database, a model) and expose it to the fleet over Project Link, no inbound ports. This is the data plane the architectures on the next pages all sit on.","\u002Fapplication-guide\u002Fflowfuse\u002Fdata-plane\u002F",{"guide":254,"slug":306,"title":307,"navOrder":233,"parent":250,"blurb":308,"path":309},"worked-examples","Worked examples","Turn an app concept into a Node-RED flow — or a few — leaning on the design patterns and data handling. The method, then the OEE apps end to end.","\u002Fapplication-guide\u002Fnode-red\u002Fworked-examples\u002F",{"guide":254,"slug":311,"title":312,"navOrder":313,"parent":306,"blurb":314,"path":315},"oee-edge-aggregator","OEE - Edge Aggregator",4.1,"The edge app from the OEE use case as a Node-RED flow — a straight-line flow packaged as a subflow and configured per line (its PLC tags, via a config UI and a get-config node), with the data treated as a stream and its counts held in context.","\u002Fapplication-guide\u002Fnode-red\u002Foee-edge-aggregator\u002F",{"guide":254,"slug":317,"title":318,"navOrder":319,"parent":306,"blurb":320,"path":321},"oee-central-dashboard","OEE - Central Dashboard",4.2,"The cloud app from the OEE use case as a Node-RED flow — one link out fanning to two link ins on separate tabs (dashboard and batched history), so the live and history paths stay separate and easy to read.","\u002Fapplication-guide\u002Fnode-red\u002Foee-central-dashboard\u002F",{"guide":236,"slug":323,"title":324,"navOrder":325,"parent":250,"blurb":326,"path":327},"architectures","Architectures",5,"Every FlowFuse deployment is the same building blocks arranged for where it runs — pick the world you're designing for.","\u002Fapplication-guide\u002Fflowfuse\u002Farchitectures\u002F",{"guide":236,"slug":329,"title":330,"navOrder":331,"parent":323,"blurb":250,"path":332},"it-architectures","IT architectures",5.1,"\u002Fapplication-guide\u002Fflowfuse\u002Fit-architectures\u002F",{"guide":236,"slug":334,"title":335,"navOrder":336,"parent":323,"blurb":250,"path":337},"ot-architectures","OT architectures",5.2,"\u002Fapplication-guide\u002Fflowfuse\u002Fot-architectures\u002F",{"guide":236,"slug":339,"title":340,"navOrder":341,"parent":323,"blurb":250,"path":342},"iiot-architectures","IIoT architectures",5.3,"\u002Fapplication-guide\u002Fflowfuse\u002Fiiot-architectures\u002F",{"guide":236,"slug":306,"title":307,"navOrder":344,"parent":250,"blurb":345,"path":346},6,"Start from a use case, break it into apps, and draw the architecture that ties them together — the same method a FlowFuse Proof of Value runs.","\u002Fapplication-guide\u002Fflowfuse\u002Fworked-examples\u002F",{"guide":236,"slug":348,"title":349,"navOrder":350,"parent":306,"blurb":351,"path":352},"worked-example","OEE, end to end",6.1,"One use case — OEE across three lines — broken into two apps and two shared services, then drawn out end to end.","\u002Fapplication-guide\u002Fflowfuse\u002Fworked-example\u002F",1787843652000]