[{"data":1,"prerenderedAt":10564},["ShallowReactive",2],{"blog-\u002Fblog\u002Fmqtt\u002F2":3,"blog-all-for-related":4,"blog-all-mqtt":5},null,[],[6,406,936,1196,1727,2033,3956,4464,4957,5368,5509,5691,6406,6624,6830,7030,7968,8208,9418,9924],{"id":7,"title":8,"authors":9,"body":11,"cta":380,"date":384,"description":385,"extension":386,"image":387,"lastUpdated":3,"meta":388,"navigation":394,"path":395,"seo":396,"sitemap":397,"stem":398,"subtitle":399,"tags":400,"tldr":404,"video":3,"__hash__":405},"blog\u002Fblog\u002F2026\u002F06\u002Fmqtt-vs-sparkplug-b.md","MQTT vs Sparkplug B: Which One (or Both) Do You Need?",[10],"sumit-shinde",{"type":12,"value":13,"toc":368},"minimark",[14,18,30,33,36,41,151,154,158,161,164,168,179,185,188,195,212,217,229,232,235,239,248,255,270,273,276,280,283,292,295,299,302,343,347,350,353],[15,16,17],"p",{},"MQTT is everywhere in industrial setups. It has been the default for moving sensor data and machine states around for a long time now, mostly because it's lightweight and it just works on almost anything.",[15,19,20,21,25,26,29],{},"The catch is that it doesn't really tell you anything about the data itself. Say a broker gets a message on ",[22,23,24],"code",{},"plant1\u002Fline4\u002Ftemp"," with a value of ",[22,27,28],{},"72",". Is that Celsius? Fahrenheit? Is the device still running, or did it go offline a few hours ago and that's just the last number it sent? MQTT won't tell you. It moves the bytes and the rest is up to you, which means everyone ends up handling it their own way.",[15,31,32],{},"That's the problem Sparkplug B tries to solve. It adds the structure that plain MQTT leaves out, so your data actually makes sense to something like a SCADA system without you having to write custom code for every device.",[15,34,35],{},"So do you need one, the other, or both? That's what this post is about.",[37,38,40],"h2",{"id":39},"mqtt-vs-sparkplug-b-at-a-glance","MQTT vs Sparkplug B at a glance",[42,43,44,59],"table",{},[45,46,47],"thead",{},[48,49,50,53,56],"tr",{},[51,52],"th",{},[51,54,55],{},"Plain MQTT",[51,57,58],{},"Sparkplug B",[60,61,62,74,85,96,107,118,129,140],"tbody",{},[48,63,64,68,71],{},[65,66,67],"td",{},"What it is",[65,69,70],{},"A lightweight transport for moving messages",[65,72,73],{},"A specification layered on top of MQTT",[48,75,76,79,82],{},[65,77,78],{},"Topic structure",[65,80,81],{},"You define your own",[65,83,84],{},"Fixed, standardized namespace",[48,86,87,90,93],{},[65,88,89],{},"Payload format",[65,91,92],{},"Anything you want, usually JSON",[65,94,95],{},"Binary Protocol Buffers, defined schema",[48,97,98,101,104],{},[65,99,100],{},"Device state",[65,102,103],{},"Not built in; roll your own heartbeat",[65,105,106],{},"Birth and death certificates out of the box",[48,108,109,112,115],{},[65,110,111],{},"Bandwidth",[65,113,114],{},"Heavier, especially with JSON",[65,116,117],{},"Compact; report-by-exception cuts traffic sharply",[48,119,120,123,126],{},[65,121,122],{},"Delivery guarantee",[65,124,125],{},"Pick your QoS: 0, 1, or 2",[65,127,128],{},"QoS 0 for all data and lifecycle messages (\"fire and forget\"); host STATE uses QoS 1",[48,130,131,134,137],{},[65,132,133],{},"Readable on the wire",[65,135,136],{},"Yes, if you use JSON",[65,138,139],{},"No, needs tooling to decode",[48,141,142,145,148],{},[65,143,144],{},"Best fit",[65,146,147],{},"Small or custom setups, data you can't lose",[65,149,150],{},"Many devices, multiple vendors, SCADA and analytics",[15,152,153],{},"The rest of this post unpacks why each row lands where it does.",[37,155,157],{"id":156},"a-pattern-that-repeats","A pattern that repeats",[15,159,160],{},"There's a story that plays out on a lot of teams, and in my experience it goes roughly the same way every time.",[15,162,163],{},"A team starts with plain MQTT because it's the obvious choice. A handful of PLCs and sensors, JSON payloads, a broker like Mosquitto in the middle, and a dashboard reading off it. It works. Then the system grows, more lines, a second site, new people, and as it grows it starts to strain in three specific places. Those three places are worth walking through, because they're the same three gaps almost everyone hits, and they're exactly what Sparkplug B was designed to close.",[37,165,167],{"id":166},"where-plain-mqtt-starts-to-hurt","Where plain MQTT starts to hurt",[15,169,170,171,178],{},"It's worth hearing this from the person who built it. ",[172,173,177],"a",{"href":174,"rel":175},"https:\u002F\u002Felement8.co.za\u002FResources\u002Farlen-nipper-co-inventor-of-mqtt-shares-his-incredible-journey-and-his-vision-for-iiot\u002F",[176],"nofollow","Arlen Nipper"," co-invented MQTT and later wrote the Sparkplug specification, and he's blunt about the trade-off at the heart of the protocol:",[180,181,182],"blockquote",{},[15,183,184],{},"Both the good and the bad thing about MQTT is, you can publish anything you want on any topic.",[15,186,187],{},"That freedom is why MQTT spread, and it's also where the strain comes from once you scale. It tends to show up in three specific places.",[15,189,190,191,194],{},"The first strain is payload bloat. JSON is easy to read, which is why people reach for it, but it isn't efficient. A single temperature reading written as ",[22,192,193],{},"{\"sensorId\":32,\"sensorValue\":24.5}"," is around 36 bytes when the actual data is a handful. That feels like nothing until you're pushing thousands of tags a second, and then it adds up fast.",[15,196,197,198,201,202,205,206,211],{},"The second is structure, or the lack of it. MQTT doesn't define any topic layout, so every integration team invents its own conventions. One group publishes temperature to ",[22,199,200],{},"line2\u002Ftemp",", another to ",[22,203,204],{},"plant\u002Fline5\u002Fsensors\u002Ftemperature\u002Fvalue",", and a contractor wires up something nobody can explain later. ",[172,207,210],{"href":208,"rel":209},"https:\u002F\u002Fwww.eclipse.org\u002Fcommunity\u002Feclipse_newsletter\u002F2021\u002Ffebruary\u002F1.php",[176],"Walker Reynolds",", the systems integrator who popularized the Unified Namespace idea, summed up the trade-off:",[180,213,214],{},[15,215,216],{},"Yes, MQTT is flexible, you can basically publish any payload to any topic, but this can create a mess in the topic namespace.",[15,218,219,220,222,223,228],{},"Keeping it all consistent across multiple plants and vendors turns into a constant chore. This is the ",[22,221,24],{}," problem from the intro, just multiplied by every team that ever touched the system. Nothing is wrong, exactly, and it all keeps running, but at some point nobody can open the broker and understand the whole thing anymore. (If you're working through how to impose order on a sprawling MQTT setup, ",[172,224,227],{"href":225,"rel":226},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2024\u002F11\u002Fgetting-the-most-out-of-mqtt-for-industrial-iot\u002F",[176],"getting the most out of MQTT for industrial IoT"," goes deeper on this.)",[15,230,231],{},"The third strain is the one that quietly causes the most trouble: state. If a device drops offline, it isn't always obvious. Plain MQTT will happily show you the last value a sensor published, steady as anything, long after the sensor itself has gone dark. Teams end up bolting on their own heartbeat logic just to answer the question \"is this device actually alive?\" There is a built-in MQTT feature that helps, the Last Will and Testament, where a client registers a message that the broker sends automatically if the connection drops, but you have to set it up yourself on every device, and plenty of setups never get around to it.",[15,233,234],{},"For small projects and proofs of concept, none of this matters and plain MQTT is completely fine. The cracks only show when you scale, twenty-plus lines or multiple sites, which is right about when teams start looking at Sparkplug B.",[37,236,238],{"id":237},"what-sparkplug-b-changes","What Sparkplug B changes",[15,240,241,242,247],{},"Sparkplug B is a specification that sits on top of MQTT, ",[172,243,246],{"href":244,"rel":245},"https:\u002F\u002Fsparkplug.eclipse.org\u002Fspecification\u002Fversion\u002F3.0\u002Fdocuments\u002Fsparkplug-specification-3.0.0.pdf",[176],"governed by the Eclipse Foundation",", and built specifically for industrial use. It doesn't replace MQTT, it adds the conventions MQTT deliberately leaves out: a fixed topic structure, a defined binary payload format using Google Protocol Buffers, and built-in device state. Look at what each one does for the three problems above.",[15,249,250,251,254],{},"For the structure problem, Sparkplug defines the topic layout so no team gets to invent its own. Every topic starts with ",[22,252,253],{},"spBv1.0"," to mark the version and encoding, then a group ID that bundles your edge nodes, usually by plant or site, followed by the message type, the edge node ID, and the device ID. The rigidity is the point. Onboarding a new line gets faster simply because everyone already speaks the same language.",[15,256,257,258,263,264,269],{},"For the bloat problem, the binary Protobuf format is far more compact than JSON. Protobuf payloads typically run 60 to 75% smaller than the equivalent JSON for the same data, since it drops the field names, repeated keys, and punctuation that JSON carries and encodes numbers as compact binary instead of text. Sparkplug also lets you batch many tag updates into a single message instead of one message per tag, which cuts broker overhead and network chatter, and it only sends when a value changes rather than polling. That report-by-exception approach, according to the ",[172,259,262],{"href":260,"rel":261},"https:\u002F\u002Fprojects.eclipse.org\u002Fprojects\u002Fiot.sparkplug",[176],"Eclipse Sparkplug project",", has been shown to cut network bandwidth by 80 to 95%, though only when the full state management is actually implemented. On constrained links like cellular or satellite, where bandwidth costs real money, that combination adds up quickly. (If you want to see what those binary savings look like in practice, here's a hands-on walkthrough of ",[172,265,268],{"href":266,"rel":267},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2025\u002F11\u002Foptimize-industrial-data-protocol-buffers\u002F",[176],"optimizing industrial data with Protocol Buffers",".)",[15,271,272],{},"For the state problem, Sparkplug uses birth and death certificates. A device publishes a birth certificate when it comes online, listing everything it offers, and a death certificate when it disconnects. So instead of writing custom scripts to guess whether a device is alive, you get that state visible in the SCADA system out of the box. One detail most write-ups blur is worth getting right: the delivery of that death certificate on an unexpected disconnect is handled by MQTT's own Last Will mechanism, not by Sparkplug. Sparkplug defines the meaning and structure; MQTT does the delivering.",[15,274,275],{},"The real payoff isn't any single number, it's operational simplicity. Less time spent troubleshooting whether a device is alive or decoding someone else's topic scheme, and more time on the actual process.",[37,277,279],{"id":278},"the-qos-catch","The QoS catch",[15,281,282],{},"Sparkplug B carries a trade-off that rarely makes it into the comparison posts, and to my mind it's a serious one.",[15,284,285,286,291],{},"The ",[172,287,290],{"href":288,"rel":289},"https:\u002F\u002Fgithub.com\u002Feclipse-sparkplug\u002Fsparkplug\u002Fblob\u002Fmaster\u002Fdocs\u002Fnormative_statements.md",[176],"Sparkplug B spec mandates QoS 0"," for all data and lifecycle messages, the NBIRTH, DBIRTH, NDATA, DDATA, NDEATH, and DDEATH messages that carry your actual telemetry and device state. The one exception is the Primary Host Application's STATE message, which uses QoS 1 so host availability is signalled reliably. But for the data you care about, QoS 0 means \"fire and forget.\" The publisher sends a message and moves on, with no delivery guarantee. In theory that's maximum speed. In practice, if the network hiccups or the broker restarts, that data is gone. For a real-time dashboard, fine. For a regulated environment where every reading has to be accounted for, that's a genuine risk. Plain MQTT, by contrast, lets you pick your quality of service: QoS 0, QoS 1 for \"at least once,\" or QoS 2 for \"exactly once.\" If you can't afford to lose data, you choose a higher level and pay for it in some performance.",[15,293,294],{},"The other costs are smaller but real. The binary payload that saves you bandwidth is also harder to debug, since you can't just read it off the wire without the right tooling. And teams used to sending plain JSON have a learning curve to climb: topic conventions, birth and death messages, protobuf schemas. For a handful of sensors, that overhead isn't worth it. Plain MQTT is simpler and does the job.",[37,296,298],{"id":297},"how-to-choose-between-mqtt-and-sparkplug-b","How to choose between MQTT and Sparkplug B",[15,300,301],{},"If you want a way to work through the decision rather than a verdict, run your situation past these in order.",[303,304,305,313,319,325,331,337],"ol",{},[306,307,308,312],"li",{},[309,310,311],"strong",{},"Map your scale and who touches the system."," Count devices, sites, teams, and vendors. A single site with a handful of sensors you fully control points to plain MQTT; many devices across multiple teams or vendors points toward Sparkplug B.",[306,314,315,318],{},[309,316,317],{},"Decide whether you can tolerate losing a message."," Sparkplug B mandates QoS 0, fire and forget, for all data and lifecycle messages, with no delivery guarantee. If your data is regulated or safety-critical and every reading must be accounted for, use plain MQTT with a higher QoS level.",[306,320,321,324],{},[309,322,323],{},"Audit your topic naming."," If teams are each inventing their own topic conventions and nobody can read the broker at a glance anymore, that disorder is the signal that Sparkplug B's fixed namespace is worth adopting.",[306,326,327,330],{},[309,328,329],{},"Check your bandwidth and network conditions."," On constrained or costly links such as cellular or satellite, Sparkplug B's compact binary payloads and report-by-exception cut traffic meaningfully. On a fast local network the difference matters less.",[306,332,333,336],{},[309,334,335],{},"Look at what consumes the data downstream."," If a SCADA system, historian, or analytics layer must understand the data without custom integration for every source, Sparkplug B's self-describing payloads pay off.",[306,338,339,342],{},[309,340,341],{},"Consider running both."," Match each protocol to the data it carries: Sparkplug B for the bulk of telemetry, plain MQTT with higher QoS for the critical data that cannot be lost.",[37,344,346],{"id":345},"mqtt-sparkplug-b-or-both","MQTT, Sparkplug B, or both",[15,348,349],{},"Run those steps and a shape usually emerges. Plain MQTT fits when you control both ends, want flexibility, or genuinely cannot lose a message and need a higher QoS than Sparkplug allows for data: small deployments, prototypes, regulated data with strict traceability. Sparkplug B earns its complexity when many devices and vendors feed something downstream that has to understand the data on its own, and the odd dropped reading isn't a catastrophe: real-time dashboards, OEE, non-critical analytics.",[15,351,352],{},"And often the honest answer is both. The pattern I've seen at larger manufacturers is to run Sparkplug B for the bulk of their telemetry and fall back to plain MQTT with higher QoS, or another protocol entirely, for the critical data that absolutely cannot be lost. They aren't really competitors. They're the same foundation with different amounts of structure and different guarantees, and the smart move is matching each to the data it's carrying.",[15,354,355,356,361,362,367],{},"Whichever way you land, the next step is wiring it up. If you're building on FlowFuse, here are practical guides for ",[172,357,360],{"href":358,"rel":359},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2024\u002F06\u002Fhow-to-use-mqtt-in-node-red\u002F",[176],"using MQTT in FlowFuse"," and for ",[172,363,366],{"href":364,"rel":365},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2024\u002F08\u002Fusing-mqtt-sparkplugb-with-node-red\u002F",[176],"using MQTT Sparkplug B with FlowFuse",".",{"title":369,"searchDepth":370,"depth":370,"links":371},"",4,[372,374,375,376,377,378,379],{"id":39,"depth":373,"text":40},2,{"id":156,"depth":373,"text":157},{"id":166,"depth":373,"text":167},{"id":237,"depth":373,"text":238},{"id":278,"depth":373,"text":279},{"id":297,"depth":373,"text":298},{"id":345,"depth":373,"text":346},{"type":381,"title":382,"description":383},"contact","Make MQTT and Sparkplug B work without the plumbing","Whether you settle on plain MQTT, Sparkplug B, or both, FlowFuse lets you connect your brokers and build dashboards and logic on that data with low-code, with an AI copilot that builds the flows for you from a prompt. FlowFuse supports both MQTT and Sparkplug B, along with all the major industrial protocols you are likely to run alongside them, so your data lands in one place regardless of what each device speaks. Talk to our team about your industrial data.","2026-06-11","A practical guide to choosing between plain MQTT and Sparkplug B for industrial IoT: where MQTT's flexibility turns into a topic-namespace mess, what Sparkplug B's structure, binary payloads, and birth\u002Fdeath certificates fix, the QoS 0 trade-off nobody mentions, and why most large deployments end up running both.","md","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fmqtt-vs-sparkplug.png",{"keywords":389,"excerpt":390},"mqtt vs sparkplug b, sparkplug b, mqtt, industrial pub sub, mqtt topic namespace, sparkplug birth death certificate, mqtt qos, protobuf vs json, unified namespace, scada mqtt, iiot messaging, report by exception",{"type":12,"value":391},[392],[15,393,17],{},true,"\u002Fblog\u002F2026\u002F06\u002Fmqtt-vs-sparkplug-b",{"title":8,"description":385},{"loc":395},"blog\u002F2026\u002F06\u002Fmqtt-vs-sparkplug-b","MQTT moves your data. Sparkplug B gives it structure. Here's how to choose.",[401,402,403],"post","mqtt","sparkplug","MQTT is a lightweight transport that moves industrial data but says nothing about what that data means, how topics are named, or whether a device is still alive. That flexibility turns into a mess at scale. Sparkplug B layers a fixed topic namespace, compact binary payloads, and birth\u002Fdeath certificates on top of MQTT to fix exactly that, at the cost of more complexity and a hard QoS 0 (fire-and-forget) delivery model for telemetry with no guarantee. Use plain MQTT for small or custom setups and data you cannot lose; use Sparkplug B for many-device, multi-vendor systems feeding SCADA or analytics; and expect larger deployments to run both, matching each protocol to the data it carries.","uKE0kC1kzzl2fJtOFe5v3iVqIUYeaXN_-jtTxGXCkzI",{"id":407,"title":408,"authors":409,"body":410,"cta":913,"date":917,"description":918,"extension":386,"image":919,"lastUpdated":920,"meta":921,"navigation":394,"path":927,"seo":928,"sitemap":929,"stem":930,"subtitle":931,"tags":932,"tldr":934,"video":3,"__hash__":935},"blog\u002Fblog\u002F2026\u002F02\u002Fmqtt-influxdb-tutorial.md","How to Build an MQTT-to-InfluxDB Data Pipeline (2026)",[10],{"type":12,"value":411,"toc":901},[412,415,418,426,430,451,455,458,479,483,486,493,498,501,519,525,529,532,556,562,571,577,580,583,601,607,611,618,742,751,784,792,799,805,809,834,840,862,868,872,875,878,881,885,888,891,894,897],[15,413,414],{},"An MQTT to InfluxDB is one of the most common and most critical pipelines in IIoT. Every timestamped telemetry event that drives decisions on the floor needs to land somewhere it can be queried, trended, and acted on.",[15,416,417],{},"The typical approach is a custom Python script that subscribes to the broker, parses the payload, and writes to InfluxDB. It works until a sensor changes its payload format, or the script quietly dies over a weekend and nobody notices until Monday. Now you're debugging a process nobody else fully understands, with no visibility into what failed or when. Others stitch together multiple tools, each with its own config, its own failure modes, and its own logs to dig through at 2am. The complexity ends up hidden in places that are hard to see, hard to debug, and hard to hand off.",[15,419,420,421,425],{},"This article takes a different approach. Using FlowFuse (the enterprise platform built on ",[172,422,424],{"href":423},"\u002F","Node-RED","), you'll build the entire pipeline as a visual flow covering MQTT subscription, payload transformation, and InfluxDB write. Every step is visible, editable, and easy to hand off.",[37,427,429],{"id":428},"tldr","TL;DR",[431,432,433,439,445],"ul",{},[306,434,435,438],{},[309,436,437],{},"What",": Build an MQTT-to-InfluxDB pipeline that subscribes to a broker, transforms the payload, and writes time-series data to InfluxDB.",[306,440,441,444],{},[309,442,443],{},"How",": Three nodes in FlowFuse: MQTT in, change node for transformation, and InfluxDB out. No custom scripts or glue code.",[306,446,447,450],{},[309,448,449],{},"Why FlowFuse",": Every step is visual, editable, and easy to hand off. When something breaks, you know exactly where to look.",[37,452,454],{"id":453},"prerequisites","Prerequisites",[15,456,457],{},"Before you start, make sure you have the following in place.",[431,459,460,463,476],{},[306,461,462],{},"A running FlowFuse instance. If you don't have one yet, [sign up]({% include \"sign-up-url.njk\" %}) to get started.",[306,464,465,466,470,471,475],{},"An MQTT broker. FlowFuse Pro and Enterprise include a ",[172,467,469],{"href":468},"\u002Fdocs\u002Fuser\u002Fteambroker\u002F","built-in broker",", and the ",[172,472,474],{"href":473},"\u002Fnode-red\u002Fflowfuse\u002Fmqtt\u002F","MQTT nodes"," configure themselves automatically. If you are using an external broker, keep your host, port, and credentials handy.",[306,477,478],{},"A running InfluxDB instance, either local or on InfluxDB Cloud. Keep your URL, token, organization, and bucket name handy.",[37,480,482],{"id":481},"building-the-pipeline","Building the Pipeline",[15,484,485],{},"The flow has three stages. An MQTT in node subscribes to your broker and receives incoming sensor payloads. A change node transforms that payload into the structure InfluxDB expects. An InfluxDB out node takes that structured data and writes it to your bucket. That's the entire pipeline. Let's build it.",[15,487,488],{},[489,490],"img",{"alt":491,"src":492,"title":491},"MQTT to InfluxDB architecture illustrating sensor data ingestion via MQTT, transformation in FlowFuse, and storage in an InfluxDB bucket","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fmqtt-to--influxdb-architecture.png",[494,495,497],"h3",{"id":496},"step-1-install-the-influxdb-node","Step 1: Install the InfluxDB Node",[15,499,500],{},"Node-RED does not include an InfluxDB node out of the box, so you will need to install it first.",[303,502,503,506,509,516],{},[306,504,505],{},"Open the Node-RED editor in your FlowFuse instance.",[306,507,508],{},"Click the main menu in the top right corner and select Manage Palette.",[306,510,511,512,367],{},"Go to the Install tab and search for ",[172,513,515],{"href":514},"\u002Fintegrations\u002Fnode-red-contrib-influxdb\u002F","node-red-contrib-influxdb",[306,517,518],{},"Click Install. Once complete, the InfluxDB nodes will appear in your palette on the left side.",[15,520,521],{},[489,522],{"alt":523,"src":524,"title":523},"Node-RED editor palette displaying the InfluxDB nodes added via the node-red-contrib-influxdb package.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Finfluxdb-nodes.png",[494,526,528],{"id":527},"step-2-configure-the-mqtt-in-node","Step 2: Configure the MQTT In Node",[15,530,531],{},"Drag an MQTT in node onto the canvas and double-click it to open its settings. Click the pencil icon next to the Server field to add a new broker connection.",[303,533,534,537,544,547,550],{},[306,535,536],{},"Enter your broker host in the Server field and set the Port.",[306,538,539,540,543],{},"Select ",[22,541,542],{},"MQTT 3.1.1"," as the protocol version.",[306,545,546],{},"Leave the Client ID blank to let Node-RED generate one automatically.",[306,548,549],{},"The keepalive is 60 seconds by default, so there’s no need to change it.",[306,551,552,553,367],{},"Check ",[22,554,555],{},"Automatically unsubscribe when disconnecting",[15,557,558],{},[489,559],{"alt":560,"src":561,"title":560},"MQTT broker connection settings in Node-RED showing server, port, protocol version, and client ID fields.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fmqtt-in--config.png",[303,563,565,568],{"start":564},6,[306,566,567],{},"Switch to the Security tab and enter your broker username and password.",[306,569,570],{},"Click Add to save the broker configuration.",[15,572,573],{},[489,574],{"alt":575,"src":576,"title":575},"MQTT broker security tab in Node-RED showing username and password fields.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fmqtt-in--security.png",[15,578,579],{},"If you are on FlowFuse Pro or Enterprise, the built-in broker details will already be picked up by the node and you can skip the above.",[15,581,582],{},"Once the broker is configured:",[303,584,585,591,594],{},[306,586,587,588,367],{},"Set the Topic to ",[22,589,590],{},"acme-motors\u002Fdetroit\u002Fwelding\u002Fline-1\u002Frobot-3\u002Ftemperature",[306,592,593],{},"Set QoS to 2 to minimize message loss and reduce duplicates between the broker and Node-RED. For true end-to-end de-duplication, add an idempotency strategy (for example, a unique key or timestamp handling) before writing to InfluxDB.",[306,595,596,597,600],{},"Give the node the name ",[22,598,599],{},"robot 3 temperature"," and click Done.",[15,602,603],{},[489,604],{"alt":605,"src":606,"title":605},"MQTT in node configured in Node-RED with topic set to the ISA-95 hierarchy and QoS set to 2.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fmqtt--in.png",[494,608,610],{"id":609},"step-3-transform-the-payload-with-a-change-node","Step 3: Transform the Payload with a Change Node",[15,612,613,614,617],{},"When the MQTT in node receives a message, ",[22,615,616],{},"msg.payload"," will look like this:",[619,620,624],"pre",{"className":621,"code":622,"language":623,"meta":369,"style":369},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"timestamp\": 1738830735000,\n  \"value\": 187.6,\n  \"unit\": \"celsius\",\n  \"sensor_id\": \"temp-robot-3\",\n  \"status\": \"normal\"\n}\n","json",[22,625,626,635,657,674,696,717,736],{"__ignoreMap":369},[627,628,631],"span",{"class":629,"line":630},"line",1,[627,632,634],{"class":633},"sMK4o","{\n",[627,636,637,640,644,647,650,654],{"class":629,"line":373},[627,638,639],{"class":633},"  \"",[627,641,643],{"class":642},"spNyl","timestamp",[627,645,646],{"class":633},"\"",[627,648,649],{"class":633},":",[627,651,653],{"class":652},"sbssI"," 1738830735000",[627,655,656],{"class":633},",\n",[627,658,660,662,665,667,669,672],{"class":629,"line":659},3,[627,661,639],{"class":633},[627,663,664],{"class":642},"value",[627,666,646],{"class":633},[627,668,649],{"class":633},[627,670,671],{"class":652}," 187.6",[627,673,656],{"class":633},[627,675,676,678,681,683,685,688,692,694],{"class":629,"line":370},[627,677,639],{"class":633},[627,679,680],{"class":642},"unit",[627,682,646],{"class":633},[627,684,649],{"class":633},[627,686,687],{"class":633}," \"",[627,689,691],{"class":690},"sfazB","celsius",[627,693,646],{"class":633},[627,695,656],{"class":633},[627,697,699,701,704,706,708,710,713,715],{"class":629,"line":698},5,[627,700,639],{"class":633},[627,702,703],{"class":642},"sensor_id",[627,705,646],{"class":633},[627,707,649],{"class":633},[627,709,687],{"class":633},[627,711,712],{"class":690},"temp-robot-3",[627,714,646],{"class":633},[627,716,656],{"class":633},[627,718,719,721,724,726,728,730,733],{"class":629,"line":564},[627,720,639],{"class":633},[627,722,723],{"class":642},"status",[627,725,646],{"class":633},[627,727,649],{"class":633},[627,729,687],{"class":633},[627,731,732],{"class":690},"normal",[627,734,735],{"class":633},"\"\n",[627,737,739],{"class":629,"line":738},7,[627,740,741],{"class":633},"}\n",[15,743,744,745,747,748,750],{},"The InfluxDB out node does not accept this structure directly. With ",[22,746,515],{},", the easiest pattern is to pass ",[22,749,616],{}," as an array, the first containing the fields to write and the second containing the tags. In InfluxDB, fields are the values you aggregate and query over, while tags are metadata used mainly for filtering and grouping. Getting this split right matters because you cannot aggregate or perform math on tags, only on fields.",[303,752,753,756],{},[306,754,755],{},"Drag a change node onto the canvas and connect it to the MQTT in node.",[306,757,758,759],{},"Double-click it to open its settings and add the following rules:\n",[431,760,761,779],{},[306,762,763,764,767,768,771,772,774,775,778],{},"Set ",[22,765,766],{},"msg.measurement"," to the string value ",[22,769,770],{},"temperature",". If your payload already contains the measurement name, you can set ",[22,773,766],{}," dynamically from ",[22,776,777],{},"msg.payload.measurement"," instead, making the flow reusable across multiple sensors without any changes. Otherwise, you can configure the measurement name directly in the InfluxDB out node.",[306,780,763,781,783],{},[22,782,616],{}," to the JSONata expression:",[619,785,790],{"className":786,"code":788,"language":789},[787],"language-text","     [{\"value\": payload.value, \"status\": payload.status, \"time\": payload.timestamp}, {\"sensor_id\": payload.sensor_id, \"unit\": payload.unit}]\n","text",[22,791,788],{"__ignoreMap":369},[303,793,794],{"start":659},[306,795,596,796,600],{},[22,797,798],{},"transform for influxdb",[15,800,801],{},[489,802],{"alt":803,"src":804,"title":803},"Change node in Node-RED configured with rules to transform the MQTT payload into the InfluxDB structure.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fchange-node-influxdb-influxdb-transform.png",[494,806,808],{"id":807},"step-4-configure-the-influxdb-out-node","Step 4: Configure the InfluxDB Out Node",[303,810,811,814,831],{},[306,812,813],{},"Drag an InfluxDB out node onto the canvas and connect it to the change node.",[306,815,816,817],{},"Double-click it to open its settings and click the pencil icon next to the Server field to add a new InfluxDB connection.\n",[431,818,819,825,828],{},[306,820,821,822,367],{},"Set Version to ",[22,823,824],{},"2.0",[306,826,827],{},"Enter your InfluxDB instance URL.",[306,829,830],{},"Enter your API token.",[306,832,833],{},"Click Add to save the connection.",[15,835,836],{},[489,837],{"alt":838,"src":839,"title":838},"InfluxDB server configuration in Node-RED showing version, URL, and API token fields.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Finfluxdb--config.png",[303,841,842,845,848,857],{"start":370},[306,843,844],{},"Set the Organization to your organization name.",[306,846,847],{},"Set the Bucket to the bucket you want to write data into.",[306,849,850,851,853,854,856],{},"Leave the Measurement field blank since we are passing it via ",[22,852,766],{}," from the change node. If you prefer to hardcode it, enter ",[22,855,770],{}," here.",[306,858,596,859,600],{},[22,860,861],{},"write to influxdb",[15,863,864],{},[489,865],{"alt":866,"src":867,"title":866},"InfluxDB out node configured in Node-RED with organization, bucket, and measurement fields.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Finfluxdb-node.png",[494,869,871],{"id":870},"step-5-deploy-and-test","Step 5: Deploy and Test",[15,873,874],{},"With all three nodes connected, click the Deploy button in the top right corner of the Node-RED editor. Once deployed, the flow will immediately start listening for messages on the topic you configured.",[15,876,877],{},"As your sensor publishes readings, open your InfluxDB instance and navigate to Data Explorer. Select your bucket, filter by measurement, and run the query. You should see the values and tags coming in from the pipeline.",[15,879,880],{},"If no data appears, open the Node-RED debug panel and check for any error messages on the InfluxDB out node. The most common issues are an incorrect API token, a mismatched organization name, or a bucket that does not exist yet in InfluxDB.",[37,882,884],{"id":883},"conclusion","Conclusion",[15,886,887],{},"Most MQTT-to-InfluxDB pipelines don't fail because the technology is wrong. They fail because the implementation is invisible: a script running somewhere, maintained by someone, that nobody else fully understands until it stops working.",[15,889,890],{},"What you've built here flips that. Three nodes, one canvas, zero ambiguity about where data comes from, how it's shaped, and where it lands. When something breaks, and in IIoT, something always eventually breaks, you're not grepping through logs or reverse-engineering a process. You're looking at a flow that tells you exactly what happened and where.",[15,892,893],{},"From here, the pipeline is yours to grow. Handle multiple sensors by parameterizing the topic and measurement. Add a catch node so malformed payloads get logged instead of silently dropped. Connect your InfluxDB bucket to a FlowFuse dashboard and put live telemetry on the floor where operators can actually see it.",[15,895,896],{},"The three nodes you deployed today are the foundation. Everything else is just adding to what's already visible.",[898,899,900],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":369,"searchDepth":370,"depth":370,"links":902},[903,904,905,912],{"id":428,"depth":373,"text":429},{"id":453,"depth":373,"text":454},{"id":481,"depth":373,"text":482,"children":906},[907,908,909,910,911],{"id":496,"depth":659,"text":497},{"id":527,"depth":659,"text":528},{"id":609,"depth":659,"text":610},{"id":807,"depth":659,"text":808},{"id":870,"depth":659,"text":871},{"id":883,"depth":373,"text":884},{"type":914,"title":915,"description":916},"sign-up","Build Pipelines You Can Actually Debug","FlowFuse turns MQTT-to-InfluxDB and every other IIoT integration into a visual flow. No custom scripts, no silent failures, no mystery at 2am. Start your free trial today.","2026-02-26","Learn how to build a reliable MQTT-to-InfluxDB data pipeline using FlowFuse and Node-RED. No custom scripts, no glue code, just a visual flow that is easy to maintain and hand off.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fmqtt-to-influxdb.png","2026-06-19",{"keywords":922,"excerpt":923},"MQTT, InfluxDB, IIoT, FlowFuse, Node-RED, Sensor telemetry, Time-series database",{"type":12,"value":924},[925],[15,926,414],{},"\u002Fblog\u002F2026\u002F02\u002Fmqtt-influxdb-tutorial",{"title":408,"description":918},{"loc":927},"blog\u002F2026\u002F02\u002Fmqtt-influxdb-tutorial","From MQTT broker to InfluxDB bucket, the right way.",[933,402],"flowfuse","Building an MQTT-to-InfluxDB pipeline in FlowFuse requires just three nodes: an MQTT in node to subscribe to sensor topics, a change node to transform the payload into InfluxDB's field-and-tag structure, and an InfluxDB out node to write the data. This visual approach eliminates the hidden failure modes of custom scripts and makes the entire pipeline easy to debug and hand off.","C69GgSsVawMKzPgvUKQaNbWnUtJaEUzZhGRFno6TlEo",{"id":937,"title":938,"authors":939,"body":940,"cta":1176,"date":1179,"description":1180,"extension":386,"image":1181,"lastUpdated":920,"meta":1182,"navigation":394,"path":1188,"seo":1189,"sitemap":1190,"stem":1191,"subtitle":1192,"tags":1193,"tldr":1194,"video":3,"__hash__":1195},"blog\u002Fblog\u002F2026\u002F02\u002Fmqtt-vs-coap.md","MQTT vs CoAP: Measure Your Constraints or Pick Wrong",[10],{"type":12,"value":941,"toc":1160},[942,945,948,951,954,958,961,964,967,970,974,977,981,984,987,990,993,996,1000,1003,1006,1009,1012,1016,1019,1022,1025,1029,1032,1036,1039,1042,1045,1048,1051,1055,1058,1061,1064,1068,1071,1074,1077,1081,1084,1087,1090,1094,1097,1100,1103,1106,1109,1113,1116,1119,1122,1125,1128,1131,1134,1137,1154,1157],[15,943,944],{},"The MQTT vs CoAP debate is mostly noise. One protocol assumes you have infrastructure and want centralized coordination. The other assumes you don't and can't. If you're still debating which is \"better,\" you haven't measured what matters.",[15,946,947],{},"MQTT dominates because it solved the hard problem: coordinating thousands of devices through centralized brokers with persistent connections, pub\u002Fsub semantics, and delivery guarantees. CoAP survived because some deployments can't afford that solution, not as a tradeoff, but as a physical impossibility. Battery-powered sensors often can't afford long-lived TCP connections (or frequent reconnects), depending on duty cycle, radio, and power budget. Microcontrollers with 16KB RAM can't run MQTT stacks. Mesh networks at the edge can't reach brokers reliably.",[15,949,950],{},"These aren't competing protocols. They're answers to incompatible constraints. MQTT requires infrastructure you can reach and connections you can sustain. CoAP requires neither. Pick MQTT for constrained devices, and watch batteries drain in months instead of years. Pick CoAP for cloud-coordinated fleets, and rebuild pub\u002Fsub patterns badly.",[15,952,953],{},"This article shows what each protocol actually demands, where each fails under real constraints, and why teams consistently choose wrong, not because they pick inferior technology, but because they never validated their deployment requirements.",[37,955,957],{"id":956},"what-actually-separates-these-protocols","What Actually Separates These Protocols",[15,959,960],{},"To choose between CoAP and MQTT, you need to understand what these protocols do and what architectural assumptions they force on your system.",[15,962,963],{},"MQTT uses a publish\u002Fsubscribe model. Devices publish messages to topics. Other devices subscribe to those topics. A central broker handles routing, persistence, and delivery guarantees. This works well for many IoT scenarios: sensors broadcasting telemetry, commands flowing to actuators, aggregating data from thousands of devices into a single pipeline. The broker decouples publishers from subscribers, enabling flexible topologies and simplified client logic. But it also requires a mandatory intermediary, a single point that must be scaled, secured, and kept reliable.",[15,965,966],{},"CoAP uses a request\u002Fresponse model. It mirrors HTTP's client-server architecture but strips the overhead that makes HTTP unsuitable for constrained devices. CoAP runs over UDP by default, supports multicast discovery, and operates peer-to-peer without centralized infrastructure. Resources are addressed using URIs. Clients request data. Servers respond.",[15,968,969],{},"This isn't just a difference in wire format. It's a difference in architectural philosophy. MQTT assumes centralized coordination is beneficial. CoAP assumes it may not be necessary or even possible. That distinction shapes how these protocols behave under network failures, how they scale at the edge, and what happens when infrastructure becomes unreliable or unavailable.",[37,971,973],{"id":972},"where-coap-has-real-advantages","Where CoAP Has Real Advantages",[15,975,976],{},"CoAP's architectural choices create measurable benefits in three specific scenarios.",[494,978,980],{"id":979},"ultra-constrained-devices","Ultra-Constrained Devices",[15,982,983],{},"CoAP was built for devices with severe resource limits: sensors running on coin cell batteries for years, microcontrollers with kilobytes of RAM, networks where every transmission costs energy and money. In these environments, MQTT's TCP requirement and broker dependency create overhead that isn't just inefficient, it's prohibitive.",[15,985,986],{},"Consider the protocol overhead. An MQTT connection requires a TCP three-way handshake, then protocol negotiation. Even with minimal configuration, that's multiple round trips before any application data moves. For a sensor that wakes once per hour to send a temperature reading, this overhead destroys battery life.",[15,988,989],{},"MQTT-SN (MQTT for Sensor Networks) attempts to bridge this gap by adapting MQTT for UDP and removing the TCP requirement. While it reduces some overhead, it still requires gateway infrastructure to translate between MQTT-SN and standard MQTT brokers, preserving the centralized architecture that CoAP avoids entirely.",[15,991,992],{},"CoAP uses UDP, has tiny message headers (as small as 4 bytes), and operates without persistent connections. This makes it objectively more efficient. Field deployments of agricultural sensors, building automation, and environmental monitoring have demonstrated power consumption reductions of 40-60% when switching from MQTT to CoAP in ultra-constrained scenarios.",[15,994,995],{},"The math is straightforward: fewer transmissions, smaller packets, no connection state. When your device budget is measured in microwatts and your network budget in bytes per day, CoAP is often the only viable option.",[494,997,999],{"id":998},"edge-architectures-without-internet-connectivity","Edge Architectures Without Internet Connectivity",[15,1001,1002],{},"CoAP's advantages become more pronounced at the system level. As more processing moves to the edge for latency, bandwidth, or regulatory reasons, the value of a centralized broker decreases. Edge gateways coordinating local sensors, device-to-device communication in factories, deployments where internet connectivity is intermittent or absent, in these scenarios, CoAP's ability to work peer-to-peer without infrastructure is a genuine advantage.",[15,1004,1005],{},"Consider a factory floor with hundreds of sensors and actuators coordinating through a local gateway. With MQTT, every sensor-to-actuator interaction must route through the broker, even when both devices are physically adjacent. The broker becomes a mandatory hop, adding latency and creating a single point of failure.",[15,1007,1008],{},"With CoAP, devices communicate directly. The gateway can still aggregate and forward data to the cloud when needed, but local control loops operate independently. When the internet connection drops, local operations continue. When latency matters, safety interlocks in industrial equipment, eliminating the broker hop can mean the difference between meeting requirements and failing them.",[15,1010,1011],{},"This distinction matters even more in mobile or disconnected scenarios: autonomous vehicles coordinating with roadside infrastructure, offshore platforms where satellite bandwidth is expensive, emergency networks operating with degraded connectivity.",[494,1013,1015],{"id":1014},"integration-with-web-infrastructure","Integration with Web Infrastructure",[15,1017,1018],{},"When distributed systems need to communicate with backend infrastructure, CoAP offers another benefit: it aligns with web semantics. CoAP deliberately mirrors HTTP: URIs, methods (GET, POST, PUT, DELETE), content negotiation, status codes. This means it integrates naturally with RESTful systems, web proxies, and developer tools built around HTTP.",[15,1020,1021],{},"For organizations already using REST APIs, CoAP presents a lower barrier than MQTT's topic-based model. HTTP-to-CoAP proxies are straightforward because the semantic models align. MQTT-to-HTTP bridges require significant translation. Topics must map to endpoints. QoS semantics must adapt. Pub\u002Fsub patterns must be forced into request\u002Fresponse or require additional infrastructure like webhooks.",[15,1023,1024],{},"None of this is impossible. Organizations bridge MQTT and HTTP successfully every day. But the mismatch is real and introduces complexity that CoAP avoids by design.",[37,1026,1028],{"id":1027},"where-mqtt-still-dominates","Where MQTT Still Dominates",[15,1030,1031],{},"These CoAP advantages are real. But if we stop here, we miss the bigger picture. MQTT isn't being displaced, and the reason goes deeper than momentum. In most production IoT deployments, MQTT's architectural choices aren't limitations, they're features that solve problems CoAP cannot.",[494,1033,1035],{"id":1034},"publishersubscriber-decoupling","Publisher\u002FSubscriber Decoupling",[15,1037,1038],{},"The pub\u002Fsub model is a fundamental decoupling mechanism that enables capabilities difficult or impossible with request\u002Fresponse.",[15,1040,1041],{},"Consider industrial telemetry. Thousands of sensors publishing measurements. Multiple backend systems consuming that data: a time-series database for analysis, a rules engine for alerts, a machine learning pipeline for predictive maintenance, a dashboard for operators.",[15,1043,1044],{},"With MQTT, adding a new consumer is trivial. Subscribe to the topics. The sensors don't know you exist. They don't need reconfiguration or firmware updates. The decoupling is complete.",[15,1046,1047],{},"With CoAP, this becomes complex. If sensors are servers, how do new clients discover them? If sensors are clients pushing data, where do they push? How do you add a destination without reconfiguring every device? You end up rebuilding what a broker provides, service discovery, routing, fan-out, but distributed across your device fleet instead of centralized in infrastructure you control.",[15,1049,1050],{},"This is why MQTT dominates cloud ingestion. When your architecture is about collecting data from many devices and distributing it to many consumers, the broker model is the right abstraction.",[494,1052,1054],{"id":1053},"delivery-guarantees","Delivery Guarantees",[15,1056,1057],{},"The broker provides something CoAP struggles to match: robust delivery guarantees across unreliable networks.",[15,1059,1060],{},"MQTT's three QoS levels (at most once, at least once, exactly once) are fundamental guarantees many production systems require. CoAP, being UDP-based, offers optional confirmable messages with retransmission. This works for many scenarios, but it's not equivalent to MQTT's QoS 2 (exactly once delivery). If your application cannot tolerate duplicates, financial transactions, command-and-control, state machine updates, MQTT's exactly-once semantics are non-negotiable.",[15,1062,1063],{},"MQTT's QoS guarantees are end-to-end through the broker. Messages can persist to disk. Sessions resume after disconnection. Client state is maintained. This makes MQTT significantly more resilient to network instability and device mobility.",[494,1065,1067],{"id":1066},"ecosystem-maturity","Ecosystem Maturity",[15,1069,1070],{},"These technical advantages are amplified by years of real-world deployment and community investment. MQTT has battle-tested brokers (Mosquitto, EMQX, HiveMQ, VerneMQ). Comprehensive client libraries in every language. Integration with major IoT platforms (AWS IoT Core, Azure IoT Hub) and widely used broker\u002Fvendor ecosystems. Monitoring tools, debugging utilities, best practices, and a large community that has solved common problems.",[15,1072,1073],{},"CoAP has matured significantly, but its ecosystem is smaller. This reflects where the use cases are. Cloud ingestion, telemetry aggregation, command and control, these patterns dominate IoT. CoAP's narrower focus on ultra-constrained devices and peer-to-peer edge scenarios means fewer developers encounter it, fewer tools get built, fewer problems get solved publicly.",[15,1075,1076],{},"Network effects matter. When MQTT is the default, more effort improves MQTT tooling, which makes MQTT more attractive, which reinforces its position.",[494,1078,1080],{"id":1079},"session-state-and-message-queuing","Session State and Message Queuing",[15,1082,1083],{},"MQTT provides another capability CoAP implementers often underestimate: stateful session management.",[15,1085,1086],{},"MQTT's persistent sessions enable offline message queuing. If a device disconnects, battery dies, network drops, enters a tunnel, messages published to its subscribed topics get queued by the broker and delivered when it reconnects. This is invaluable for mobile devices, intermittently connected sensors, and scenarios where guaranteed delivery matters more than real-time delivery. Examples include fleet management tracking vehicles, medical devices uploading telemetry, and remote monitoring in areas with poor connectivity.",[15,1088,1089],{},"CoAP can implement message queuing, but it requires additional infrastructure, essentially building broker-like services for state management and persistence. At which point, you've rebuilt the pattern MQTT provides natively.",[37,1091,1093],{"id":1092},"security-choose-based-on-what-you-can-measure","Security: Choose Based on What You Can Measure",[15,1095,1096],{},"MQTT and CoAP impose fundamentally different security architectures. MQTT's broker creates a centralized security choke point with TLS-protected connections, certificate-based authentication, and topic-level authorization. This simplifies policy enforcement and audit trails but introduces measurable overhead, a TLS handshake consumes 30-50% of total power for sensors transmitting hourly, prohibitive for ultra-constrained devices where battery life is measured in years.",[15,1098,1099],{},"CoAP distributes security across peer-to-peer networks. DTLS provides encrypted UDP communication with similar handshake costs to TLS. For constrained deployments, OSCORE enables application-layer security without connection establishment, reducing wake time by 60-80%. But this efficiency trades centralized control for distributed key management complexity that scales poorly without additional infrastructure.",[15,1101,1102],{},"The architectural trade-off is concrete: MQTT centralizes authentication and policy enforcement but requires broker infrastructure with power overhead. CoAP eliminates broker dependency but pushes authorization to individual devices, requiring distributed policy updates and log aggregation.",[15,1104,1105],{},"The most common security failure is choosing based on perceived simplicity rather than measured requirements. Teams select MQTT assuming TLS is well understood, then discover field batteries depleting in weeks. Teams choose CoAP to avoid broker dependency, then realize they cannot revoke compromised credentials without manual intervention across distributed devices.",[15,1107,1108],{},"Before choosing, measure connection establishment cost in actual power consumption for your device profile, operational cost of key management at your projected scale, and whether your compliance requirements favor centralized audit trails or distributed authorization. The right security model is the one that matches the operational reality you can actually sustain.",[37,1110,1112],{"id":1111},"the-measurement-discipline-that-matters","The Measurement Discipline That Matters",[15,1114,1115],{},"What separates successful deployments from failed ones isn't choosing the \"better\" protocol. It's starting with measured constraints rather than architectural preferences.",[15,1117,1118],{},"The teams that ship working systems know their sensor consumes 12 microamps in sleep and 45 milliamps during transmission. A CR2032 battery provides 235 milliamp-hours. For three-year operation, the math reveals a daily transmission budget of roughly 200 messages. Protocol overhead becomes concrete. Connection establishment costs aren't theoretical, they determine whether you meet requirements or miss by months.",[15,1120,1121],{},"Teams that struggle start with vague requirements. \"Low power\" sounds reasonable until batteries die early in field trials. \"Real-time\" invites endless debate until you specify \"actuator response within 50 milliseconds for 99% of events.\" Precision transforms discussion into engineering.",[15,1123,1124],{},"If you need to decouple thousands of publishers from dozens of consumers with guaranteed delivery across unreliable networks, MQTT's broker model provides exactly that. The centralized architecture handles message routing, persistence, and quality of service.",[15,1126,1127],{},"If your constraint is battery operation where every transmission costs operational lifetime, and infrastructure cannot be deployed reliably, CoAP's lightweight UDP approach becomes necessary. TCP overhead and broker coordination would exceed your power budget.",[15,1129,1130],{},"If your system genuinely spans both contexts, use both protocols where each fits. The constraints will make this obvious.",[15,1132,1133],{},"Most failed projects share a common pattern. They selected protocols before measuring deployment reality. They assumed requirements without validation. They copied architectures without understanding the underlying trade-offs. Then field deployment revealed the gaps.",[15,1135,1136],{},"So before choosing between MQTT and CoAP, answer these with measured data:",[431,1138,1139,1142,1145,1148,1151],{},[306,1140,1141],{},"What is your power budget per device?",[306,1143,1144],{},"What transmission frequency and payload size does your application require?",[306,1146,1147],{},"How does latency behave under network degradation?",[306,1149,1150],{},"During partitions, can operations continue locally or must activity queue?",[306,1152,1153],{},"What do infrastructure costs look like at production scale?",[15,1155,1156],{},"If you cannot answer with measurements, build a prototype. Instrument it. Run it under realistic conditions. Measure power, latency, and costs under stress. Then choose based on evidence, not assumptions.",[15,1158,1159],{},"The protocol debate becomes irrelevant once you measure. MQTT and CoAP each solve distinct problems well. Understand your constraints, and the choice becomes clear.",{"title":369,"searchDepth":370,"depth":370,"links":1161},[1162,1163,1168,1174,1175],{"id":956,"depth":373,"text":957},{"id":972,"depth":373,"text":973,"children":1164},[1165,1166,1167],{"id":979,"depth":659,"text":980},{"id":998,"depth":659,"text":999},{"id":1014,"depth":659,"text":1015},{"id":1027,"depth":373,"text":1028,"children":1169},[1170,1171,1172,1173],{"id":1034,"depth":659,"text":1035},{"id":1053,"depth":659,"text":1054},{"id":1066,"depth":659,"text":1067},{"id":1079,"depth":659,"text":1080},{"id":1092,"depth":373,"text":1093},{"id":1111,"depth":373,"text":1112},{"type":381,"title":1177,"description":1178},"Connect Any Protocol, at Any Scale","FlowFuse gives you enterprise Node-RED to build production IoT systems that work with MQTT, CoAP, or both. No rewiring your architecture, just reliable data flow at the scale you need.","2026-02-05","Learn whether MQTT or CoAP fits your IoT deployment. Learn how device constraints, power budgets, and network architecture determine the right protocol for reliable, efficient IoT systems.","\u002Fblog\u002F2026\u002F02\u002Fimages\u002Fcoap-vs-mqtt.png",{"keywords":1183,"excerpt":1184},"MQTT, CoAP, IoT protocols, constrained devices, edge computing, message broker, pub\u002Fsub, request\u002Fresponse, IoT architecture",{"type":12,"value":1185},[1186],[15,1187,944],{},"\u002Fblog\u002F2026\u002F02\u002Fmqtt-vs-coap",{"title":938,"description":1180},{"loc":1188},"blog\u002F2026\u002F02\u002Fmqtt-vs-coap","The only protocol debate that matters is the one you measure.",[933,402],"MQTT and CoAP are not competing protocols they solve incompatible constraints. MQTT excels at coordinating large fleets through centralized brokers with strong delivery guarantees, while CoAP's UDP-based, broker-free design is the only viable option for ultra-constrained devices where TCP overhead would destroy battery life. The right choice comes from measuring your actual power budget, transmission frequency, and infrastructure requirements rather than debating which protocol is abstractly better.","AdiDSfBS8zl0BOO25DHj7MP_x3HZ-rK03yB8Uxqxf48",{"id":1197,"title":1198,"authors":1199,"body":1200,"cta":1702,"date":1705,"description":1706,"extension":386,"image":1707,"lastUpdated":1708,"meta":1709,"navigation":394,"path":1717,"seo":1718,"sitemap":1719,"stem":1720,"subtitle":1721,"tags":1722,"tldr":1724,"video":1725,"__hash__":1726},"blog\u002Fblog\u002F2026\u002F01\u002Fopcua-vs-mqtt.md","MQTT vs OPC UA: Why This Question Never Has a Straight Answer",[10],{"type":12,"value":1201,"toc":1682},[1202,1205,1208,1211,1214,1217,1220,1224,1227,1231,1238,1243,1246,1252,1255,1275,1278,1283,1297,1300,1303,1307,1310,1313,1318,1321,1327,1330,1335,1338,1341,1346,1384,1387,1392,1395,1398,1402,1405,1408,1411,1414,1422,1425,1429,1438,1441,1444,1447,1451,1454,1458,1461,1464,1467,1471,1474,1477,1480,1483,1487,1490,1493,1496,1500,1503,1506,1509,1512,1516,1519,1522,1525,1529,1532,1535,1538,1542,1545,1548,1555,1558,1561,1564,1567,1570,1574,1577,1580,1583,1588,1591,1596,1599,1604,1607,1612,1615,1623,1629,1632,1635,1639,1642,1660,1663,1666,1669,1672,1675],[15,1203,1204],{},"The question itself is broken.",[15,1206,1207],{},"MQTT moves messages. OPC UA defines meaning. They operate at different layers of the stack. Comparing them is like comparing TCP to JSON.",[15,1209,1210],{},"Yet the debate persists. Vendors position them as competitors. Consultants bill by the complexity. Your procurement department demands a choice.",[15,1212,1213],{},"The industry knows better. OPC UA includes MQTT in its spec. Real factories use both: MQTT for telemetry, OPC UA for machine coordination. The technologies have been converging over time.",[15,1215,1216],{},"The persistent debate exists because the distinction between their purposes remains unclear to many decision-makers.",[15,1218,1219],{},"This article explains what each does, where they differ, and how to decide based on requirements instead of marketing.",[37,1221,1223],{"id":1222},"what-each-actually-does","What Each Actually Does",[15,1225,1226],{},"The confusion starts with a category error. Asking \"MQTT or OPC UA?\" is like asking \"HTTP or PostgreSQL?\" One moves bytes. The other organizes meaning.",[494,1228,1230],{"id":1229},"mqtt-the-minimalist-messenger","MQTT: The Minimalist Messenger",[15,1232,1233,1234],{},"MQTT is a publish-subscribe messaging protocol designed in 1999 for satellite oil pipeline monitoring. It does exactly one thing: ",[1235,1236,1237],"em",{},"move small messages between devices over unreliable networks with minimal overhead.",[15,1239,1240],{},[309,1241,1242],{},"The entire protocol is remarkably compact:",[15,1244,1245],{},"Publishers send messages to named topics. Subscribers express interest in topic patterns. A broker routes messages from publishers to matching subscribers. That's it.",[619,1247,1250],{"className":1248,"code":1249,"language":789},[787],"Device A publishes: \"factory\u002Fline3\u002Ftemperature\" → 72.4\nDevice B subscribes: \"factory\u002Fline3\u002F#\"\nBroker delivers: Device B receives 72.4\n",[22,1251,1249],{"__ignoreMap":369},[15,1253,1254],{},"MQTT's three quality-of-service levels handle network reality:",[431,1256,1257,1263,1269],{},[306,1258,1259,1262],{},[309,1260,1261],{},"QoS 0",": Fire and forget. Message might arrive. Might not. Zero guarantees.",[306,1264,1265,1268],{},[309,1266,1267],{},"QoS 1",": At least once delivery. Message arrives one or more times. Duplicates possible.",[306,1270,1271,1274],{},[309,1272,1273],{},"QoS 2",": Exactly once delivery between client and broker, using a four-way handshake.",[15,1276,1277],{},"The protocol header is 2 bytes. A temperature reading with topic and payload fits in under 50 bytes. This efficiency matters when you're transmitting over cellular networks, paying per kilobyte, or running on battery-powered sensors.",[15,1279,1280],{},[309,1281,1282],{},"What MQTT doesn't provide:",[15,1284,1285,1286,1289,1290,1289,1293,1296],{},"MQTT has no concept of data types. That \"72.4\" could be Celsius, Fahrenheit, or an error code; the protocol doesn't know or care. It doesn't validate message structure, enforce schemas, or understand relationships between data points. Topic namespaces are conventions, not specifications. ",[22,1287,1288],{},"factory\u002Fline3\u002Ftemp"," and ",[22,1291,1292],{},"factory\u002Fline3\u002Ftemperature",[22,1294,1295],{},"line3\u002Ffactory\u002Ftemp"," are entirely different topics with no semantic relationship.",[15,1298,1299],{},"The broker is a single point of failure unless you architect clustering separately. Security implementation depends on broker configuration; MQTT itself focuses on message transport. Discovery mechanisms must be implemented externally; subscribers must know exact topic names in advance or use wildcards and filter received messages.",[15,1301,1302],{},"MQTT is deliberately minimal. This simplicity at the transport layer enables its flexibility and efficiency.",[494,1304,1306],{"id":1305},"opc-ua-the-semantic-framework","OPC UA: The Semantic Framework",[15,1308,1309],{},"OPC UA (Unified Architecture) isn't primarily about moving data; it's about describing what data means, how it relates to other data, and what operations are valid.",[15,1311,1312],{},"Released in 2008, OPC UA replaced a fragmented collection of Windows-only industrial protocols with a platform-independent standard. Where MQTT is minimal, OPC UA is comprehensive. The specification spans 37 parts in the core specification covering everything from information modeling to historical data access to alarm conditions",[15,1314,1315],{},[309,1316,1317],{},"At its core is the address space, a hierarchical graph of nodes:",[15,1319,1320],{},"Every piece of industrial equipment is modeled as a connected set of typed nodes. A motor isn't just a collection of variables; it's an object with defined properties, methods, and relationships.",[619,1322,1325],{"className":1323,"code":1324,"language":789},[787],"Motor (ObjectNode)\n├── Speed (VariableNode: Double, Engineering Units: RPM)\n├── Temperature (VariableNode: Float, Range: 0-150°C)\n├── Status (VariableNode: Enum {Running, Stopped, Fault})\n├── Start() (MethodNode: Returns StatusCode)\n└── ConnectedTo → Pump_A (Reference: HasComponent)\n",[22,1326,1324],{"__ignoreMap":369},[15,1328,1329],{},"The type system is rich. Variables carry metadata: engineering units, valid ranges, historical access, alarm limits. References define relationships: hierarchical containment, semantic associations, type inheritance.",[15,1331,1332],{},[309,1333,1334],{},"Companion specifications extend this model for specific industries:",[15,1336,1337],{},"The Euromap 83 specification defines a complete injection molding machine in OPC UA terms: every sensor, every actuator, every state transition. A client connecting to any Euromap 83 compliant machine encounters the same address space structure. Software written for one machine works with any conforming machine, no custom integration required.",[15,1339,1340],{},"This semantic interoperability is OPC UA's primary value. Two systems can exchange meaningful information without prior coordination because the information model is standardized, not just the byte format.",[15,1342,1343],{},[309,1344,1345],{},"OPC UA provides multiple interaction patterns:",[431,1347,1348,1354,1360,1366,1372,1378],{},[306,1349,1350,1353],{},[309,1351,1352],{},"Data access",": Read\u002Fwrite variables synchronously",[306,1355,1356,1359],{},[309,1357,1358],{},"Subscriptions",": Monitor variables, receive change notifications",[306,1361,1362,1365],{},[309,1363,1364],{},"Methods",": Execute operations on server objects (start motor, set recipe)",[306,1367,1368,1371],{},[309,1369,1370],{},"Events",": Structured alarm and event notifications",[306,1373,1374,1377],{},[309,1375,1376],{},"Historical access",": Time-series query interface",[306,1379,1380,1383],{},[309,1381,1382],{},"PubSub"," (Part 14): Publish address space updates to message brokers, including MQTT",[15,1385,1386],{},"Security is integrated. Certificate-based authentication, message signing, and encryption are specification requirements, not implementation options. Every OPC UA server must support security policies.",[15,1388,1389],{},[309,1390,1391],{},"The tradeoff is implementation complexity:",[15,1393,1394],{},"Implementing an OPC UA server requires managing an address space, handling multiple services, maintaining subscriptions, and processing security handshakes. Client libraries are measured in megabytes, not kilobytes. A simple \"read a value\" operation involves session establishment, service negotiation, and potentially certificate exchange.",[15,1396,1397],{},"This overhead is impractical for battery-powered sensors with infrequent reporting requirements. It's appropriate for a $2M manufacturing cell where understanding that a temperature reading represents \"bearing temperature on the output shaft of motor 3, measured in Celsius, with a normal operating range of 40-65°C and critical alarm at 85°C\" matters.",[494,1399,1401],{"id":1400},"the-layer-mismatch","The Layer Mismatch",[15,1403,1404],{},"Think about the OSI model, that seven-layer networking abstraction everyone learns and immediately forgets:",[15,1406,1407],{},"MQTT operates at the application layer of the OSI model. It is a messaging protocol that happens to carry application data, but what that data represents is outside its scope.",[15,1409,1410],{},"OPC UA also operates at the application layer. It defines data models, type systems, and semantic relationships. Transport is abstracted; OPC UA can run over TCP, HTTPS, WebSockets, or MQTT.",[15,1412,1413],{},"Comparing them is comparing different architectural concerns:",[431,1415,1416,1419],{},[306,1417,1418],{},"MQTT answers: \"How do I efficiently move this message from publisher to subscriber?\"",[306,1420,1421],{},"OPC UA answers: \"What does this data represent, and how does it relate to other data?\"",[15,1423,1424],{},"They're not competing solutions to the same problem. They're solving different problems that happen to intersect in industrial automation architectures.",[494,1426,1428],{"id":1427},"the-convergence","The Convergence",[15,1430,1431,1432,1437],{},"OPC UA ",[172,1433,1436],{"href":1434,"rel":1435},"https:\u002F\u002Freference.opcfoundation.org\u002FCore\u002FPart14\u002Fv104\u002Fdocs\u002F",[176],"Part 14"," specifies OPC UA PubSub, a publish-subscribe model that can use MQTT as its transport mechanism. An OPC UA server publishes address space updates as MQTT messages encoded with OPC UA's type information.",[15,1439,1440],{},"MQTT Sparkplug B introduced structured payloads inspired by OPC UA’s semantic modeling concepts, adding type definitions and metric metadata to MQTT payloads. A Sparkplug message doesn't just carry \"72.4\"; it carries \"Temperature (Float32, Engineering Units: °C, timestamp: 1704470400000) = 72.4\".",[15,1442,1443],{},"The technologies are converging, not diverging. Industry 4.0 architectures increasingly use both: OPC UA for machine-to-machine communication where semantic interoperability matters, MQTT for high-frequency telemetry where bandwidth efficiency matters, and OPC UA PubSub over MQTT where both matter.",[15,1445,1446],{},"Yet vendor marketing, procurement processes, and consultant billable hours perpetuate the false choice. The question isn't \"which one?\"; it's \"which one for what?\"",[37,1448,1450],{"id":1449},"where-they-actually-differ","Where They Actually Differ",[15,1452,1453],{},"Understanding real differences requires moving past marketing claims to examine what each technology optimizes for and what constraints it accepts as tradeoffs.",[494,1455,1457],{"id":1456},"network-assumptions","Network Assumptions",[15,1459,1460],{},"MQTT was designed for unreliable networks. The protocol was built for satellite links where latency is measured in seconds and packet loss is expected. QoS levels give explicit control over delivery guarantees versus bandwidth cost. The persistent session feature lets devices reconnect after network interruptions and resume exactly where they left off, receiving any messages published while offline.",[15,1462,1463],{},"OPC UA was designed for reliable networks and builds on that foundation. The request-response model expects millisecond response times. Session management assumes stable connections. Historical access and complex queries make sense when networks can support them. Running OPC UA over cellular or satellite links works, This operates outside the protocol’s primary design parameters.",[15,1465,1466],{},"This difference cascades into deployment patterns. MQTT excels when you're collecting data from thousands of remote assets: wind turbines, pipeline sensors, fleet vehicles. OPC UA excels when you're integrating systems within a plant where network quality is controlled and semantic understanding matters more than last-mile efficiency.",[494,1468,1470],{"id":1469},"discovery-and-configuration","Discovery and Configuration",[15,1472,1473],{},"Walk up to an OPC UA server with a generic client. Hit the discovery endpoint. The server returns its complete address space: every node, every relationship, every available operation. You can browse the hierarchy, inspect type definitions, and understand capabilities without reading documentation. The server is self-describing.",[15,1475,1476],{},"MQTT itself does not define a discovery mechanism; discovery is typically handled through external conventions or platform-specific tooling. Topic structures and available data must be known in advance or determined through external documentation. The broker doesn't know what topics exist until something publishes to them. Subscribers must know exact topic patterns in advance or use wildcards and filter everything they receive. Topic naming is pure convention with no enforcement.",[15,1478,1479],{},"This reflects philosophical differences. OPC UA optimizes for systems integration where understanding what's available matters. MQTT optimizes for data distribution where publishers and subscribers coordinate through external mechanisms: configuration files, documentation, human agreement.",[15,1481,1482],{},"In practice, MQTT deployments build discovery and schema management in separate layers. Sparkplug defines topic namespaces and birth certificates that announce available metrics. Cloud platforms provide device registries and schema repositories. These additions extend MQTT's core capabilities to address requirements in complex industrial systems.",[494,1484,1486],{"id":1485},"state-and-synchronization","State and Synchronization",[15,1488,1489],{},"OPC UA maintains state. The server knows current variable values. Clients can read the current state at any time. Subscriptions detect changes and notify clients. If a client disconnects and reconnects, it can query what changed during the outage. The historical access service provides time-series queries.",[15,1491,1492],{},"MQTT focuses on message transport rather than state management. The broker routes messages but doesn't track values. If you want the current temperature, someone has to publish it after you subscribe. The \"retained message\" feature lets the broker store the last message per topic, but that's a single value with no history or change tracking. There's no way to query \"what happened between 2PM and 3PM yesterday?\"",[15,1494,1495],{},"This difference shapes architecture. OPC UA servers are often treated as authoritative sources of truth within an architecture. MQTT systems require separate databases if historical data or current state matters. Time-series databases like InfluxDB or Timescale became standard MQTT architecture components specifically because MQTT itself doesn't retain data.",[494,1497,1499],{"id":1498},"security-models","Security Models",[15,1501,1502],{},"OPC UA integrates security into the specification. Every implementation must support certificate-based authentication and encrypted sessions. Security policies are negotiated during connection establishment. Message signing and encryption are first-class protocol features. The specification defines exactly how certificates should be managed, what cipher suites are allowed, and how security auditing works.",[15,1504,1505],{},"MQTT delegates security implementation to the broker and transport layer rather than defining it within the protocol specification. MQTT 3.1.1 supports username\u002Fpassword authentication and expects TLS encryption to happen at the transport layer, but these are optional features. Securing an MQTT deployment means configuring the broker correctly, managing TLS certificates, implementing access control lists, and possibly adding an authentication service. Two MQTT brokers can have completely different security characteristics.",[15,1507,1508],{},"MQTT 5.0 added enhanced authentication mechanisms, but security remains a broker implementation concern rather than a protocol guarantee. In practice, MQTT security depends on broker configuration and deployment choices, ranging from open development environments to enterprise-grade implementations with full authentication and encryption.",[15,1510,1511],{},"For regulated industries (pharmaceuticals, food processing, utilities) OPC UA's integrated security approach often simplifies compliance documentation, as the protocol specification itself defines security requirements rather than depending on correct broker configuration.",[494,1513,1515],{"id":1514},"bandwidth-and-overhead","Bandwidth and Overhead",[15,1517,1518],{},"MQTT's 2-byte header and compact binary format minimize overhead. Publishing a temperature reading consumes roughly 50 bytes including topic and payload. Over a cellular connection transmitting 10,000 readings per day, that's under 500KB. At $1 per megabyte (typical M2M cellular rates), you're paying $0.50 per device per day just for bandwidth.",[15,1520,1521],{},"OPC UA's overhead varies by transport, but even optimized binary encoding uses hundreds of bytes per value due to security handshakes, message signatures, and type information. The same 10,000 readings might consume 5-10MB. At cellular data rates, that's $5-10 per device per day.",[15,1523,1524],{},"For battery-powered remote sensors, this difference determines project feasibility. For plant-floor equipment connected via ethernet, it's less significant. The question isn't which protocol has less overhead; it's whether that overhead matters in your deployment.",[494,1526,1528],{"id":1527},"scalability-patterns","Scalability Patterns",[15,1530,1531],{},"MQTT scales horizontally through broker clustering. Mosquitto, EMQX, and HiveMQ all support distributed deployments where multiple broker instances share message routing. Add brokers as subscriber count grows. Millions of devices can publish to a broker cluster, and the brokers handle distribution to subscribers.",[15,1533,1534],{},"OPC UA scales through federation and aggregation. An aggregation server connects to multiple OPC UA devices, presents a unified address space, and handles client connections. Clients connect to the aggregator instead of individual devices. Adding devices means configuring the aggregator, not changing the client.",[15,1536,1537],{},"These patterns fit different problems. MQTT's approach works when you're collecting data from massive device fleets. OPC UA's approach works when you're building a plant information system that integrates hundreds of machines.",[37,1539,1541],{"id":1540},"the-unified-namespace-question","The Unified Namespace Question",[15,1543,1544],{},"\"Just use Unified Namespace\" appears in every MQTT versus OPC UA discussion, framed as the answer that makes protocol choice irrelevant.",[15,1546,1547],{},"It is not sufficient.",[15,1549,1550,1554],{},[172,1551,1553],{"href":1552},"\u002Fblog\u002F2023\u002F12\u002Fintroduction-to-unified-namespace\u002F","UNS"," is an integration pattern: all plant data flows through a central MQTT broker with hierarchical topics. Systems publish once. Systems subscribe to what they need. Instead of 200 point-to-point connections, you have one hub. Add systems without breaking existing integrations. This solves real problems in brownfield plants.",[15,1556,1557],{},"But UNS doesn't eliminate protocol choice. It relocates it.",[15,1559,1560],{},"Your OPC UA machines still speak OPC UA. Edge gateways consume that semantic data, translate it to MQTT Sparkplug, and publish to the UNS broker. Protocol choice happens at the edge. Your MES connects via OPC UA when it needs semantic precision, subscribes via MQTT when it just needs telemetry. Same downstream system, different protocols for different needs.",[15,1562,1563],{},"UNS centralizes data flow. It doesn't centralize protocol decisions; those still happen at every connection point based on the same factors: semantic requirements, bandwidth constraints, scale characteristics, native support.",[15,1565,1566],{},"The question changes from \"MQTT or OPC UA for everything?\" to \"MQTT or OPC UA for this specific connection?\"",[15,1568,1569],{},"UNS is valuable architecture. It's not a protocol substitute.",[494,1571,1573],{"id":1572},"how-to-actually-decide","How to Actually Decide",[15,1575,1576],{},"Most protocol comparisons start with feature matrices. Yours should start with data flow diagrams.",[15,1578,1579],{},"Map your requirements first, not your preferences. Draw every connection in your architecture. Each arrow represents a data flow with distinct characteristics that should guide protocol selection. A temperature sensor transmitting hourly readings over satellite has fundamentally different needs than a CNC machine coordinating with your MES where both systems must agree on what \"cycle complete\" means.",[15,1581,1582],{},"Consider four factors for each data flow:",[15,1584,1585],{},[309,1586,1587],{},"1. Semantic requirements",[15,1589,1590],{},"Do the connected systems need shared understanding of what data means? If your MES and machines must coordinate on production states, downtime codes, and quality parameters, OPC UA's information modeling provides that common language. If you're collecting sensor data for ML analysis where patterns matter more than metadata, MQTT with basic context suffices.",[15,1592,1593],{},[309,1594,1595],{},"2. Network constraints",[15,1597,1598],{},"Let the infrastructure decide. Gigabit plant ethernet makes protocol overhead less critical; choose based on semantic needs. Cellular links where you pay per megabyte make the difference between MQTT's 50-byte messages and OPC UA's kilobyte handshakes a line-item cost. Satellite connections with multi-second latency benefit from MQTT's QoS handling regardless of other factors.",[15,1600,1601],{},[309,1602,1603],{},"3. Native protocol support",[15,1605,1606],{},"Work with your equipment, not against it. Siemens PLCs, Rockwell controllers, and Schneider drives speak OPC UA natively. AWS IoT expects MQTT. HiveMQ clusters scale MQTT efficiently. Leveraging native support reduces integration complexity.",[15,1608,1609],{},[309,1610,1611],{},"4. Scale characteristics",[15,1613,1614],{},"Five hundred vibration sensors streaming to cloud storage align with MQTT's horizontal scaling through broker clusters. Fifty machines requiring discovered operations and validated method calls align with OPC UA's self-describing address spaces. Different problems, different optimal solutions.",[15,1616,1617,1618,1622],{},"For example, you're connecting 50 CNC machines, 500 environmental sensors, ",[172,1619,1621],{"href":1620},"\u002Fsolutions\u002Fmes\u002F","MES",", predictive maintenance, and cloud analytics.",[619,1624,1627],{"className":1625,"code":1626,"language":789},[787],"- Machines → Edge: OPC UA (semantic interoperability for production coordination)\n- Sensors → Edge: MQTT (efficient collection at scale)\n- Edge → Cloud: MQTT Sparkplug (metadata preservation with bandwidth efficiency)  \n- Edge → MES: OPC UA (shared understanding of manufacturing operations)\n",[22,1628,1626],{"__ignoreMap":369},[15,1630,1631],{},"Four data flows, two protocols, zero false choices. The architecture reflects requirements, not vendor marketing.",[15,1633,1634],{},"The pattern emerges naturally: OPC UA where systems must share meaning. MQTT where efficiency and scale matter. OPC UA PubSub when you need both. Protocol choice becomes a local optimization within each data flow, not a global architecture decision that locks you into one approach.",[37,1636,1638],{"id":1637},"moving-forward","Moving Forward",[15,1640,1641],{},"The persistence of this debate reveals something: we're still thinking protocol-first instead of problem-first.",[15,1643,1644,1645,1649,1650,1654,1655,1659],{},"Stop asking \"which protocol?\" Start mapping your actual data flows and constraints. That pipeline sensor? ",[172,1646,1648],{"href":1647},"\u002Fblog\u002F2024\u002F06\u002Fhow-to-use-mqtt-in-node-red\u002F","MQTT",". That machine coordination? ",[172,1651,1653],{"href":1652},"\u002Fblog\u002F2025\u002F07\u002Freading-and-writing-plc-data-using-opc-ua\u002F","OPC UA",". That edge-to-cloud telemetry? ",[172,1656,1658],{"href":1657},"\u002Fblog\u002F2024\u002F08\u002Fusing-mqtt-sparkplugb-with-node-red\u002F","Sparkplug",". The modern industrial stack uses multiple protocols because different problems have different optimal solutions.",[15,1661,1662],{},"The convergence technologies (OPC UA PubSub, MQTT Sparkplug, edge gateways) prove the industry already knows this. Protocol choice is becoming a local optimization, not a global architecture decision.",[15,1664,1665],{},"Your next project: map requirements first, select protocols second. Use semantic modeling where systems must share meaning. Use efficient messaging where scale and bandwidth matter. Use both when both matter.",[15,1667,1668],{},"The right question isn't \"MQTT or OPC UA?\"",[15,1670,1671],{},"It's \"MQTT where? OPC UA where? Both where?\"",[15,1673,1674],{},"Answer that based on your requirements, not vendor marketing.",[15,1676,1677,1678,367],{},"For a practical guide to connecting PLCs via both OPC UA and MQTT in FlowFuse, alongside EtherNet\u002FIP, Siemens S7, and Modbus, see the ",[172,1679,1681],{"href":1680},"\u002Flanding\u002Fplc\u002F","FlowFuse PLC integration overview",{"title":369,"searchDepth":370,"depth":370,"links":1683},[1684,1690,1698,1701],{"id":1222,"depth":373,"text":1223,"children":1685},[1686,1687,1688,1689],{"id":1229,"depth":659,"text":1230},{"id":1305,"depth":659,"text":1306},{"id":1400,"depth":659,"text":1401},{"id":1427,"depth":659,"text":1428},{"id":1449,"depth":373,"text":1450,"children":1691},[1692,1693,1694,1695,1696,1697],{"id":1456,"depth":659,"text":1457},{"id":1469,"depth":659,"text":1470},{"id":1485,"depth":659,"text":1486},{"id":1498,"depth":659,"text":1499},{"id":1514,"depth":659,"text":1515},{"id":1527,"depth":659,"text":1528},{"id":1540,"depth":373,"text":1541,"children":1699},[1700],{"id":1572,"depth":659,"text":1573},{"id":1637,"depth":373,"text":1638},{"type":381,"title":1703,"description":1704},"Stop Choosing Protocols. Start Mapping Requirements.","FlowFuse connects both MQTT and OPC UA natively, so you don't have to pick sides. See how teams are building industrial data architectures that use the right protocol for every data flow.","2026-01-21","MQTT vs OPC UA isn't a real choice; they solve different problems. Learn when to use each protocol based on your actual requirements, not vendor marketing.","\u002Fblog\u002F2026\u002F01\u002Fimages\u002Fopcua-vs-mqtt.png","2026-06-17",{"keywords":1710,"excerpt":1711},"MQTT vs OPC UA, MQTT protocol, OPC UA protocol, industrial communication, IIoT architecture, OPC UA PubSub, MQTT Sparkplug",{"type":12,"value":1712},[1713,1715],[15,1714,1204],{},[15,1716,1207],{},"\u002Fblog\u002F2026\u002F01\u002Fopcua-vs-mqtt",{"title":1198,"description":1706},{"loc":1717},"blog\u002F2026\u002F01\u002Fopcua-vs-mqtt","Why comparing MQTT and OPC UA is a category error, and how to choose based on requirements rather than marketing",[933,1723,402],"opcua","MQTT and OPC UA are not competing solutions; MQTT efficiently moves messages while OPC UA defines what data means, and they often work together. Choose per data flow based on semantic requirements, network constraints, native protocol support, and scale rather than picking one protocol for everything. Use OPC UA where systems must share meaning, MQTT where bandwidth and scale matter, and OPC UA PubSub (or MQTT Sparkplug) when both matter.","DJ7qc1KPU1A","k0vLYcgAEwf42dmTJ8Qo6ZaiVZ_UNIviREqsOaZWPrg",{"id":1728,"title":1729,"authors":1730,"body":1731,"cta":3,"date":2015,"description":2016,"extension":386,"image":2017,"lastUpdated":1708,"meta":2018,"navigation":394,"path":2024,"seo":2025,"sitemap":2026,"stem":2027,"subtitle":2028,"tags":2029,"tldr":2031,"video":3,"__hash__":2032},"blog\u002Fblog\u002F2025\u002F12\u002Fkafka-vs-mqtt.md","MQTT vs Kafka: Complete Comparison Guide 2026",[10],{"type":12,"value":1732,"toc":2001},[1733,1736,1740,1743,1746,1752,1779,1782,1787,1792,1797,1800,1804,1807,1810,1816,1819,1822,1825,1829,1833,1836,1839,1843,1846,1849,1853,1856,1859,1863,1866,1876,1879,1883,1886,1889,1896,1900,1903,1908,1928,1933,1953,1956,1960,1963,1966,1976,1979,1993,1995,1998],[15,1734,1735],{},"Building IoT systems means making hard choices about how messages flow through your infrastructure. Apache Kafka and MQTT couldn't be more different in their approaches. MQTT came from the world of sensors and resource-constrained devices. Kafka was designed to push massive data streams between backend systems. Getting this choice right early determines whether your architecture scales smoothly or hits a wall.",[37,1737,1739],{"id":1738},"what-makes-mqtt-different","What Makes MQTT Different",[15,1741,1742],{},"MQTT (Message Queuing Telemetry Transport) showed up in 1999 when engineers needed to monitor oil pipelines with SCADA systems over unreliable satellite links. The whole point was squeezing messages through terrible networks without killing battery life.",[15,1744,1745],{},"The protocol uses binary encoding with headers as small as 2 bytes. That's it. This matters when you're running on an ESP32 with 520KB of RAM or sending data over a 2G connection that costs per kilobyte. MQTT runs over TCP\u002FIP and supports TLS when you need encryption.",[15,1747,1748],{},[489,1749],{"alt":1750,"src":1751},"Image: How MQTT Works","\u002Fblog\u002F2025\u002F12\u002Fimages\u002Fmqtt.png",[15,1753,1754,1755,1758,1759,1762,1763,1766,1767,1770,1771,1774,1775,1778],{},"Here's how it works: A central broker sits in the middle. Devices publish messages to topics like ",[22,1756,1757],{},"factory\u002Fline-1\u002Ftemperature",". Other devices subscribe to those topics. The broker figures out who gets what. Topics use forward slashes to create hierarchies, so you can subscribe to ",[22,1760,1761],{},"factory\u002F#"," and catch everything happening in the factory. You can also use wildcards: ",[22,1764,1765],{},"#"," matches multiple levels (like ",[22,1768,1769],{},"factory\u002F# ","for everything under factory), while ",[22,1772,1773],{},"+"," matches exactly one level (like ",[22,1776,1777],{},"sensors\u002F+\u002Ftemperature"," for temperature readings from any single sensor).",[15,1780,1781],{},"MQTT has three Quality of Service levels:",[15,1783,1784,1786],{},[309,1785,1261],{}," - Fire and forget. Send the message once, hope it arrives. No acknowledgment, no retry. Fast but unreliable.",[15,1788,1789,1791],{},[309,1790,1267],{}," - At least once delivery. The broker acknowledges receipt and retries if needed. You might get duplicates.",[15,1793,1794,1796],{},[309,1795,1273],{}," - Exactly once through a four-way handshake. Slowest but guaranteed.",[15,1798,1799],{},"Pick based on what you're sending. Temperature readings every 10 seconds? QoS 0 is fine. Critical alarm messages? QoS 2.",[37,1801,1803],{"id":1802},"how-kafka-works","How Kafka Works",[15,1805,1806],{},"LinkedIn built Kafka in 2011 because they were drowning in activity streams and operational metrics. Traditional message queues couldn't keep up. So they designed something that acts more like a distributed database than a message broker.",[15,1808,1809],{},"Kafka organizes everything into topics, and topics split into partitions. Each partition is just an ordered log of messages that never changes once written. Producers append messages to the end. Consumers track where they are in each partition using offsets. Multiple producers and consumers can hammer different partitions simultaneously, which is how Kafka gets ridiculous throughput.",[15,1811,1812],{},[489,1813],{"alt":1814,"src":1815},"Image: How Kafka Works","\u002Fblog\u002F2025\u002F12\u002Fimages\u002Fkafka.png",[15,1817,1818],{},"The architecture spreads partitions across multiple broker servers. Each partition gets replicated to other brokers based on your replication factor. If a broker crashes, another one takes over for its partitions immediately. No data loss, no downtime.",[15,1820,1821],{},"Unlike MQTT, messages don't disappear after delivery. Everything writes to disk. You configure retention policies, keep messages for 7 days, 30 days, or forever. This means you can replay messages, let new consumers read historical data, or reprocess everything if your analytics code had a bug.",[15,1823,1824],{},"Early Kafka needed Apache Zookeeper for cluster coordination, which added complexity. Recent versions support KRaft mode that removes this dependency, though many production systems still run Zookeeper.",[37,1826,1828],{"id":1827},"the-real-differences","The Real Differences",[494,1830,1832],{"id":1831},"architecture-philosophy","Architecture Philosophy",[15,1834,1835],{},"MQTT keeps things simple with a central broker. Devices connect, the broker routes messages, everyone's happy. You can get started with a single Raspberry Pi running Mosquitto. The 2-byte headers and compact binary format mean your sensor data flows efficiently even on constrained networks.",[15,1837,1838],{},"Kafka is distributed by design. Topics partition across brokers. Consumers track offsets themselves. Everything replicates for fault tolerance. You need coordination infrastructure (Zookeeper or KRaft), multiple brokers for production, and someone who knows distributed systems. But this complexity buys you throughput that single-broker systems simply can't match.",[494,1840,1842],{"id":1841},"performance-reality","Performance Reality",[15,1844,1845],{},"MQTT delivers messages in milliseconds. It runs on microcontrollers with kilobytes of RAM. A sensor reading might be 10-20 bytes including protocol overhead. A decent broker handles thousands to tens of thousands of messages per second, which works fine when you have hundreds of thousands of devices sending data every few seconds.",[15,1847,1848],{},"Kafka sacrifices latency for volume. Messages take tens to hundreds of milliseconds because of disk writes, replication, and consumer polling. But a single broker can handle hundreds of thousands of messages per second. Clusters process billions daily. You need real hardware, multiple cores, 32GB+ memory, fast SSDs, but you get data movement at enterprise scale.",[494,1850,1852],{"id":1851},"how-messages-get-delivered","How Messages Get Delivered",[15,1854,1855],{},"MQTT's three QoS levels give you options. QoS 0 is fast but lossy. QoS 1 guarantees delivery but might duplicate. QoS 2 does exactly-once with a four-way handshake. Brokers can queue messages for offline subscribers, but they're not designed for long-term storage.",[15,1857,1858],{},"Kafka writes everything to disk based on your retention policy. Producers pick acknowledgment levels: wait for the leader broker (fast, less safe) or wait for all replicas (slower, fully durable). Consumers commit offsets after processing messages. Modern Kafka supports exactly-once semantics through transactions and idempotent producers. The persistence model enables message replay and handles consumer failures completely differently than MQTT.",[494,1860,1862],{"id":1861},"running-this-stuff-in-production","Running This Stuff in Production",[15,1864,1865],{},"Setting up an MQTT broker is straightforward. You can start with something like Mosquitto for development, or choose from production-ready brokers that support clustering and high availability. Configure authentication, add redundancy as needed, and monitor connection counts, message rates, and queue depths, most brokers expose metrics via REST APIs or monitoring endpoints.",[180,1867,1868],{},[15,1869,1870,1871,1875],{},"FlowFuse includes a managed MQTT broker built right into the platform, no separate infrastructure to set up or maintain. It connects directly with your Node-RED flows, so you can publish and subscribe to topics without leaving the environment. Check out the ",[172,1872,1874],{"href":1873},"\u002Fblog\u002F2025\u002F10\u002Fplc-to-mqtt-using-flowfuse\u002F#step-3%3A-set-up-mqtt-with-flowfuse","details"," to see how it works.",[15,1877,1878],{},"Kafka demands more. You need at least three brokers plus coordination services. Monitor partition distribution, replication lag, consumer group status, disk usage. Plan capacity for both storage and network bandwidth. Rolling upgrades require care. Partition reassignment needs coordination. The learning curve is real, but the system handles failures gracefully once you understand it.",[494,1880,1882],{"id":1881},"where-to-use-each-one","Where to Use Each One",[15,1884,1885],{},"MQTT dominates in manufacturing plants with sensor networks, building automation, remote sites on cellular connections, and fleet tracking. It's the right call when devices have limited CPU and memory, networks constrain bandwidth, you're dealing with thousands of messages per second, and you don't need long-term storage.",[15,1887,1888],{},"Kafka powers financial transaction processing, e-commerce backends, infrastructure monitoring at scale, and data engineering pipelines. Use it when message volumes hit hundreds of thousands per second, multiple systems need independent access to the same data stream, you need replay capabilities, or you're feeding data into analytics platforms.",[15,1890,1891],{},[1235,1892,1893],{},[309,1894,1895],{},"Most real systems use both. MQTT handles the edge, Kafka moves data between central systems. You see this pattern everywhere, MQTT at factory sites, Kafka in the data center.",[37,1897,1899],{"id":1898},"making-the-choice","Making the Choice",[15,1901,1902],{},"Here's how to think about it:",[15,1904,1905],{},[309,1906,1907],{},"Pick MQTT when:",[431,1909,1910,1913,1916,1919,1922,1925],{},[306,1911,1912],{},"Your devices are resource-constrained (microcontrollers, embedded systems)",[306,1914,1915],{},"Network bandwidth is limited or expensive",[306,1917,1918],{},"You're handling thousands of messages per second",[306,1920,1921],{},"Simple deployment matters",[306,1923,1924],{},"You need efficient edge device communication",[306,1926,1927],{},"Long-term message storage isn't a requirement",[15,1929,1930],{},[309,1931,1932],{},"Pick Kafka when:",[431,1934,1935,1938,1941,1944,1947,1950],{},[306,1936,1937],{},"Message volumes hit hundreds of thousands per second or more",[306,1939,1940],{},"Multiple applications need independent access to message streams",[306,1942,1943],{},"You need message replay or event sourcing capabilities",[306,1945,1946],{},"Stream processing is part of the architecture",[306,1948,1949],{},"Integration with big data tools matters",[306,1951,1952],{},"Your ops team knows distributed systems",[15,1954,1955],{},"Neither is \"better.\" They solve different problems. Your requirements drive the decision.",[37,1957,1959],{"id":1958},"integrating-mqtt-and-kafka","Integrating MQTT and Kafka",[15,1961,1962],{},"As mentioned, real production systems don’t choose between these, they use both. Devices and sensors typically publish data over MQTT, while analytics platforms, data lakes, and stream processors consume events from Kafka. The real challenge lies in bridging the two reliably and cleanly.",[15,1964,1965],{},"Most teams write custom bridge services or deploy Kafka Connect with MQTT source connectors. Custom bridges give you complete control but require development and maintenance. Kafka Connect reduces code but adds configuration complexity, especially when you need transformation logic beyond simple field mapping.",[15,1967,1968,1969,1289,1971,1975],{},"FlowFuse takes a different approach using Node-RED's visual programming model. ",[172,1970,1648],{"href":1647},[172,1972,1974],{"href":1973},"\u002Fblog\u002F2024\u002F03\u002Fusing-kafka-with-node-red\u002F","Kafka"," nodes connect through flows that define routing and transformation logic. The platform manages protocol connections and flow execution without separate bridge infrastructure.",[15,1977,1978],{},"As mentioned before, FlowFuse includes a managed MQTT broker built directly into the platform. Beyond MQTT and Kafka, it supports industrial protocols like Modbus, OPC UA, and HTTP. Device connections, message processing, and Kafka integration all happen in one environment. You get built-in version control, deployment management, team collaboration, and much more.",[15,1980,1981,1982,1987,1988,1992],{},"FlowFuse offers a free trial for testing MQTT-Kafka workflows. ",[172,1983,1986],{"href":1984,"rel":1985},"https:\u002F\u002Fapp.flowfuse.com\u002F",[176],"Start building"," or ",[172,1989,1991],{"href":1990},"\u002Fcontact-us\u002F","schedule a consultation"," to discuss your specific needs.",[37,1994,884],{"id":883},[15,1996,1997],{},"MQTT and Kafka solve different problems. MQTT gives you efficient device connectivity with minimal overhead. Kafka delivers high-throughput event streaming with persistence and replay.",[15,1999,2000],{},"Understanding these differences helps you pick the right tool for the job. Most production systems use both, leveraging each where it provides the most value. Base your decision on message volumes, device capabilities, operational requirements, and team expertise, not on whatever's trending on Hacker News.",{"title":369,"searchDepth":370,"depth":370,"links":2002},[2003,2004,2005,2012,2013,2014],{"id":1738,"depth":373,"text":1739},{"id":1802,"depth":373,"text":1803},{"id":1827,"depth":373,"text":1828,"children":2006},[2007,2008,2009,2010,2011],{"id":1831,"depth":659,"text":1832},{"id":1841,"depth":659,"text":1842},{"id":1851,"depth":659,"text":1852},{"id":1861,"depth":659,"text":1862},{"id":1881,"depth":659,"text":1882},{"id":1898,"depth":373,"text":1899},{"id":1958,"depth":373,"text":1959},{"id":883,"depth":373,"text":884},"2025-12-17","MQTT vs Kafka comparison guide: Discover the key differences between Apache Kafka and MQTT messaging protocols. Learn which is best for IoT, industrial automation, and real-time data streaming with practical examples and use cases","\u002Fblog\u002F2025\u002F12\u002Fimages\u002Fkafka-vs-mqtt.png",{"keywords":2019,"excerpt":2020},"Kafka vs MQTT, MQTT vs Kafka, Apache Kafka, MQTT protocol, IoT messaging, message broker comparison, pub-sub messaging, event streaming, industrial IoT, real-time messaging, IoT protocols, messaging protocol comparison, Kafka MQTT differences",{"type":12,"value":2021},[2022],[15,2023,1735],{},"\u002Fblog\u002F2025\u002F12\u002Fkafka-vs-mqtt",{"title":1729,"description":2016},{"loc":2024},"blog\u002F2025\u002F12\u002Fkafka-vs-mqtt","Compare features, performance, and use cases to choose the right protocol",[933,402,2030],"kafka","MQTT is a lightweight pub\u002Fsub protocol built for resource-constrained IoT devices and unreliable networks, delivering low-latency messages with minimal overhead. Kafka is a distributed event streaming platform built for high-throughput, persistent data movement between backend systems, with message replay at the cost of higher latency and operational complexity. Neither is universally better: choose MQTT for edge device connectivity and Kafka for large-scale data processing. Most production systems use both, with MQTT at the edge and Kafka in the backend, bridged through tools like FlowFuse.","tTKZBhVdvVVkk1YpSVGXJd0VV5uTYhKhcGkgpxu6hNs",{"id":2034,"title":2035,"authors":2036,"body":2037,"cta":3,"date":3939,"description":3940,"extension":386,"image":3941,"lastUpdated":1708,"meta":3942,"navigation":394,"path":3948,"seo":3949,"sitemap":3950,"stem":3951,"subtitle":3952,"tags":3953,"tldr":3954,"video":3,"__hash__":3955},"blog\u002Fblog\u002F2025\u002F11\u002Fcsv-mqtt-database-dashboard-flowfuse.md","How to Ingest CSV Logs into MQTT, Databases, and Dashboards",[10],{"type":12,"value":2038,"toc":3910},[2039,2042,2045,2048,2051,2053,2056,2074,2080,2084,2087,2116,2120,2123,2127,2130,2166,2175,2195,2201,2205,2208,2233,2242,2245,2249,2252,2263,2416,2420,2423,2427,2433,2438,2454,2599,2603,2643,2649,2652,2658,2667,2675,2679,2683,2686,2690,2693,2740,2744,2766,2770,2773,2783,3026,3030,3033,3037,3046,3049,3053,3056,3126,3130,3133,3146,3746,3751,3754,3758,3765,3769,3798,3802,3822,3829,3833,3836,3861,3870,3877,3880,3889,3893,3896,3899,3907],[15,2040,2041],{},"If you work in manufacturing, you likely have gigabytes of data in CSV files, temperature logs, production counts, machine status records. The data exists and is organized, but it's not accessible to the systems that need it.",[15,2043,2044],{},"PLCs log directly to CSV through proprietary software. Legacy SCADA systems write flat files. Custom applications generate daily reports. These systems are reliable, but they weren't built to integrate with MQTT brokers or databases.",[15,2046,2047],{},"If you're using FlowFuse to log data, you can send to MQTT and databases as data flows through FlowFuse. But if your CSV files come from PLCs, SCADA systems, or other external tools, you need to read and ingest them after they're written.",[15,2049,2050],{},"This guide shows you how to read CSV files, whether real-time or historical, and route them to MQTT brokers, databases, and dashboards.",[494,2052,454],{"id":453},[15,2054,2055],{},"Before starting, ensure you have:",[431,2057,2058,2065,2068,2071],{},[306,2059,2060,2061],{},"A running FlowFuse instance. If you don't have one, ",[172,2062,2064],{"href":1984,"rel":2063},[176],"sign up for free",[306,2066,2067],{},"CSV log files with industrial data",[306,2069,2070],{},"Access to an MQTT broker",[306,2072,2073],{},"Access to a database",[15,2075,2076,2079],{},[309,2077,2078],{},"Note:"," If you have an Enterprise account, you won't need to set up external MQTT brokers or databases, FlowFuse provides these services built into the platform.",[494,2081,2083],{"id":2082},"sample-data","Sample Data",[15,2085,2086],{},"If you don't have a CSV file and want to follow along, you can import the following flow and deploy it. This flow will simulate a temperature sensor and log readings to a daily CSV file.",[15,2088,2089,2090,2115],{},"{% renderFlow 300 %}\n",[627,2091,2092,2093,2096,2097,2100,2101,2104,2105,2107,2108,2111,2112,2114],{},"{\"id\":\"66776385db5794bc\",\"type\":\"group\",\"z\":\"5a0080d134f80f7d\",\"name\":\"\",\"style\":{\"fill\":\"none\",\"label\":true,\"fill-opacity\":\"0.57\"},\"nodes\":",[627,2094,2095],{},"\"ac0d35a6466cfcb4\",\"4aff5b57cbb63b8f\",\"a5c5746934670306\",\"23ebc0da4315ac46\",\"2518dc909d447655\"",",\"x\":214,\"y\":279,\"w\":892,\"h\":82},{\"id\":\"ac0d35a6466cfcb4\",\"type\":\"csv\",\"z\":\"5a0080d134f80f7d\",\"g\":\"66776385db5794bc\",\"name\":\"\",\"spec\":\"rfc\",\"sep\":\",\",\"hdrin\":true,\"hdrout\":\"once\",\"multi\":\"one\",\"ret\":\"\\r\",\"temp\":\"timestamp,temperature\",\"skip\":\"0\",\"strings\":true,\"include_empty_strings\":\"\",\"include_null_values\":\"\",\"x\":670,\"y\":320,\"wires\":[[\"a5c5746934670306\"]]},{\"id\":\"4aff5b57cbb63b8f\",\"type\":\"function\",\"z\":\"5a0080d134f80f7d\",\"g\":\"66776385db5794bc\",\"name\":\"Daily PLC Logger\",\"func\":\"\u002F\u002F @ts-ignore Node ≥ 18.15 provides fs.statfsSync; editor types may lag\\n\\nconst now = new Date();\\nconst dateStr = now.toISOString().split('T')",[627,2098,2099],{},"0",";\\nconst timestamp = now.toISOString();\\n\\nconst filename = ",[22,2102,2103],{},".\u002Fplc_data_${dateStr}.csv",";\\n\\nmsg.payload = {\\n    timestamp: timestamp,\\n    temperature: msg.payload,\\n};\\n\\nmsg.filename = filename;\\n\\n\u002F\u002F Track last date in flow context\\nconst lastDate = flow.get('lastDate') || '';\\nif (lastDate !== dateStr) {\\n    msg.reset = true; \u002F\u002F Will trigger CSV node to write headers\\n    flow.set('lastDate', dateStr);\\n} \\n\\nreturn msg;\\n\",\"outputs\":1,\"timeout\":0,\"noerr\":0,\"initialize\":\"\",\"finalize\":\"\",\"libs\":",[627,2106],{},",\"x\":490,\"y\":320,\"wires\":[[\"ac0d35a6466cfcb4\"]]},{\"id\":\"a5c5746934670306\",\"type\":\"file\",\"z\":\"5a0080d134f80f7d\",\"g\":\"66776385db5794bc\",\"name\":\"Log Data to CSV file\",\"filename\":\"filename\",\"filenameType\":\"msg\",\"appendNewline\":true,\"createDir\":true,\"overwriteFile\":\"false\",\"encoding\":\"none\",\"x\":840,\"y\":320,\"wires\":[[\"2518dc909d447655\"]]},{\"id\":\"23ebc0da4315ac46\",\"type\":\"inject\",\"z\":\"5a0080d134f80f7d\",\"g\":\"66776385db5794bc\",\"name\":\"\",\"props\":",[627,2109,2110],{},"{\"p\":\"payload\"}",",\"repeat\":\"5\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"$round(70 + ($random() * 2), 2)\",\"payloadType\":\"jsonata\",\"x\":310,\"y\":320,\"wires\":[[\"4aff5b57cbb63b8f\"]]},{\"id\":\"2518dc909d447655\",\"type\":\"debug\",\"z\":\"5a0080d134f80f7d\",\"g\":\"66776385db5794bc\",\"name\":\"Result\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":1010,\"y\":320,\"wires\":",[627,2113],{},"}","\n{% endrenderFlow %}",[37,2117,2119],{"id":2118},"real-time-data-pipeline","Real-Time Data Pipeline",[15,2121,2122],{},"This pipeline monitors CSV files for changes and immediately publishes new data to MQTT topics. Use this approach when you need live data streams for dashboards, alerting systems, or real-time coordination between multiple systems.",[494,2124,2126],{"id":2125},"step-1-monitoring-csv-files","Step 1: Monitoring CSV Files",[15,2128,2129],{},"The Watch node continuously monitors a directory and triggers whenever a file is created or modified.",[303,2131,2132,2142,2157],{},[306,2133,2134,2135,2138,2139,367],{},"Drag the ",[309,2136,2137],{},"Watch node"," onto the canvas and double-click to configure it. Enter the directory path you want to monitor in the Files field, such as ",[22,2140,2141],{},"\u002Fhome\u002Fuser\u002Fdata\u002F",[306,2143,2144,2145,2148,2149,2152,2153,2156],{},"Drag a ",[309,2146,2147],{},"Change node"," onto the canvas to set the correct filename. Configure it to set ",[22,2150,2151],{},"msg.filename"," using a JSONata expression: ",[22,2154,2155],{},"\"plc_data_\" & $moment().format(\"YYYY-MM-DD\") & \".csv\""," which dynamically constructs the filename based on today's date. If your files use a different naming convention, adjust the expression accordingly.",[306,2158,2144,2159,2162,2163,2165],{},[309,2160,2161],{},"Read File node"," onto the canvas to read the file contents. Set the Filename field to ",[22,2164,2151],{}," as a message property. Configure the Output as \"a single utf8 string\" and leave Encoding at Default.",[15,2167,2168,2172],{},[489,2169],{"alt":2170,"dataZoomable":369,"src":2171},"Configuration screen of the Read File node showing filename set to msg.filename, output format as utf8 string, and default encoding","\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fread-file-node.png",[1235,2173,2174],{},"Configuration of the File In node to read CSV file contents",[303,2176,2177,2192],{"start":370},[306,2178,2179,2180,2182,2183,2185,2186,2182,2188,2191],{},"Connect the output of the ",[309,2181,2137],{}," to the input of the ",[309,2184,2147],{},", and the output of the ",[309,2187,2147],{},[309,2189,2190],{},"Read File"," node.",[306,2193,2194],{},"Deploy the flow.",[15,2196,2197,2198,2200],{},"At this point, whenever a CSV file in your monitored directory is created or modified, the flow reads its contents. The raw CSV data is now in ",[22,2199,616],{}," as a text string, ready to be parsed.",[494,2202,2204],{"id":2203},"step-2-parsing-csv-data","Step 2: Parsing CSV Data",[15,2206,2207],{},"Now we'll convert the raw CSV text into structured data.",[303,2209,2210],{},[306,2211,2144,2212,2215,2216],{},[309,2213,2214],{},"CSV node"," onto the canvas and connect it to the File In node output. Double-click to configure it to set:\n",[431,2217,2218,2221,2224,2227],{},[306,2219,2220],{},"Separator: Comma",[306,2222,2223],{},"Parser: RFC4180",[306,2225,2226],{},"Check \"First row contains column names\" and \"Parse numerical values\"",[306,2228,2229,2230,646],{},"Output: \"a single message ",[627,2231,2232],{},"array",[15,2234,2235,2239],{},[489,2236],{"alt":2237,"dataZoomable":369,"src":2238},"CSV node configuration showing comma separator, RFC4180 parser, first row as column names, parse numerical values enabled, and output as single message array","\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fcsv-node-config.png",[1235,2240,2241],{},"CSV parser configuration for batch processing with RFC4180 standard",[15,2243,2244],{},"The CSV node now converts the raw text into an array of objects, where each object represents a row with named properties from the column headers.",[494,2246,2248],{"id":2247},"step-3-extracting-the-latest-record","Step 3: Extracting the Latest Record",[15,2250,2251],{},"Since we’re reading the entire file each time it changes, we only need to publish the most recent data point to MQTT.",[303,2253,2254,2260],{},[306,2255,2144,2256,2259],{},[309,2257,2258],{},"Function node"," onto the canvas and connect it to the CSV node output.",[306,2261,2262],{},"Add this code to extract only the latest row:",[619,2264,2268],{"className":2265,"code":2266,"language":2267,"meta":369,"style":369},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F msg.payload is an array of all CSV rows\nconst rows = msg.payload;\n\n\u002F\u002F Extract only the latest row\nif (rows && rows.length > 0) {\n    msg.payload = rows[rows.length - 1];\n    return msg;\n} else {\n    \u002F\u002F No data in file yet\n    return null;\n}\n","javascript",[22,2269,2270,2276,2299,2304,2309,2340,2377,2386,2397,2403,2411],{"__ignoreMap":369},[627,2271,2272],{"class":629,"line":630},[627,2273,2275],{"class":2274},"sHwdD","\u002F\u002F msg.payload is an array of all CSV rows\n",[627,2277,2278,2281,2285,2288,2291,2293,2296],{"class":629,"line":373},[627,2279,2280],{"class":642},"const",[627,2282,2284],{"class":2283},"sTEyZ"," rows ",[627,2286,2287],{"class":633},"=",[627,2289,2290],{"class":2283}," msg",[627,2292,367],{"class":633},[627,2294,2295],{"class":2283},"payload",[627,2297,2298],{"class":633},";\n",[627,2300,2301],{"class":629,"line":659},[627,2302,2303],{"emptyLinePlaceholder":394},"\n",[627,2305,2306],{"class":629,"line":370},[627,2307,2308],{"class":2274},"\u002F\u002F Extract only the latest row\n",[627,2310,2311,2315,2318,2321,2324,2326,2329,2332,2335,2338],{"class":629,"line":698},[627,2312,2314],{"class":2313},"s7zQu","if",[627,2316,2317],{"class":2283}," (rows ",[627,2319,2320],{"class":633},"&&",[627,2322,2323],{"class":2283}," rows",[627,2325,367],{"class":633},[627,2327,2328],{"class":2283},"length ",[627,2330,2331],{"class":633},">",[627,2333,2334],{"class":652}," 0",[627,2336,2337],{"class":2283},") ",[627,2339,634],{"class":633},[627,2341,2342,2345,2347,2349,2352,2354,2358,2361,2363,2366,2369,2372,2375],{"class":629,"line":564},[627,2343,2344],{"class":2283},"    msg",[627,2346,367],{"class":633},[627,2348,2295],{"class":2283},[627,2350,2351],{"class":633}," =",[627,2353,2323],{"class":2283},[627,2355,2357],{"class":2356},"swJcz","[",[627,2359,2360],{"class":2283},"rows",[627,2362,367],{"class":633},[627,2364,2365],{"class":2283},"length",[627,2367,2368],{"class":633}," -",[627,2370,2371],{"class":652}," 1",[627,2373,2374],{"class":2356},"]",[627,2376,2298],{"class":633},[627,2378,2379,2382,2384],{"class":629,"line":738},[627,2380,2381],{"class":2313},"    return",[627,2383,2290],{"class":2283},[627,2385,2298],{"class":633},[627,2387,2389,2391,2394],{"class":629,"line":2388},8,[627,2390,2114],{"class":633},[627,2392,2393],{"class":2313}," else",[627,2395,2396],{"class":633}," {\n",[627,2398,2400],{"class":629,"line":2399},9,[627,2401,2402],{"class":2274},"    \u002F\u002F No data in file yet\n",[627,2404,2406,2408],{"class":629,"line":2405},10,[627,2407,2381],{"class":2313},[627,2409,2410],{"class":633}," null;\n",[627,2412,2414],{"class":629,"line":2413},11,[627,2415,741],{"class":633},[303,2417,2418],{"start":659},[306,2419,2194],{},[15,2421,2422],{},"Your parsed data now flows through as individual records, ready to be published to MQTT.",[494,2424,2426],{"id":2425},"step-4-publishing-to-mqtt","Step 4: Publishing to MQTT",[15,2428,2429,2430,367],{},"Now we'll publish the parsed CSV data to an MQTT broker for real-time distribution. If you have FlowFuse Team or Enterprise tier, ",[172,2431,2432],{"href":1873},"enable the MQTT broker within your FlowFuse team",[2434,2435,2437],"h4",{"id":2436},"adding-context-to-your-data","Adding Context to Your Data",[303,2439,2440,2448],{},[306,2441,2144,2442,2444,2445,2447],{},[309,2443,2147],{}," onto the canvas and connect it to the output of the ",[309,2446,2258],{},". This step adds useful context for better data traceability.",[306,2449,2450,2451,2453],{},"Configure the node to set ",[22,2452,616],{}," to a structured object, customize it based on your data and application needs:",[619,2455,2457],{"className":2265,"code":2456,"language":2267,"meta":369,"style":369},"{\n    \"timestamp\": payload.timestamp,\n    \"site\": \"tokyo_plant\",\n    \"line\": \"assembly_line_a\",\n    \"device\": \"press_01\",\n    \"measurement\": \"temperature\",\n    \"value\": payload.temperature,\n    \"unit\": \"celsius\"\n}\n",[22,2458,2459,2463,2483,2503,2522,2542,2561,2579,2595],{"__ignoreMap":369},[627,2460,2461],{"class":629,"line":630},[627,2462,634],{"class":633},[627,2464,2465,2468,2470,2472,2475,2477,2479,2481],{"class":629,"line":373},[627,2466,2467],{"class":633},"    \"",[627,2469,643],{"class":690},[627,2471,646],{"class":633},[627,2473,2474],{"class":2356},": ",[627,2476,2295],{"class":2283},[627,2478,367],{"class":633},[627,2480,643],{"class":2283},[627,2482,656],{"class":633},[627,2484,2485,2487,2490,2492,2494,2496,2499,2501],{"class":629,"line":659},[627,2486,2467],{"class":633},[627,2488,2489],{"class":690},"site",[627,2491,646],{"class":633},[627,2493,2474],{"class":2356},[627,2495,646],{"class":633},[627,2497,2498],{"class":690},"tokyo_plant",[627,2500,646],{"class":633},[627,2502,656],{"class":633},[627,2504,2505,2507,2509,2511,2513,2515,2518,2520],{"class":629,"line":370},[627,2506,2467],{"class":633},[627,2508,629],{"class":690},[627,2510,646],{"class":633},[627,2512,2474],{"class":2356},[627,2514,646],{"class":633},[627,2516,2517],{"class":690},"assembly_line_a",[627,2519,646],{"class":633},[627,2521,656],{"class":633},[627,2523,2524,2526,2529,2531,2533,2535,2538,2540],{"class":629,"line":698},[627,2525,2467],{"class":633},[627,2527,2528],{"class":690},"device",[627,2530,646],{"class":633},[627,2532,2474],{"class":2356},[627,2534,646],{"class":633},[627,2536,2537],{"class":690},"press_01",[627,2539,646],{"class":633},[627,2541,656],{"class":633},[627,2543,2544,2546,2549,2551,2553,2555,2557,2559],{"class":629,"line":564},[627,2545,2467],{"class":633},[627,2547,2548],{"class":690},"measurement",[627,2550,646],{"class":633},[627,2552,2474],{"class":2356},[627,2554,646],{"class":633},[627,2556,770],{"class":690},[627,2558,646],{"class":633},[627,2560,656],{"class":633},[627,2562,2563,2565,2567,2569,2571,2573,2575,2577],{"class":629,"line":738},[627,2564,2467],{"class":633},[627,2566,664],{"class":690},[627,2568,646],{"class":633},[627,2570,2474],{"class":2356},[627,2572,2295],{"class":2283},[627,2574,367],{"class":633},[627,2576,770],{"class":2283},[627,2578,656],{"class":633},[627,2580,2581,2583,2585,2587,2589,2591,2593],{"class":629,"line":2388},[627,2582,2467],{"class":633},[627,2584,680],{"class":690},[627,2586,646],{"class":633},[627,2588,2474],{"class":2356},[627,2590,646],{"class":633},[627,2592,691],{"class":690},[627,2594,735],{"class":633},[627,2596,2597],{"class":629,"line":2399},[627,2598,741],{"class":633},[2434,2600,2602],{"id":2601},"configuring-the-mqtt-publisher","Configuring the MQTT Publisher",[303,2604,2605,2614,2636],{},[306,2606,2134,2607,2610,2611,2613],{},[309,2608,2609],{},"ff-mqtt-out node"," onto the canvas and connect it to the ",[309,2612,2147],{},". When you drag the node, it will be automatically configured with the FlowFuse MQTT broker, you do not need to manually add configuration.",[306,2615,2616,2617,2620,2621,2624,2625,2628,2629,1289,2632,2635],{},"By default, the client automatically created for your instance only has ",[309,2618,2619],{},"subscribe"," permissions. Click ",[309,2622,2623],{},"Configure Access Control"," next to the server in the node configuration window. This will redirect you to the platform’s broker client management page, filtered to show the client associated with this instance. Click the ",[309,2626,2627],{},"Edit"," button, enable both ",[309,2630,2631],{},"Publish",[309,2633,2634],{},"Subscribe"," actions, and then restart your instance.",[306,2637,2638,2639,2642],{},"Set the ",[309,2640,2641],{},"topic"," following ISA-95 hierarchy:",[619,2644,2647],{"className":2645,"code":2646,"language":789},[787],"company\u002Fsite\u002Farea\u002Fline\u002Fcell\u002Fdevice\u002Fmeasurement\n",[22,2648,2646],{"__ignoreMap":369},[15,2650,2651],{},"For example:",[619,2653,2656],{"className":2654,"code":2655,"language":789},[787],"acme\u002Ftokyo\u002Fassembly\u002Fline-a\u002Fpress-01\u002Ftemperature\n",[22,2657,2655],{"__ignoreMap":369},[303,2659,2660],{"start":370},[306,2661,2662,2663,2666],{},"Configure the ",[309,2664,2665],{},"QoS level"," in the MQTT node. Set it to QoS 1 for reliable delivery, this ensures your data reaches subscribers even if there are brief network issues, or choose according to your reliability requirements (QoS 0 for high-frequency non-critical data, QoS 2 for critical data).",[15,2668,2669,2673],{},[489,2670],{"alt":2671,"dataZoomable":369,"src":2672},"Configuring the MQTT Out node","\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fcsv-to-mqtt.png",[1235,2674,2671],{},[303,2676,2677],{"start":698},[306,2678,2194],{},[37,2680,2682],{"id":2681},"batch-processing-pipeline","Batch Processing Pipeline",[15,2684,2685],{},"This pipeline reads CSV files on a schedule and writes data to databases in efficient batches. Use this approach for historical data storage, trend analysis, and reporting where immediate writes aren't necessary.",[494,2687,2689],{"id":2688},"step-1-reading-csv-files-on-schedule","Step 1: Reading CSV Files on Schedule",[15,2691,2692],{},"Unlike the real-time pipeline that watches for file changes, batch processing runs on a timer.",[303,2694,2695,2713,2724,2730],{},[306,2696,2697,2698,2701,2702],{},"Drag an ",[309,2699,2700],{},"Inject node"," onto the canvas. Configure it to trigger on your desired schedule:",[431,2703,2704,2707,2710],{},[306,2705,2706],{},"For hourly batches: Set repeat interval to \"interval\" and enter 1 hour",[306,2708,2709],{},"For shift-based batches: Add multiple inject nodes, For example, one at 08:00 for night shift end, another at 16:00 for day shift end, and a third at 00:00 for evening shift end.",[306,2711,2712],{},"For daily batches: Set to trigger \"at a specific time\" once per day",[306,2714,2144,2715,2717,2718,2720,2721,2723],{},[309,2716,2147],{}," and configure it to set ",[22,2719,2151],{}," to your CSV file path. Use a JSONata expression if you need dynamic filenames: ",[22,2722,2155],{},". If your files use a different naming convention, adjust the expression accordingly.",[306,2725,2144,2726,2162,2728,2165],{},[309,2727,2161],{},[22,2729,2151],{},[306,2731,2179,2732,2182,2734,2185,2736,2182,2738,2191],{},[309,2733,2700],{},[309,2735,2147],{},[309,2737,2147],{},[309,2739,2190],{},[494,2741,2743],{"id":2742},"step-2-parsing-all-records","Step 2: Parsing All Records",[303,2745,2746,2751],{},[306,2747,2144,2748,2750],{},[309,2749,2214],{}," and connect it to the File In node output.",[306,2752,2753,2754],{},"Configure it the same way as in the real-time pipeline:",[431,2755,2756,2758,2760,2762],{},[306,2757,2220],{},[306,2759,2223],{},[306,2761,2226],{},[306,2763,2229,2764,646],{},[627,2765,2232],{},[494,2767,2769],{"id":2768},"step-3-filtering-new-records","Step 3: Filtering New Records",[15,2771,2772],{},"Since we’re reading the entire CSV file each time, we need to track which rows have already been written to the database to avoid duplicates.",[303,2774,2775],{},[306,2776,2144,2777,2779,2780,2782],{},[309,2778,2258],{}," and connect it to the ",[309,2781,2214],{}," output. Add this code:",[619,2784,2786],{"className":2265,"code":2785,"language":2267,"meta":369,"style":369},"const allRows = msg.payload;\n\n\u002F\u002F Get the last processed row count from flow context\nlet lastRowCount = flow.get('lastRowCount') || 0;\n\n\u002F\u002F Get only new rows since last processing\nconst newRows = allRows.slice(lastRowCount);\n\nif (newRows.length > 0) {\n    \u002F\u002F Update the row count for next run\n    flow.set('lastRowCount', allRows.length);\n    \n    msg.payload = newRows;\n    return msg;\n} else {\n    \u002F\u002F No new data to process\n    node.warn(\"No new records to process\");\n    return null;\n}\n",[22,2787,2788,2805,2809,2814,2853,2857,2862,2884,2888,2907,2912,2944,2950,2966,2975,2984,2990,3014,3021],{"__ignoreMap":369},[627,2789,2790,2792,2795,2797,2799,2801,2803],{"class":629,"line":630},[627,2791,2280],{"class":642},[627,2793,2794],{"class":2283}," allRows ",[627,2796,2287],{"class":633},[627,2798,2290],{"class":2283},[627,2800,367],{"class":633},[627,2802,2295],{"class":2283},[627,2804,2298],{"class":633},[627,2806,2807],{"class":629,"line":373},[627,2808,2303],{"emptyLinePlaceholder":394},[627,2810,2811],{"class":629,"line":659},[627,2812,2813],{"class":2274},"\u002F\u002F Get the last processed row count from flow context\n",[627,2815,2816,2819,2822,2824,2827,2829,2833,2836,2839,2842,2844,2846,2849,2851],{"class":629,"line":370},[627,2817,2818],{"class":642},"let",[627,2820,2821],{"class":2283}," lastRowCount ",[627,2823,2287],{"class":633},[627,2825,2826],{"class":2283}," flow",[627,2828,367],{"class":633},[627,2830,2832],{"class":2831},"s2Zo4","get",[627,2834,2835],{"class":2283},"(",[627,2837,2838],{"class":633},"'",[627,2840,2841],{"class":690},"lastRowCount",[627,2843,2838],{"class":633},[627,2845,2337],{"class":2283},[627,2847,2848],{"class":633},"||",[627,2850,2334],{"class":652},[627,2852,2298],{"class":633},[627,2854,2855],{"class":629,"line":698},[627,2856,2303],{"emptyLinePlaceholder":394},[627,2858,2859],{"class":629,"line":564},[627,2860,2861],{"class":2274},"\u002F\u002F Get only new rows since last processing\n",[627,2863,2864,2866,2869,2871,2874,2876,2879,2882],{"class":629,"line":738},[627,2865,2280],{"class":642},[627,2867,2868],{"class":2283}," newRows ",[627,2870,2287],{"class":633},[627,2872,2873],{"class":2283}," allRows",[627,2875,367],{"class":633},[627,2877,2878],{"class":2831},"slice",[627,2880,2881],{"class":2283},"(lastRowCount)",[627,2883,2298],{"class":633},[627,2885,2886],{"class":629,"line":2388},[627,2887,2303],{"emptyLinePlaceholder":394},[627,2889,2890,2892,2895,2897,2899,2901,2903,2905],{"class":629,"line":2399},[627,2891,2314],{"class":2313},[627,2893,2894],{"class":2283}," (newRows",[627,2896,367],{"class":633},[627,2898,2328],{"class":2283},[627,2900,2331],{"class":633},[627,2902,2334],{"class":652},[627,2904,2337],{"class":2283},[627,2906,634],{"class":633},[627,2908,2909],{"class":629,"line":2405},[627,2910,2911],{"class":2274},"    \u002F\u002F Update the row count for next run\n",[627,2913,2914,2917,2919,2922,2924,2926,2928,2930,2933,2935,2937,2939,2942],{"class":629,"line":2413},[627,2915,2916],{"class":2283},"    flow",[627,2918,367],{"class":633},[627,2920,2921],{"class":2831},"set",[627,2923,2835],{"class":2356},[627,2925,2838],{"class":633},[627,2927,2841],{"class":690},[627,2929,2838],{"class":633},[627,2931,2932],{"class":633},",",[627,2934,2873],{"class":2283},[627,2936,367],{"class":633},[627,2938,2365],{"class":2283},[627,2940,2941],{"class":2356},")",[627,2943,2298],{"class":633},[627,2945,2947],{"class":629,"line":2946},12,[627,2948,2949],{"class":2356},"    \n",[627,2951,2953,2955,2957,2959,2961,2964],{"class":629,"line":2952},13,[627,2954,2344],{"class":2283},[627,2956,367],{"class":633},[627,2958,2295],{"class":2283},[627,2960,2351],{"class":633},[627,2962,2963],{"class":2283}," newRows",[627,2965,2298],{"class":633},[627,2967,2969,2971,2973],{"class":629,"line":2968},14,[627,2970,2381],{"class":2313},[627,2972,2290],{"class":2283},[627,2974,2298],{"class":633},[627,2976,2978,2980,2982],{"class":629,"line":2977},15,[627,2979,2114],{"class":633},[627,2981,2393],{"class":2313},[627,2983,2396],{"class":633},[627,2985,2987],{"class":629,"line":2986},16,[627,2988,2989],{"class":2274},"    \u002F\u002F No new data to process\n",[627,2991,2993,2996,2998,3001,3003,3005,3008,3010,3012],{"class":629,"line":2992},17,[627,2994,2995],{"class":2283},"    node",[627,2997,367],{"class":633},[627,2999,3000],{"class":2831},"warn",[627,3002,2835],{"class":2356},[627,3004,646],{"class":633},[627,3006,3007],{"class":690},"No new records to process",[627,3009,646],{"class":633},[627,3011,2941],{"class":2356},[627,3013,2298],{"class":633},[627,3015,3017,3019],{"class":629,"line":3016},18,[627,3018,2381],{"class":2313},[627,3020,2410],{"class":633},[627,3022,3024],{"class":629,"line":3023},19,[627,3025,741],{"class":633},[494,3027,3029],{"id":3028},"step-4-inserting-to-database","Step 4: Inserting to Database",[15,3031,3032],{},"Now we'll configure the database insertion to write batched data efficiently.",[2434,3034,3036],{"id":3035},"enabling-flowfuse-database","Enabling FlowFuse Database",[15,3038,3039,3040,3045],{},"If you have a Enterprise account, you can use the built-in PostgreSQL database service instead of setting up an external database. Follow the instructions in ",[172,3041,3044],{"href":3042,"rel":3043},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2025\u002F08\u002Fgetting-started-with-flowfuse-tables\u002F#step-1%3A-enable-the-database-in-your-project",[176],"Getting Started with FlowFuse Tables"," to enable the database in your project.",[15,3047,3048],{},"Once enabled, you'll have access to a fully managed PostgreSQL database that's automatically configured and ready to use with your FlowFuse flows.",[2434,3050,3052],{"id":3051},"creating-the-database-table","Creating the Database Table",[15,3054,3055],{},"Before inserting data, you need to create a table to store your sensor readings.",[303,3057,3058,3065,3072,3100,3106,3113,3123],{},[306,3059,3060,3061,3064],{},"In your Node-RED editor, drag a ",[309,3062,3063],{},"Query node"," onto the canvas. Just like the FlowFuse MQTT nodes, it will automatically configure itself when added to the canvas.",[306,3066,3067,3068,3071],{},"Double-click to open it and click ",[309,3069,3070],{},"\"Ask the FlowFuse Expert\""," at the top of the configuration dialog.",[306,3073,3074,3075,3099],{},"In the assistant prompt, enter:\n",[1235,3076,3077,3078,3081,3082,3084,3085,3084,3087,3084,3089,3084,3091,3084,3093,3095,3096,3098],{},"“Create a new table named ",[22,3079,3080],{},"sensor_data"," to store sensor readings with the following columns: ",[22,3083,643],{},", ",[22,3086,2489],{},[22,3088,629],{},[22,3090,2528],{},[22,3092,2548],{},[22,3094,664],{},", and ",[22,3097,680],{},".”",", Modify the table name and columns as needed to match your specific data and application requirements.",[306,3101,3102,3103,3105],{},"Click the ",[309,3104,3070],{}," button. The assistant will generate the SQL query for you and automatically populate it in the Query field.",[306,3107,2697,3108,3110,3111,367],{},[309,3109,2700],{}," onto the canvas, set it to trigger once, and connect it to the ",[309,3112,3063],{},[306,3114,3115,3116,3119,3120,3122],{},"Add a ",[309,3117,3118],{},"Debug node"," connected to the ",[309,3121,3063],{}," output to see the result.",[306,3124,3125],{},"Deploy the flow and click the Inject button to create the table.",[2434,3127,3129],{"id":3128},"preparing-data-for-batch-insert","Preparing Data for Batch Insert",[15,3131,3132],{},"Instead of writing each CSV row individually to the database, we'll use batch inserts for much better performance. A single transaction with many rows is far more efficient than many separate transactions.",[303,3134,3135,3143],{},[306,3136,2144,3137,3139,3140,3142],{},[309,3138,2258],{}," onto the canvas and connect it to the previous ",[309,3141,2258],{}," (the one that filters new records).",[306,3144,3145],{},"Name this node \"Prepare Batch Insert\" and add the following code:",[619,3147,3149],{"className":2265,"code":3148,"language":2267,"meta":369,"style":369},"\u002F\u002F msg.payload contains the new rows from CSV\nconst newRows = msg.payload;\n\n\u002F\u002F Transform each row to match your database schema\nconst formattedData = newRows.map(row => ({\n    timestamp: row.timestamp,\n    site: 'tokyo_plant',\n    line: 'assembly_line_a', \n    device: 'press_01',\n    measurement: 'temperature',\n    value: row.temperature,\n    unit: 'celsius'\n}));\n\n\u002F\u002F Generate parameter placeholders for batch insert\n\u002F\u002F Each row has 7 fields, so we need 7 parameters per row\n\u002F\u002F Example: ($1,$2,$3,$4,$5,$6,$7), ($8,$9,$10,$11,$12,$13,$14), ...\nconst values = formattedData.map((_, i) => \n    `($${i * 7 + 1}, $${i * 7 + 2}, $${i * 7 + 3}, $${i * 7 + 4}, $${i * 7 + 5}, $${i * 7 + 6}, $${i * 7 + 7})`\n).join(',');\n\n\u002F\u002F Build the SQL insert query with placeholders, modify the query according to your table name and schema.\nmsg.query = `\n    INSERT INTO sensor_data \n    (timestamp, site, line, device, measurement, value, unit)\n    VALUES ${values};\n`;\n\n\u002F\u002F Flatten the data into a single array of parameters\n\u002F\u002F Order must match the columns in the INSERT statement\nmsg.params = formattedData.flatMap(r => [\n    r.timestamp,\n    r.site,\n    r.line,\n    r.device,\n    r.measurement,\n    r.value,\n    r.unit\n]);\n\nreturn msg;\n",[22,3150,3151,3156,3172,3176,3181,3211,3227,3243,3261,3276,3291,3306,3320,3329,3333,3338,3343,3348,3382,3516,3538,3543,3549,3565,3571,3577,3592,3600,3605,3611,3617,3646,3658,3669,3680,3691,3702,3713,3723,3731,3736],{"__ignoreMap":369},[627,3152,3153],{"class":629,"line":630},[627,3154,3155],{"class":2274},"\u002F\u002F msg.payload contains the new rows from CSV\n",[627,3157,3158,3160,3162,3164,3166,3168,3170],{"class":629,"line":373},[627,3159,2280],{"class":642},[627,3161,2868],{"class":2283},[627,3163,2287],{"class":633},[627,3165,2290],{"class":2283},[627,3167,367],{"class":633},[627,3169,2295],{"class":2283},[627,3171,2298],{"class":633},[627,3173,3174],{"class":629,"line":659},[627,3175,2303],{"emptyLinePlaceholder":394},[627,3177,3178],{"class":629,"line":370},[627,3179,3180],{"class":2274},"\u002F\u002F Transform each row to match your database schema\n",[627,3182,3183,3185,3188,3190,3192,3194,3197,3199,3203,3206,3209],{"class":629,"line":698},[627,3184,2280],{"class":642},[627,3186,3187],{"class":2283}," formattedData ",[627,3189,2287],{"class":633},[627,3191,2963],{"class":2283},[627,3193,367],{"class":633},[627,3195,3196],{"class":2831},"map",[627,3198,2835],{"class":2283},[627,3200,3202],{"class":3201},"sHdIc","row",[627,3204,3205],{"class":642}," =>",[627,3207,3208],{"class":2283}," (",[627,3210,634],{"class":633},[627,3212,3213,3216,3218,3221,3223,3225],{"class":629,"line":564},[627,3214,3215],{"class":2356},"    timestamp",[627,3217,649],{"class":633},[627,3219,3220],{"class":2283}," row",[627,3222,367],{"class":633},[627,3224,643],{"class":2283},[627,3226,656],{"class":633},[627,3228,3229,3232,3234,3237,3239,3241],{"class":629,"line":738},[627,3230,3231],{"class":2356},"    site",[627,3233,649],{"class":633},[627,3235,3236],{"class":633}," '",[627,3238,2498],{"class":690},[627,3240,2838],{"class":633},[627,3242,656],{"class":633},[627,3244,3245,3248,3250,3252,3254,3256,3258],{"class":629,"line":2388},[627,3246,3247],{"class":2356},"    line",[627,3249,649],{"class":633},[627,3251,3236],{"class":633},[627,3253,2517],{"class":690},[627,3255,2838],{"class":633},[627,3257,2932],{"class":633},[627,3259,3260],{"class":2283}," \n",[627,3262,3263,3266,3268,3270,3272,3274],{"class":629,"line":2399},[627,3264,3265],{"class":2356},"    device",[627,3267,649],{"class":633},[627,3269,3236],{"class":633},[627,3271,2537],{"class":690},[627,3273,2838],{"class":633},[627,3275,656],{"class":633},[627,3277,3278,3281,3283,3285,3287,3289],{"class":629,"line":2405},[627,3279,3280],{"class":2356},"    measurement",[627,3282,649],{"class":633},[627,3284,3236],{"class":633},[627,3286,770],{"class":690},[627,3288,2838],{"class":633},[627,3290,656],{"class":633},[627,3292,3293,3296,3298,3300,3302,3304],{"class":629,"line":2413},[627,3294,3295],{"class":2356},"    value",[627,3297,649],{"class":633},[627,3299,3220],{"class":2283},[627,3301,367],{"class":633},[627,3303,770],{"class":2283},[627,3305,656],{"class":633},[627,3307,3308,3311,3313,3315,3317],{"class":629,"line":2946},[627,3309,3310],{"class":2356},"    unit",[627,3312,649],{"class":633},[627,3314,3236],{"class":633},[627,3316,691],{"class":690},[627,3318,3319],{"class":633},"'\n",[627,3321,3322,3324,3327],{"class":629,"line":2952},[627,3323,2114],{"class":633},[627,3325,3326],{"class":2283},"))",[627,3328,2298],{"class":633},[627,3330,3331],{"class":629,"line":2968},[627,3332,2303],{"emptyLinePlaceholder":394},[627,3334,3335],{"class":629,"line":2977},[627,3336,3337],{"class":2274},"\u002F\u002F Generate parameter placeholders for batch insert\n",[627,3339,3340],{"class":629,"line":2986},[627,3341,3342],{"class":2274},"\u002F\u002F Each row has 7 fields, so we need 7 parameters per row\n",[627,3344,3345],{"class":629,"line":2992},[627,3346,3347],{"class":2274},"\u002F\u002F Example: ($1,$2,$3,$4,$5,$6,$7), ($8,$9,$10,$11,$12,$13,$14), ...\n",[627,3349,3350,3352,3355,3357,3360,3362,3364,3366,3368,3371,3373,3376,3378,3380],{"class":629,"line":3016},[627,3351,2280],{"class":642},[627,3353,3354],{"class":2283}," values ",[627,3356,2287],{"class":633},[627,3358,3359],{"class":2283}," formattedData",[627,3361,367],{"class":633},[627,3363,3196],{"class":2831},[627,3365,2835],{"class":2283},[627,3367,2835],{"class":633},[627,3369,3370],{"class":3201},"_",[627,3372,2932],{"class":633},[627,3374,3375],{"class":3201}," i",[627,3377,2941],{"class":633},[627,3379,3205],{"class":642},[627,3381,3260],{"class":2283},[627,3383,3384,3387,3390,3393,3396,3399,3402,3405,3407,3409,3412,3414,3416,3418,3420,3422,3425,3427,3429,3431,3433,3435,3437,3439,3442,3444,3446,3448,3450,3452,3454,3456,3459,3461,3463,3465,3467,3469,3471,3473,3476,3478,3480,3482,3484,3486,3488,3490,3493,3495,3497,3499,3501,3503,3505,3507,3509,3511,3513],{"class":629,"line":3023},[627,3385,3386],{"class":633},"    `",[627,3388,3389],{"class":690},"($",[627,3391,3392],{"class":633},"${",[627,3394,3395],{"class":2283},"i ",[627,3397,3398],{"class":633},"*",[627,3400,3401],{"class":652}," 7",[627,3403,3404],{"class":633}," +",[627,3406,2371],{"class":652},[627,3408,2114],{"class":633},[627,3410,3411],{"class":690},", $",[627,3413,3392],{"class":633},[627,3415,3395],{"class":2283},[627,3417,3398],{"class":633},[627,3419,3401],{"class":652},[627,3421,3404],{"class":633},[627,3423,3424],{"class":652}," 2",[627,3426,2114],{"class":633},[627,3428,3411],{"class":690},[627,3430,3392],{"class":633},[627,3432,3395],{"class":2283},[627,3434,3398],{"class":633},[627,3436,3401],{"class":652},[627,3438,3404],{"class":633},[627,3440,3441],{"class":652}," 3",[627,3443,2114],{"class":633},[627,3445,3411],{"class":690},[627,3447,3392],{"class":633},[627,3449,3395],{"class":2283},[627,3451,3398],{"class":633},[627,3453,3401],{"class":652},[627,3455,3404],{"class":633},[627,3457,3458],{"class":652}," 4",[627,3460,2114],{"class":633},[627,3462,3411],{"class":690},[627,3464,3392],{"class":633},[627,3466,3395],{"class":2283},[627,3468,3398],{"class":633},[627,3470,3401],{"class":652},[627,3472,3404],{"class":633},[627,3474,3475],{"class":652}," 5",[627,3477,2114],{"class":633},[627,3479,3411],{"class":690},[627,3481,3392],{"class":633},[627,3483,3395],{"class":2283},[627,3485,3398],{"class":633},[627,3487,3401],{"class":652},[627,3489,3404],{"class":633},[627,3491,3492],{"class":652}," 6",[627,3494,2114],{"class":633},[627,3496,3411],{"class":690},[627,3498,3392],{"class":633},[627,3500,3395],{"class":2283},[627,3502,3398],{"class":633},[627,3504,3401],{"class":652},[627,3506,3404],{"class":633},[627,3508,3401],{"class":652},[627,3510,2114],{"class":633},[627,3512,2941],{"class":690},[627,3514,3515],{"class":633},"`\n",[627,3517,3519,3521,3523,3526,3528,3530,3532,3534,3536],{"class":629,"line":3518},20,[627,3520,2941],{"class":2283},[627,3522,367],{"class":633},[627,3524,3525],{"class":2831},"join",[627,3527,2835],{"class":2283},[627,3529,2838],{"class":633},[627,3531,2932],{"class":690},[627,3533,2838],{"class":633},[627,3535,2941],{"class":2283},[627,3537,2298],{"class":633},[627,3539,3541],{"class":629,"line":3540},21,[627,3542,2303],{"emptyLinePlaceholder":394},[627,3544,3546],{"class":629,"line":3545},22,[627,3547,3548],{"class":2274},"\u002F\u002F Build the SQL insert query with placeholders, modify the query according to your table name and schema.\n",[627,3550,3552,3555,3557,3560,3562],{"class":629,"line":3551},23,[627,3553,3554],{"class":2283},"msg",[627,3556,367],{"class":633},[627,3558,3559],{"class":2283},"query ",[627,3561,2287],{"class":633},[627,3563,3564],{"class":633}," `\n",[627,3566,3568],{"class":629,"line":3567},24,[627,3569,3570],{"class":690},"    INSERT INTO sensor_data \n",[627,3572,3574],{"class":629,"line":3573},25,[627,3575,3576],{"class":690},"    (timestamp, site, line, device, measurement, value, unit)\n",[627,3578,3580,3583,3585,3588,3590],{"class":629,"line":3579},26,[627,3581,3582],{"class":690},"    VALUES ",[627,3584,3392],{"class":633},[627,3586,3587],{"class":2283},"values",[627,3589,2114],{"class":633},[627,3591,2298],{"class":690},[627,3593,3595,3598],{"class":629,"line":3594},27,[627,3596,3597],{"class":633},"`",[627,3599,2298],{"class":633},[627,3601,3603],{"class":629,"line":3602},28,[627,3604,2303],{"emptyLinePlaceholder":394},[627,3606,3608],{"class":629,"line":3607},29,[627,3609,3610],{"class":2274},"\u002F\u002F Flatten the data into a single array of parameters\n",[627,3612,3614],{"class":629,"line":3613},30,[627,3615,3616],{"class":2274},"\u002F\u002F Order must match the columns in the INSERT statement\n",[627,3618,3620,3622,3624,3627,3629,3631,3633,3636,3638,3641,3643],{"class":629,"line":3619},31,[627,3621,3554],{"class":2283},[627,3623,367],{"class":633},[627,3625,3626],{"class":2283},"params ",[627,3628,2287],{"class":633},[627,3630,3359],{"class":2283},[627,3632,367],{"class":633},[627,3634,3635],{"class":2831},"flatMap",[627,3637,2835],{"class":2283},[627,3639,3640],{"class":3201},"r",[627,3642,3205],{"class":642},[627,3644,3645],{"class":2283}," [\n",[627,3647,3649,3652,3654,3656],{"class":629,"line":3648},32,[627,3650,3651],{"class":2283},"    r",[627,3653,367],{"class":633},[627,3655,643],{"class":2283},[627,3657,656],{"class":633},[627,3659,3661,3663,3665,3667],{"class":629,"line":3660},33,[627,3662,3651],{"class":2283},[627,3664,367],{"class":633},[627,3666,2489],{"class":2283},[627,3668,656],{"class":633},[627,3670,3672,3674,3676,3678],{"class":629,"line":3671},34,[627,3673,3651],{"class":2283},[627,3675,367],{"class":633},[627,3677,629],{"class":2283},[627,3679,656],{"class":633},[627,3681,3683,3685,3687,3689],{"class":629,"line":3682},35,[627,3684,3651],{"class":2283},[627,3686,367],{"class":633},[627,3688,2528],{"class":2283},[627,3690,656],{"class":633},[627,3692,3694,3696,3698,3700],{"class":629,"line":3693},36,[627,3695,3651],{"class":2283},[627,3697,367],{"class":633},[627,3699,2548],{"class":2283},[627,3701,656],{"class":633},[627,3703,3705,3707,3709,3711],{"class":629,"line":3704},37,[627,3706,3651],{"class":2283},[627,3708,367],{"class":633},[627,3710,664],{"class":2283},[627,3712,656],{"class":633},[627,3714,3716,3718,3720],{"class":629,"line":3715},38,[627,3717,3651],{"class":2283},[627,3719,367],{"class":633},[627,3721,3722],{"class":2283},"unit\n",[627,3724,3726,3729],{"class":629,"line":3725},39,[627,3727,3728],{"class":2283},"])",[627,3730,2298],{"class":633},[627,3732,3734],{"class":629,"line":3733},40,[627,3735,2303],{"emptyLinePlaceholder":394},[627,3737,3739,3742,3744],{"class":629,"line":3738},41,[627,3740,3741],{"class":2313},"return",[627,3743,2290],{"class":2283},[627,3745,2298],{"class":633},[303,3747,3748],{"start":659},[306,3749,3750],{},"Click Done.",[15,3752,3753],{},"This function generates a parameterized SQL query that inserts all rows in a single database transaction, which is significantly faster than individual inserts.",[37,3755,3757],{"id":3756},"visualizing-csv-data-on-dashboard","Visualizing CSV Data on Dashboard",[15,3759,3760,3761],{},"Now that we've ingested CSV data into MQTT and databases, let's visualize it on a dashboard. We'll focus on real-time visualization using the MQTT pipeline we built earlier. For historical data visualization from FlowFuse Tables, refer to our comprehensive guide: ",[172,3762,3764],{"href":3763},"\u002Fblog\u002F2025\u002F08\u002Ftime-series-dashboard-flowfuse-postgresql\u002F","Building Time-Series Dashboards with FlowFuse Tables",[2434,3766,3768],{"id":3767},"step-1-installing-dashboard","Step 1: Installing Dashboard",[303,3770,3771,3774,3779,3786,3792],{},[306,3772,3773],{},"In your Node-RED editor, click the hamburger menu (≡) in the top right corner.",[306,3775,539,3776,367],{},[309,3777,3778],{},"Manage palette",[306,3780,3781,3782,3785],{},"Go to the ",[309,3783,3784],{},"Install"," tab.",[306,3787,3788,3789,367],{},"Search for ",[22,3790,3791],{},"@flowfuse\u002Fnode-red-dashboard",[306,3793,3794,3795,3797],{},"Click ",[309,3796,3784],{}," and confirm.",[2434,3799,3801],{"id":3800},"step-2-subscribing-to-mqtt-data","Step 2: Subscribing to MQTT Data",[303,3803,3804,3810,3816],{},[306,3805,2697,3806,3809],{},[309,3807,3808],{},"ff-mqtt-in node"," onto the canvas.",[306,3811,3812,3813],{},"Configure the Topic to match your publisher: ",[22,3814,3815],{},"acme\u002Ftokyo\u002Fassembly\u002Fline-a\u002Fpress-01\u002Ftemperature",[306,3817,763,3818,3821],{},[309,3819,3820],{},"Output"," to \"auto-detect (string or buffer)\".",[15,3823,3824,3827],{},[489,3825],{"alt":2671,"dataZoomable":369,"src":3826},"\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fmqtt-to-dashboard.png",[1235,3828,2671],{},[2434,3830,3832],{"id":3831},"step-3-creating-the-dashboard-widgets","Step 3: Creating the Dashboard Widgets",[15,3834,3835],{},"Now we'll add a chart to visualize the temperature data in real-time.",[303,3837,3838,3844,3847],{},[306,3839,2144,3840,3843],{},[309,3841,3842],{},"ui-chart"," widget onto the canvas and double-click it. Create a new UI group for it to render.",[306,3845,3846],{},"Set the size according to your needs for the chart, label to \"Temperature\", type to \"line\", action to \"append\", and x-axis to \"timescale\".",[306,3848,3849,3850,3853,3854,3857,3858,367],{},"Next, set series to ",[22,3851,3852],{},"msg.payload.device",", x to ",[22,3855,3856],{},"msg.payload.timestamp",", and y to ",[22,3859,3860],{},"msg.payload.value",[15,3862,3863,3867],{},[489,3864],{"alt":3865,"dataZoomable":369,"src":3866},"UI Chart configuration showing line chart type, append action, timescale x-axis, with series, x, and y values mapped to payload properties","\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fchart-node-config.png",[1235,3868,3869],{},"Chart widget configuration for real-time temperature visualization",[303,3871,3872],{"start":370},[306,3873,3794,3874,367],{},[309,3875,3876],{},"Deploy",[15,3878,3879],{},"Once deployed, open the dashboard, you should see a real-time line chart displaying temperature values over time, with each device shown as a separate series. Data points will automatically update as new MQTT messages arrive.",[15,3881,3882,3886],{},[489,3883],{"alt":3884,"dataZoomable":369,"src":3885},"Dashboard showing real-time line chart with temperature data updating as new MQTT messages arrive","\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fflowfuse-dashboard.gif",[1235,3887,3888],{},"Live dashboard displaying real-time temperature readings from CSV data stream",[37,3890,3892],{"id":3891},"whats-next","What's Next",[15,3894,3895],{},"You've transformed static CSV files into live data streams that flow through MQTT, databases, and dashboards. Your legacy equipment now communicates with modern systems without any hardware changes.",[15,3897,3898],{},"This tutorial walked you through building a data pipeline. FlowFuse takes it further by handling both development and production deployment. When you need to scale across multiple production lines, manage team collaboration, deploy to hundreds of devices remotely, or maintain infrastructure like MQTT brokers and databases, FlowFuse provides the platform to do it all. As you saw, it also includes an FlowFuse Expert to speed up your workflow.",[15,3900,3901,3902,3906],{},"If you want to see more on how FlowFuse helps with scaling and production deployments, ",[172,3903,3905],{"href":3904},"\u002Fbook-demo\u002F","book a demo"," today.",[898,3908,3909],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":369,"searchDepth":370,"depth":370,"links":3911},[3912,3913,3914,3923,3933,3938],{"id":453,"depth":659,"text":454},{"id":2082,"depth":659,"text":2083},{"id":2118,"depth":373,"text":2119,"children":3915},[3916,3917,3918,3919],{"id":2125,"depth":659,"text":2126},{"id":2203,"depth":659,"text":2204},{"id":2247,"depth":659,"text":2248},{"id":2425,"depth":659,"text":2426,"children":3920},[3921,3922],{"id":2436,"depth":370,"text":2437},{"id":2601,"depth":370,"text":2602},{"id":2681,"depth":373,"text":2682,"children":3924},[3925,3926,3927,3928],{"id":2688,"depth":659,"text":2689},{"id":2742,"depth":659,"text":2743},{"id":2768,"depth":659,"text":2769},{"id":3028,"depth":659,"text":3029,"children":3929},[3930,3931,3932],{"id":3035,"depth":370,"text":3036},{"id":3051,"depth":370,"text":3052},{"id":3128,"depth":370,"text":3129},{"id":3756,"depth":373,"text":3757,"children":3934},[3935,3936,3937],{"id":3767,"depth":370,"text":3768},{"id":3800,"depth":370,"text":3801},{"id":3831,"depth":370,"text":3832},{"id":3891,"depth":373,"text":3892},"2025-11-10","Learn how to ingest CSV logs from PLCs and SCADA systems into MQTT brokers, databases, and dashboards. Build real-time and batch processing pipelines with Node-RED and FlowFuse.","\u002Fblog\u002F2025\u002F11\u002Fimages\u002Fhow-to-ingest-csv-logs.png",{"keywords":3943,"excerpt":3944},"CSV ingestion, MQTT broker, Node-RED, FlowFuse, industrial data, PLC logging, SCADA systems, real-time data pipeline, batch processing, database integration, data visualization, manufacturing data, Node-RED dashboard, sensor data, time-series data, industrial IoT, data orchestration, legacy systems integration",{"type":12,"value":3945},[3946],[15,3947,2041],{},"\u002Fblog\u002F2025\u002F11\u002Fcsv-mqtt-database-dashboard-flowfuse",{"title":2035,"description":3940},{"loc":3948},"blog\u002F2025\u002F11\u002Fcsv-mqtt-database-dashboard-flowfuse","Turn old CSV logs into live data streams using FlowFuse.",[933,402],"This tutorial shows how to turn static CSV logs from PLCs and SCADA systems into live data using FlowFuse and Node-RED. It covers a real-time pipeline that watches CSV files and publishes the latest readings to MQTT, and a batch pipeline that reads files on a schedule and writes new rows to a database in efficient batches. Finally, it visualizes the data on a real-time FlowFuse Dashboard line chart.","QnkuZP9thlEvxZRSQXyniTR78ugB3uj8Bj9tiRS-VWo",{"id":3957,"title":3958,"authors":3959,"body":3960,"cta":3,"date":4445,"description":4446,"extension":386,"image":4447,"lastUpdated":1708,"meta":4448,"navigation":394,"path":4454,"seo":4455,"sitemap":4456,"stem":4457,"subtitle":4458,"tags":4459,"tldr":4462,"video":3,"__hash__":4463},"blog\u002Fblog\u002F2025\u002F10\u002Fplc-to-mqtt-using-flowfuse.md","How to Connect Any PLC to MQTT in Under an Hour",[10],{"type":12,"value":3961,"toc":4435},[3962,3965,3968,3971,3975,3978,3981,3984,3987,3990,3993,3995,3998,4012,4017,4020,4027,4030,4034,4037,4040,4043,4084,4093,4097,4103,4106,4117,4124,4127,4130,4134,4137,4142,4145,4148,4154,4161,4166,4175,4180,4183,4193,4198,4201,4208,4212,4215,4218,4221,4224,4232,4237,4251,4256,4259,4265,4270,4273,4276,4283,4286,4312,4317,4332,4335,4345,4353,4368,4376,4383,4391,4399,4403,4406,4409,4412,4415,4418,4422,4430],[15,3963,3964],{},"Getting PLC data into systems where it can be monitored, analyzed, and acted upon is essential for modern manufacturing. MQTT has become the standard for moving this data. It's lightweight, handles unreliable networks well, and excels at real-time streaming. Once your PLC data is published to MQTT, it creates a common pipeline that IT systems understand, flowing easily to cloud platforms, analytics tools, dashboards, and eliminating protocol translation headaches.",[15,3966,3967],{},"The protocol itself is simple. But implementation in a real factory, with actual PLCs and production networks, is where things fall apart. Costs pile up, timelines drag on, and you end up needing expertise that's hard to find.",[15,3969,3970],{},"This guide cuts through that complexity. You'll learn how to connect PLCs using MQTT without the typical headaches. We'll walk through extracting data from any PLC protocol, transforming it properly, and publishing it reliably, with working examples you can adapt to your own setup.",[37,3972,3974],{"id":3973},"why-plc-to-cloud-gets-so-complicated","Why PLC-to-Cloud Gets So Complicated",[15,3976,3977],{},"Before diving into the solution, it's worth understanding why this is so difficult.",[15,3979,3980],{},"First, there's the proprietary protocols. Factory floors have PLCs from different manufacturers, each speaking their own language: Modbus, OPC-UA, Ethernet\u002FIP, Profinet, FINS, etc. Getting data out means dealing with all of them at once, maintaining multiple drivers and troubleshooting different failure modes.",[15,3982,3983],{},"Then there's the networking challenge. Factory networks weren't built for internet connectivity. Isolated subnets, strict firewalls, and security-conscious IT departments mean getting approval for gateways (whether edge devices or software platforms) involves security reviews and architecture decisions that can drag on for months.",[15,3985,3986],{},"The costs add up quickly. Cloud platforms charge per message, and streaming data from dozens of machines easily reaches thousands per month, before gateway hardware and licenses.",[15,3988,3989],{},"And there's the expertise gap. Plant engineers know PLCs but not cloud APIs. IT teams know infrastructure but not industrial protocols. You end up needing expensive consultants, turning what should be straightforward into a six-figure project.",[15,3991,3992],{},"The solution lies in low-code integration platforms that consolidate protocol handling, edge computing, and cloud connectivity into a single system. This guide demonstrates one approach using FlowFuse, a platform built on Node-RED that addresses each challenge outlined above.",[37,3994,454],{"id":453},[15,3996,3997],{},"Before you start, make sure you have the following:",[431,3999,4000,4003],{},[306,4001,4002],{},"A properly configured and fully operational PLCs, located on the same network as the edge device that will be reading its data.",[306,4004,4005,4006,4011],{},"A running FlowFuse instance on your edge device. If you do not have an account, ",[172,4007,4010],{"href":4008,"rel":4009},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2025\u002F09\u002Finstalling-node-red\u002F",[176],"sign up for a free trial"," and set up your instance following the instructions in this article.",[4013,4014,4016],"h1",{"id":4015},"getting-started","Getting Started",[15,4018,4019],{},"Now, let's get started. First, watch this demo, where I have built a FlowFuse flow that collects data from four sources: Siemens S7 and Allen-Bradley PLCs, an OPC UA server, and a Modbus simulator.",[4021,4022],"lite-youtube",{"videoid":4023,"params":4024,"style":4025,"title":4026},"vptAoDR78Cc","rel=0","margin-top: 20px; margin-bottom: 20px; width: 100%; height: 480px;","YouTube video player",[15,4028,4029],{},"This flow standardizes data from each protocol into a consistent JSON format, enriches it with contextual metadata, and publishes everything to the FlowFuse MQTT Broker, all within a single instance. The following guide explains how to replicate this setup for any PLC on your factory floor.",[37,4031,4033],{"id":4032},"step-1-extract-data-from-your-plc","Step 1: Extract Data from Your PLC",[15,4035,4036],{},"As mentioned earlier, extracting data is the first and most complex step. Get this wrong, and the complexity and costs can spiral out of control. FlowFuse simplifies this process. Its pre-built connectors handle Modbus, OPC UA, EtherNet\u002FIP, and other protocols right out of the box, no custom coding, expensive proprietary gateways, or per-tag licensing fees required. You can configure your connections visually and have data flowing within minutes.",[15,4038,4039],{},"This is not just theory, Fortune 500 manufacturers are already running production systems on FlowFuse. Their consistent feedback? Massive cost savings compared to legacy systems, especially when deployed across multiple facilities. The enterprise features of FlowFuse handle the scale and security requirements large operations demand.",[15,4041,4042],{},"The Node-RED ecosystem that powers FlowFuse offers comprehensive protocol support. You'll find nodes available for every major PLC manufacturer, including:",[431,4044,4045,4051,4057,4063,4069,4075,4081],{},[306,4046,4047,4050],{},[22,4048,4049],{},"node-red-contrib-modbus"," – Modbus RTU\u002FTCP PLCs and devices",[306,4052,4053,4056],{},[22,4054,4055],{},"node-red-contrib-s7"," – Siemens S7-300\u002F400\u002F1200\u002F1500",[306,4058,4059,4062],{},[22,4060,4061],{},"node-red-contrib-opcua"," – OPC UA servers",[306,4064,4065,4068],{},[22,4066,4067],{},"node-red-contrib-cip-ethernet-ip"," – Allen-Bradley PLCs",[306,4070,4071,4074],{},[22,4072,4073],{},"node-red-contrib-mcprotocol"," – Mitsubishi PLCs",[306,4076,4077,4080],{},[22,4078,4079],{},"node-red-contrib-omron-fins"," – Omron PLCs",[306,4082,4083],{},"and many more",[15,4085,4086,4087,4089,4090,4092],{},"Adding a protocol node to your FlowFuse instance takes just a few clicks. Open the palette manager from the hamburger menu, select ",[309,4088,3778],{},", go to the ",[309,4091,3784],{}," tab, and search for the node you need.",[37,4094,4096],{"id":4095},"convincing-the-it-team","Convincing the IT Team",[15,4098,4099,4100,367],{},"When talking to people in the IIoT community, one recurring challenge always comes up, ",[309,4101,4102],{},"convincing the IT team",[15,4104,4105],{},"Traditional industrial gateways require inbound connections from the cloud. This means opening specific ports in your firewall, creating security exceptions, and giving external systems a pathway into your production network. IT security teams push back on this, and rightly so. Inbound connections expand your attack surface and violate the principle of defense in depth.",[15,4107,4108,4109,4112,4113,4116],{},"FlowFuse solves this with an ",[309,4110,4111],{},"edge-first architecture",". The Device Agent installs directly on hardware inside your factory network, a Raspberry Pi, an industrial PC, or even directly on supported PLCs. Once running, the agent initiates ",[309,4114,4115],{},"outbound"," connections to the FlowFuse platform using standard web protocols (HTTPS and WebSocket over port 443). All communication flows through this outbound connection. The platform never initiates connections back to your network.",[15,4118,4119,4120,4123],{},"From a security standpoint, this changes everything. Your firewall configuration does not change.",[4121,4122],"br",{},"\nNo new inbound rules. No DMZ setup. No VPN tunnels to maintain.",[15,4125,4126],{},"The device agent behaves like any other business application making secure outbound HTTPS requests, something your network already allows.",[15,4128,4129],{},"For networks with proxy servers, the agent supports standard proxy configurations through environment variables. For air-gapped networks, you can pre-cache Node-RED modules and deploy without internet connectivity after the initial setup.",[37,4131,4133],{"id":4132},"step-2-transform-and-structure-your-data","Step 2: Transform and Structure Your Data",[15,4135,4136],{},"Now let's move to the next step. Raw PLC data needs reshaping before cloud transmission. Register values, bit arrays, floating points, and timestamps arrive in different formats. FlowFuse offers several transformation methods suitable for different skill levels.",[15,4138,4139],{},[309,4140,4141],{},"Visual Transformation with Change Nodes and JSONata",[15,4143,4144],{},"Change nodes handle simple transformations without coding. They allow you to map fields, modify values, convert units, and add metadata using dropdowns and form fields. JSONata allows more advanced data manipulation directly within the Change node.",[15,4146,4147],{},"Plant engineers can work directly with these visual tools, no programming required.",[15,4149,4150,4151,4153],{},"For example, suppose you are receiving a pressure sensor value as ",[22,4152,616],{}," but it lacks context.",[15,4155,4156,4157,4160],{},"You can use a ",[309,4158,4159],{},"Change"," node to:",[431,4162,4163],{},[306,4164,4165],{},"Add contextual information such as the machine ID, facility, or sensor location, unit",[15,4167,4168,4172],{},[489,4169],{"alt":4170,"dataZoomable":369,"src":4171},"Change node adding context to data","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fchange-node-adding-context.png",[1235,4173,4174],{},"Change node used to convert temperature and add machine context",[15,4176,4177],{},[309,4178,4179],{},"Function Nodes for Custom Logic",[15,4181,4182],{},"Function nodes provide full JavaScript access for complex requirements. Write custom logic, install npm packages, and access the complete JavaScript standard library when Change nodes and JSONata reach their limits.",[15,4184,4185],{},[1235,4186,4187,4188,4192],{},"Tip: Use the ",[172,4189,4191],{"href":4190},"\u002Fblog\u002F2025\u002F07\u002Fflowfuse-ai-assistant-better-node-red-manufacturing\u002F","FlowFuse Expert"," to generate function nodes. Describe the transformation you need in plain English, and it will create the code for you. For best results, provide sample input data to ensure the output matches your requirements.",[15,4194,4195],{},[309,4196,4197],{},"Pre-built Community Nodes",[15,4199,4200],{},"Before building custom solutions, check the palette manager. The Node-RED ecosystem includes thousands of nodes for data aggregation, statistical analysis, time-series buffering, and unit conversions. Many common transformation tasks already have ready-made solutions.",[15,4202,4203,4204,4207],{},"For example, a popular node I'm using in my demo for parsing and transforming data is ",[22,4205,4206],{},"node-red-contrib-buffer-parser",". This node is especially useful when working with Modbus or PLC outputs, as it converts raw data into structured formats that can be easily processed further.",[37,4209,4211],{"id":4210},"step-3-set-up-mqtt-with-flowfuse","Step 3: Set Up MQTT with FlowFuse",[15,4213,4214],{},"Most MQTT implementations require setting up a separate broker either paying for a managed service or hosting your own. FlowFuse includes a managed MQTT broker built directly into the platform, eliminating this extra step.",[15,4216,4217],{},"Traditional PLC-to-cloud setups typically involve several moving parts: edge gateways running protocol drivers, a separate MQTT broker (cloud-hosted or self-managed), and your destination cloud services. Each layer adds configuration work, licensing costs, and potential failure points. When data stops flowing, you end up troubleshooting across multiple systems to locate the issue.",[15,4219,4220],{},"FlowFuse consolidates those layers into a single integrated platform. It provides enterprise-grade features for management, scaling, deployment, and security, all handled by the FlowFuse infrastructure. You retain full control over configuration settings through a clean, intuitive interface, without needing to maintain multiple external systems.",[15,4222,4223],{},"To use the FlowFuse MQTT broker, you'll need a FlowFuse Pro or higher-tier account. Once on the Pro plan, you can enable the managed MQTT service by navigating to the Broker section from the left sidebar and selecting FlowFuse Broker.",[15,4225,4226,4230],{},[489,4227],{"alt":4228,"dataZoomable":369,"src":4229},"Enabling FlowFuse MQTT Broker","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fset-broker.png",[1235,4231,4228],{},[15,4233,4234],{},[309,4235,4236],{},"Configure Publishing",[303,4238,4239,4245,4248],{},[306,4240,2144,4241,4244],{},[309,4242,4243],{},"FlowFuse MQTT Out"," node onto your canvas.",[306,4246,4247],{},"Open the node configuration. It will automatically pick up its configuration.",[306,4249,4250],{},"Set the topic following ISA-95 hierarchy:",[619,4252,4254],{"className":4253,"code":2646,"language":789},[787],[22,4255,2646],{"__ignoreMap":369},[15,4257,4258],{},"For Example:",[619,4260,4263],{"className":4261,"code":4262,"language":789},[787],"acme\u002Fplant-a\u002Fassembly\u002Fline1\u002Fpress-1\u002Fpressure01\u002Fbar\n",[22,4264,4262],{"__ignoreMap":369},[15,4266,4267],{},[309,4268,4269],{},"Why ISA-95 for MQTT Topics",[15,4271,4272],{},"The ISA-95 Equipment Hierarchy Model is an international standard that defines how to organize manufacturing operations into logical layers. When you structure MQTT topics using this model, you're building toward a Unified Namespace (UNS), a single, consistent way to organize all operational data across your entire organization.",[15,4274,4275],{},"The goal of UNS is to eliminate data silos. Instead of each system maintaining its own proprietary structure, everything publishes to one shared namespace using a common hierarchy. Applications subscribe to exactly the data they need without knowing where it physically comes from or how it was collected.",[15,4277,4278,4279,4282],{},"ISA-95 makes this possible because it maps to how factories actually operate. ",[22,4280,4281],{},"company\u002Fsite\u002Farea\u002Fline\u002Fcell"," matches your organizational structure. When you expand to new facilities or add equipment, the hierarchy extends naturally. Analytics tools can compare performance across sites. MES systems subscribe to production line data. Dashboards pull from specific cells. Everything uses the same addressing scheme.",[15,4284,4285],{},"This enables powerful wildcard subscriptions:",[431,4287,4288,4294,4300,4306],{},[306,4289,4290,4293],{},[22,4291,4292],{},"acme\u002F#"," - all company data",[306,4295,4296,4299],{},[22,4297,4298],{},"acme\u002Fchicago\u002F#"," - single site",[306,4301,4302,4305],{},[22,4303,4304],{},"+\u002F+\u002Fassembly\u002F#"," - assembly operations everywhere",[306,4307,4308,4311],{},[22,4309,4310],{},"acme\u002Fchicago\u002Fassembly\u002Fline2\u002F#"," - one production line",[15,4313,4314],{},[1235,4315,4316],{},"Note: Use lowercase with hyphens for multi-word names.",[303,4318,4319,4328],{"start":370},[306,4320,763,4321,4324,4325,367],{},[309,4322,4323],{},"QoS"," to ",[309,4326,4327],{},"1",[306,4329,3794,4330,367],{},[309,4331,3876],{},[15,4333,4334],{},"After deploying the flow, the MQTT client for your device will be automatically created. To configure access:",[303,4336,4337,4340],{"start":564},[306,4338,4339],{},"Double-click the MQTT Out node.",[306,4341,3794,4342,4344],{},[309,4343,2623],{},". You will be redirected to the platform's broker client management section, filtered to show the client created for this instance.",[15,4346,4347,4351],{},[489,4348],{"alt":4349,"dataZoomable":369,"src":4350},"Configure MQTT Client Access Control","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fconfigure-access-control.png",[1235,4352,4349],{},[303,4354,4355],{"start":2388},[306,4356,4357,4358,4361,4362,4364,4365,367],{},"Click the client ",[309,4359,4360],{},"edit",", select ",[309,4363,2631],{},", and then click ",[309,4366,4367],{},"Confirm",[15,4369,4370,4374],{},[489,4371],{"alt":4372,"dataZoomable":369,"src":4373},"Configuring Client Access Control","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fclient-access-control.jpg",[1235,4375,4349],{},[15,4377,4378,4379,4382],{},"That's it. You now have PLC data flowing to MQTT with proper access controls configured and a topic structure that scales with your organization. To view the topic hierarchy and the schema for your topics, go to the FlowFuse Broker section. Here, you'll see all the topics within your MQTT broker. By clicking ",[309,4380,4381],{},"Open Schema",", you can view the auto-generated schema document created by FlowFuse.",[15,4384,4385,4389],{},[489,4386],{"alt":4387,"dataZoomable":369,"src":4388},"FlowFuse Topic Hierarchy View","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fmqtt-topic-hierarchy.png",[1235,4390,4387],{},[15,4392,4393,4397],{},[489,4394],{"alt":4395,"dataZoomable":369,"src":4396},"Topic schema auto-generated by FlowFuse","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fmqtt-topic-schema-document.png",[1235,4398,4395],{},[37,4400,4402],{"id":4401},"bridging-the-expertise-gap-and-cutting-costs","Bridging the Expertise Gap and Cutting Costs",[15,4404,4405],{},"Now let's talk about the remaining problems: the expertise gap and cost. FlowFuse solves both by changing how the work gets done.",[15,4407,4408],{},"Plant engineers configure PLC connections, transform data, contextualize it, and send it to MQTT through drag-and-drop interfaces without writing code, that's what you saw in the steps above. IT teams manage security and access controls through standard web tools. Neither needs expertise in the other's domain.",[15,4410,4411],{},"The FlowFuse Expert fills remaining gaps, describe what you need in plain English, and it generates function nodes, database queries, or dashboard components. Click \"Explain\" on any flow to get instant documentation.",[15,4413,4414],{},"This eliminates the consultant dependency that inflates project costs. Your team handles implementation and maintenance without external help at $150-$250 per hour, saving $12,000 to $30,000 on setup alone. The managed MQTT broker includes unlimited messaging with no per-message fees. Protocol drivers are free and open-source with no per-tag licensing. Deploy on existing industrial hardware instead of buying $10,000 proprietary gateways.",[15,4416,4417],{},"Manufacturers typically see substantial cost reduction in the first year, with improving economics as you scale since hardware and licensing costs stay eliminated. Most engineers ship production flows in their first session.",[37,4419,4421],{"id":4420},"get-started","Get Started",[15,4423,4424,4425,4429],{},"Connect your first PLC today. ",[172,4426,4428],{"href":1984,"rel":4427},[176],"Sign up for FlowFuse",", install the Device Agent on your edge hardware, and have data flowing to MQTT in under an hour. The platform handles the complexity, you focus on turning factory data into insights.",[15,4431,4432,4433,367],{},"MQTT is one of several ways FlowFuse connects PLCs to the modern industrial stack. For a full view of supported protocols, OPC UA, EtherNet\u002FIP, Siemens S7, Modbus, and more, see the ",[172,4434,1681],{"href":1680},{"title":369,"searchDepth":370,"depth":370,"links":4436},[4437,4438,4439,4440,4441,4442,4443,4444],{"id":3973,"depth":373,"text":3974},{"id":453,"depth":373,"text":454},{"id":4032,"depth":373,"text":4033},{"id":4095,"depth":373,"text":4096},{"id":4132,"depth":373,"text":4133},{"id":4210,"depth":373,"text":4211},{"id":4401,"depth":373,"text":4402},{"id":4420,"depth":373,"text":4421},"2025-10-27","Learn how to extract data from Siemens, Allen-Bradley, Omron, Mitsubishi, OPC UA, and Modbus, transform it, and publish to MQTT using FlowFuse, without expensive gateways or consultants.","\u002Fblog\u002F2025\u002F10\u002Fimages\u002Fplc-to-mqtt.png",{"keywords":4449,"excerpt":4450},"MQTT, PLC, Siemens, S7, Allen-Bradley, EtherNet\u002FIP, Omron, FINS, Mitsubishi, MC Protocol, Modbus, Modbus-RTU, Modbus-TCP, OPC-UA, FlowFuse, Node-RED, Industrial IoT, IIoT",{"type":12,"value":4451},[4452],[15,4453,3964],{},"\u002Fblog\u002F2025\u002F10\u002Fplc-to-mqtt-using-flowfuse",{"title":3958,"description":4446},{"loc":4454},"blog\u002F2025\u002F10\u002Fplc-to-mqtt-using-flowfuse","Connect any PLC to MQTT without the typical complexity, costs, and expertise requirements",[933,4460,402,4461],"modbus","plc","This tutorial shows how to publish PLC data to MQTT using FlowFuse and Node-RED without expensive gateways or consultants. You extract data from any PLC protocol (Modbus, OPC UA, EtherNet\u002FIP, Siemens S7, and more) using pre-built connectors, transform and contextualize it into consistent JSON with Change, Function, or community nodes, then publish it to the built-in FlowFuse MQTT broker using an ISA-95 topic hierarchy with proper access controls. FlowFuse's edge-first architecture keeps firewalls closed to inbound traffic, letting plant engineers ship production flows in under an hour.","iXlNoqWxawYlRLfLHSUTlUMBAtOb9J8uyDRM0dnYmlI",{"id":4465,"title":4466,"authors":4467,"body":4468,"cta":3,"date":4942,"description":4943,"extension":386,"image":4944,"lastUpdated":3,"meta":4945,"navigation":394,"path":4950,"seo":4951,"sitemap":4952,"stem":4953,"subtitle":4954,"tags":4955,"tldr":3,"video":3,"__hash__":4956},"blog\u002Fblog\u002F2025\u002F03\u002Fmanaging-mqtt-connections-at-scale-in-flowfuse.md","Managing MQTT Connections at Scale in FlowFuse",[10],{"type":12,"value":4469,"toc":4927},[4470,4473,4476,4480,4483,4486,4498,4502,4505,4508,4573,4577,4580,4584,4591,4599,4607,4615,4622,4631,4688,4691,4694,4698,4701,4704,4716,4725,4731,4739,4745,4753,4758,4761,4764,4813,4817,4820,4823,4831,4834,4837,4868,4876,4879,4883,4886,4894,4897,4901,4904,4912,4919,4921,4924],[15,4471,4472],{},"FlowFuse makes it easy to deploy Node-RED flows at scale using DevOps pipelines and device groups. However, different stages in a pipeline may need different MQTT brokers, for example, one for development and another for production. Manually configuring each stage can be time-consuming, especially when a stage has multiple remote instances (devices).",[15,4474,4475],{},"This article shows how to continue using FlowFuse’s one-click deployment while ensuring that remote instances in each stage of your pipeline connect to the desired MQTT broker without manual configuration.",[37,4477,4479],{"id":4478},"goal-and-prerequisites","Goal and Prerequisites",[15,4481,4482],{},"This article explains how to deploy Node-RED flows across different pipeline stages while ensuring each stage connects to its appropriate MQTT broker.",[15,4484,4485],{},"To proceed, ensure that the DevOps pipeline is created with the correct stages. If a stage includes remote instances, verify that all instances are running the FlowFuse Device Agent and are connected to your team.",[15,4487,4488,4489,4493,4494,367],{},"For more information on how to create a DevOps pipeline, refer to ",[172,4490,4492],{"href":4491},"\u002Fblog\u002F2024\u002F10\u002Fhow-to-build-automate-devops-pipelines-node-red-deployments\u002F","How to Build and Automate DevOps Pipelines for Node-RED Deployments",". For instructions on how to create a device group, refer to the ",[172,4495,4497],{"href":4496},"\u002Fdocs\u002Fuser\u002Fdevice-groups\u002F","Device Groups Documentation",[37,4499,4501],{"id":4500},"setting-environment-variables-for-development-instance","Setting Environment Variables for Development Instance",[15,4503,4504],{},"For this guide, environment variables will be the key tool to ensure each pipeline stage connects to the correct MQTT broker without manual intervention, allowing for a smooth deployment process.",[15,4506,4507],{},"Since the development remote instance is where the flow will be built and tested, start by adding the necessary environment variables for its MQTT configuration. Setting these up first ensures the flow runs as expected before deploying it to other pipeline stages.",[303,4509,4510,4513,4520,4567],{},[306,4511,4512],{},"Go to the remote\u002Fhosted instance settings in the FlowFuse platform.",[306,4514,4515,4516,4519],{},"Switch to the ",[309,4517,4518],{},"Environment"," settings.",[306,4521,4522,4523],{},"Add the following environment variables with the appropriate values for that specific device:",[431,4524,4525,4531,4537,4543,4549,4555,4561],{},[306,4526,4527,4530],{},[22,4528,4529],{},"HOST"," – The MQTT broker's hostname or IP address.",[306,4532,4533,4536],{},[22,4534,4535],{},"PORT"," – The port number the broker is listening on.",[306,4538,4539,4542],{},[22,4540,4541],{},"USERNAME"," – The authentication username for the MQTT broker.",[306,4544,4545,4548],{},[22,4546,4547],{},"PASSWORD"," – The authentication password for the MQTT broker.",[306,4550,4551,4554],{},[22,4552,4553],{},"CLIENT_ID"," – A unique identifier for the device connecting to the broker.",[306,4556,4557,4560],{},[22,4558,4559],{},"CLIENT_ID_SUFFIX"," – A suffix shared among client IDs within the broker.",[306,4562,4563,4566],{},[22,4564,4565],{},"TOPIC"," – The MQTT topic used for message communication.",[306,4568,3794,4569,4572],{},[309,4570,4571],{},"Save Settings"," to apply the changes and restart the device.",[37,4574,4576],{"id":4575},"configuring-mqtt-in-node-red-with-environment-variables","Configuring MQTT in Node-RED with Environment Variables",[15,4578,4579],{},"Now, let's explore how these environment variables can be used within Node-RED to configure the MQTT broker. Node-RED offers multiple ways to reference environment variables. Here are two primary methods to configure MQTT nodes using environment variables:",[494,4581,4583],{"id":4582},"_1-using-the-configuration-dialog","1. Using the Configuration Dialog:",[15,4585,4586,4587,4590],{},"Environment variables can be directly referenced in the MQTT node properties using the ",[22,4588,4589],{},"${ENV_NAME}"," syntax as shown in the following images.",[15,4592,4593,4597],{},[489,4594],{"alt":4595,"dataZoomable":369,"src":4596},"Setting up MQTT connection using environment variables.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fmqtt-config-with-env.png",[1235,4598,4595],{},[15,4600,4601,4605],{},[489,4602],{"alt":4603,"dataZoomable":369,"src":4604},"Configuring MQTT node security settings using environment variables in Node-RED.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fmqtt-node-security-config.png",[1235,4606,4603],{},[15,4608,4609,4613],{},[489,4610],{"alt":4611,"dataZoomable":369,"src":4612},"Configuring the MQTT topic in Node-RED using environment variables.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fmqtt-broker-out-config.png",[1235,4614,4611],{},[494,4616,4618,4619,4621],{"id":4617},"_2-setting-values-dynamically-via-the-msg-object","2. Setting Values Dynamically via the ",[22,4620,3554],{}," Object",[15,4623,4624,4625,4627,4628,4630],{},"In this approach, a ",[309,4626,2147],{}," is used to retrieve environment variables and set the necessary MQTT configuration properties in the ",[22,4629,3554],{}," object. These properties include:",[431,4632,4633,4639,4649,4658,4664,4670,4676,4682],{},[306,4634,4635,4638],{},[22,4636,4637],{},"msg.broker.broker"," – The MQTT broker’s URL or IP address.",[306,4640,4641,4644,4645,4648],{},[22,4642,4643],{},"msg.action"," – Must be set to ",[22,4646,4647],{},"\"connect\""," when establishing a connection.",[306,4650,4651,4644,4654,4657],{},[22,4652,4653],{},"msg.broker.force",[22,4655,4656],{},"true"," to enforce the connection.",[306,4659,4660,4663],{},[22,4661,4662],{},"msg.broker.port"," – The port number for the MQTT connection.",[306,4665,4666,4669],{},[22,4667,4668],{},"msg.broker.clientid"," – The unique client identifier for the device.",[306,4671,4672,4675],{},[22,4673,4674],{},"msg.broker.username"," – The MQTT username for authentication.",[306,4677,4678,4681],{},[22,4679,4680],{},"msg.broker.password"," – The MQTT password for authentication.",[306,4683,4684,4687],{},[22,4685,4686],{},"msg.topic"," – The MQTT topic to which the device will publish or subscribe.",[15,4689,4690],{},"While the first method (direct reference in the MQTT node) is simpler and does not require additional nodes, it has limitations. It works well when there is only a single instance in the pipeline stage. However, when multiple instances exist within the same stage, the client ID, username, password, and topics often vary from device to device. The second method provides greater flexibility by dynamically adjusting these values, ensuring each device connects with the correct credentials and configurations. This approach makes the setup scalable and adaptable, eliminating the need for manual updates during deployment.",[15,4692,4693],{},"Unlike the first approach, which restricts direct combinations (e.g., string + environment variables or environment variables + environment variables), the second method enables dynamic modifications.",[2434,4695,4697],{"id":4696},"ensuring-unique-mqtt-credentials-and-topics","Ensuring Unique MQTT Credentials and Topics",[15,4699,4700],{},"As we mentioned in the multi-device deployment scenario, each device needs to establish its own connection to the MQTT broker while maintaining unique credentials and topics. If multiple devices in the same stage use identical configurations, connection conflicts, such as client ID duplication, may occur. To avoid these issues, each device must be assigned a unique client ID, username, password for security, and topic.",[15,4702,4703],{},"To ensure uniqueness, we can use the default environment variables available for each remote instance, such as:",[431,4705,4706,4711],{},[306,4707,4708],{},[22,4709,4710],{},"FF_DEVICE_NAME",[306,4712,4713],{},[22,4714,4715],{},"FF_DEVICE_ID",[15,4717,4718,4719,4721,4722,4724],{},"When generating the client ID for the MQTT broker, the device name (",[22,4720,4710],{},") can be used as the username. Since all client IDs share the same suffix, this suffix can be stored as a device-level environment variable (",[22,4723,4559],{},"). By combining both values, we can get the client ID of the device without manual intervention.",[15,4726,4727,4728,4730],{},"For the password, you can use the device ID (",[22,4729,4715],{},"), which is assigned when creating the client. Alternatively, you can set a common password for all clients by defining it as a device group-level environment variable.",[15,4732,4733,4737],{},[489,4734],{"alt":4735,"dataZoomable":369,"src":4736},"Using a Change node to dynamically set MQTT broker connection properties.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002FCHANGE-NODE-1.png",[1235,4738,4735],{},[15,4740,4741,4742,4744],{},"For topics, a combination of a string and ",[22,4743,4710],{}," can be used to ensure uniqueness.",[15,4746,4747,4751],{},[489,4748],{"alt":4749,"dataZoomable":369,"src":4750},"Configuring MQTT topics dynamically using a Change node in Node-RED.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002FCHANGE-NODE-TOPIC-1.png",[1235,4752,4749],{},[15,4754,4755],{},[1235,4756,4757],{},"Note: Ensure that the topic configuration is set dynamically when sending the payload, not when establishing the connection.",[15,4759,4760],{},"Once you have built your flow to connect to the intended MQTT broker using environment variables, deploy it and verify that it works as expected.",[15,4762,4763],{},"Also, if you need an example flow to test and explore in more detail, the following flow is provided. It demonstrates how to configure the MQTT connection dynamically using environment variables and, where needed, generate some settings by combining strings with environment variables.",[15,4765,4766,4767,2115],{},"{% renderFlow %}\n",[627,4768,4769,4770,4772,4773,4776,4777,4780,4781,4784,4785,4798,4799,4802,4803,4805,4806,4809,4810,4812],{},"{\"id\":\"0301bbe611a22e6d\",\"type\":\"cpu\",\"z\":\"aeaff62b91a987d4\",\"name\":\"\",\"msgCore\":false,\"msgOverall\":true,\"msgArray\":false,\"msgTemp\":false,\"x\":450,\"y\":380,\"wires\":[[\"0c0ee596549272d4\"]]},{\"id\":\"4b8f4fec3983d558\",\"type\":\"inject\",\"z\":\"aeaff62b91a987d4\",\"name\":\"Trigger every 5-second interval.\",\"props\":",[627,4771],{},",\"repeat\":\"5\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":190,\"y\":440,\"wires\":[[\"0301bbe611a22e6d\",\"e12765d187a7b502\",\"43e83b87e202428b\",\"552b49b55fbf8071\"]]},{\"id\":\"e12765d187a7b502\",\"type\":\"Memory\",\"z\":\"aeaff62b91a987d4\",\"name\":\"\",\"scale\":\"Gigabyte\",\"x\":440,\"y\":420,\"wires\":[[\"fe3d07cd9f4f1b20\"]]},{\"id\":\"43e83b87e202428b\",\"type\":\"Uptime\",\"z\":\"aeaff62b91a987d4\",\"name\":\"\",\"x\":440,\"y\":460,\"wires\":[[\"29541f3dafd85db9\"]]},{\"id\":\"552b49b55fbf8071\",\"type\":\"Loadavg\",\"z\":\"aeaff62b91a987d4\",\"name\":\"\",\"x\":440,\"y\":500,\"wires\":[[\"7b09b1eae14fac16\"]]},{\"id\":\"0c0ee596549272d4\",\"type\":\"change\",\"z\":\"aeaff62b91a987d4\",\"name\":\"CPU USAGE\",\"rules\":",[627,4774,4775],{},"{\"t\":\"set\",\"p\":\"data\",\"pt\":\"msg\",\"to\":\"{}\",\"tot\":\"json\"},{\"t\":\"set\",\"p\":\"data.CPU_USAGE\",\"pt\":\"msg\",\"to\":\"payload\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":650,\"y\":380,\"wires\":[[\"75445a62bac2e0c7\"]]},{\"id\":\"fe3d07cd9f4f1b20\",\"type\":\"change\",\"z\":\"aeaff62b91a987d4\",\"name\":\"MEMORY USAGE\",\"rules\":",[627,4778,4779],{},"{\"t\":\"set\",\"p\":\"data\",\"pt\":\"msg\",\"to\":\"{}\",\"tot\":\"json\"},{\"t\":\"set\",\"p\":\"data.MEMORY_USAGE\",\"pt\":\"msg\",\"to\":\"payload\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":670,\"y\":420,\"wires\":[[\"75445a62bac2e0c7\"]]},{\"id\":\"29541f3dafd85db9\",\"type\":\"change\",\"z\":\"aeaff62b91a987d4\",\"name\":\"SYSTEM UPTIME\",\"rules\":",[627,4782,4783],{},"{\"t\":\"set\",\"p\":\"data\",\"pt\":\"msg\",\"to\":\"{}\",\"tot\":\"json\"},{\"t\":\"set\",\"p\":\"data.UPTIME\",\"pt\":\"msg\",\"to\":\"payload.uptime\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":670,\"y\":460,\"wires\":[[\"75445a62bac2e0c7\"]]},{\"id\":\"7b09b1eae14fac16\",\"type\":\"change\",\"z\":\"aeaff62b91a987d4\",\"name\":\"LOAD AVERAGE\",\"rules\":",[627,4786,4787,4788,4790,4791,4793,4794,4797],{},"{\"t\":\"set\",\"p\":\"data\",\"pt\":\"msg\",\"to\":\"{}\",\"tot\":\"json\"},{\"t\":\"set\",\"p\":\"data.LOAD_AVERAGE.ONE_MIN\",\"pt\":\"msg\",\"to\":\"payload.loadavg",[627,4789,2099],{},"\",\"tot\":\"msg\"},{\"t\":\"set\",\"p\":\"data.LOAD_AVERAGE.FIVE_MIN\",\"pt\":\"msg\",\"to\":\"payload.loadavg",[627,4792,4327],{},"\",\"tot\":\"msg\"},{\"t\":\"set\",\"p\":\"data.LOAD_AVERAGE.FIFTEEN_MIN\",\"pt\":\"msg\",\"to\":\"payload.loadavg",[627,4795,4796],{},"2","\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":670,\"y\":500,\"wires\":[[\"75445a62bac2e0c7\"]]},{\"id\":\"75445a62bac2e0c7\",\"type\":\"join\",\"z\":\"aeaff62b91a987d4\",\"name\":\"\",\"mode\":\"custom\",\"build\":\"merged\",\"property\":\"data\",\"propertyType\":\"msg\",\"key\":\"topic\",\"joiner\":\"\\n\",\"joinerType\":\"str\",\"useparts\":false,\"accumulate\":false,\"timeout\":\"\",\"count\":\"4\",\"reduceRight\":false,\"reduceExp\":\"\",\"reduceInit\":\"\",\"reduceInitType\":\"\",\"reduceFixup\":\"\",\"x\":870,\"y\":440,\"wires\":[[\"acf3b791d682a13d\"]]},{\"id\":\"272ec74227a151db\",\"type\":\"change\",\"z\":\"aeaff62b91a987d4\",\"name\":\"Dynamically Configure MQTT Connection Using Environment Variables\",\"rules\":",[627,4800,4801],{},"{\"t\":\"set\",\"p\":\"action\",\"pt\":\"msg\",\"to\":\"connect\",\"tot\":\"str\"},{\"t\":\"set\",\"p\":\"broker.broker\",\"pt\":\"msg\",\"to\":\"HOST\",\"tot\":\"env\"},{\"t\":\"set\",\"p\":\"broker.port\",\"pt\":\"msg\",\"to\":\"PORT\",\"tot\":\"env\"},{\"t\":\"set\",\"p\":\"broker.clientid\",\"pt\":\"msg\",\"to\":\"${FF_DEVICE_NAME}${Client_ID_SUFFIX}\",\"tot\":\"env\"},{\"t\":\"set\",\"p\":\"broker.username\",\"pt\":\"msg\",\"to\":\"broker.clientid\",\"tot\":\"msg\"},{\"t\":\"set\",\"p\":\"broker.password\",\"pt\":\"msg\",\"to\":\"FF_DEVICE_ID\",\"tot\":\"env\"},{\"t\":\"set\",\"p\":\"broker.force\",\"pt\":\"msg\",\"to\":\"true\",\"tot\":\"bool\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":820,\"y\":580,\"wires\":[[\"4860cc23dfca9720\"]]},{\"id\":\"4860cc23dfca9720\",\"type\":\"mqtt out\",\"z\":\"aeaff62b91a987d4\",\"name\":\"\",\"topic\":\"\",\"qos\":\"0\",\"retain\":\"\",\"respTopic\":\"\",\"contentType\":\"\",\"userProps\":\"\",\"correl\":\"\",\"expiry\":\"\",\"broker\":\"f484702903e298e7\",\"x\":1270,\"y\":580,\"wires\":",[627,4804],{},"},{\"id\":\"acf3b791d682a13d\",\"type\":\"change\",\"z\":\"aeaff62b91a987d4\",\"name\":\"Set payload and topic\",\"rules\":",[627,4807,4808],{},"{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"data\",\"tot\":\"msg\"},{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"factory\u002Fline2\u002F${FF_DEVICE_NAME}\",\"tot\":\"env\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1080,\"y\":440,\"wires\":[[\"4860cc23dfca9720\"]]},{\"id\":\"79dfc62b4b21d20b\",\"type\":\"inject\",\"z\":\"aeaff62b91a987d4\",\"name\":\"Trigger on deploy\",\"props\":",[627,4811],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"x\":210,\"y\":580,\"wires\":[[\"272ec74227a151db\"]]},{\"id\":\"f484702903e298e7\",\"type\":\"mqtt-broker\",\"name\":\"\",\"broker\":\"localhost\",\"port\":1883,\"clientid\":\"\",\"autoConnect\":false,\"usetls\":false,\"protocolVersion\":4,\"keepalive\":60,\"cleansession\":true,\"autoUnsubscribe\":true,\"birthTopic\":\"\",\"birthQos\":\"0\",\"birthRetain\":\"false\",\"birthPayload\":\"\",\"birthMsg\":{},\"closeTopic\":\"\",\"closeQos\":\"0\",\"closeRetain\":\"false\",\"closePayload\":\"\",\"closeMsg\":{},\"willTopic\":\"\",\"willQos\":\"0\",\"willRetain\":\"false\",\"willPayload\":\"\",\"willMsg\":{},\"userProps\":\"\",\"sessionExpiry\":\"\"}",[37,4814,4816],{"id":4815},"setting-environment-variables-for-a-device-group","Setting Environment Variables for a Device Group",[15,4818,4819],{},"After confirming that your flow in the development stage remote instance works as expected and connects to the broker correctly, the next step is to add environment variables.",[15,4821,4822],{},"If your target stage has only a single instance, you can set the environment variables at the instance level, as shown in the image below, and use the first method discussed earlier. This approach is straightforward and efficient for configuring a single instance using environment variables.",[15,4824,4825,4829],{},[489,4826],{"alt":4827,"dataZoomable":369,"src":4828},"Setting environment variables at the instance level in FlowFuse.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fenv-vars-blur.png",[1235,4830,4827],{},[15,4832,4833],{},"However, when multiple remote instances exist within the same stage, such as in a device group, configuring them individually can be impractical, especially when most settings remain the same. To simplify this process, FlowFuse allows you to set environment variables at the device group level, and you can use the second method to make the configuration quick and easy while using remote instance default environment variables.",[15,4835,4836],{},"To add the device group level environment variables follow the steps:",[303,4838,4839,4846,4863],{},[306,4840,4841,4842,4845],{},"Go to your ",[309,4843,4844],{},"device group’s settings"," in the FlowFuse platform.",[306,4847,4848,4849],{},"Add the following environment variables with the appropriate values:",[431,4850,4851,4855,4859],{},[306,4852,4853],{},[22,4854,4529],{},[306,4856,4857],{},[22,4858,4535],{},[306,4860,4861],{},[22,4862,4559],{},[306,4864,3794,4865,4867],{},[309,4866,4571],{}," to apply the changes.",[15,4869,4870,4874],{},[489,4871],{"alt":4872,"dataZoomable":369,"src":4873},"Configuring environment variables at the device group level.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fenv-settings.png",[1235,4875,4872],{},[15,4877,4878],{},"With this approach, you do not need to set environment variables separately for each instance. Instead, the environment variables defined at the device group level will apply to all remote instances within the group, ensuring a consistent and efficient configuration.",[37,4880,4882],{"id":4881},"deploying-flow-with-stage-specific-configurations-via-devops-pipeline","Deploying Flow with Stage-Specific Configurations via DevOps Pipeline",[15,4884,4885],{},"Now that everything is set up, trigger the deployment pipeline for the development stage. This will push the flow and settings to the next-stage instances while preserving the existing environment variables. Before applying the new configuration, all remote instances in the target stage will restart automatically.",[15,4887,4888,4892],{},[489,4889],{"alt":4890,"dataZoomable":369,"src":4891},"Deploying Node-RED flows using FlowFuse's DevOps pipeline.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fdevops-pipeline.png",[1235,4893,4890],{},[15,4895,4896],{},"If everything is configured correctly, the MQTT nodes in each remote Node-RED instance will connect to the appropriate broker configured at the device group level.",[37,4898,4900],{"id":4899},"monitoring-mqtt-topic-hierarchy-with-flowfuse","Monitoring MQTT Topic Hierarchy with FlowFuse",[15,4902,4903],{},"Once the Node-RED flow is deployed on all remote instances in the device group and the MQTT nodes in each instance are connected to the broker, you can monitor and manage all topics across all brokers directly in FlowFuse.",[15,4905,4906,4910],{},[489,4907],{"alt":4908,"dataZoomable":369,"src":4909},"Monitoring MQTT topics in FlowFuse across multiple brokers.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fmqtt-broker-monitoring.png",[1235,4911,4908],{},[15,4913,4914,4915],{},"Watch this short video to learn how to bring your own brokers for topic monitoring in FlowFuse: ",[172,4916,4917],{"href":4917,"rel":4918},"https:\u002F\u002Fyoutube.com\u002Fshorts\u002F-8TPXb0h0vA?si=wi3wghi4vUWlXJTZ",[176],[37,4920,884],{"id":883},[15,4922,4923],{},"FlowFuse makes it easy to deploy Node-RED flows while ensuring each stage connects to the right MQTT broker. By using environment variables at both the instance and device group levels, you can automate MQTT configurations, reducing manual setup and ensuring consistency.",[15,4925,4926],{},"[Get Started Now]({% include \"sign-up-url.njk\" %})",{"title":369,"searchDepth":370,"depth":370,"links":4928},[4929,4930,4931,4938,4939,4940,4941],{"id":4478,"depth":373,"text":4479},{"id":4500,"depth":373,"text":4501},{"id":4575,"depth":373,"text":4576,"children":4932},[4933,4934],{"id":4582,"depth":659,"text":4583},{"id":4617,"depth":659,"text":4935,"children":4936},"2. Setting Values Dynamically via the msg Object",[4937],{"id":4696,"depth":370,"text":4697},{"id":4815,"depth":373,"text":4816},{"id":4881,"depth":373,"text":4882},{"id":4899,"depth":373,"text":4900},{"id":883,"depth":373,"text":884},"2025-03-28","Learn how to configure MQTT brokers dynamically in FlowFuse using environment variables at both instance and device group levels. Streamline deployments across pipeline stages and monitor MQTT topics efficiently.","\u002Fblog\u002F2025\u002F03\u002Fimages\u002Fscaling-mqtt-connections.png",{"excerpt":4946},{"type":12,"value":4947},[4948],[15,4949,4472],{},"\u002Fblog\u002F2025\u002F03\u002Fmanaging-mqtt-connections-at-scale-in-flowfuse",{"title":4466,"description":4943},{"loc":4950},"blog\u002F2025\u002F03\u002Fmanaging-mqtt-connections-at-scale-in-flowfuse","Automating MQTT Configuration in FlowFuse Using Environment Variables",[933,402],"yXg30IOBgm-WiAESS09AEK_RzaMpLw7lvVKR_uG66uQ",{"id":4958,"title":4959,"authors":4960,"body":4961,"cta":5347,"date":5351,"description":5352,"extension":386,"image":5353,"lastUpdated":5354,"meta":5355,"navigation":394,"path":5360,"seo":5361,"sitemap":5362,"stem":5363,"subtitle":5364,"tags":5365,"tldr":3,"video":3,"__hash__":5367},"blog\u002Fblog\u002F2025\u002F01\u002Fdesigning-topic-hierarchy-for-your-uns.md","Designing a Clear Topic Structure for Your UNS",[10],{"type":12,"value":4962,"toc":5341},[4963,4966,4969,4972,4976,4983,4986,4988,4993,4996,4999,5016,5019,5022,5025,5037,5040,5043,5046,5053,5056,5059,5062,5066,5069,5072,5075,5078,5081,5089,5092,5099,5102,5105,5122,5125,5132,5135,5137,5154,5157,5164,5167,5169,5186,5189,5196,5199,5201,5218,5221,5228,5231,5233,5250,5253,5257,5260,5265,5268,5273,5276,5287,5292,5295,5300,5303,5308,5311,5314,5317,5321,5324,5327,5335,5338],[15,4964,4965],{},"Topic structuring is not just a technical concern when building a high-performance Unified Namespace (UNS) for manufacturing environments; it's a strategic design choice that can determine the system's scalability, efficiency, and overall effectiveness.",[15,4967,4968],{},"A well-structured topic hierarchy is critical in manufacturing, where vast amounts of data flow from sensors, machines, and systems. By organizing your topics correctly, you can streamline data flow, simplify scaling, and make your system more manageable as your operations grow.",[15,4970,4971],{},"In this post, we'll explore the significance of topic structuring for your UNS, outline why it's essential for scalability and performance, and share best practices for designing a robust topic hierarchy that can evolve alongside your business.",[37,4973,4975],{"id":4974},"why-topic-structuring-is-crucial-for-your-uns","Why Topic Structuring is Crucial for Your UNS",[15,4977,4978,4979,4982],{},"When building a UNS for manufacturing environments, ",[172,4980,1648],{"href":4981},"\u002Fblog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns\u002F"," is one of the most popular and preferred choices due to its lightweight, efficient, and scalable design. MQTT’s publish-subscribe model is perfect for handling the real-time, high-volume data flow in factories, where machines, sensors, and devices constantly generate information. However, while MQTT is a powerful tool, how you structure your topics plays a pivotal role in ensuring that your UNS is scalable and efficient.",[15,4984,4985],{},"Manufacturing operations often experience rapid growth. The sheer number of sensors, machines, and production lines increases over time, and so does the complexity of the data. MQTT topics are hierarchical, which means they follow a tree-like structure with levels separated by a forward slash (\u002F). This hierarchical structure can mirror the physical layout of your factory floor, providing a logical, scalable framework for your data.",[15,4987,2651],{},[15,4989,4990],{},[22,4991,4992],{},"\u002Ffactory\u002Fline1\u002Fmachine1\u002Ftemperature",[15,4994,4995],{},"This topic structure indicates that the data comes from machine1 on line1 of your factory, specifically from a temperature sensor. The structure is intuitive because it directly reflects the factory’s layout.\nAdding more machines, sensors, or production lines is straightforward as your factory grows.",[15,4997,4998],{},"For instance, as your factory adds a second production line, you can add topics like:",[431,5000,5001,5006,5011],{},[306,5002,5003],{},[22,5004,5005],{},"\u002Ffactory\u002Fline2\u002Fmachine1\u002Ftemperature",[306,5007,5008],{},[22,5009,5010],{},"\u002Ffactory\u002Fline2\u002Fmachine1\u002Fvibration",[306,5012,5013],{},[22,5014,5015],{},"\u002Ffactory\u002Fline2\u002Fmachine2\u002Ftemperature",[15,5017,5018],{},"This hierarchical system scales seamlessly as you add more machines, sensors, and production lines without creating unnecessary complexity.",[15,5020,5021],{},"A well-structured topic hierarchy improves the performance of both the network and edge devices. When monitoring or data analysis systems subscribe to topics, they can choose the data they need. This means they are not overwhelmed by unnecessary traffic, which could otherwise strain network bandwidth and device processing power.",[15,5023,5024],{},"For example, imagine a maintenance team only needs to monitor the temperature of machines in line 1. With a clean topic structure, they can subscribe to:",[431,5026,5027,5032],{},[306,5028,5029],{},[22,5030,5031],{},"\u002Ffactory\u002Fline1\u002Fmachine1\u002Ftemperature ",[306,5033,5034],{},[22,5035,5036],{},"\u002Ffactory\u002Fline1\u002Fmachine2\u002Ftemperature",[15,5038,5039],{},"By filtering the data, they avoid receiving irrelevant data, such as vibration readings from other machines or temperatures from machines on different production lines. This reduces network load, ensures more responsive performance, and prevents overloads on edge devices.",[15,5041,5042],{},"A well-organized topic structure makes maintenance and troubleshooting much more efficient. When equipment malfunctions or a sensor starts reporting erroneous data in a smart factory, the ability to pinpoint the issue quickly is crucial. With a hierarchical topic system, you can easily trace the problem to a specific machine, sensor, or production line.",[15,5044,5045],{},"For instance, imagine a temperature sensor on machine 3 in line 2 reporting abnormal values. A topic like:",[431,5047,5048],{},[306,5049,5050],{},[22,5051,5052],{},"\u002Ffactory\u002Fline2\u002Fmachine3\u002Ftemperature",[15,5054,5055],{},"Immediately indicates the affected machine and production line. This clarity lets your team act quickly, reducing downtime and improving system reliability.",[15,5057,5058],{},"Without a clear topic structure, identifying and diagnosing problems can become time-consuming, leading to extended downtime and inefficiencies.",[15,5060,5061],{},"As new equipment, sensors, or production lines are added to the factory, a well-structured topic system helps onboard new engineers, technicians, and operators easily. A clear hierarchy provides a visual map of the system, making it easier for new users to understand the architecture and begin working with it quickly.",[37,5063,5065],{"id":5064},"designing-a-topic-structure-for-your-uns","Designing a Topic Structure for Your UNS",[15,5067,5068],{},"Before you start collecting data in your UNS, it’s essential to design your topic structure. While it might seem like a small step, it’s the foundation of your system. Taking the time to plan will save you significant time and effort down the road. More importantly, it gives you a clear, high-level view of your entire factory, which is crucial for scaling effectively.",[15,5070,5071],{},"First, think about the key components of your factory. For example, you might have different plants or production lines in a manufacturing setting. There will be machines or devices within each production line that produce data. Then, you’ll have various data points coming from sensors on these machines, such as temperature, humidity, or pressure.",[15,5073,5074],{},"By organizing your topics around these components, you’re setting up a structure that’s easy to scale.",[15,5076,5077],{},"Next, remember that MQTT topics are hierarchical, so think of them like a tree. At the top of the tree, you’ll have the broadest categories (like plants or regions). As you go down, you’ll get more specific, with production lines, machines, and then individual data points like sensor readings. The key is to keep things logical so that you can locate the data you need quickly. This organization lets you promptly expand your system later by adding new plants, lines, or machines without disrupting the entire structure.",[15,5079,5080],{},"The concept of structuring topics logically and hierarchically draws from a well-known framework in manufacturing: ISA-95. ISA-95 is a standard that defines a hierarchical model for organizing and managing manufacturing systems. It divides operations from the company level to individual machines, providing a clear structure for system management.",[15,5082,5083,5087],{},[489,5084],{"alt":5085,"dataZoomable":369,"src":5086},"ISA-95 Equipment Hierarchy Model","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Fisa-95-equipement-model.png",[1235,5088,5085],{},[15,5090,5091],{},"Here’s a brief breakdown of the ISA-95 levels and how they can be translated to MQTT topics:",[431,5093,5094],{},[306,5095,5096],{},[309,5097,5098],{},"Level 0 – Physical Devices and Control",[15,5100,5101],{},"This is where the physical data originates: sensors, actuators, and devices directly interacting with machinery and production lines. These are typically represented as devices in your MQTT topic structure.",[15,5103,5104],{},"Example Topics:",[431,5106,5107,5112,5117],{},[306,5108,5109],{},[22,5110,5111],{},"\u002FplantA\u002FproductionLine1\u002FmachineB\u002Fsensor\u002Ftemperature",[306,5113,5114],{},[22,5115,5116],{},"\u002FplantA\u002FproductionLine1\u002FmachineB\u002Fsensor\u002Fpressure",[306,5118,5119],{},[22,5120,5121],{},"\u002FplantA\u002FproductionLine2\u002FmachineC\u002Fsensor\u002Fhumidity",[15,5123,5124],{},"At this level, you're dealing with specific machines and sensors. The topic name clearly defines the device type (e.g., \"sensor\") and the type of data it generates (e.g., \"temperature\"). This structure makes tracking sensor data easy for each machine or production line.",[431,5126,5127],{},[306,5128,5129],{},[309,5130,5131],{},"Level 1 – Control Devices and Systems",[15,5133,5134],{},"This level represents the control systems that operate the machinery and manage the data flow. These systems include PLCs, SCADA systems, or other control devices that manage real-time operations.",[15,5136,5104],{},[431,5138,5139,5144,5149],{},[306,5140,5141],{},[22,5142,5143],{},"\u002FplantA\u002FproductionLine1\u002FmachineB\u002FPLC\u002Fstatus",[306,5145,5146],{},[22,5147,5148],{},"\u002FplantA\u002FproductionLine1\u002FmachineB\u002FPLC\u002Fmode",[306,5150,5151],{},[22,5152,5153],{},"\u002FplantA\u002FproductionLine2\u002FmachineC\u002FSCADA\u002Falerts",[15,5155,5156],{},"Topics at this level might focus on the status and control functions of the machines. Separating control systems like PLCs or SCADA ensures that operational data (e.g., machine modes or alerts) is distinct from raw sensor data. This approach ensures that each system component can be monitored and managed independently.",[431,5158,5159],{},[306,5160,5161],{},[309,5162,5163],{},"Level 2 – Monitoring and Supervisory Control",[15,5165,5166],{},"At this level, systems monitor and manage operations. They might include higher-level systems that oversee the production lines, collect data from multiple PLCs, and trigger alerts or analyses based on predefined criteria.",[15,5168,5104],{},[431,5170,5171,5176,5181],{},[306,5172,5173],{},[22,5174,5175],{},"\u002FplantA\u002FproductionLine1\u002Fsupervisor\u002Falerts",[306,5177,5178],{},[22,5179,5180],{},"\u002FplantA\u002FproductionLine1\u002Fsupervisor\u002Fperformance",[306,5182,5183],{},[22,5184,5185],{},"\u002FplantA\u002FproductionLine2\u002Fsupervisor\u002Futilization",[15,5187,5188],{},"Here, you might aggregate data from several control devices (like PLCs) and provide higher-level insight into the overall system. For example, a \"performance\" topic could aggregate sensor data to monitor the efficiency of a production line, while \"alerts\" might be used for system-wide warnings.",[431,5190,5191],{},[306,5192,5193],{},[309,5194,5195],{},"Level 3 – Manufacturing Operations Management",[15,5197,5198],{},"This level encompasses managing the overall production process, such as scheduling, production orders, and resource management. This is often where MES (Manufacturing Execution Systems) comes into play.",[15,5200,5104],{},[431,5202,5203,5208,5213],{},[306,5204,5205],{},[22,5206,5207],{},"\u002FplantA\u002FproductionLine1\u002FMES\u002FproductionOrder",[306,5209,5210],{},[22,5211,5212],{},"\u002FplantA\u002FproductionLine2\u002FMES\u002Fscheduling",[306,5214,5215],{},[22,5216,5217],{},"\u002FplantB\u002FproductionLine1\u002FMES\u002FinventoryStatus",[15,5219,5220],{},"The data becomes more abstract at this level as you deal with business logic, production orders, and scheduling systems. For example, the \"productionOrder\" topic could track orders for specific products, while \"inventoryStatus\" could provide data on material availability for each production line.",[431,5222,5223],{},[306,5224,5225],{},[309,5226,5227],{},"Level 4 – Enterprise Resource Planning (ERP)",[15,5229,5230],{},"The highest level in the ISA-95 hierarchy is focused on enterprise-wide resource planning, financials, and decision-making processes. ERP systems integrate with manufacturing systems to provide broader business insights.",[15,5232,5104],{},[431,5234,5235,5240,5245],{},[306,5236,5237],{},[22,5238,5239],{},"\u002Fenterprise\u002FERP\u002Finventory\u002Foverview",[306,5241,5242],{},[22,5243,5244],{},"\u002Fenterprise\u002FERP\u002Fsales\u002Forders",[306,5246,5247],{},[22,5248,5249],{},"\u002Fenterprise\u002FERP\u002Fproduction\u002Fmetrics",[15,5251,5252],{},"At the ERP level, topics reflect cross-plant business data like inventory, order management, or performance metrics. These are less granular than lower levels and provide decision-makers with high-level insights into the health of the overall business.",[37,5254,5256],{"id":5255},"best-practices-for-managing-your-topic-structure","Best Practices for Managing Your Topic Structure",[15,5258,5259],{},"As your UNS scales, following some essential best practices will ensure your topic structure remains efficient, secure, and easy to manage.",[303,5261,5262],{},[306,5263,5264],{},"Maintain Clear Documentation:",[15,5266,5267],{},"First and foremost, maintaining clear documentation is key. A well-documented topic hierarchy is a reference point for everyone involved in the system, from developers and engineers to system administrators. This documentation should outline the naming conventions, the purpose of each topic, and how new issues should be added. Without it, there's a risk of inconsistency creeping into your system, especially as new data streams and devices are introduced. An apparent, organized reference ensures your team can efficiently navigate and expand the system without confusion.",[303,5269,5270],{"start":373},[306,5271,5272],{},"Ensuring Consistency in Naming and Structure:",[15,5274,5275],{},"Using clear, descriptive names for each topic and sticking to a consistent naming pattern across your system is essential for long-term success. A well-defined naming convention ensures that everyone involved, whether developers, engineers, or system administrators, can easily understand the purpose of each topic. Navigating your UNS becomes intuitive when topics are consistently named, and troubleshooting issues is much easier.",[15,5277,5278,5279,5282,5283,5286],{},"For instance, avoid vague or overly generic names like ",[22,5280,5281],{},"\u002Fsensor1\u002Fdata",", which don’t offer much context. Instead, adopt more descriptive, hierarchical names that reflect the actual source and nature of the data, such as ",[22,5284,5285],{},"\u002FplantA\u002FproductionLine1\u002FmachineB\u002Ftemperature",". A consistent structure not only enhances system readability but also ensures scalability.",[303,5288,5289],{"start":659},[306,5290,5291],{},"Keep Topic Names Simple and Avoid Special Characters:",[15,5293,5294],{},"While it’s essential to have descriptive topic names, they should also be simple and easy to use. Long topic names can make working with your UNS quickly and efficiently harder. Also, avoid using spaces or special characters, which might cause compatibility issues with some MQTT brokers or clients.",[303,5296,5297],{"start":370},[306,5298,5299],{},"Perform Regular Topic Cleanup and Expiration:",[15,5301,5302],{},"Next, don’t overlook the importance of topic cleanup and expiration. Over time, unused or obsolete topics can accumulate, adding unnecessary complexity and overhead to the system. Left unchecked, these stale topics can lead to unwanted confusion. It’s important to regularly audit the issues in your UNS, archiving or removing those no longer needed. While some MQTT systems support automatic topic expiration, implementing manual checks as part of your routine system maintenance is still a good practice. You’ll also want to manage the use of retained messages carefully. While they can help provide the latest state to new subscribers, overuse or misuse can lead to outdated information circulating across the system. Be mindful about which topics should retain data and ensure they are updated or cleaned up regularly.",[303,5304,5305],{"start":698},[306,5306,5307],{},"Implement Robust Access Control:",[15,5309,5310],{},"Access control is essential in managing a large-scale UNS. The hierarchical structure of MQTT topics naturally supports role-based access control (RBAC), allowing you to assign permissions based on topics. This ensures users and devices only access the data they need.",[15,5312,5313],{},"For example, engineers might only need access to machine-level sensor data, while plant managers require broader visibility into performance metrics across production lines. Additionally, you can restrict which devices can publish data on specific topics, ensuring only authorized systems send critical updates.",[15,5315,5316],{},"By defining clear access rules, you enhance security, maintain data integrity, and ensure that your UNS can scale efficiently as your organization grows.",[37,5318,5320],{"id":5319},"effortless-mqtt-and-topic-management-with-flowfuse","Effortless MQTT and Topic Management with FlowFuse",[15,5322,5323],{},"FlowFuse is more than just a low-code platform; it’s a game-changer for building and scaling your UNS. By seamlessly integrating MQTT, FlowFuse empowers you to connect, manage, and scale your industrial data systems efficiently.",[15,5325,5326],{},"FlowFuse's built-in MQTT broker gives you high-performance data handling without additional infrastructure overhead. The platform also features an interface for managing MQTT clients with access control for topics and an intuitive Topic Hierarchy View, which provides a real-time, visual representation of your entire MQTT topic structure. This makes organizing, monitoring, and managing your topics easy, ensuring clarity and consistency as your system grows.",[15,5328,5329,5333],{},[489,5330],{"alt":5331,"dataZoomable":369,"src":5332},"Image showing FlowFuse topic hierarchy interface for UNS","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Fflowfuse-mqtt-topic-hierarchy-monitoring.png",[1235,5334,5331],{},[15,5336,5337],{},"What truly stands out is FlowFuse's ability to handle both legacy and modern industrial protocols, effortlessly bridging the gap between old and new systems. Whether adding new devices, integrating data streams, or scaling to thousands of devices, FlowFuse gives you the flexibility, scalability, and security you need to optimize your UNS at every step.",[15,5339,5340],{},"FlowFuse doesn’t just help you manage topics, it streamlines collaboration, enhances system performance, and accelerates your journey toward a fully integrated, future-proof UNS.",{"title":369,"searchDepth":370,"depth":370,"links":5342},[5343,5344,5345,5346],{"id":4974,"depth":373,"text":4975},{"id":5064,"depth":373,"text":5065},{"id":5255,"depth":373,"text":5256},{"id":5319,"depth":373,"text":5320},{"type":5348,"title":5349,"description":5350},"demo","See FlowFuse's Topic Hierarchy View in Action","FlowFuse gives you a built-in MQTT broker, visual topic hierarchy monitoring, and access control, everything you need to design, manage, and scale your UNS topic structure without the complexity.","2025-01-31","Learn why topic structuring is crucial for your UNS’s performance and scalability. This post explores best practices and strategies to design an effective topic hierarchy for your system.","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Funs-topic-structer.png","2025-07-23",{"excerpt":5356},{"type":12,"value":5357},[5358],[15,5359,4965],{},"\u002Fblog\u002F2025\u002F01\u002Fdesigning-topic-hierarchy-for-your-uns",{"title":4959,"description":5352},{"loc":5360},"blog\u002F2025\u002F01\u002Fdesigning-topic-hierarchy-for-your-uns","Why Topic Structuring is Key to Scaling and Optimizing Your UNS",[933,5366,402],"unified-namespace","HUDx7LtNQTbu2W8n26mQT8oX273gPhgeYbyiiVhGKjQ",{"id":5369,"title":5370,"authors":5371,"body":5372,"cta":5487,"date":5490,"description":5491,"extension":386,"image":5492,"lastUpdated":5354,"meta":5493,"navigation":394,"path":5501,"seo":5502,"sitemap":5503,"stem":5504,"subtitle":5505,"tags":5506,"tldr":3,"video":3,"__hash__":5508},"blog\u002Fblog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns-part-2.md","MQTT: The Frontrunner for Your UNS Broker - Part 2",[10],{"type":12,"value":5373,"toc":5481},[5374,5381,5385,5388,5391,5394,5397,5406,5410,5413,5416,5419,5423,5426,5443,5446,5449,5453,5456,5464,5469,5472,5475,5478],[15,5375,5376,5377,5380],{},"In ",[172,5378,5379],{"href":4981},"Part 1",", we discussed the  reasons behind MQTT's popularity as a choice for Unified Namespace (UNS) implementations; focusing on its lightweight design, low latency, and reliable message delivery. In this second part, we’ll explore additional factors that further establish MQTT as the leading protocol for UNS brokers, diving into its connectivity, scalability, structured topic management.",[37,5382,5384],{"id":5383},"wide-connectivity","Wide Connectivity",[15,5386,5387],{},"For your UNS to be truly effective, it must be able to connect seamlessly with every part of your IIoT environment, whether it’s a device or the cloud. MQTT is an excellent protocol for this because it’s widely adopted in both cloud-based systems and industrial environments.",[15,5389,5390],{},"In a typical industrial data architecture, you typically have a mix of physical devices (like sensors and machines) and cloud systems. To make real-time decisions, data needs to flow seamlessly from the shop floor to the cloud. MQTT excels at connecting modern devices with the cloud. However, one challenge is that it doesn’t natively support older systems that typically use protocols like OPC UA or MODBUS.",[15,5392,5393],{},"This isn’t a major issue, though. You can bridge the gap using tools like FlowFuse and Node-RED, which allow MQTT to communicate with older systems.",[15,5395,5396],{},"Overall, MQTT has better compatibility than many other protocols. Some other protocols may offer better compatibility, but they can hardly surpass MQTT in meeting the core requirements of a UNS.",[15,5398,5399,5403,5404],{},[489,5400],{"alt":5401,"dataZoomable":369,"src":5402},"MQTT's Compatibility","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Fmqtt-compatiblity.png","{width=\"550px\"}\n",[1235,5405,5401],{},[37,5407,5409],{"id":5408},"easily-scalable","Easily Scalable",[15,5411,5412],{},"A UNS broker needs to be able to grow as your factory or system expands. What starts with just a few sensors or devices might quickly scale up to hundreds or thousands over time. Can MQTT handle this growth? Absolutely.",[15,5414,5415],{},"MQTT's lightweight architecture, based on a simple publish-subscribe model, makes it easy to scale. Adding new devices doesn’t disrupt existing operations. The system can handle thousands of devices and connections without performance issues. As your network grows, new devices can easily connect to the broker and start exchanging data without major changes to the infrastructure.",[15,5417,5418],{},"MQTT brokers handle large volumes of data and can distribute messages to many clients at once. This ensures that as more devices are added, the system remains stable. The broker can also scale horizontally, meaning you can add more brokers or resources to handle the increased load, without affecting the performance or reliability of the system.",[37,5420,5422],{"id":5421},"semantic-hierarchy-with-topics","Semantic Hierarchy with Topics",[15,5424,5425],{},"When setting up a UNS, it’s not just about collecting all your data in one place, it’s about organizing it so that it’s easy to navigate. A semantic hierarchy helps do this by arranging data from broad categories down to more specific details. For example, in a factory, you might have levels like factory, area, line, and machine, with data points like temperature or humidity at the bottom. This is similar to how files are organized in folders, making it simple to find what you need.",[15,5427,5428,5429,5432,5433,5435,5436,5438,5439,5442],{},"MQTT works well for this kind of organization because its topics are already structured in a hierarchical way. Topics in MQTT are like paths that break down data into different levels, such as ",[22,5430,5431],{},"factory\u002Farea-2\u002Fline-1\u002Fmachine-5\u002Ftemperature",". You can easily follow these paths to find the exact data you need. Furthermore, MQTT supports wildcard characters, which offer flexibility for subscriptions. The # wildcard matches all levels beneath a given level, so a subscription to ",[22,5434,1761],{}," will match any topic under the \"factory\" level, regardless of how deep the path goes. Similarly, the ",[22,5437,1773],{}," wildcard matches only a single level, so ",[22,5440,5441],{},"factory\u002F+\u002Fline-1\u002Fmachine-5\u002Ftemperature"," will match any topic that follows the same structure but with different areas.",[15,5444,5445],{},"While  AMQP and Kafka also support topics and wildcards, they handle them differently. AMQP uses routing keys for message routing rather than a direct hierarchical topic structure like MQTT. Though AMQP has a topic exchange for routing based on patterns (similar to topics), it doesn’t provide the same natural hierarchical organization. Kafka, on the other hand, uses a flat topic model without a hierarchy, which can make it more difficult to maintain clarity and structure as the system grows in complexity. While both AMQP and Kafka can still be used in a UNS, their lack of a natural topic hierarchy makes them more challenging manage compared to MQTT, which provides a simpler, more intuitive way to organize and access data.",[15,5447,5448],{},"In conclusion, MQTT is an excellent choice for your UNS broker because it offers simplicity, scalability, and efficient data organization. Its lightweight design ensures smooth performance as your system grows, while the publish-subscribe  model decouples producers and consumers, allowing them to operate independently. This reduces direct dependencies between devices and systems, making the overall architecture more flexible and easier to scale. MQTT’s hierarchical topic structure further simplifies data management and access. Compared to other options like AMQP and Kafka, MQTT provides a more intuitive, reliable, and scalable and most importantly simple solution for building a Unified Namespace that can adapt to future needs.",[37,5450,5452],{"id":5451},"build-your-uns-with-flowfuse-now","Build Your UNS with FlowFuse Now",[15,5454,5455],{},"Now that you understand why MQTT is the best choice for your UNS, it’s time to build it. FlowFuse is the ideal platform for implementing your UNS with MQTT.",[15,5457,5458,5459,5463],{},"Please read our article: ",[172,5460,5462],{"href":5461},"\u002Fblog\u002F2024\u002F11\u002Fbuilding-uns-with-flowfuse\u002F","Building Your UNS with FlowFuse"," where I show you how to build it quickly, just in 15 minutes!",[15,5465,5466],{},[309,5467,5468],{},"Why choose FlowFuse?",[15,5470,5471],{},"FlowFuse is an industrial data platform that leverages the power of Node-RED, a popular open-source low-code platform for industrial automation. With over 5000 community-contributed nodes, it simplifies the process of collecting, transforming, and integrating data from a wide variety of industrial hardware and services, supporting nearly all industrial protocols. This means you have nearly everything you need to implement a UNS, all you need is the MQTT broker service.",[15,5473,5474],{},"Good news! Recently, FlowFuse has added a built-in MQTT broker service within the platform, making it even easier to manage your MQTT connections. This includes an interface for securely managing MQTT clients and, most importantly, a comprehensive topic hierarchy monitoring tool that’s ideal for managing your UNS.",[15,5476,5477],{},"FlowFuse not only allows you to build and manage your UNS, but also provides a collaborative environment where teams can work in real time. It offers scalability, security, and ease of use, making it simple to grow your system as your needs evolve.",[15,5479,5480],{},"With FlowFuse, you get everything you need to handle data pipelines, implement a UNS, and scale efficiently, all within a single platform.",{"title":369,"searchDepth":370,"depth":370,"links":5482},[5483,5484,5485,5486],{"id":5383,"depth":373,"text":5384},{"id":5408,"depth":373,"text":5409},{"id":5421,"depth":373,"text":5422},{"id":5451,"depth":373,"text":5452},{"type":5348,"title":5488,"description":5489},"Build Your Unified Namespace With FlowFuse","FlowFuse gives you a built-in MQTT broker, topic hierarchy monitoring, and Node-RED integration, everything you need to implement a scalable, well-organized UNS in one platform.","2025-01-13","Learn why MQTT is the top choice for Unified Namespace (UNS) brokers and explore the ideal platform that simplifies the connection of devices and services while providing a reliable MQTT broker service.","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Fmqtt-for-uns-2.png",{"keywords":5494,"excerpt":5495},"mqtt unified namespace, why use mqtt in uns, mqtt in a unified namespace, mqtt data modeling UNS, Best protocols for UNS IoT, Implementing UNS with MQTT, Unified Namespace protocols",{"type":12,"value":5496},[5497],[15,5498,5376,5499,5380],{},[172,5500,5379],{"href":4981},"\u002Fblog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns-part-2",{"title":5370,"description":5491},{"loc":5501},"blog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns-part-2","Why MQTT is the Best Choice for Your UNS Broker",[402,5507,5366],"uns","ff9g-ynZ1Nih24pEMKHVq9khW0Y321h4usm7NHDgKuM",{"id":5510,"title":5511,"authors":5512,"body":5513,"cta":3,"date":5677,"description":5491,"extension":386,"image":5678,"lastUpdated":5354,"meta":5679,"navigation":394,"path":5685,"seo":5686,"sitemap":5687,"stem":5688,"subtitle":5505,"tags":5689,"tldr":3,"video":3,"__hash__":5690},"blog\u002Fblog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns.md","MQTT: The Frontrunner for Your UNS Broker - Part 1",[10],{"type":12,"value":5514,"toc":5670},[5515,5518,5521,5531,5545,5548,5552,5558,5564,5571,5574,5578,5581,5584,5587,5590,5597,5601,5610,5613,5616,5625,5629,5632,5635,5638,5649,5652,5655,5658],[15,5516,5517],{},"Choosing the right broker for your UNS is crucial. It must support real-time data, scale easily, and integrate seamlessly with devices and services. MQTT often comes out as the best choice for these needs.",[15,5519,5520],{},"In this first part of our series, we’ll explain why MQTT is the standout choice for UNS implementations. With its focus on lightweight, real-time messaging and robust reliability, MQTT delivers the performance IIoT environments demand, making it the perfect fit for a future-proof, scalable UNS.",[15,5522,285,5523,5527,5528,367],{},[172,5524,5526],{"href":5525},"\u002Fsolutions\u002Funs\u002F","Unified Namespace (UNS)"," is a data architecture (not just a tool or new technology) that centralizes and organizes data from various sources into a single, unified structure. It eliminates data silos by providing a standardized way to represent, access, and share information across different devices, systems, and services. For more information on what is UNS, read our article: ",[172,5529,5530],{"href":1552},"Introduction to the Unified Namespace",[15,5532,5533,5534,3084,5538,5540,5541],{},"When choosing a broker for your UNS, it's crucial to consider how well the selected broker fits the specific requirements of your IIoT environment, including the types of devices and systems involved, as well as factors like scalability, reliability, and ease of integration. Several options are available alongside MQTT, including ",[172,5535,5537],{"href":5536},"\u002Fnode-red\u002Fprotocol\u002Famqp\u002F","AMQP",[172,5539,1974],{"href":1973},", and cloud message brokers like AWS Kinesis and GCP Pub\u002FSub. While these alternatives offer unique features, MQTT stands out, and we’ll explain why later in this article. But If you’re interested in a brief overview of why these alternatives are not the best fit for UNS, check out our article: ",[172,5542,5544],{"href":5543},"\u002Fblog\u002F2024\u002F01\u002Funified-namespace-what-broker\u002F","Unified Namespace: What Broker to Use?",[15,5546,5547],{},"There is also an ongoing debate regarding the use of OPC-UA and other protocols for implementing UNS. While I won’t dive into this in detail here as i havent explored it much yet, I encourage you to start with the approach we call reverse engineering. First, understand why MQTT is the preferred choice for implementing UNS, and then explore how its features align with UNS needs. From there, you can evaluate whether other protocols offer similar capabilities. By following this process, you will find the right answer of your questions.",[37,5549,5551],{"id":5550},"background-of-mqtt","Background of MQTT",[15,5553,5554,5555,5557],{},"Before diving into its specific advantages for UNS, let’s take a brief look at the history of ",[309,5556,1648],{}," and how it became the backbone of modern IoT communication.",[15,5559,5560,5563],{},[172,5561,1648],{"href":5562},"\u002Fnode-red\u002Fprotocol\u002Fmqtt\u002F"," was developed in the late 1990s by Andy Stanford-Clark at IBM and Arlen Nipper at Eurotech to address communication challenges in low-bandwidth, unreliable networks. This early focus on lightweight messaging paved the way for MQTT to become a pioneering solution for the rapidly expanding IoT space.",[15,5565,5566,5567,5570],{},"Since then, MQTT has evolved significantly. The protocol has gone through several iterations, from MQTT 3.1.1 to the more feature-rich MQTT 5.0, each version enhancing the protocol's capabilities to meet the demands of an increasingly connected world. Today, more than 25 years later, MQTT remains the ",[309,5568,5569],{},"de facto protocol"," for IoT applications, and its simplicity, scalability, and reliability continue to make it an ideal choice for industrial systems.",[15,5572,5573],{},"But, what exactly makes MQTT the frontrunner for UNS implementations? Let's take a deeper look at some of its key features?",[37,5575,5577],{"id":5576},"publish-subscribe-model-and-event-driven-architecture","Publish-Subscribe Model and Event-Driven Architecture",[15,5579,5580],{},"One of the standout features of MQTT is its publish-subscribe (Pub\u002FSub) model, which is the primary need of an UNS. In this model, data producers (such as sensors or devices) don’t need to know who is receiving the data or how many consumers are out there. Instead, they publish their data to a central broker, and any consumer (like a monitoring system, data warehouse, or analytics engine) that is interested simply subscribes to the relevant data stream.",[15,5582,5583],{},"This approach decouples producers and consumers, removing the need for direct, point-to-point connections between them. In traditional systems, every device would need to know about every other device it communicates with, leading to a messy, tightly coupled network. As your IIoT ecosystem grows, managing these connections becomes increasingly difficult and prone to error. But with MQTT’s Pub\u002FSub model, adding new devices or services is seamless and doesn’t disrupt existing data flows.",[15,5585,5586],{},"Beyond this, MQTT’s event-driven architecture takes the system to a whole new level of efficiency and responsiveness. Imagine a scenario where a machine detects an issue, rather than waiting for a periodic check-in, the event is immediately sent to the right consumer, triggering an alert in real time. This push mechanism is far more efficient than traditional polling, where systems continuously ask, “Is there new data yet?” and waste precious resources in the process.",[15,5588,5589],{},"With MQTT, data is pushed as soon as it’s available, enabling faster decision-making and real-time responses. This means events like machine faults or environmental changes are addressed immediately, making the Our UNS more agile, responsive, and capable of scaling as needed which is one of priamary need of IIoT environemnt.",[15,5591,5592,5593,367],{},"If you’d like to understand the importance of Publish-Subscribe (Pub\u002FSub) architecture in detail for UNS, I highly recommend reading our article: ",[172,5594,5596],{"href":5595},"\u002Fblog\u002F2024\u002F11\u002Fwhy-pub-sub-in-uns\u002F","Why UNS Needs Pub\u002FSub",[494,5598,5600],{"id":5599},"low-latency-and-lightweight-messaging","Low Latency and Lightweight Messaging",[15,5602,5603,5604,5609],{},"Downtime in industrial operations can be very costly, ranging from $15,000 to $20,000 per minute or more. For engineers and operators watching over machines, waiting for data can mean the difference between smooth operations and expensive disruptions,  If you're interested in learning more about downtime, read this research by Siemens from 2022: ",[172,5605,5608],{"href":5606,"rel":5607},"https:\u002F\u002Fassets.new.siemens.com\u002Fsiemens\u002Fassets\u002Fapi\u002Fuuid:3d606495-dbe0-43e4-80b1-d04e27ada920\u002Fdics-b10153-00-7600truecostofdowntime2022-144.pdf",[176],"True Cost of Downtime 2022",". Low-latency messaging is key in these situations, which is why data architectures like UNS are being explored to make sure systems and devices in your IIoT setup communicate without delays. MQTT is the protocol that makes this possible.",[15,5611,5612],{},"As we explored, MQTT uses a publish-subscribe model, which is built for real-time communication with minimal delay. Unlike traditional request-response systems that can cause delays due to constant querying, MQTT keeps a persistent connection open. Once a device connects, it can immediately send data or receive updates on important topics, cutting out the need for repeated requests and making sure data flows instantly. This helps engineers make decisions and take action faster.",[15,5614,5615],{},"In addition to being fast, MQTT is very efficient. Its messages are small and use little bandwidth, important when working with low-bandwidth networks or many connected devices. Even with limited resources, MQTT allows devices to send data without overwhelming the system. The result? As soon as a sensor detects a change, like a temperature spike or a production issue, it can send the information right away to the right system, triggering immediate actions to avoid costly downtime.",[15,5617,5618,5622,5623],{},[489,5619],{"alt":5620,"src":5621},"MQTT Packet Structer","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Fmqtt-packate-size.png","  ",[1235,5624,5620],{},[494,5626,5628],{"id":5627},"reliability","Reliability",[15,5630,5631],{},"When it comes to building a UNS, reliability is absolutely crucial. Missing or duplicate data can lead to poor decision-making, system malfunctions, or even costly downtime, things no one wants in their IIoT environment.",[15,5633,5634],{},"This is where MQTT truly shines. It’s built with a Quality of Service (QoS) mechanism that allows you to control how reliably your messages are delivered. Depending on the level you choose, you can ensure that data is delivered exactly as you need it, without compromising on system performance.",[15,5636,5637],{},"MQTT offers three levels of QoS to suit different use cases:",[431,5639,5640,5643,5646],{},[306,5641,5642],{},"QoS 0 - \"At most once\": The message is delivered once and isn’t acknowledged. This is fine for non-critical data where the occasional loss of a message is acceptable.",[306,5644,5645],{},"QoS 1 - \"At least once\": The message is delivered at least once, with an acknowledgment to ensure it was received. This is ideal for most IIoT applications, where you need reliable delivery, but duplicate messages are not a major concern.",[306,5647,5648],{},"QoS 2 - \"Exactly once\": This guarantees the message is delivered exactly once, no duplicates, no omissions. It's the best choice for mission-critical applications where data integrity is paramount.",[15,5650,5651],{},"Now, some other protocols like AMQP or Kafka also provide reliability guarantees, but they tend to be more complex and come with heavier infrastructure requirements. MQTT, on the other hand, offers a simple and lightweight design while still giving you just the right level of reliability for most IIoT scenarios. You can scale your network with ease, all while maintaining a high standard of reliability in your data flows.",[15,5653,5654],{},"MQTT is the ideal broker for a UNS in IIoT environments, offering real-time, low-latency communication through its Publish-Subscribe model. With Quality of Service (QoS) options for reliable data delivery, it balances performance, scalability, and simplicity. MQTT’s lightweight design makes it perfect for handling large-scale, mission-critical data flows without the complexity of heavier protocols.",[15,5656,5657],{},"In Part 2, we will explore MQTT's scalability, topic organization, and wide connectivity providing even more compelling reasons why it is the ultimate choice for UNS brokers.",[15,5659,5660,5661,5664,5665,5669],{},"If you're looking to build your own UNS with MQTT, check out our step-by-step ",[172,5662,5663],{"href":5461},"Article on Building UNS with FlowFuse",". Plus, we've made it even easier by offering a built-in MQTT broker service within the FlowFuse Platform, allowing you to manage all your MQTT clients, devices, services, and data from a single, centralized interface. Check it out ",[172,5666,5668],{"href":5667},"\u002Fblog\u002F2024\u002F10\u002Fannouncement-mqtt-broker\u002F?utm_campaign=60718323-BCTA&utm_source=blog&utm_medium=cta%20mqtt%20announcement&utm_term=high_intent&utm_content=MQTT%3A%20The%20Frontrunner%20for%20Your%20UNS%20Broker%20-%20Part%201","here","!",{"title":369,"searchDepth":370,"depth":370,"links":5671},[5672,5673],{"id":5550,"depth":373,"text":5551},{"id":5576,"depth":373,"text":5577,"children":5674},[5675,5676],{"id":5599,"depth":659,"text":5600},{"id":5627,"depth":659,"text":5628},"2025-01-07","\u002Fblog\u002F2025\u002F01\u002Fimages\u002Fmqtt-for-uns-1.png",{"keywords":5680,"excerpt":5681},"mqtt unified namespace, why use mqtt in uns, mqtt in a unified namespace, mqtt data modeling UNS, best protocols for UNS IoT, implementing UNS with MQTT, unified namespace protocols",{"type":12,"value":5682},[5683],[15,5684,5517],{},"\u002Fblog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns",{"title":5511,"description":5491},{"loc":5685},"blog\u002F2025\u002F01\u002Fmqtt-frontrunner-for-uns",[402,5507,5366],"Y1cWGaxxPTIcSK1TGhANrUwVCH49YigYQlWUDfCWniQ",{"id":5692,"title":5693,"authors":5694,"body":5695,"cta":6385,"date":6388,"description":6389,"extension":386,"image":6390,"lastUpdated":5354,"meta":6391,"navigation":394,"path":6399,"seo":6400,"sitemap":6401,"stem":6402,"subtitle":6403,"tags":6404,"tldr":3,"video":3,"__hash__":6405},"blog\u002Fblog\u002F2024\u002F11\u002Fbuilding-uns-with-flowfuse.md","Building a Unified Namespace (UNS) with FlowFuse",[10],{"type":12,"value":5696,"toc":6373},[5697,5703,5709,5712,5716,5719,5723,5726,5729,5732,5751,5755,5758,5763,5783,5787,5790,5828,5835,5843,5846,5905,5908,5916,5923,5995,5998,6003,6013,6021,6024,6108,6121,6125,6133,6138,6184,6189,6194,6202,6206,6209,6215,6218,6226,6229,6232,6237,6242,6254,6259,6262,6266,6274,6282,6292,6300,6305,6316,6324,6329,6335,6338,6346,6349,6357,6365,6367,6370],[15,5698,5699,5700,5702],{},"As systems and devices become more connected, managing data from different sources can be tricky. A ",[172,5701,5526],{"href":5525}," solves this by centralizing all your data in one place, making it easy to access and use.",[15,5704,5705,5708],{},[172,5706,5707],{"href":423},"FlowFuse"," makes building a UNS simple. It connects old and new systems, collects data from devices and applications, and streamlines workflows. With tools like Node-RED for data flow, MQTT for real-time updates, and a central management layer, FlowFuse helps you improve efficiency and make better decisions.",[15,5710,5711],{},"This article will show you how to build your UNS using FlowFuse, step by step.",[37,5713,5715],{"id":5714},"building-a-uns-with-real-time-sensor-data","Building a UNS with Real-Time Sensor Data",[15,5717,5718],{},"This section explains how to set up a Unified Namespace (UNS) using FlowFuse, a Raspberry Pi, and an ADXL345 sensor. The Raspberry Pi collects data from the sensor, which we collect and process in Node-RED, calculate vibration magnitude, format it, and send it to the UNS using standardized topic names.",[494,5720,5722],{"id":5721},"step-1-collect-metrics-from-devices","Step 1: Collect Metrics from Devices",[15,5724,5725],{},"The first step in building your UNS is collecting data from your devices. The method you choose will depend on the type of device and the communication protocol it supports. For example, many devices use traditional communication standards like Modbus, while others, such as industrial controllers, might rely on OPC-UA.",[15,5727,5728],{},"Fortunately, Node-RED provides support for a wide range of industrial protocols, from legacy to modern ones. While older protocols like Modbus and OPC-UA were originally designed for machine-to-machine (M2M) communication and are not directly compatible with cloud systems, Node-RED acts as a bridge to overcome this limitation.",[15,5730,5731],{},"By leveraging Node-RED, you can collect data from these legacy systems, process and transform the data using low-code workflows, and then seamlessly send it to the cloud via modern protocols such as MQTT, Kafka, AMQP, and more.",[15,5733,5734,5735,5740,5741,5745,5746,5750],{},"In our example, Node-RED can directly collect metrics from sensor using ",[172,5736,5739],{"href":5737,"rel":5738},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002Fnode-red-contrib-i2c",[176],"I2C"," on the Raspberry Pi. This approach simplifies the process by eliminating the need for additional communication layers. To run Node-RED on the Raspberry Pi, we use ",[172,5742,5744],{"href":5743},"\u002Fplatform\u002Fdevice-agent\u002F","FlowFuse Device Agent",", This agent enables you to remotely monitor, manage, and build Node-RED flows securely through the FlowFuse platform remotely. ",[172,5747,5749],{"href":5748},"\u002Fnode-red\u002Fhardware\u002F","See here"," for more details on how to set up and run FlowFuse Device Agent on different devices.",[494,5752,5754],{"id":5753},"step-2-transform-and-process-the-collected-metrics","Step 2: Transform and Process the Collected metrics",[15,5756,5757],{},"Once you've collected data from your devices, the next step is to transform it using Node-RED. Industrial systems often use different protocols such as Modbus and OPC UA, and each might have its own data structure, which can create challenges for integration. For example, the ADXL345 sensor which we are uisng in our practile example outputs raw data as electrical signals (buffer data). We first need to format it into a human-readable format and then calculate the Magnitude, a standard vibration monitoring unit.",[15,5759,5760],{},[309,5761,5762],{},"Why Data Transformation Matters:",[431,5764,5765,5771,5777],{},[306,5766,5767,5770],{},[309,5768,5769],{},"Consistency",": Ensures data from different sources follows the same structure.",[306,5772,5773,5776],{},[309,5774,5775],{},"Integration",": It makes integrating data from various systems easier.",[306,5778,5779,5782],{},[309,5780,5781],{},"Speed",": Simplifies data access for faster insights and decision-making.",[2434,5784,5786],{"id":5785},"example-transforming-data-from-adxl345-sensor-raspberry-pi","Example: Transforming Data from ADXL345 Sensor (Raspberry Pi)",[15,5788,5789],{},"Raw data from the ADXL345 sensor might look like this:",[619,5791,5793],{"className":621,"code":5792,"language":623,"meta":369,"style":369},"[26,0,244,255,37,255]  \n",[22,5794,5795],{"__ignoreMap":369},[627,5796,5797,5799,5802,5804,5806,5808,5811,5813,5816,5818,5821,5823,5825],{"class":629,"line":630},[627,5798,2357],{"class":633},[627,5800,5801],{"class":652},"26",[627,5803,2932],{"class":633},[627,5805,2099],{"class":652},[627,5807,2932],{"class":633},[627,5809,5810],{"class":652},"244",[627,5812,2932],{"class":633},[627,5814,5815],{"class":652},"255",[627,5817,2932],{"class":633},[627,5819,5820],{"class":652},"37",[627,5822,2932],{"class":633},[627,5824,5815],{"class":652},[627,5826,5827],{"class":633},"]\n",[15,5829,5830,5831,5834],{},"Using a ",[172,5832,2258],{"href":5833},"\u002Fnode-red\u002Fcore-nodes\u002Ffunction\u002F"," in Node-RED, we can convert this into a human-readable format.",[15,5836,5837,5841],{},[489,5838],{"alt":5839,"dataZoomable":369,"src":5840},"Function node: Transforming Raw Data into Readable Format","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Ffunction-node.png",[1235,5842,5839],{},[15,5844,5845],{},"After transformation, the data will look as shown below.",[619,5847,5849],{"className":621,"code":5848,"language":623,"meta":369,"style":369},"{\n    \"x\":0.09765625,\n    \"y\":-0.046875,\n    \"z\":-0.8828125\n}  \n",[22,5850,5851,5855,5871,5887,5901],{"__ignoreMap":369},[627,5852,5853],{"class":629,"line":630},[627,5854,634],{"class":633},[627,5856,5857,5859,5862,5864,5866,5869],{"class":629,"line":373},[627,5858,2467],{"class":633},[627,5860,5861],{"class":642},"x",[627,5863,646],{"class":633},[627,5865,649],{"class":633},[627,5867,5868],{"class":652},"0.09765625",[627,5870,656],{"class":633},[627,5872,5873,5875,5878,5880,5882,5885],{"class":629,"line":659},[627,5874,2467],{"class":633},[627,5876,5877],{"class":642},"y",[627,5879,646],{"class":633},[627,5881,649],{"class":633},[627,5883,5884],{"class":652},"-0.046875",[627,5886,656],{"class":633},[627,5888,5889,5891,5894,5896,5898],{"class":629,"line":370},[627,5890,2467],{"class":633},[627,5892,5893],{"class":642},"z",[627,5895,646],{"class":633},[627,5897,649],{"class":633},[627,5899,5900],{"class":652},"-0.8828125\n",[627,5902,5903],{"class":629,"line":698},[627,5904,741],{"class":633},[15,5906,5907],{},"While this is more readable, it can still be challenging to monitor changes in vibration quickly or detect anomalies. To simplify monitoring, we can calculate the Magnitude, a single metric commonly used in vibration monitoring.",[15,5909,5910,5914],{},[489,5911],{"alt":5912,"dataZoomable":369,"src":5913},"Change node: Calculating Magnitude","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fchange-node-calculating-magnitude.png",[1235,5915,5912],{},[15,5917,5918,5919,5922],{},"After calculating the Magnitude using a ",[172,5920,2147],{"href":5921},"\u002Fnode-red\u002Fcore-nodes\u002Fchange\u002F",", the data might look like this:",[619,5924,5926],{"className":621,"code":5925,"language":623,"meta":369,"style":369},"{\n    \"x\":0.00390625,\n    \"y\":-0.07421875,\n    \"z\":-0.8515625,\n    \"magnitude\":0.8547996098775871\n}  \n",[22,5927,5928,5932,5947,5962,5977,5991],{"__ignoreMap":369},[627,5929,5930],{"class":629,"line":630},[627,5931,634],{"class":633},[627,5933,5934,5936,5938,5940,5942,5945],{"class":629,"line":373},[627,5935,2467],{"class":633},[627,5937,5861],{"class":642},[627,5939,646],{"class":633},[627,5941,649],{"class":633},[627,5943,5944],{"class":652},"0.00390625",[627,5946,656],{"class":633},[627,5948,5949,5951,5953,5955,5957,5960],{"class":629,"line":659},[627,5950,2467],{"class":633},[627,5952,5877],{"class":642},[627,5954,646],{"class":633},[627,5956,649],{"class":633},[627,5958,5959],{"class":652},"-0.07421875",[627,5961,656],{"class":633},[627,5963,5964,5966,5968,5970,5972,5975],{"class":629,"line":370},[627,5965,2467],{"class":633},[627,5967,5893],{"class":642},[627,5969,646],{"class":633},[627,5971,649],{"class":633},[627,5973,5974],{"class":652},"-0.8515625",[627,5976,656],{"class":633},[627,5978,5979,5981,5984,5986,5988],{"class":629,"line":698},[627,5980,2467],{"class":633},[627,5982,5983],{"class":642},"magnitude",[627,5985,646],{"class":633},[627,5987,649],{"class":633},[627,5989,5990],{"class":652},"0.8547996098775871\n",[627,5992,5993],{"class":629,"line":564},[627,5994,741],{"class":633},[15,5996,5997],{},"Now, the data is easier to monitor with a single metric (Magnitude), but this structure is still not optimal for a UNS. We need to transform it further to provide more context.",[15,5999,6000],{},[309,6001,6002],{},"Enhanced Data Structure for UNS:",[15,6004,6005,6006,3084,6008,3084,6010,6012],{},"To make the data more useful for integration and interpretation in a UNS, we can transform it to include additional context, such as units and timestamps, while removing unnecessary metrics like the three-axis components (",[22,6007,5861],{},[22,6009,5877],{},[22,6011,5893],{},"). The easiest and most low-code approach for achieving this in Node-RED is to use the Change node, which is specifically designed for formatting and structuring payloads.",[15,6014,6015,6019],{},[489,6016],{"alt":6017,"dataZoomable":369,"src":6018},"Change Node: Formatting and structuring payload for UNS","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fchange-node-structering-data.png",[1235,6020,6017],{},[15,6022,6023],{},"After formatting, the data will look as shown below:",[619,6025,6027],{"className":621,"code":6026,"language":623,"meta":369,"style":369},"{\n  \"name\": \"vibration\",\n  \"timestamp\": \"2024-11-13T10:00:00Z\",\n  \"unit\": \"m\u002Fs²\",\n  \"value\": 0.8547996098775871\n}\n",[22,6028,6029,6033,6053,6072,6091,6104],{"__ignoreMap":369},[627,6030,6031],{"class":629,"line":630},[627,6032,634],{"class":633},[627,6034,6035,6037,6040,6042,6044,6046,6049,6051],{"class":629,"line":373},[627,6036,639],{"class":633},[627,6038,6039],{"class":642},"name",[627,6041,646],{"class":633},[627,6043,649],{"class":633},[627,6045,687],{"class":633},[627,6047,6048],{"class":690},"vibration",[627,6050,646],{"class":633},[627,6052,656],{"class":633},[627,6054,6055,6057,6059,6061,6063,6065,6068,6070],{"class":629,"line":659},[627,6056,639],{"class":633},[627,6058,643],{"class":642},[627,6060,646],{"class":633},[627,6062,649],{"class":633},[627,6064,687],{"class":633},[627,6066,6067],{"class":690},"2024-11-13T10:00:00Z",[627,6069,646],{"class":633},[627,6071,656],{"class":633},[627,6073,6074,6076,6078,6080,6082,6084,6087,6089],{"class":629,"line":370},[627,6075,639],{"class":633},[627,6077,680],{"class":642},[627,6079,646],{"class":633},[627,6081,649],{"class":633},[627,6083,687],{"class":633},[627,6085,6086],{"class":690},"m\u002Fs²",[627,6088,646],{"class":633},[627,6090,656],{"class":633},[627,6092,6093,6095,6097,6099,6101],{"class":629,"line":698},[627,6094,639],{"class":633},[627,6096,664],{"class":642},[627,6098,646],{"class":633},[627,6100,649],{"class":633},[627,6102,6103],{"class":652}," 0.8547996098775871\n",[627,6105,6106],{"class":629,"line":564},[627,6107,741],{"class":633},[15,6109,6110,6111,3084,6113,3095,6115,6117,6118,6120],{},"This format is more structured and consistent, with important labels like ",[22,6112,664],{},[22,6114,680],{},[22,6116,643],{}," that provide meaningful context. It clarifies that the value represents the Magnitude of vibration in ",[309,6119,6086],{}," and provides the precise time when the data was collected.",[494,6122,6124],{"id":6123},"step-3-setting-up-your-uns-broker","Step 3: Setting Up Your UNS Broker",[15,6126,6127,6128,6132],{},"Now, it's time to configure your UNS broker. As mentioned, we’ll use the ",[172,6129,6131],{"href":6130},"\u002Fblog\u002F2024\u002F10\u002Fannouncement-mqtt-broker\u002F","FlowFuse MQTT Broker",". This broker is integrated within the FlowFuse platform to simplify your workflow by eliminating the need for multiple separate services. With FlowFuse, you can monitor and configure everything from a single, centralized platform. This ensures you can efficiently monitor, manage, and configure your UNS without juggling multiple tools or services.",[15,6134,6135],{},[309,6136,6137],{},"Steps to Set Up the FlowFuse MQTT Broker:",[303,6139,6140,6147,6153,6178],{},[306,6141,6142,6143,6146],{},"Log in to the FlowFuse platform and navigate to ",[309,6144,6145],{},"\"Broker\""," in the left sidebar.",[306,6148,3102,6149,6152],{},[309,6150,6151],{},"\"Create Client\""," button at the top-right corner to add a new MQTT client.",[306,6154,6155,6158,6159],{},[309,6156,6157],{},"Configure the client",":\n",[431,6160,6161,6171],{},[306,6162,6163,6164,1289,6167,6170],{},"Provide a ",[309,6165,6166],{},"Username",[309,6168,6169],{},"Password"," for secure access.",[306,6172,6173,6174,6177],{},"Define an ",[309,6175,6176],{},"Access Pattern"," to manage client permissions.",[306,6179,3794,6180,6183],{},[309,6181,6182],{},"\"Create\""," to generate the client.",[15,6185,6186],{},[1235,6187,6188],{},"Note: Enterprise-level teams can register up to 20 clients, and teams-level teams can register up to 5 clients as part of their plan. The ability to purchase additional packs of clients will come in a near future release.",[303,6190,6191],{"start":698},[306,6192,6193],{},"Copy the client ID you generated from the list and save it somewhere for later use.",[15,6195,6196,6200],{},[489,6197],{"alt":6198,"dataZoomable":369,"src":6199},"FlowFuse Interface for creating MQTT Client","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fcreating-client-interface.png",[1235,6201,6198],{},[494,6203,6205],{"id":6204},"step-4-choosing-your-topic-naming-convention","Step 4: Choosing Your Topic Naming Convention",[15,6207,6208],{},"The key to building a successful UNS is organizing your data with a clear and consistent naming convention. A well-designed convention ensures data is accessible and understandable across systems and users, simplifying communication and integration.",[15,6210,6211,6214],{},[309,6212,6213],{},"ISA-95"," is a standard for industrial systems encompassing various manufacturing and communication aspects. However, when it comes to communication, ISA-95 often relies on point-to-point (P2P) connections between systems and devices. These connections can introduce complexity, delays, and other challenges.",[15,6216,6217],{},"While we are building a UNS to address the problems and limitations we observed with point-to-point communication, we can still leverage key elements of ISA-95 that remain valuable for improving production efficiency. One of the central aspects of ISA-95 is its equipment hierarchical model, which links various layers of a factory, from physical devices to enterprise systems. By adapting this model to your data architecture, you can simplify data access and management across the entire system.",[15,6219,6220,6224],{},[489,6221],{"alt":6222,"dataZoomable":369,"src":6223},"ISA-95 : Equipment Hierarchical Model","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fisa-95-equipement-model.png",[1235,6225,6222],{},[15,6227,6228],{},"For example, following an ISA-95-based equipment hierarchy to define your topic naming convention allows you to access data from devices, sensors, or any other source without knowing their specific addresses or tags, such as for a PLC. With clarity and ease, this logical structure enables you to retrieve relevant information from different system layers (e.g., from control systems to MES or ERP).",[15,6230,6231],{},"Example topic structure based on ISA-95 equipment model hierarchy:",[15,6233,6234],{},[22,6235,6236],{},"Plant1\u002FArea3\u002FLine4\u002FCell2\u002FDeviceA",[15,6238,6239],{},[22,6240,6241],{},"Plant1\u002FArea4\u002FLine5\u002FCell6\u002FDeviceB",[15,6243,6244,6245,6249,6250,6253],{},"You can also use the ",[172,6246,6247],{"href":1657},[309,6248,58],{}," naming convention for MQTT topics, which offers a structured hierarchy and standard. However, the Sparkplug B convention has some limitations in terms of flexibility. A typical ",[309,6251,6252],{},"Sparkplug B topic"," follows this structure:",[15,6255,6256],{},[22,6257,6258],{},"spBv1.0\u002F{groupID}\u002F{edgeNodeID}\u002F{deviceID}\u002F{messageType}",[15,6260,6261],{},"While Sparkplug B provides a standardized topic model, its hierarchy may not always suit the specific needs of your architecture. Alternative methods, such as the Paris and Schultz models, help address these limitations with Sparkplug B topics. However, to keep things simple and avoid unnecessary complexity, we will use plain MQTT with the ISA-95 hierarchy.",[494,6263,6265],{"id":6264},"step-5-sending-collected-metrics-to-uns","Step 5: Sending Collected metrics to UNS",[15,6267,6268,6269,6273],{},"With your topic naming convention chosen, it’s time to send the data to the UNS. In Node-RED, we will use the ",[172,6270,6272],{"href":6271},"\u002Fnode-red\u002Fcore-nodes\u002Fmqtt-in\u002F","MQTT Out"," node to send the transformed data to the broker.",[303,6275,6276,6279],{},[306,6277,6278],{},"Drag an MQTT out node into your flow.",[306,6280,6281],{},"Configure the node to connect to the FlowFuse MQTT Broker using the client credentials generated earlier.",[15,6283,6284,6287,6288,367],{},[309,6285,6286],{},"Note",": Use environment variables to secure configuration and prevent exposing credentials when sharing flows. This ensures that sensitive data remains secure and allows easy sharing without compromising security. For more details, refer to the ",[172,6289,6291],{"href":6290},"\u002Fblog\u002F2023\u002F01\u002Fenvironment-variables-in-node-red\u002F","Article: Using Environment Variables in Node-RED",[15,6293,6294,6298],{},[489,6295],{"alt":6296,"dataZoomable":369,"src":6297},"Configuring mqtt-broker-config node","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fmqtt-broker-node-config.png",[1235,6299,6296],{},[15,6301,6302,6303],{},"![Configuring mqtt-broker-config node](.\u002Fimages\u002Fmqtt-broker-config-security\n.png){data-zoomable}\n",[1235,6304,6296],{},[303,6306,6307],{"start":659},[306,6308,2638,6309,6311,6312,6315],{},[309,6310,2641],{}," using your predefined naming convention (e.g., ",[22,6313,6314],{},"Plant1\u002FArea3\u002FLine4\u002FCell2\u002FRPI1",").",[15,6317,6318,6322],{},[489,6319],{"alt":6320,"dataZoomable":369,"src":6321},"Configuring mqtt-out node","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fmqtt-out-node-config.png",[1235,6323,6320],{},[303,6325,6326],{"start":370},[306,6327,6328],{},"Connect the input of the mqtt out node to your data transformation flow and deploy the flow.",[15,6330,6331,6332],{},"For information on how to use MQTT with Node-RED, refer to ",[172,6333,6334],{"href":1647},"Using MQTT with Node-RED",[15,6336,6337],{},"After deploying, you can monitor the topic hierarchy on the FlowFuse platform by switching to the \"Hierarchy\" tab in the Broker interface.",[15,6339,6340,6344],{},[489,6341],{"alt":6342,"dataZoomable":369,"src":6343},"Monitoring your mqtt topic hierarchy within FlowFuse","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Ftopic-hierarchy.png",[1235,6345,6342],{},[15,6347,6348],{},"Once your data is in the UNS, you have a centralized, real-time view of your operations. This unified structure enables easier access, sharing, and analysis of data across systems, helping you drive better decisions, improve efficiency, and gain valuable insights to optimize your processes.",[15,6350,6351,6352,6356],{},"With real-time data access, you can create monitoring dashboards using the ",[172,6353,6355],{"href":6354},"\u002Fplatform\u002Fdashboard\u002F","FlowFuse Dashboard"," with a low-code approach, integrate with other cloud solutions, or leverage it further for enhanced analytics or automation.",[15,6358,6359,6363],{},[489,6360],{"alt":6361,"dataZoomable":369,"src":6362},"FlowFuse Dashboard Monitoring Vibrations","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fflowfuse-dashboard.png",[1235,6364,6361],{},[37,6366,884],{"id":883},[15,6368,6369],{},"FlowFuse makes building a Unified Namespace (UNS) easy by centralizing data from systems, devices, and sensors. With seamless integration of Node-RED, MQTT, and its enterprise layer, FlowFuse ensures smooth data flow, real-time insights, and efficient management. It simplifies operations, enhances productivity, and improves system interoperability, making it easy to adapt your UNS to specific needs and support real-time analytics and automation.",[898,6371,6372],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":369,"searchDepth":370,"depth":370,"links":6374},[6375,6384],{"id":5714,"depth":373,"text":5715,"children":6376},[6377,6378,6381,6382,6383],{"id":5721,"depth":659,"text":5722},{"id":5753,"depth":659,"text":5754,"children":6379},[6380],{"id":5785,"depth":370,"text":5786},{"id":6123,"depth":659,"text":6124},{"id":6204,"depth":659,"text":6205},{"id":6264,"depth":659,"text":6265},{"id":883,"depth":373,"text":884},{"type":5348,"title":6386,"description":6387},"See How FlowFuse Powers a Unified Namespace","FlowFuse brings together Node-RED, a built-in MQTT broker, and centralized device management, everything you need to connect your shop floor data into a single, real-time namespace.","2024-11-28","Discover how FlowFuse helps you build a Unified Namespace (UNS) effortlessly, streamlining industrial data sharing, improving operational efficiency, and enabling real-time insights for smarter decision-making.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fbuilding-uns-with-flowfuse.png",{"keywords":6392,"excerpt":6393},"building unified namespace using nodered, nodered uns, uns nodered",{"type":12,"value":6394},[6395],[15,6396,5699,6397,5702],{},[172,6398,5526],{"href":5525},"\u002Fblog\u002F2024\u002F11\u002Fbuilding-uns-with-flowfuse",{"title":5693,"description":6389},{"loc":6399},"blog\u002F2024\u002F11\u002Fbuilding-uns-with-flowfuse","Implement your Unified Namespace seamlessly using our low-code platform",[933,5366,402],"qoYvZg0PVWbDwn4_VVIbiF9YrxAAQ1-unI7Z3fRH0y8",{"id":6407,"title":6408,"authors":6409,"body":6410,"cta":6606,"date":6608,"description":6609,"extension":386,"image":6610,"lastUpdated":5354,"meta":6611,"navigation":394,"path":6617,"seo":6618,"sitemap":6619,"stem":6620,"subtitle":6621,"tags":6622,"tldr":3,"video":3,"__hash__":6623},"blog\u002Fblog\u002F2024\u002F11\u002Fwhy-point-to-point-connection-is-dead.md","The Death of Point-to-Point: Why You Need a Unified Namespace",[10],{"type":12,"value":6411,"toc":6594},[6412,6415,6419,6427,6430,6433,6436,6440,6443,6447,6450,6458,6461,6465,6468,6471,6475,6478,6481,6484,6488,6491,6494,6497,6501,6504,6507,6510,6513,6517,6526,6536,6539,6542,6550,6557,6562,6567,6575,6581,6587,6591],[15,6413,6414],{},"Manufacturing has changed significantly over the years, driven by new technology and the need for better communication between systems. In the past, point-to-point (P2P) connections, where devices communicate directly with each other, were the standard. However, as factories become more complex, P2P connections are no longer practical. This article explains why P2P connections are outdated and how a Unified Namespace (UNS) offers a better, more flexible solution.",[37,6416,6418],{"id":6417},"what-are-point-to-point-connections","What are Point-to-Point Connections?",[15,6420,6421,6425],{},[489,6422],{"alt":6423,"dataZoomable":369,"src":6424},"Point-to-point connection","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fp2p.png",[1235,6426,6423],{},[15,6428,6429],{},"Point-to-point (P2P) connections are direct links between two systems or devices, allowing them to communicate with each other. They can be physical, like cables, or network-based (client-server), like a machine sending data to a server.",[15,6431,6432],{},"In a P2P setup, each connection links exactly two systems. These systems could be hardware, software, or even databases, exchanging data tailored to their needs.",[15,6434,6435],{},"For example, a machine might send performance data directly to a control system, or a sensor could send real-time measurements to a monitoring device. It’s a straightforward way to get systems talking, but as the number of devices grows, it becomes increasingly complex to manage.",[37,6437,6439],{"id":6438},"why-point-to-point-connections-no-longer-work","Why Point-to-Point Connections No Longer Work",[15,6441,6442],{},"As manufacturing moves toward more modern, interconnected approaches like Industry 4.0, the limitations of point-to-point connections become more apparent. Here's why P2P connections are no longer sufficient for today’s manufacturing environments:",[494,6444,6446],{"id":6445},"_1-limited-data-sharing-visibility-and-delayed-data","1. Limited Data Sharing, Visibility, and Delayed Data",[15,6448,6449],{},"Point-to-point connections often lead to data silos, where devices or machines communicate only with their immediate hierarchy level. This isolation severely limits system-wide visibility, making it challenging to share critical data in real-time. Consequently, problems such as defective products, unexpected downtime, and the need for rework may go unnoticed until the damage is done.",[15,6451,6452,6453,367],{},"In modern manufacturing, real-time data is indispensable for maintaining operational efficiency. However, point-to-point connections introduce significant delays, as data must traverse multiple layers, control systems (Level 1), supervisory control (Level 2), manufacturing execution systems (Level 3), and finally, higher-level management systems (Level 4) as outlined in the ISA-95 model. Each additional layer compounds latency, slowing response times and postponing the detection of issues, see also our post on ",[172,6454,6457],{"href":6455,"rel":6456},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2023\u002F08\u002Fisa-95-automation-pyramid-to-unified-namespace\u002F",[176],"Why the Automation Pyramid slows you down",[15,6459,6460],{},"Without integrated, real-time data across teams, such as quality control, problems like defective parts may not be addressed promptly, leading to increased waste and customer dissatisfaction. The lack of seamless data sharing results in visibility gaps that impede decision-making, reducing the ability to act swiftly. In fast-paced environments, these delays not only hinder operational efficiency but also have a direct negative impact on profitability.",[494,6462,6464],{"id":6463},"_2-inflexibility-limiting-innovation-and-causing-downtime","2. Inflexibility, Limiting Innovation, and Causing Downtime",[15,6466,6467],{},"Point-to-point connections create a rigid and inflexible network. When new technology or equipment is added, the entire system often requires reconfiguration, leading to significant downtime. For instance, if a new machine is introduced to the production line, many connections may need to be adjusted or re-established, which can temporarily halt production.",[15,6469,6470],{},"This downtime disrupts the flow of operations and makes it harder to implement new technologies quickly, slowing down innovation. As a result, manufacturers may struggle to stay competitive, as they can't integrate advancements like automation, real-time analytics, or AI without significant delays and costly interruptions.",[494,6472,6474],{"id":6473},"_3-high-costs-over-time-and-maintenance-complexity","3. High Costs Over Time and Maintenance Complexity",[15,6476,6477],{},"At first glance, point-to-point (P2P) connections may appear to be a cost-effective and straightforward solution. However, as systems expand, the true costs and complexities become increasingly apparent. In the automation pyramid (ISA-95 model), communication occurs across multiple hierarchical levels, with field devices interacting with controllers, controllers with SCADA, and SCADA with higher-level systems such as MES and ERP.",[15,6479,6480],{},"While this layered structure can keep connections orderly, it quickly becomes a logistical nightmare when scaling. Introducing new devices often triggers a cascade of necessary updates and reconfigurations across various levels. For example, adding a new field device typically requires adjustments to the controller, followed by updates to the SCADA system, creating a ripple effect that impacts the entire system.",[15,6482,6483],{},"This ongoing need for constant reconfiguration not only drives up costs but also introduces significant complexity in maintenance. As the system grows, so does the effort and resources required to manage it, making the P2P model inefficient and prohibitively expensive in environments that demand agility, scalability, and long-term sustainability. Ultimately, the simplicity of P2P connections gives way to an increasingly cumbersome and expensive maintenance burden, undermining its initial advantages.",[494,6485,6487],{"id":6486},"_4-security-vulnerabilities","4. Security Vulnerabilities",[15,6489,6490],{},"As the number of point-to-point connections increases, so does the risk of security breaches. Each connection represents a potential vulnerability, and if one connection in the network is compromised, the entire system becomes a target for attackers.",[15,6492,6493],{},"In large manufacturing environments, securing every individual connection becomes daunting. Any new device or system can introduce additional vulnerabilities, creating more opportunities for attackers to exploit. A compromised point-to-point connection could lead to production halts, loss of sensitive data, or even physical damage to machinery.",[15,6495,6496],{},"For example, imagine a situation where a hacker gains access to a machine’s control system through a compromised point-to-point connection. The attacker could intentionally cause a malfunction, halt production, or extract confidential information. The complexity of managing security for each connection makes it difficult to maintain a secure, reliable network.",[494,6498,6500],{"id":6499},"_5-scalability-issues","5. Scalability Issues",[15,6502,6503],{},"One of the most significant drawbacks of P2P connections in manufacturing is their inability to scale efficiently. As production lines grow, so too do the number of devices, systems, and connections that must be managed. With a P2P architecture, each new device or system typically requires a direct, dedicated connection to each relevant part of the network. This creates a spaghetti network of interwoven links that becomes increasingly unwieldy and difficult to manage as the system expands.",[15,6505,6506],{},"In a traditional P2P setup, scaling the network means manually creating additional links, configuring them, and ensuring that the new connections fit seamlessly into the existing infrastructure. This process is time-consuming, error-prone, and highly resource-intensive, leading to increased complexity and longer downtimes as you scale.",[15,6508,6509],{},"When scaling a P2P network, changes made to one part of the system often trigger a ripple effect throughout the entire network. For instance, adding a new sensor may require updating the controller, the SCADA system, and even the Manufacturing Execution System (MES). This cascading need for updates across different layers of the network makes scaling more complicated and costly. Furthermore, the introduction of new devices means additional configuration and troubleshooting, often leading to disruptions in operations and extended downtimes while the new devices are integrated.",[15,6511,6512],{},"These issues compound when scaling across multiple production lines or sites, creating an increasingly complex web of p2p connections. As the number of devices grows, so does the risk of errors, network failures, and delays. This makes it difficult for manufacturers to respond to the growing demands of production while maintaining efficiency, reliability, and uptime.",[37,6514,6516],{"id":6515},"unified-namespace-the-modern-solution","Unified Namespace: The Modern Solution",[15,6518,6519,6523,6524],{},[489,6520],{"alt":6521,"dataZoomable":369,"src":6522},"Hub and Spoke Model","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fhub.png","{width=\"400px\"}\n",[1235,6525,6521],{},[15,6527,6528,6529,6532,6533,367],{},"A Unified Namespace (UNS) is a more straightforward way to connect devices and systems in a factory. Instead of having separate connections between each device, everything is connected through one central hub, which we call the ",[309,6530,6531],{},"hub-and-spoke"," model. This means devices don’t need to be directly linked to each other, making the system easier to manage and maintain; for more information on Unified Namespace, read our article: ",[172,6534,6535],{"href":1552},"Introduction to unified namespace",[15,6537,6538],{},"With a UNS, adding new devices or systems becomes straightforward. Rather than setting up multiple direct connections, like in a point-to-point system, new devices (spokes) connect to the central hub. This reduces the complexity of growing your system and eliminates downtime. If equipment is replaced or updated, only that device needs to be reconnected to the hub rather than reconfiguring the entire network.",[15,6540,6541],{},"A UNS also improves data sharing. All data is collected in one place, so any system that needs it can access it in real time. This leads to quicker decisions and faster responses to problems. With fewer connections to manage, the costs of maintaining the system are lower. Plus, the central hub makes the whole system more secure, as fewer direct connections need to be protected.",[15,6543,6544,6548],{},[489,6545],{"alt":6546,"dataZoomable":369,"src":6547},"Publish-Subscribe Archtecture","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fpub-sub.png",[1235,6549,6546],{},[15,6551,6552,6553,6556],{},"We use a ",[309,6554,6555],{},"publish-subscribe (pub\u002Fsub)"," architecture to implement a hub-and-spoke model in a UNS. In this architecture, devices, systems send data to a central broker, and other devices can subscribe to the data they need. This approach eliminates the need for a complex network of point-to-point connections, making it easier to scale, update, and maintain the system.",[15,6558,6559,6560,367],{},"This model addresses all the significant problems of point-to-point connections. For more information on how pub\u002Fsub solves these problems or why UNS needs pub\u002Fsub, read the article: ",[172,6561,5596],{"href":5595},[15,6563,6564,6566],{},[172,6565,1648],{"href":1647}," is a widely used for implementing the publish-subscribe model. It is lightweight, efficient, and works well in manufacturing environments where network reliability can be inconsistent.",[15,6568,6569,6573],{},[489,6570],{"alt":6571,"dataZoomable":369,"src":6572},"Unified Namespace","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fnr-in-uns.png",[1235,6574,6571],{},[15,6576,6577,6578,6580],{},"To simplify the creation of a UNS in your manufacturing environment, ",[172,6579,5707],{"href":423}," provides an integrated MQTT broker service. The platform makes building, scaling, and managing Node-RED solutions easy. It supports seamless connections between devices, services, and APIs using over 5,000 community-contributed nodes for data collection. FlowFuse also enables efficient data transformation and visualization with a low-code approach, remote management of edge devices, and team collaboration on projects. With everything centralized on one platform, FlowFuse offers high security, scalability, and availability to optimize and maintain your system effectively.",[15,6582,6583,6584,367],{},"Get started with this article ",[172,6585,6586],{"href":5461},"Building UNS with FlowFuse",[37,6588,6590],{"id":6589},"summary","Summary",[15,6592,6593],{},"Due to complexity, high maintenance costs, and security risks, point-to-point (P2P) connections are becoming less effective in modern factories. A Unified Namespace (UNS) solves these problems by connecting devices through a central hub, making managing, scaling, and securing systems easier. UNS improves data sharing and reduces downtime. Tools like FlowFuse make it simple to set up and manage a UNS, offering a more efficient and flexible solution for manufacturing.",{"title":369,"searchDepth":370,"depth":370,"links":6595},[6596,6597,6604,6605],{"id":6417,"depth":373,"text":6418},{"id":6438,"depth":373,"text":6439,"children":6598},[6599,6600,6601,6602,6603],{"id":6445,"depth":659,"text":6446},{"id":6463,"depth":659,"text":6464},{"id":6473,"depth":659,"text":6474},{"id":6486,"depth":659,"text":6487},{"id":6499,"depth":659,"text":6500},{"id":6515,"depth":373,"text":6516},{"id":6589,"depth":373,"text":6590},{"type":5348,"title":6386,"description":6607},"FlowFuse gives you a built-in MQTT broker, Node-RED integration, and centralized device management, everything you need to move from a spaghetti network of point-to-point connections to a clean, scalable UNS.","2024-11-26","Learn why point-to-point connections are outdated in modern manufacturing and how a Unified Namespace (UNS) simplifies system integration, enhances data sharing, and improves scalability and security.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fthe-death-of-point-to-point.png",{"keywords":6612,"excerpt":6613},"uns, cons of p2p, cons of point-to-point connection, drawbacks of point-to-point connection, publish-subscribe, mqtt",{"type":12,"value":6614},[6615],[15,6616,6414],{},"\u002Fblog\u002F2024\u002F11\u002Fwhy-point-to-point-connection-is-dead",{"title":6408,"description":6609},{"loc":6617},"blog\u002F2024\u002F11\u002Fwhy-point-to-point-connection-is-dead","Traditional Point-to-Point Connection Model is Holding Back Manufacturing Innovation - Unified Namespace (UNS) Can Transform Factory Operations",[933,402,5366],"NM9lIXp3U313XHvNQd6hAJw1jHWloSM-f8PAjjsl294",{"id":6625,"title":6626,"authors":6627,"body":6628,"cta":6812,"date":6815,"description":6816,"extension":386,"image":6817,"lastUpdated":5354,"meta":6818,"navigation":394,"path":6823,"seo":6824,"sitemap":6825,"stem":6826,"subtitle":6827,"tags":6828,"tldr":3,"video":3,"__hash__":6829},"blog\u002Fblog\u002F2024\u002F11\u002Fgetting-the-most-out-of-mqtt-for-industrial-iot.md","Getting the Most Out of MQTT for Industrial IoT",[10],{"type":12,"value":6629,"toc":6801},[6630,6633,6636,6640,6643,6646,6652,6656,6659,6662,6665,6668,6672,6675,6678,6681,6698,6701,6704,6708,6711,6714,6717,6720,6723,6727,6730,6733,6736,6740,6743,6746,6749,6752,6755,6758,6762,6765,6768,6771,6774,6778,6781,6787,6790,6793,6796,6798],[15,6631,6632],{},"MQTT is a go-to protocol for industrial IoT, known for its efficiency, scalability, and ease of use. While it offers great flexibility in handling real-time data, there are key factors to consider in order to get the most out of it. From ensuring data consistency to addressing security and performance concerns, these factors can significantly enhance MQTT’s effectiveness in industrial settings.",[15,6634,6635],{},"This post dives into how to optimize MQTT for industrial IoT, covering best practices and key considerations. It also highlights how FlowFuse can help streamline MQTT communication, improving data reliability, security, and integration across devices and systems.",[37,6637,6639],{"id":6638},"standardizing-data-formats-for-better-quality-and-consistency","Standardizing Data Formats for Better Quality and Consistency",[15,6641,6642],{},"Industrial data is generated by a wide variety of devices, machines, and systems, making it highly valuable. However, to fully leverage this data, it needs to be standardized and formatted in a way that ensures seamless processing across different systems, especially since it can come in a variety of formats.",[15,6644,6645],{},"One of MQTT’s key strengths is its flexibility in handling various data formats. While this is an advantage, it can sometimes require additional effort to ensure that the data is structured consistently and in a way that’s easy to use. Standardizing data formats helps organizations streamline processes, making data easier to interpret, analyze, and act upon. Without a consistent approach, data inconsistencies may arise, slowing down insights or causing compatibility issues.",[15,6647,6648,6649,6651],{},"Frameworks like ",[172,6650,58],{"href":1657}," are designed to help address this by providing a standardized way to handle MQTT payloads. By adopting such frameworks, companies can ensure that data is delivered in a consistent, well-structured format, improving compatibility and making it easier to analyze. This not only simplifies integration across diverse systems but also enables more reliable decision-making and efficient operations.",[37,6653,6655],{"id":6654},"optimizing-payloads-and-bandwidth-for-efficient-mqtt-communication","Optimizing Payloads and Bandwidth for Efficient MQTT Communication",[15,6657,6658],{},"MQTT is designed for lightweight, efficient messaging, which makes it ideal for many IIoT applications. However, in cases where large amounts of data or high-frequency messages need to be transmitted, bandwidth constraints can sometimes impact performance.",[15,6660,6661],{},"While the MQTT protocol supports large message payloads (up to 250 MB), transmitting large files such as high-resolution images or detailed sensor data can slow down communication. Fortunately, there are simple yet effective strategies to keep your MQTT network running smoothly, even when dealing with sizable payloads.",[15,6663,6664],{},"To optimize performance, consider compressing your data before sending it, which reduces the overall size of the payload and makes transmission faster and more efficient. For even larger files, such as video or binary data, a great approach is to store these files externally (e.g., in cloud storage like AWS S3) and send only a reference or pointer to the data. This avoids the need to transmit large files over MQTT while ensuring data accessibility.",[15,6666,6667],{},"By using these strategies, you can optimize MQTT performance and ensure that your system runs efficiently, even when handling large or high-frequency data. These techniques allow MQTT to continue providing fast, reliable, and scalable communication, regardless of the data size or frequency.",[37,6669,6671],{"id":6670},"ensuring-reliable-data-delivery-with-mqtts-qos-levels","Ensuring Reliable Data Delivery with MQTT’s QoS Levels",[15,6673,6674],{},"In industrial environments, the accuracy and timeliness of data transmission are crucial for maintaining operational efficiency and safety. MQTT’s publish-subscribe model is designed for lightweight, real-time messaging, but it’s important to understand how to leverage its features to ensure the reliability and integrity of the data flow.",[15,6676,6677],{},"While the protocol is generally robust, in some cases, challenges such as network disruptions or temporary communication failures can occur. These can lead to issues such as message loss or delivery out of order. Fortunately, MQTT provides built-in mechanisms to address these challenges and ensure that messages reach their intended destination reliably.",[15,6679,6680],{},"One of the key feature for managing message delivery is Quality of Service (QoS), which defines how MQTT handles message delivery:",[431,6682,6683,6688,6693],{},[306,6684,6685,6687],{},[309,6686,1261],{},": Messages are delivered at most once, with no guarantee of delivery or order. This level is ideal for scenarios where occasional message loss is acceptable and minimizing network overhead is critical.",[306,6689,6690,6692],{},[309,6691,1267],{},": Guarantees that messages are delivered at least once, although duplicates may occur. This is useful when data consistency is important, but some duplication can be handled by the system.",[306,6694,6695,6697],{},[309,6696,1273],{},": Ensures messages are delivered exactly once and in the correct order. This highest level of QoS is suitable for scenarios where data integrity and sequencing are paramount, such as in robotic control systems or safety-critical operations.",[15,6699,6700],{},"By choosing the right QoS level, you can align MQTT’s behavior with the operational needs of your system, balancing between performance, data reliability, and system resources. For real-time applications, a lower QoS level may be sufficient, while in more critical situations, the higher QoS levels offer a stronger guarantee of data delivery and integrity.",[15,6702,6703],{},"With these options, MQTT allows you to fine-tune message delivery to meet the specific requirements of your industrial IoT environment, ensuring that data flows smoothly and reliably, even in challenging network conditions.",[37,6705,6707],{"id":6706},"implementing-acknowledgment-mechanisms-in-mqtt","Implementing Acknowledgment Mechanisms in MQTT",[15,6709,6710],{},"One important consideration when working with MQTT is the lack of built-in acknowledgment mechanisms. Unlike traditional request-response communication models, where the receiver explicitly confirms the receipt of a message, MQTT doesn't natively offer a direct way for the receiver to acknowledge successful message receipt.",[15,6712,6713],{},"This lack of visibility can pose challenges in scenarios where it’s crucial to ensure that data has been transmitted successfully and processed as expected. In some industrial systems, failure to confirm receipt of messages could lead to operational uncertainty or potential errors.",[15,6715,6716],{},"However, while MQTT does not provide this feature out-of-the-box, it is possible to implement acknowledgment mechanisms to enhance reliability. we can use a separate topic where the receiver sends a confirmation message (such as “ack” or “received”) back to the sender, indicating that the message was successfully processed.",[15,6718,6719],{},"This allow you to implement acknowledgment functionality, but they do require additional planning and development effort. Ensuring that these mechanisms are correctly designed and integrated can improve system reliability by providing the necessary feedback loop for confirming message receipt and processing.",[15,6721,6722],{},"By incorporating acknowledgment systems, you can enhance the visibility and confidence in data transmission, ensuring that your industrial IoT system operates smoothly and that no critical messages are missed or lost.",[37,6724,6726],{"id":6725},"optimizing-mqtt-for-resource-constrained-environments","Optimizing MQTT for Resource-Constrained Environments",[15,6728,6729],{},"While MQTT’s use of TCP\u002FIP ensures reliable message delivery, it can introduce challenges in environments where devices have limited resources. Maintaining persistent TCP connections can consume significant processing power and memory, which may be a concern for low-power or resource-constrained devices.",[15,6731,6732],{},"To address this, some IoT systems use MQTT-SN (MQTT for Sensor Networks), a variant that operates over UDP and is specifically designed for devices with limited resources. MQTT-SN reduces the overhead associated with maintaining a TCP connection, making it a better fit for battery-powered or embedded devices that need to conserve energy. However, it's important to note that MQTT-SN is distinct from the standard MQTT specification, as it involves different message formats and communication mechanisms.",[15,6734,6735],{},"By carefully selecting the appropriate protocol and architecture for your specific use case, you can continue to leverage MQTT-like messaging capabilities, while optimizing performance in environments with limited resources.",[37,6737,6739],{"id":6738},"ensuring-security-in-mqtt-deployments","Ensuring Security in MQTT Deployments",[15,6741,6742],{},"Security is essential when using MQTT in industrial environments. While MQTT offers powerful features like encryption and authentication, it's crucial to configure these elements correctly to maximize security. A properly secured MQTT deployment ensures that your system remains protected from risks such as data interception, unauthorized access, or man-in-the-middle attacks, while ensuring that your communication remains secure and reliable.",[15,6744,6745],{},"To begin, implementing encryption (SSL\u002FTLS) is an important step to protect the data transmitted between devices and brokers. This ensures that sensitive information is kept confidential and is shielded from unauthorized access. By enabling encryption, you create a secure communication pathway that prevents eavesdropping and data tampering.",[15,6747,6748],{},"Next, consider authentication for all devices and users. By using mechanisms such as usernames, passwords, or client certificates, you can ensure that only authorized devices and users can connect to your MQTT broker. This access control mechanism ensures that only the right people and devices have access to the network, safeguarding it from potential threats.",[15,6750,6751],{},"Topic-level access control is another key aspect of securing your MQTT deployment. By managing who can publish or subscribe to specific topics, you can prevent unauthorized access to sensitive data or critical commands. For example, you can restrict which devices or users are allowed to subscribe to specific topics that control industrial equipment or monitor sensitive processes. This level of control ensures that only trusted entities can interact with certain parts of your system, reducing the risk of malicious actions.",[15,6753,6754],{},"In addition to restricting access to topics, it's also important to regularly monitor your MQTT traffic for any unusual activity or anomalies. By staying vigilant and analyzing traffic patterns, you can identify potential security threats early and take action to prevent any disruptions.",[15,6756,6757],{},"By configuring your MQTT setup with encryption, authentication, topic-level access control, and ongoing monitoring, you can create a secure, reliable, and scalable IoT system. A well-secured MQTT deployment not only reduces risks but also enhances the efficiency and safety of industrial operations, providing peace of mind as your system grows.",[37,6759,6761],{"id":6760},"minimizing-risks-of-single-point-of-failure-and-vendor-lock-in","Minimizing Risks of Single Point of Failure and Vendor Lock-In",[15,6763,6764],{},"When using MQTT for industrial operations, it’s important to address the potential risks associated with a single point of failure, specifically the central broker. While the broker is crucial for managing message delivery, its failure could disrupt the entire data flow, impacting operations. However, this challenge can be effectively managed with strategies like high availability, load balancing, and robust backup solutions. By implementing these best practices, you ensure that your system remains reliable and resilient, even in the event of a failure.",[15,6766,6767],{},"Another consideration is vendor lock-in, which can occur when businesses become reliant on a specific MQTT broker or service. While this may seem convenient at first, it can make future changes or migrations difficult due to proprietary features or configurations that aren't easily compatible with other systems. This is a scenario that can be easily avoided with careful planning.",[15,6769,6770],{},"Although MQTT is an open standard, some cloud services may not fully adhere to the MQTT 3.1.1 specification. This can sometimes lead companies to rely on proprietary software development kits (SDKs) for sending MQTT messages. While these tools can work well initially, they can limit your ability to switch vendors or integrate with other systems down the road.",[15,6772,6773],{},"To maintain flexibility and avoid vendor lock-in, it's crucial to choose an MQTT broker that fully supports MQTT's open standards. Brokers that follow standards like MQTT 3.1.1 or MQTT 5.0 ensure compatibility and interoperability, making it easier to switch providers or integrate new technologies as your needs evolve.",[37,6775,6777],{"id":6776},"how-flowfuse-enhances-your-industrial-iot-system","How FlowFuse Enhances Your Industrial IoT System",[15,6779,6780],{},"FlowFuse is an industrial data platform that streamlines the management, scaling, and security of IoT applications. Built on Node-RED at its core, FlowFuse offers seamless integration with various industrial protocols, including MQTT, ensuring reliable communication between devices. With its robust feature set, FlowFuse makes it easier to build secure, scalable, and efficient IoT solutions for industrial environments",[15,6782,6783,6784,6786],{},"A key strength of FlowFuse is its ability to standardize data before sending it to the MQTT broker. Using Node-RED’s intuitive low-code programming capabilities, you can define consistent data formats and topics across all connected devices. This ensures smooth integration between diverse systems and maintains data consistency, allowing everything to work together seamlessly. FlowFuse also supports frameworks like ",[172,6785,58],{"href":1657},", providing additional structure for more reliable communication with MQTT payloads.",[15,6788,6789],{},"Security is another area where FlowFuse excels. It allows you to configure MQTT nodes with SSL\u002FTLS encryption, username\u002Fpassword authentication, and other security measures to ensure secure communication between devices. This protects sensitive data from unauthorized access and ensures that your system’s communications remain confidential.",[15,6791,6792],{},"FlowFuse also simplifies the creation of acknowledgment mechanisms. With Node-RED, you can design custom workflows to track message receipt and processing, ensuring data integrity and improving operational transparency. This level of control guarantees that your system operates smoothly and reliably.",[15,6794,6795],{},"Additionally, FlowFuse provides its own MQTT broker service that follows open standards, helping you avoid vendor lock-in and offering the flexibility to scale and adapt as your needs evolve. With built-in high availability, load balancing, and access control mechanisms, FlowFuse ensures continuous and reliable and secure data flow. And you can scale its capabilities by contacting FlowFuse support to meet the growing demands of your industrial IoT system.",[37,6797,884],{"id":883},[15,6799,6800],{},"Getting the most out of MQTT for industrial IoT is all about smart strategies and the right tools. By focusing on data consistency, security, and performance, you can build a resilient and efficient IoT ecosystem. With FlowFuse, you get a powerful, flexible platform that not only streamlines MQTT communication but also helps you stay ahead of challenges like security risks and vendor lock-in. Whether you're optimizing payloads, enhancing security, or scaling your system, FlowFuse makes it easier to unlock the full potential of your industrial IoT operations.",{"title":369,"searchDepth":370,"depth":370,"links":6802},[6803,6804,6805,6806,6807,6808,6809,6810,6811],{"id":6638,"depth":373,"text":6639},{"id":6654,"depth":373,"text":6655},{"id":6670,"depth":373,"text":6671},{"id":6706,"depth":373,"text":6707},{"id":6725,"depth":373,"text":6726},{"id":6738,"depth":373,"text":6739},{"id":6760,"depth":373,"text":6761},{"id":6776,"depth":373,"text":6777},{"id":883,"depth":373,"text":884},{"type":5348,"title":6813,"description":6814},"Get More Out of MQTT in Your Industrial Environment","FlowFuse gives you a built-in MQTT broker, Node-RED integration, SSL\u002FTLS security, and centralized device management, everything you need to run reliable, scalable industrial IoT communication.","2024-11-25","Learn how to optimize MQTT for industrial IoT with best practices for data consistency, security, performance, and scalability. Discover how FlowFuse enhances your IoT system with streamlined MQTT communication and robust features.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fmqtt-common-pitfalls.png",{"keywords":3,"excerpt":6819},{"type":12,"value":6820},[6821],[15,6822,6632],{},"\u002Fblog\u002F2024\u002F11\u002Fgetting-the-most-out-of-mqtt-for-industrial-iot",{"title":6626,"description":6816},{"loc":6823},"blog\u002F2024\u002F11\u002Fgetting-the-most-out-of-mqtt-for-industrial-iot","Best Practices for Optimizing MQTT in Industrial IoT Systems",[401,933,402],"_tQQM88QpqNzIR9tXv799neiddnW5ZPmxgEk-jsjVDY",{"id":6831,"title":6832,"authors":6833,"body":6834,"cta":7007,"date":7010,"description":7011,"extension":386,"image":7012,"lastUpdated":5354,"meta":7013,"navigation":394,"path":7023,"seo":7024,"sitemap":7025,"stem":7026,"subtitle":7027,"tags":7028,"tldr":3,"video":3,"__hash__":7029},"blog\u002Fblog\u002F2024\u002F11\u002Fwhy-pub-sub-in-uns.md","Why UNS needs Pub\u002FSub",[10],{"type":12,"value":6835,"toc":6995},[6836,6839,6846,6853,6857,6860,6867,6878,6881,6885,6888,6892,6895,6902,6905,6908,6911,6915,6918,6921,6925,6928,6931,6934,6937,6941,6944,6947,6950,6953,6957,6960,6963,6966,6969,6972,6976,6979,6986,6990,6992],[15,6837,6838],{},"As the manufacturing industry evolves and becomes increasingly connected through the Industrial Internet of Things (IIoT), the concept of a Unified Namespace (UNS) has emerged as a critical architecture for centralizing and organizing data. UNS serves as a central reference point where all operational data, from machines to the enterprise, can be accessed in a consistent and structured way. Over time, more and more manufacturers have adopted UNS to simplify data integration and improve real-time visibility across systems.",[15,6840,6841,6842,6845],{},"If you're unfamiliar with UNS, please read our ",[172,6843,6844],{"href":1552},"Introduction to Unified Namespace"," for a basic understanding of UNS.",[15,6847,6848,6849,6852],{},"If you're familiar with or already using a UNS, you might be asking: ",[309,6850,6851],{},"Why does a UNS need Pub\u002FSub","? Here, we’ll explore how combining the Pub\u002FSub model with a Unified Namespace can help manufacturers streamline data flow, reduce latency, and enable more responsive and scalable operations.",[37,6854,6856],{"id":6855},"what-is-pubsub","What is Pub\u002FSub?",[15,6858,6859],{},"Before discussing why Publish\u002FSubscribe (Pub\u002FSub) is essential for a UNS, let's first define the Pub\u002FSub model.",[15,6861,6862,6865],{},[489,6863],{"alt":6864,"dataZoomable":369,"src":6547},"Publish Subscribe Model",[1235,6866,6864],{},[15,6868,6869,6870,3084,6872,3095,6875,6877],{},"The Pub\u002FSub model is a way for systems to communicate where one component, called the publisher, sends messages to a central system ( Broker such as ",[172,6871,1648],{"href":1647},[172,6873,6874],{"href":5536},"RabitMQ",[172,6876,1974],{"href":1973}," ), and other components, called subscribers, receive those messages. The publisher doesn’t need to know who the subscribers are, and the subscribers don’t know who the publishers are. The central system, or broker, ensures the right messages go to the right subscribers based on their interests.",[15,6879,6880],{},"Additionally, it’s important to note that the roles of publisher and subscriber are not mutually exclusive. A component can act as a publisher in one context, sending messages to the broker, and as a subscriber in another, receiving messages from the broker.",[37,6882,6884],{"id":6883},"why-does-a-uns-need-pubsub","Why Does a UNS Need Pub\u002FSub?",[15,6886,6887],{},"Now that you have a basic understanding of Pub\u002FSub, let’s dive into why this architecture is essential for a Unified Namespace.",[494,6889,6891],{"id":6890},"decoupling-producers-and-consumers-with-flexible-communication","Decoupling Producers and Consumers with Flexible Communication",[15,6893,6894],{},"In traditional manufacturing setups, various systems and machines often operate in silos, requiring point-to-point connections for communication. This means each device or system must be directly linked to others, which quickly becomes complex and cumbersome as the number of systems grows. Point-to-point integrations are hard to scale because each new device needs a dedicated connection. This not only makes data harder to access but also blocks innovation by creating dependencies between systems.",[15,6896,6897,6898],{},"To learn more about how point-to-point systems restrict innovation, please read the article: ",[172,6899,6901],{"href":6900},"\u002Fblog\u002F2023\u002F08\u002Fisa-95-automation-pyramid-to-unified-namespace\u002F","Why the Automation Pyramid Blocks Digital Transformation",[15,6903,6904],{},"The Pub\u002FSub model provides a more scalable solution. In this model, publishers (such as IoT devices or machines) generate data and send it to a central system. Subscribers (other systems, applications, or users) then receive only the data relevant to them. Crucially, the publishers and subscribers do not need to know about each other, relying instead on a central Namespace to distribute the data efficiently.",[15,6906,6907],{},"By using Pub\u002FSub in a UNS, industries can create a single reference point for all data, enabling systems to subscribe to the data streams they need, without direct connections to every other system. For example, a production line monitoring system can easily access data from temperature sensors, pressure gauges, and robotic arms without the need for complex point-to-point integrations.",[15,6909,6910],{},"Unlike point-to-point systems, the Pub\u002FSub model allows for flexible communication, whether one-to-one, one-to-many, or many-to-many, without the need for direct connections between each system. This flexibility ensures that as your factory evolves, new devices and applications can easily be integrated into the UNS, driving innovation.",[494,6912,6914],{"id":6913},"event-driven-and-asynchronous-communication","Event-driven and Asynchronous Communication",[15,6916,6917],{},"The Pub\u002FSub model is particularly well-suited for event-driven architectures, where systems react to changes in data rather than periodically polling for updates. This is important in environments where responsiveness is key, such as in predictive maintenance, supply chain optimization, or automated decision-making.",[15,6919,6920],{},"For instance, a predictive maintenance system can subscribe to real-time sensor data from machines in a UNS. When the system detects an anomaly (e.g., a machine vibration out of normal parameters), it can immediately trigger an alert or maintenance action. This type of asynchronous communication is more efficient and scalable than synchronous polling or direct communication between producers and consumers.",[494,6922,6924],{"id":6923},"less-delay-more-efficiency","Less Delay, More Efficiency",[15,6926,6927],{},"In industries where IIoT-enabled operations are prevalent, real-time data is essential for effective decision-making. Traditional systems often introduce delays due to multiple layers of data collection, storage, and processing. These delays can result in inefficiencies such as slow machine adjustments, missed production targets, or equipment failures.",[15,6929,6930],{},"The Pub\u002FSub model reduces latency by immediately pushing data to subscribers as soon as it’s available. There’s no need for systems to poll or wait for periodic updates. Instead, they can respond to real-time events as soon as they occur.",[15,6932,6933],{},"For instance, in a smart factory, if a machine’s temperature exceeds a threshold, a maintenance system could instantly react by scheduling a technician, triggering an alert, or even pausing operations. Without Pub\u002FSub, the system would have to rely on polling mechanisms, which are less efficient and often introduce unnecessary delays.",[15,6935,6936],{},"In real-time environments, these immediate actions can make the difference between preventing costly downtime or catching a problem too late.",[494,6938,6940],{"id":6939},"easy-to-scale-as-you-grow","Easy to Scale as You Grow",[15,6942,6943],{},"Manufacturers are always expanding, whether by adding more machines to the production line, introducing new automation systems, or scaling up to handle more products or more data. Scaling traditional systems to keep up with this growth can be complex and costly, especially when new devices or technologies need to be integrated.",[15,6945,6946],{},"The beauty of Pub\u002FSub is that it scales effortlessly. When new machines or sensors are introduced, they simply publish their data to the namespace. No complex reconfiguration or integration is required. Similarly, if a new application needs to access this data, it can simply subscribe to the relevant streams.",[15,6948,6949],{},"For example, consider a car manufacturer adding new robotic arms to the production line. These robots can publish real-time performance data, such as arm movement speeds, energy consumption, and fault alerts, directly into the UNS. The factory’s existing data systems can then subscribe to this new data without requiring changes to the entire system, making integration quick and cost-effective.",[15,6951,6952],{},"This level of scalability helps manufacturers keep up with growth without worrying about complex system upgrades or slowdowns.",[494,6954,6956],{"id":6955},"making-your-systems-more-reliable","Making Your Systems More Reliable",[15,6958,6959],{},"In manufacturing, system downtime is costly. However traditional, monolithic systems often rely on point-to-point connections, which can create vulnerabilities. If one part of the system goes down, it can bring down other systems or halt production entirely.",[15,6961,6962],{},"With a Pub\u002FSub architecture, this is less of a concern. If one publisher (like a sensor or machine) fails or goes offline, the rest of the systems can continue operating as normal. Other sensors or machines can continue to send their data, and subscribers can still receive real-time updates from other sources.",[15,6964,6965],{},"Consider a delivery system in a Point-to-Point setup, all vehicles send data directly to a central dispatch system. If the central dispatch system fails, data from all vehicles is lost. In a Pub\u002FSub setup, vehicles send their data to a central namespace instead of directly to the dispatch system. If the central dispatch system fails, it doesn’t result in data loss. Vehicles can still send their updates.",[15,6967,6968],{},"This decoupling of systems improves resilience, meaning that your factory can continue running smoothly even if individual components experience issues.",[15,6970,6971],{},"While the broker is a critical part of the Pub\u002FSub system and can also go down, this risk can be mitigated. Strategies such as high-availability brokers, failover mechanisms, and clustered deployments can be implemented to prevent downtime and ensure uninterrupted data flow.",[494,6973,6975],{"id":6974},"taking-action","Taking Action",[15,6977,6978],{},"As we've discussed, the Pub\u002FSub model is a game-changer for Unified Namespace architectures in the manufacturing industry. One of the most widely adopted protocols for implementing Pub\u002FSub is MQTT (Message Queuing Telemetry Transport). MQTT is known for its simplicity, efficiency, and low-bandwidth requirements, making it an ideal choice for Industrial applications.",[15,6980,6981,6982,367],{},"To help you leverage the power of MQTT in your manufacturing operations along with Node-RED, Flowfuse offers a robust MQTT broker service. Now, Flowfuse will not only help you build, scale, and manage Node-RED solutions, collaborate across teams, and manage edge devices, but it will also simplify your integration of IIoT data streams into your Unified Namespace. For more information on how our FlowFuse MQTT broker Service, read our ",[172,6983,6985],{"href":6984},"\u002Fblog\u002F2024\u002F10\u002Fannouncement-mqtt-broker\u002F?utm_campaign=60718323-BCTA&utm_source=blog&utm_medium=cta%20mqtt%20announcement&utm_term=high_intent&utm_content=Why%20UNS%20needs%20Pub%2FSub","MQTT Broker Service Announcement",[15,6987,6583,6988,367],{},[172,6989,6586],{"href":5461},[37,6991,884],{"id":883},[15,6993,6994],{},"Integrating Pub\u002FSub with a Unified Namespace enhances manufacturing operations by enabling real-time data flow, reducing latency, and improving scalability. This combination ensures efficient, resilient, and future-ready systems, empowering manufacturers to stay competitive in the IIoT era.",{"title":369,"searchDepth":370,"depth":370,"links":6996},[6997,6998,7006],{"id":6855,"depth":373,"text":6856},{"id":6883,"depth":373,"text":6884,"children":6999},[7000,7001,7002,7003,7004,7005],{"id":6890,"depth":659,"text":6891},{"id":6913,"depth":659,"text":6914},{"id":6923,"depth":659,"text":6924},{"id":6939,"depth":659,"text":6940},{"id":6955,"depth":659,"text":6956},{"id":6974,"depth":659,"text":6975},{"id":883,"depth":373,"text":884},{"type":5348,"title":7008,"description":7009},"Build a Real-Time, Scalable UNS With FlowFuse","FlowFuse gives you a built-in MQTT broker, Node-RED integration, and centralized device management, so you can implement Pub\u002FSub and Unified Namespace without stitching together multiple tools.","2024-11-19","Explore why integrating Publish\u002FSubscribe (Pub\u002FSub) with Unified Namespace (UNS) is key to optimizing manufacturing data flow. Learn how this combination reduces latency, improves scalability, and enables real-time decision-making in IIoT systems.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fwhy-uns-needs-pub-sub.png",{"keywords":7014,"excerpt":7015},"unified namespace, pub\u002Fsub, mqtt, iiot, manufacturing, real-time data, event-driven, scalability, smart factory, flowfuse, iot integration",{"type":12,"value":7016},[7017,7019],[15,7018,6838],{},[15,7020,6841,7021,6845],{},[172,7022,6844],{"href":1552},"\u002Fblog\u002F2024\u002F11\u002Fwhy-pub-sub-in-uns",{"title":6832,"description":7011},{"loc":7023},"blog\u002F2024\u002F11\u002Fwhy-pub-sub-in-uns","Discover How Pub\u002FSub Transforms Unified Namespace into a Scalable, Real-Time Data Powerhouse for Modern Manufacturing.",[933,402,5366],"EQ6A287pOK5EtHsmzFBzd8briSNMr7d2E6f5cM4Cm7U",{"id":7031,"title":7032,"authors":7033,"body":7034,"cta":7944,"date":7948,"description":7949,"extension":386,"image":7950,"lastUpdated":7951,"meta":7952,"navigation":394,"path":7958,"seo":7959,"sitemap":7960,"stem":7961,"subtitle":7962,"tags":7963,"tldr":7966,"video":3,"__hash__":7967},"blog\u002Fblog\u002F2024\u002F11\u002Fesp32-with-node-red.md","Interacting with ESP32 Using Node-RED and MQTT (2026)",[10],{"type":12,"value":7035,"toc":7933},[7036,7039,7043,7045,7048,7090,7093,7097,7100,7104,7114,7117,7121,7124,7127,7136,7139,7144,7166,7174,7185,7189,7192,7197,7252,7259,7293,7311,7314,7322,7326,7333,7338,7358,7363,7368,7856,7867,7870,7879,7882,7886,7908,7913,7925,7927,7930],[15,7037,7038],{},"The ESP32 is an affordable and powerful microchip that combines Wi-Fi and Bluetooth in one small package. It's commonly used in smart devices like home automation systems, wearables, and other IoT projects. Despite its low cost (around $6), it offers strong performance, and low power consumption, and is compatible with popular platforms like Arduino. Whether you're a hobbyist or a business, the ESP32 provides great value, making it easy to create wireless devices without a big investment. This tutorial demonstrates how to set up communication between the ESP32 and Node-RED using MQTT, along with an interactive dashboard via FlowFuse for a user-friendly interface.",[4021,7040],{"videoid":7041,"params":4024,"style":7042,"title":4026},"ecfJ-9MxyVE","width: 704px; height: 100%;",[37,7044,454],{"id":453},[15,7046,7047],{},"To follow this tutorial, you'll need the following:",[431,7049,7050,7056,7062,7084],{},[306,7051,7052,7055],{},[309,7053,7054],{},"ESP32 microcontroller",": The hardware you'll be using for this project.",[306,7057,7058,7061],{},[309,7059,7060],{},"USB cable",": To connect the ESP32 to your computer.",[306,7063,7064,7067,7068,7073,7074],{},[309,7065,7066],{},"Arduino IDE",": Installed and set up to program your ESP32. ",[172,7069,7072],{"href":7070,"rel":7071},"https:\u002F\u002Fsupport.arduino.cc\u002Fhc\u002Fen-us\u002Farticles\u002F360019833020-Download-and-install-Arduino-IDE",[176],"Download"," the Arduino IDE if you haven't already done so.\n",[431,7075,7076],{},[306,7077,7078,7079],{},"Additionally, if you haven't set up the Arduino IDE for the ESP32 board, please follow this tutorial: ",[172,7080,7083],{"href":7081,"rel":7082},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=CD8VJl27n94",[176],"How to Set Up ESP32 with Arduino IDE",[306,7085,7086,7089],{},[309,7087,7088],{},"FlowFuse account",": This will allow you to create and deploy Node-RED instances securely on the cloud with a single click, collaborate on your Node-RED projects with your team, manage and program your edge devices remotely, and provide an MQTT broker with an interface for securely managing clients.",[15,7091,7092],{},"If you haven’t signed up for a FlowFuse account yet, [sign up]({% include \"sign-up-url.njk\" %}?utm_campaign=60718323-BCTA&utm_source=blog&utm_medium=cta&utm_term=high_intent&utm_content=Interacting%20with%20ESP32%20Using%20Node-RED%20and%20MQTT) now.",[37,7094,7096],{"id":7095},"getting-started-with-esp32-and-node-red","Getting Started with ESP32 and Node-RED",[15,7098,7099],{},"In this section, we’ll set up Node-RED on FlowFuse, create an MQTT connection, and configure everything to interact with your ESP32. This will lay the foundation for building your IoT flows and controlling devices.",[494,7101,7103],{"id":7102},"step-1-creating-node-red-instance-on-flowfuse-cloud","Step 1: Creating Node-RED instance on FlowFuse Cloud",[15,7105,7106,7107,7109,7110,367],{},"Start by logging into your ",[172,7108,5707],{"href":423}," account and creating a new Node-RED instance. For more information on creating a Node-RED instance, refer to the ",[172,7111,7113],{"href":7112},"\u002Fdocs\u002Fuser\u002Fintroduction\u002F#creating-a-node-red-instance","FlowFuse documentation",[15,7115,7116],{},"Once the instance is created, open the Node-RED editor.",[494,7118,7120],{"id":7119},"step-2-creating-and-configuring-mqtt-clients-in-flowfuse","Step 2: Creating and Configuring MQTT Clients in FlowFuse",[15,7122,7123],{},"In this step, we’ll set up MQTT to enable communication between Node-RED and the ESP32. MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol designed for reliable, low-bandwidth communication between devices in IoT applications.",[15,7125,7126],{},"We use MQTT because it allows devices to communicate over a network (like Wi-Fi) without the need for a direct physical connection. This makes it perfect for long-distance communication, where devices need to send and receive data efficiently, even when they are not physically connected or close to each other.",[15,7128,7129,7133],{},[489,7130],{"alt":7131,"dataZoomable":369,"src":7132},"Diagram showing the flow of data and how commands are sent to the ESP32 using MQTT using Node-RED.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fesp32-mqtt-node-red.png",[1235,7134,7135],{},"Diagram showing the flow of data and how commands are sent to the ESP32 using MQTT using Node-RED",[15,7137,7138],{},"In our setup, Node-RED will publish commands to the MQTT broker, and the ESP32 will subscribe to topics to receive responses. The ESP32 will then perform actions, such as controlling an LED. To facilitate this, we’ll create two MQTT clients in FlowFuse (since the MQTT broker is already set up and managed by FlowFuse, you don’t need to worry about its configuration or maintenance). One client will be for Node-RED, and the other will be for the ESP32. These clients will handle the secure and reliable exchange of messages, ensuring smooth communication between the two devices.",[15,7140,7141],{},[309,7142,7143],{},"To Create MQTT Clients in FlowFuse:",[303,7145,7146,7149,7152,7155],{},[306,7147,7148],{},"Navigate to your FlowFuse platform and log in to your account.",[306,7150,7151],{},"In the left sidebar, click on \"Broker\".",[306,7153,7154],{},"In the newly opened interface, click the “Create Client” button.",[306,7156,7157,7158],{},"Enter a username and password for your MQTT client. Confirm the password.\n",[431,7159,7160],{},[306,7161,7162,7163,7165],{},"You can leave the default pattern as ",[22,7164,1765],{}," for access control, or set a custom pattern if needed.",[15,7167,7168,7172],{},[489,7169],{"alt":7170,"dataZoomable":369,"src":7171},"Interface for setting MQTT client details and credentials","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fmqtt-client-create.png",[1235,7173,7170],{},[303,7175,7176,7179,7182],{"start":698},[306,7177,7178],{},"Click \"Create\" to generate the client.",[306,7180,7181],{},"Copy the client ID and save it somewhere secure for later use.",[306,7183,7184],{},"Repeat the same steps to create the second MQTT client for the ESP32.",[494,7186,7188],{"id":7187},"step-3-building-a-node-red-dashboard-to-send-commands-over-mqtt","Step 3: Building a Node-RED Dashboard to Send Commands Over MQTT",[15,7190,7191],{},"Now that we’ve created the MQTT clients, it’s time to build a Node-RED dashboard and create a flow that will publish commands to the FlowFuse MQTT broker. This will later allow you to interact with your ESP32 using a user-friendly interface.",[15,7193,7194],{},[309,7195,7196],{},"Let's first create a flow to connect to the MQTT broker with the client config we have created:",[303,7198,7199,7205,7211,7214,7234,7237,7243,7246,7249],{},[306,7200,2134,7201,7204],{},[309,7202,7203],{},"mqtt out"," node onto the canvas in Node-RED.",[306,7206,7207,7208,7210],{},"Double-click the ",[309,7209,7203],{}," node to open the settings.",[306,7212,7213],{},"Click the pencil icon next to the Server field to open the MQTT broker configuration.",[306,7215,7216,7217],{},"In the configuration, enter the following details:\n",[431,7218,7219,7225,7228,7231],{},[306,7220,7221,7222],{},"Server: ",[22,7223,7224],{},"broker.flowfuse.cloud",[306,7226,7227],{},"Client ID: The Client ID you created earlier.",[306,7229,7230],{},"Username: The MQTT username (Client ID).",[306,7232,7233],{},"Password: The MQTT password.",[306,7235,7236],{},"Click \"Add\" to save the configuration, then select the newly added configuration.",[306,7238,7239,7240,367],{},"In the Topic field, enter a topic name, such as ",[22,7241,7242],{},"\u002FLEDControl",[306,7244,7245],{},"Click \"Done\" to close the settings.",[306,7247,7248],{},"Click \"Deploy\" in the top-right corner to deploy the flow.",[306,7250,7251],{},"Once deployed, check the MQTT out node for a Connected status, confirming the connection to the MQTT broker.",[15,7253,7254,7255],{},"For this example, we will create a very simple dashboard. If you're not familiar with FlowFuse Dashboard, you can refer to the following blog to get started: ",[172,7256,7258],{"href":7257},"\u002Fblog\u002F2024\u002F03\u002Fdashboard-getting-started\u002F","FlowFuse Dashboard: Getting Started",[303,7260,7261,7267,7274,7280,7285,7290],{},[306,7262,7263,7264,7266],{},"Install the ",[22,7265,3791],{}," from the Node-RED Palette Manager.",[306,7268,7269,7270,7273],{},"Drag two ",[309,7271,7272],{},"ui-button"," widgets onto the canvas.",[306,7275,7276,7277,7279],{},"Double-click on the first button and set the Label to \"ON\", the Background Color to Green, and the Payload to ",[22,7278,4327],{},". Adjust the Width and Height as needed.",[306,7281,7282,7283,367],{},"Double-click on the second button and set the Label to \"OFF\", the Background Color to Red, and the Payload to ",[22,7284,4796],{},[306,7286,7287,7288,2191],{},"Connect the output of both buttons to the input of the ",[309,7289,7203],{},[306,7291,7292],{},"Click \"Deploy\" to save the flow.",[15,7294,4766,7295,2115],{},[627,7296,7297,7298,7300,7301,7304,7305,7308,7309,2114],{},"{\"id\":\"59887a8115c95eae\",\"type\":\"tab\",\"label\":\"Flow 1\",\"disabled\":false,\"info\":\"\",\"env\":",[627,7299],{},"},{\"id\":\"02c25e8a30f9379d\",\"type\":\"ui-base\",\"name\":\"My Dashboard\",\"path\":\"\u002Fdashboard\",\"appIcon\":\"\",\"includeClientData\":true,\"acceptsClientConfig\":",[627,7302,7303],{},"\"ui-notification\",\"ui-control\"",",\"showPathInSidebar\":false,\"showPageTitle\":true,\"navigationStyle\":\"default\",\"titleBarStyle\":\"default\"},{\"id\":\"cfb2ab9ff30660fc\",\"type\":\"ui-theme\",\"name\":\"Default Theme\",\"colors\":{\"surface\":\"#ffffff\",\"primary\":\"#0094CE\",\"bgPage\":\"#eeeeee\",\"groupBg\":\"#ffffff\",\"groupOutline\":\"#cccccc\"},\"sizes\":{\"density\":\"default\",\"pagePadding\":\"12px\",\"groupGap\":\"12px\",\"groupBorderRadius\":\"4px\",\"widgetGap\":\"12px\"}},{\"id\":\"d263574af6876c7a\",\"type\":\"ui-page\",\"name\":\"ESP32\",\"ui\":\"02c25e8a30f9379d\",\"path\":\"\u002Fpage1\",\"icon\":\"home\",\"layout\":\"grid\",\"theme\":\"cfb2ab9ff30660fc\",\"breakpoints\":",[627,7306,7307],{},"{\"name\":\"Default\",\"px\":\"0\",\"cols\":\"3\"},{\"name\":\"Tablet\",\"px\":\"576\",\"cols\":\"6\"},{\"name\":\"Small Desktop\",\"px\":\"768\",\"cols\":\"9\"},{\"name\":\"Desktop\",\"px\":\"1024\",\"cols\":\"12\"}",",\"order\":1,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"3ae115ea7ede6827\",\"type\":\"ui-group\",\"name\":\"Group 1\",\"page\":\"d263574af6876c7a\",\"width\":\"6\",\"height\":\"1\",\"order\":1,\"showTitle\":false,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\",\"groupType\":\"default\"},{\"id\":\"def97b29f5f7baab\",\"type\":\"mqtt-broker\",\"name\":\"\",\"broker\":\"broker.flowfuse.cloud\",\"port\":\"1883\",\"clientid\":\"\",\"autoConnect\":true,\"usetls\":false,\"protocolVersion\":\"4\",\"keepalive\":\"60\",\"cleansession\":true,\"autoUnsubscribe\":true,\"birthTopic\":\"\",\"birthQos\":\"0\",\"birthRetain\":\"false\",\"birthPayload\":\"\",\"birthMsg\":{},\"closeTopic\":\"\",\"closeQos\":\"0\",\"closeRetain\":\"false\",\"closePayload\":\"\",\"closeMsg\":{},\"willTopic\":\"\",\"willQos\":\"0\",\"willRetain\":\"false\",\"willPayload\":\"\",\"willMsg\":{},\"userProps\":\"\",\"sessionExpiry\":\"\"},{\"id\":\"5a9162986a34a4d6\",\"type\":\"ui-button\",\"z\":\"59887a8115c95eae\",\"group\":\"3ae115ea7ede6827\",\"name\":\"\",\"label\":\"ON\",\"order\":1,\"width\":\"3\",\"height\":\"2\",\"emulateClick\":false,\"tooltip\":\"\",\"color\":\"\",\"bgcolor\":\"\",\"className\":\"\",\"icon\":\"\",\"iconPosition\":\"left\",\"payload\":\"1\",\"payloadType\":\"num\",\"topic\":\"topic\",\"topicType\":\"msg\",\"buttonColor\":\"green\",\"textColor\":\"\",\"iconColor\":\"\",\"enableClick\":true,\"enablePointerdown\":false,\"pointerdownPayload\":\"\",\"pointerdownPayloadType\":\"str\",\"enablePointerup\":false,\"pointerupPayload\":\"\",\"pointerupPayloadType\":\"str\",\"x\":190,\"y\":120,\"wires\":[[\"9239f8a7cca5c858\"]]},{\"id\":\"f9c194994d9491a8\",\"type\":\"ui-button\",\"z\":\"59887a8115c95eae\",\"group\":\"3ae115ea7ede6827\",\"name\":\"\",\"label\":\"OFF\",\"order\":2,\"width\":\"3\",\"height\":\"2\",\"emulateClick\":false,\"tooltip\":\"\",\"color\":\"\",\"bgcolor\":\"\",\"className\":\"\",\"icon\":\"\",\"iconPosition\":\"left\",\"payload\":\"2\",\"payloadType\":\"num\",\"topic\":\"topic\",\"topicType\":\"msg\",\"buttonColor\":\"red\",\"textColor\":\"\",\"iconColor\":\"\",\"enableClick\":true,\"enablePointerdown\":false,\"pointerdownPayload\":\"\",\"pointerdownPayloadType\":\"str\",\"enablePointerup\":false,\"pointerupPayload\":\"\",\"pointerupPayloadType\":\"str\",\"x\":190,\"y\":160,\"wires\":[[\"9239f8a7cca5c858\"]]},{\"id\":\"9239f8a7cca5c858\",\"type\":\"mqtt out\",\"z\":\"59887a8115c95eae\",\"name\":\"\",\"topic\":\"\u002FLedControl\",\"qos\":\"\",\"retain\":\"\",\"respTopic\":\"\",\"contentType\":\"\",\"userProps\":\"\",\"correl\":\"\",\"expiry\":\"\",\"broker\":\"def97b29f5f7baab\",\"x\":390,\"y\":140,\"wires\":",[627,7310],{},[15,7312,7313],{},"Now, when you click either the \"ON\" or \"OFF\" button on the dashboard, it will send either 1 or 2 as the payload. The ESP32 will use this payload in its code to turn the LED on or off. To view the dashboard, switch to the Dashboard 2.0 tab on the right side and click the Open Dashboard button. The dashboard will look similar to the image below.",[15,7315,7316,7320],{},[489,7317],{"alt":7318,"dataZoomable":369,"src":7319},"FlowFuse Dashboard Build to control the ESP32 LED","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fdashboard2.png",[1235,7321,7318],{},[494,7323,7325],{"id":7324},"step-4-programming-esp32-to-receive-commands-from-mqtt-and-control-led","Step 4: Programming ESP32 to receive commands from MQTT and Control LED",[15,7327,7328,7329,7332],{},"Now, let's move on to the final step. Before proceeding, make sure your ESP32 is ",[309,7330,7331],{},"connected to your laptop or computer via USB","*. The USB connection is essential for uploading the code (sketch) to the ESP32, which will enable it to connect to the internet and communicate with the MQTT broker.\nThe ESP32 will subscribe to the MQTT topic we configured earlier (e.g., \u002FLEDControl). Based on the received payload (1 or 2), it will control the LED accordingly, turning it on or off.",[15,7334,7335],{},[309,7336,7337],{},"Setting up Arduino IDE:",[303,7339,7340,7343,7346,7349,7352,7355],{},[306,7341,7342],{},"Open the Arduino IDE on your computer.",[306,7344,7345],{},"Ensure you have selected the correct board and port in the Tools menu.",[306,7347,7348],{},"Install the necessary library:",[306,7350,7351],{},"Go to Tools > \"Manage Libraries\".",[306,7353,7354],{},"Search for and install the \"EspMQTTClient\" library by Patrick Lapointe.",[306,7356,7357],{},"The library installation will prompt you to install its dependencies, ensure that you tick that option and proceed to install.",[15,7359,7360],{},[309,7361,7362],{},"Code for ESP32:",[303,7364,7365],{},[306,7366,7367],{},"Copy the following code into the Arduino IDE:",[619,7369,7373],{"className":7370,"code":7371,"language":7372,"meta":369,"style":369},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#if defined(ESP32)\n#include \u003CWiFi.h>\n#elif defined(ESP8266)\n#include \u003CESP8266WiFi.h>\n#endif\n\n#include \u003CPubSubClient.h>\n\n#define LedPin 2 \u002F\u002F ESP32 built-in LED pin\n\n\u002F\u002F WiFi and MQTT settings\nconst char* ssid = \"\"; \u002F\u002F Change this to your WiFi SSID\nconst char* password = \"\"; \u002F\u002F Change this to your WiFi password\nconst char* mqtt_server = \"broker.flowfuse.cloud\"; \u002F\u002F FlowFuse MQTT broker server\n\n\u002F\u002F MQTT client credentials\nconst char* mqtt_client_id = \"\"; \u002F\u002F Replace with your MQTT client ID\nconst char* mqtt_username = \"\"; \u002F\u002F Replace with your MQTT username\nconst char* mqtt_password = \"\"; \u002F\u002F Replace with your MQTT password\n\nWiFiClient espClient;\nPubSubClient client(espClient);\n\n\u002F\u002F Function to connect to WiFi\nvoid setup_wifi() {\n    delay(10);\n    Serial.println();\n    Serial.print(\"Connecting to \");\n    Serial.print(ssid);\n    WiFi.begin(ssid, password);\n\n    while(WiFi.status() != WL_CONNECTED) {\n        delay(500);\n        Serial.print(\".\");\n }\n\n    Serial.println(\"\\nWiFi connected\");\n    Serial.print(\"IP address: \");\n    Serial.println(WiFi.localIP());\n}\n\n\u002F\u002F Callback function to handle messages from subscribed topics\nvoid callback(char* topic, byte* payload, unsigned int length) {\n\n String msg;\n    for (int i = 0; i \u003C length; i++) {\n msg += (char)payload[i];\n }\n\n \u002F\u002F Control LED based on message\n    if (msg == \"1\") {\n        digitalWrite(LedPin, HIGH); \u002F\u002F Turn LED on\n }\n    else if (msg == \"2\") {\n        digitalWrite(LedPin, LOW); \u002F\u002F Turn LED off\n }\n}\n\n\u002F\u002F Function to connect to MQTT broker\nvoid reconnect() {\n    while (!client.connected()) {\n        Serial.println(\"Attempting MQTT connection...\");\n\n \u002F\u002F Connect to MQTT broker with the client ID, username, and password\n        if (client.connect(mqtt_client_id, mqtt_username, mqtt_password)) {\n            Serial.println(\"Connected to MQTT broker\");\n            client.subscribe(\"\u002FLedControl\");\n }\n        else {\n            Serial.print(\"Failed, rc=\");\n            Serial.print(client.state());\n            Serial.println(\" trying again in 5 seconds\");\n            delay(5000);\n }\n }\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    pinMode(LedPin, OUTPUT);\n    setup_wifi();\n    client.setServer(mqtt_server, 1883);\n    client.setCallback(callback);\n}\n\nvoid loop() {\n    if (!client.connected()) {\n        reconnect();\n }\n    client.loop();\n}\n","cpp",[22,7374,7375,7380,7385,7390,7395,7400,7404,7409,7413,7421,7425,7430,7435,7440,7445,7449,7454,7459,7464,7469,7473,7478,7483,7487,7492,7497,7502,7507,7512,7517,7522,7526,7531,7536,7541,7546,7550,7555,7560,7565,7569,7573,7579,7585,7590,7596,7602,7608,7613,7618,7624,7630,7636,7641,7647,7653,7658,7663,7668,7674,7680,7686,7692,7697,7703,7709,7715,7721,7726,7732,7738,7744,7750,7756,7761,7766,7771,7776,7782,7788,7794,7800,7806,7812,7817,7822,7828,7834,7840,7845,7851],{"__ignoreMap":369},[627,7376,7377],{"class":629,"line":630},[627,7378,7379],{},"#if defined(ESP32)\n",[627,7381,7382],{"class":629,"line":373},[627,7383,7384],{},"#include \u003CWiFi.h>\n",[627,7386,7387],{"class":629,"line":659},[627,7388,7389],{},"#elif defined(ESP8266)\n",[627,7391,7392],{"class":629,"line":370},[627,7393,7394],{},"#include \u003CESP8266WiFi.h>\n",[627,7396,7397],{"class":629,"line":698},[627,7398,7399],{},"#endif\n",[627,7401,7402],{"class":629,"line":564},[627,7403,2303],{"emptyLinePlaceholder":394},[627,7405,7406],{"class":629,"line":738},[627,7407,7408],{},"#include \u003CPubSubClient.h>\n",[627,7410,7411],{"class":629,"line":2388},[627,7412,2303],{"emptyLinePlaceholder":394},[627,7414,7415,7418],{"class":629,"line":2399},[627,7416,7417],{},"#define LedPin 2",[627,7419,7420],{}," \u002F\u002F ESP32 built-in LED pin\n",[627,7422,7423],{"class":629,"line":2405},[627,7424,2303],{"emptyLinePlaceholder":394},[627,7426,7427],{"class":629,"line":2413},[627,7428,7429],{},"\u002F\u002F WiFi and MQTT settings\n",[627,7431,7432],{"class":629,"line":2946},[627,7433,7434],{},"const char* ssid = \"\"; \u002F\u002F Change this to your WiFi SSID\n",[627,7436,7437],{"class":629,"line":2952},[627,7438,7439],{},"const char* password = \"\"; \u002F\u002F Change this to your WiFi password\n",[627,7441,7442],{"class":629,"line":2968},[627,7443,7444],{},"const char* mqtt_server = \"broker.flowfuse.cloud\"; \u002F\u002F FlowFuse MQTT broker server\n",[627,7446,7447],{"class":629,"line":2977},[627,7448,2303],{"emptyLinePlaceholder":394},[627,7450,7451],{"class":629,"line":2986},[627,7452,7453],{},"\u002F\u002F MQTT client credentials\n",[627,7455,7456],{"class":629,"line":2992},[627,7457,7458],{},"const char* mqtt_client_id = \"\"; \u002F\u002F Replace with your MQTT client ID\n",[627,7460,7461],{"class":629,"line":3016},[627,7462,7463],{},"const char* mqtt_username = \"\"; \u002F\u002F Replace with your MQTT username\n",[627,7465,7466],{"class":629,"line":3023},[627,7467,7468],{},"const char* mqtt_password = \"\"; \u002F\u002F Replace with your MQTT password\n",[627,7470,7471],{"class":629,"line":3518},[627,7472,2303],{"emptyLinePlaceholder":394},[627,7474,7475],{"class":629,"line":3540},[627,7476,7477],{},"WiFiClient espClient;\n",[627,7479,7480],{"class":629,"line":3545},[627,7481,7482],{},"PubSubClient client(espClient);\n",[627,7484,7485],{"class":629,"line":3551},[627,7486,2303],{"emptyLinePlaceholder":394},[627,7488,7489],{"class":629,"line":3567},[627,7490,7491],{},"\u002F\u002F Function to connect to WiFi\n",[627,7493,7494],{"class":629,"line":3573},[627,7495,7496],{},"void setup_wifi() {\n",[627,7498,7499],{"class":629,"line":3579},[627,7500,7501],{},"    delay(10);\n",[627,7503,7504],{"class":629,"line":3594},[627,7505,7506],{},"    Serial.println();\n",[627,7508,7509],{"class":629,"line":3602},[627,7510,7511],{},"    Serial.print(\"Connecting to \");\n",[627,7513,7514],{"class":629,"line":3607},[627,7515,7516],{},"    Serial.print(ssid);\n",[627,7518,7519],{"class":629,"line":3613},[627,7520,7521],{},"    WiFi.begin(ssid, password);\n",[627,7523,7524],{"class":629,"line":3619},[627,7525,2303],{"emptyLinePlaceholder":394},[627,7527,7528],{"class":629,"line":3648},[627,7529,7530],{},"    while(WiFi.status() != WL_CONNECTED) {\n",[627,7532,7533],{"class":629,"line":3660},[627,7534,7535],{},"        delay(500);\n",[627,7537,7538],{"class":629,"line":3671},[627,7539,7540],{},"        Serial.print(\".\");\n",[627,7542,7543],{"class":629,"line":3682},[627,7544,7545],{}," }\n",[627,7547,7548],{"class":629,"line":3693},[627,7549,2303],{"emptyLinePlaceholder":394},[627,7551,7552],{"class":629,"line":3704},[627,7553,7554],{},"    Serial.println(\"\\nWiFi connected\");\n",[627,7556,7557],{"class":629,"line":3715},[627,7558,7559],{},"    Serial.print(\"IP address: \");\n",[627,7561,7562],{"class":629,"line":3725},[627,7563,7564],{},"    Serial.println(WiFi.localIP());\n",[627,7566,7567],{"class":629,"line":3733},[627,7568,741],{},[627,7570,7571],{"class":629,"line":3738},[627,7572,2303],{"emptyLinePlaceholder":394},[627,7574,7576],{"class":629,"line":7575},42,[627,7577,7578],{},"\u002F\u002F Callback function to handle messages from subscribed topics\n",[627,7580,7582],{"class":629,"line":7581},43,[627,7583,7584],{},"void callback(char* topic, byte* payload, unsigned int length) {\n",[627,7586,7588],{"class":629,"line":7587},44,[627,7589,2303],{"emptyLinePlaceholder":394},[627,7591,7593],{"class":629,"line":7592},45,[627,7594,7595],{}," String msg;\n",[627,7597,7599],{"class":629,"line":7598},46,[627,7600,7601],{},"    for (int i = 0; i \u003C length; i++) {\n",[627,7603,7605],{"class":629,"line":7604},47,[627,7606,7607],{}," msg += (char)payload[i];\n",[627,7609,7611],{"class":629,"line":7610},48,[627,7612,7545],{},[627,7614,7616],{"class":629,"line":7615},49,[627,7617,2303],{"emptyLinePlaceholder":394},[627,7619,7621],{"class":629,"line":7620},50,[627,7622,7623],{}," \u002F\u002F Control LED based on message\n",[627,7625,7627],{"class":629,"line":7626},51,[627,7628,7629],{},"    if (msg == \"1\") {\n",[627,7631,7633],{"class":629,"line":7632},52,[627,7634,7635],{},"        digitalWrite(LedPin, HIGH); \u002F\u002F Turn LED on\n",[627,7637,7639],{"class":629,"line":7638},53,[627,7640,7545],{},[627,7642,7644],{"class":629,"line":7643},54,[627,7645,7646],{},"    else if (msg == \"2\") {\n",[627,7648,7650],{"class":629,"line":7649},55,[627,7651,7652],{},"        digitalWrite(LedPin, LOW); \u002F\u002F Turn LED off\n",[627,7654,7656],{"class":629,"line":7655},56,[627,7657,7545],{},[627,7659,7661],{"class":629,"line":7660},57,[627,7662,741],{},[627,7664,7666],{"class":629,"line":7665},58,[627,7667,2303],{"emptyLinePlaceholder":394},[627,7669,7671],{"class":629,"line":7670},59,[627,7672,7673],{},"\u002F\u002F Function to connect to MQTT broker\n",[627,7675,7677],{"class":629,"line":7676},60,[627,7678,7679],{},"void reconnect() {\n",[627,7681,7683],{"class":629,"line":7682},61,[627,7684,7685],{},"    while (!client.connected()) {\n",[627,7687,7689],{"class":629,"line":7688},62,[627,7690,7691],{},"        Serial.println(\"Attempting MQTT connection...\");\n",[627,7693,7695],{"class":629,"line":7694},63,[627,7696,2303],{"emptyLinePlaceholder":394},[627,7698,7700],{"class":629,"line":7699},64,[627,7701,7702],{}," \u002F\u002F Connect to MQTT broker with the client ID, username, and password\n",[627,7704,7706],{"class":629,"line":7705},65,[627,7707,7708],{},"        if (client.connect(mqtt_client_id, mqtt_username, mqtt_password)) {\n",[627,7710,7712],{"class":629,"line":7711},66,[627,7713,7714],{},"            Serial.println(\"Connected to MQTT broker\");\n",[627,7716,7718],{"class":629,"line":7717},67,[627,7719,7720],{},"            client.subscribe(\"\u002FLedControl\");\n",[627,7722,7724],{"class":629,"line":7723},68,[627,7725,7545],{},[627,7727,7729],{"class":629,"line":7728},69,[627,7730,7731],{},"        else {\n",[627,7733,7735],{"class":629,"line":7734},70,[627,7736,7737],{},"            Serial.print(\"Failed, rc=\");\n",[627,7739,7741],{"class":629,"line":7740},71,[627,7742,7743],{},"            Serial.print(client.state());\n",[627,7745,7747],{"class":629,"line":7746},72,[627,7748,7749],{},"            Serial.println(\" trying again in 5 seconds\");\n",[627,7751,7753],{"class":629,"line":7752},73,[627,7754,7755],{},"            delay(5000);\n",[627,7757,7759],{"class":629,"line":7758},74,[627,7760,7545],{},[627,7762,7764],{"class":629,"line":7763},75,[627,7765,7545],{},[627,7767,7769],{"class":629,"line":7768},76,[627,7770,741],{},[627,7772,7774],{"class":629,"line":7773},77,[627,7775,2303],{"emptyLinePlaceholder":394},[627,7777,7779],{"class":629,"line":7778},78,[627,7780,7781],{},"void setup() {\n",[627,7783,7785],{"class":629,"line":7784},79,[627,7786,7787],{},"    Serial.begin(115200);\n",[627,7789,7791],{"class":629,"line":7790},80,[627,7792,7793],{},"    pinMode(LedPin, OUTPUT);\n",[627,7795,7797],{"class":629,"line":7796},81,[627,7798,7799],{},"    setup_wifi();\n",[627,7801,7803],{"class":629,"line":7802},82,[627,7804,7805],{},"    client.setServer(mqtt_server, 1883);\n",[627,7807,7809],{"class":629,"line":7808},83,[627,7810,7811],{},"    client.setCallback(callback);\n",[627,7813,7815],{"class":629,"line":7814},84,[627,7816,741],{},[627,7818,7820],{"class":629,"line":7819},85,[627,7821,2303],{"emptyLinePlaceholder":394},[627,7823,7825],{"class":629,"line":7824},86,[627,7826,7827],{},"void loop() {\n",[627,7829,7831],{"class":629,"line":7830},87,[627,7832,7833],{},"    if (!client.connected()) {\n",[627,7835,7837],{"class":629,"line":7836},88,[627,7838,7839],{},"        reconnect();\n",[627,7841,7843],{"class":629,"line":7842},89,[627,7844,7545],{},[627,7846,7848],{"class":629,"line":7847},90,[627,7849,7850],{},"    client.loop();\n",[627,7852,7854],{"class":629,"line":7853},91,[627,7855,741],{},[303,7857,7858,7861,7864],{"start":373},[306,7859,7860],{},"Replace the placeholder values in the code: SSID (your Wi-Fi network's SSID), Wi-Fi Password (your Wi-Fi network's password), MQTT Client ID (the MQTT client ID you generated for esp32), MQTT Username and Password (the MQTT credentials you created).",[306,7862,7863],{},"After you've made these changes, click \"Upload\" in the Arduino IDE to upload the code to your ESP32.",[306,7865,7866],{},"Once the upload is complete, open the Serial Monitor (set the baud rate to 115200) to monitor the output.",[15,7868,7869],{},"If everything is set up correctly, you should see the output in the Serial Monitor as shown in the image.",[15,7871,7872,7876],{},[489,7873],{"alt":7874,"dataZoomable":369,"src":7875},"Serial monitor displaying the result when everything is set up correctly.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fserial-monitor.png",[1235,7877,7878],{},"Serial monitor displays the result when everything is set up correctly.",[15,7880,7881],{},"Once you verify the setup, you can unplug the USB from the computer and connect the ESP32 to a power adapter. With this, your ESP32 is now powered and connected to Wi-Fi (make sure your device is on the same Wi-Fi network as the one configured in the code), allowing you to control the LED from anywhere in the world via the MQTT commands sent through Node-RED.",[494,7883,7885],{"id":7884},"troubleshooting","Troubleshooting",[303,7887,7888,7903],{},[306,7889,7890,7893],{},[309,7891,7892],{},"Can't Upload Code to ESP32",[431,7894,7895],{},[306,7896,7897,7898,7902],{},"Solution: Make sure the correct board and port are selected in the Arduino IDE.\nCheck Tools > Board for the right ESP32 model and Tools > Port for the correct connection.\nIf the port is missing, ",[172,7899,7072],{"href":7900,"rel":7901},"https:\u002F\u002Fwww.silabs.com\u002Fdeveloper-tools\u002Fusb-to-uart-bridge-vcp-drivers?tab=downloads",[176]," and reinstall the CP210x USB drivers.",[306,7904,7905],{},[309,7906,7907],{},"ESP32 Keeps Disconnecting from MQTT",[431,7909,7910],{},[306,7911,7912],{},"Solution: Make sure both the ESP32 and Node-RED have unique MQTT client IDs.\nIf both devices share the same client ID, they will conflict and cause disconnections.",[303,7914,7915],{"start":659},[306,7916,7917,7920],{},[309,7918,7919],{},"ESP32 Doesn’t Respond to Commands (LED Not Turning On\u002FOff)",[431,7921,7922],{},[306,7923,7924],{},"Solution: Verify the topic in the ESP32 code matches the one in Node-RED (e.g., \u002FLedControl). If it still doesn't work, try rebooting your ESP32.",[37,7926,884],{"id":883},[15,7928,7929],{},"In this tutorial, we successfully connected the ESP32 to Node-RED using MQTT, enabling remote control of an LED via a FlowFuse dashboard. This simple IoT setup demonstrates how easy it is to interact with devices using MQTT and Node-RED, offering a flexible and scalable solution for future projects. With the ESP32, Node-RED, and FlowFuse, you can easily expand and integrate more devices into your IoT system.",[898,7931,7932],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":369,"searchDepth":370,"depth":370,"links":7934},[7935,7936,7943],{"id":453,"depth":373,"text":454},{"id":7095,"depth":373,"text":7096,"children":7937},[7938,7939,7940,7941,7942],{"id":7102,"depth":659,"text":7103},{"id":7119,"depth":659,"text":7120},{"id":7187,"depth":659,"text":7188},{"id":7324,"depth":659,"text":7325},{"id":7884,"depth":659,"text":7885},{"id":883,"depth":373,"text":884},{"type":7945,"title":7946,"description":7947},"signup","Build and Scale Your IoT Projects with FlowFuse","Going from one ESP32 to a fleet of devices? FlowFuse gives you a managed MQTT broker, hosted Node-RED, remote device management, and dashboards in one platform, so you can deploy, monitor, and update your IoT devices from anywhere without managing infrastructure. Start free today.","2024-11-14","Learn how to connect an ESP32 to Node-RED using MQTT in 2026. Step-by-step guide covering the MQTT broker setup, Arduino IDE code, and building a dashboard to control your IoT device remotely, ideal for beginners and IoT hobbyists.","\u002Fblog\u002F2024\u002F11\u002Fimages\u002Fesp32-with-node-red.png","2026-06-03",{"keywords":7953,"excerpt":7954},"esp32 with node red, node red esp32, connect esp32 to node red, esp node red, esp32 mqtt node red, esp32 node red, esp32 node red mqtt, mqtt esp32 node red, mqtt node red esp32, node red mqtt esp32, node red with esp32",{"type":12,"value":7955},[7956],[15,7957,7038],{},"\u002Fblog\u002F2024\u002F11\u002Fesp32-with-node-red",{"title":7032,"description":7949},{"loc":7958},"blog\u002F2024\u002F11\u002Fesp32-with-node-red","A step-by-step guide to controlling and monitoring an ESP32 over MQTT, with a FlowFuse dashboard.",[7964,7965,402],"node-red","how-to","This guide explains how to connect an ESP32 to Node-RED using MQTT. The two devices don't talk directly, they exchange messages through an MQTT broker. Using FlowFuse's managed broker (broker.flowfuse.cloud), you create one MQTT client for Node-RED and one for the ESP32, build a Node-RED flow and FlowFuse dashboard that publishes commands (for example to \u002FLedControl), and program the ESP32 in the Arduino IDE with the PubSubClient library to subscribe to that topic and act on the payload, turning an LED on or off. Because everything routes through the broker, you can control the device from anywhere with Wi-Fi, and the same pattern works in reverse to read sensor data back into Node-RED.","X1ipdpj0DIsS_ivAQw8hXDwYq9oNghuNi4EvuQxUrr8",{"id":7969,"title":7970,"authors":7971,"body":7973,"cta":3,"date":8190,"description":8191,"extension":386,"image":8192,"lastUpdated":3,"meta":8193,"navigation":394,"path":8200,"seo":8201,"sitemap":8202,"stem":8203,"subtitle":8191,"tags":8204,"tldr":3,"video":3,"__hash__":8207},"blog\u002Fblog\u002F2024\u002F10\u002Fannouncement-mqtt-broker.md","MQTT Service Now Available on FlowFuse",[7972],"joe-pavitt",{"type":12,"value":7974,"toc":8183},[7975,7983,7992,7995,7999,8002,8024,8028,8031,8051,8054,8056,8064,8072,8080,8091,8094,8097,8106,8109,8118,8122,8128,8131,8141,8149,8156,8159,8180],[15,7976,7977,7978,7982],{},"In our ",[172,7979,7981],{"href":7980},"\u002Fblog\u002F2024\u002F10\u002Fflowfuse-release-2-10","recent product update"," we have added our very own MQTT service, built-in and ready to use alongside your Node-RED applications. We are always engaging with users and prospective customers and this has been a highly requested feature, and so we are delighted to announce that this is now live on FlowFuse Cloud for our Pro and Enterprise teams.",[15,7984,7985,7986,7991],{},"The MQTT Service is available now on ",[172,7987,7990],{"href":7988,"rel":7989},"https:\u002F\u002Fflowfuse.com\u002Fplatform\u002Fcloud\u002F",[176],"FlowFuse Cloud",". FlowFuse permits you to setup your own secure clients to begin publishing and subscribing to your own topics.",[15,7993,7994],{},"You can now use FlowFuse to manage your own MQTT Clients alongside your Node-RED instances, making it easier to build full-stack, event-driven applications within FlowFuse.",[37,7996,7998],{"id":7997},"use-cases","Use Cases",[15,8000,8001],{},"FlowFuse MQTT Service simplifies access to real-time data, an important element in optimizing industrial processes. With the power of FlowFuse, Node-RED and the MQTT service, your integrations are now even easier. Here are some typical uses cases:",[431,8003,8004,8018,8021],{},[306,8005,8006,8007],{},"Connect your MQTT enabled PLCs (like Omron N Series, Siemens S7, etc) to your Node-RED instance to open up such possibilities like:\n",[431,8008,8009,8012,8015],{},[306,8010,8011],{},"Data collection and analysis, Predictive Maintenance, OEE, Condition Based Monitoring.",[306,8013,8014],{},"Triggering actions like sending Emails or alerting your engineers about an event.",[306,8016,8017],{},"Realtime production monitoring of your facility.",[306,8019,8020],{},"Make use of modern IIoT devices on legacy systems by bridging the gap with MQTT.",[306,8022,8023],{},"Connect disparate systems together where Node-RED and FlowFuse act as the central hub for data processing and routing. This gives you the advantage of transforming data on the fly, applying extra contextual data from other systems, apply routing rules, and much more.",[37,8025,8027],{"id":8026},"pricing","Pricing",[15,8029,8030],{},"If you're on the Pro or Enterprise tiers of FlowFuse Cloud, then you don't have to pay any extra to get started with the MQTT Service.",[431,8032,8033,8043],{},[306,8034,8035,8038,8039,8042],{},[309,8036,8037],{},"Pro Tier:"," Includes ",[309,8040,8041],{},"5 clients for free"," as part of your existing plan",[306,8044,8045,8038,8048,8042],{},[309,8046,8047],{},"Enterprise Tier:",[309,8049,8050],{},"20 clients for free",[15,8052,8053],{},"In the near future we'll be publishing extra packages of clients that you can add to your team, beyond the amounts included with the base tiers.",[37,8055,4016],{"id":4015},[15,8057,8058,8059,8063],{},"To get started with your own MQTT Clients, navigate to ",[172,8060,7990],{"href":8061,"rel":8062},"https:\u002F\u002Fapp.flowfuse.com",[176],", and Sign In.",[303,8065,8066,8069],{},[306,8067,8068],{},"Click the new \"Broker\" option in the left navigation menu",[306,8070,8071],{},"Click \"Create Client\"",[15,8073,8074,8078],{},[489,8075],{"alt":8076,"dataZoomable":369,"src":8077},"Screenshot of FlowFuse's \"Create Client\" interface","\u002Fblog\u002F2024\u002F10\u002Fimages\u002Fmqtt-broker-add-client.png",[1235,8079,8076],{},[303,8081,8082,8085,8088],{"start":659},[306,8083,8084],{},"Fill out the client's credentials (Username + Password)",[306,8086,8087],{},"Define the \"Access Control Rules\" (see more below)",[306,8089,8090],{},"Click \"Confirm\"",[15,8092,8093],{},"With your client created, you can then, in Node-RED, use the MQTT nodes to connect to your new client.",[15,8095,8096],{},"Setting up a new broker in Node-RED, you can use your credentials accordingly:",[15,8098,8099,8103,8104],{},[489,8100],{"alt":8101,"dataZoomable":369,"src":8102},"Screenshot of the MQTT Config, \"Connection\" tab in the Node-RED Editor","\u002Fblog\u002F2024\u002F10\u002Fimages\u002Fmqtt-broker-config.png","{width=400}\n",[1235,8105,8101],{},[15,8107,8108],{},"And the respective \"Security\" tab:",[15,8110,8111,8115,8116],{},[489,8112],{"alt":8113,"dataZoomable":369,"src":8114},"Screenshot of the MQTT Config, \"Security\" tab in the Node-RED Editor","\u002Fblog\u002F2024\u002F10\u002Fimages\u002Fmqtt-broker-security.png","{width=440}\n",[1235,8117,8113],{},[494,8119,8121],{"id":8120},"access-control-rules","Access Control Rules",[15,8123,8124,8125,367],{},"In MQTT, you can publish and subscribe to ",[1235,8126,8127],{},"topics",[15,8129,8130],{},"These topics are strings that you can use to organise your data. In the Access Control Rules, you can define which topics your client can publish and subscribe to.",[15,8132,8133,8134,3084,8137,8140],{},"For example, in a flow deployed to many PLCs on your factory floor, you might be publishing to the topics ",[22,8135,8136],{},"factory\u002Fbody-shop\u002Fplc\u002F1",[22,8138,8139],{},"factory\u002Fbody-shop\u002Fplc\u002F2",", etc.",[15,8142,8143,8147],{},[489,8144],{"alt":8145,"dataZoomable":369,"src":8146},"Simplified example of MQTT data flow for a Factory Floor","\u002Fblog\u002F2024\u002F10\u002Fimages\u002Fmqtt-factory-architecture.jpg",[1235,8148,8145],{},[15,8150,8151,8152,8155],{},"Then, in a Cloud-Hosted flow, you can subscribe to ",[22,8153,8154],{},"factory\u002Fbody-shop\u002Fplc\u002F#"," to receive all messages from all PLCs in the body shop, and display relevant data into a Dashboard.",[15,8157,8158],{},"Each client that you create can be constrained in two ways:",[431,8160,8161,8174],{},[306,8162,8163,8166,8167,8170,8171,8173],{},[309,8164,8165],{},"Action",": You can limit clients to whether than can ",[1235,8168,8169],{},"only"," subscribe, ",[1235,8172,8169],{}," publish, or conduct both actions.",[306,8175,8176,8179],{},[309,8177,8178],{},"Topic",": You can control which topics a given client can interact with.",[15,8181,8182],{},"These constraints are particularly useful to ensure security throughout your MQTT network, and to ensure that data is only being sent and received by the correct components.",{"title":369,"searchDepth":370,"depth":370,"links":8184},[8185,8186,8187],{"id":7997,"depth":373,"text":7998},{"id":8026,"depth":373,"text":8027},{"id":4015,"depth":373,"text":4016,"children":8188},[8189],{"id":8120,"depth":659,"text":8121},"2024-10-31","We are thrilled to announce a significant milestone for FlowFuse, we now offer our very own MQTT service, built-in and ready to use with your Node-RED applications.","\u002Fblog\u002F2024\u002F10\u002Fimages\u002Fff-mqtt.png",{"excerpt":8194},{"type":12,"value":8195},[8196],[15,8197,7977,8198,7982],{},[172,8199,7981],{"href":7980},"\u002Fblog\u002F2024\u002F10\u002Fannouncement-mqtt-broker",{"title":7970,"description":8191},{"loc":8200},"blog\u002F2024\u002F10\u002Fannouncement-mqtt-broker",[8205,8206,933,7964,402],"posts","news","WXUOFi01v2jpXLWIrgNeEbl-UCyv-kViaja0zKXX3ag",{"id":8209,"title":8210,"authors":8211,"body":8212,"cta":3,"date":9401,"description":9402,"extension":386,"image":3,"lastUpdated":9403,"meta":9404,"navigation":394,"path":9410,"seo":9411,"sitemap":9412,"stem":9413,"subtitle":9414,"tags":9415,"tldr":9416,"video":3,"__hash__":9417},"blog\u002Fblog\u002F2024\u002F08\u002Fusing-mqtt-sparkplugb-with-node-red.md","MQTT Sparkplug B Implementation: Protocol, Architecture & Best Practices",[10],{"type":12,"value":8213,"toc":9373},[8214,8217,8221,8240,8243,8247,8262,8265,8274,8281,8290,8294,8297,8301,8304,8307,8314,8318,8321,8324,8328,8345,8348,8352,8355,8358,8361,8364,8368,8378,8385,8389,8397,8401,8411,8421,8425,8428,8431,8435,8459,8463,8478,8481,8770,8774,8777,8783,8789,8792,8795,8799,8802,8819,8823,8854,8864,8868,9002,9013,9027,9036,9047,9053,9069,9073,9107,9115,9122,9126,9129,9140,9187,9190,9232,9243,9250,9270,9273,9290,9299,9303,9306,9359,9361,9364,9367,9370],[15,8215,8216],{},"Connected devices can generate a lot of data, but without a standardized format, managing and consuming it can be tricky. MQTT certainly simplifies getting your messages delivered but it does not enforce any structure. This is where MQTT Sparkplug B helps by providing a clear, standardized format for data. In this guide, we’ll show you how to use MQTT Sparkplug B with Node-RED to make managing your device data easier and more organized.",[37,8218,8220],{"id":8219},"what-is-mqtt-sparkplug","What is MQTT Sparkplug?",[15,8222,8223,8224,8229,8230,8234,8235,8239],{},"MQTT Sparkplug B is an open-source specification governed by the ",[172,8225,8228],{"href":8226,"rel":8227},"https:\u002F\u002Fwww.eclipse.org\u002Fprojects\u002Fefsp\u002F",[176],"Eclipse Foundation Specification Process (EFSP)",". It defines a standardized MQTT topic namespace and payload format specifically designed for Industrial IoT (IIoT), with particular focus on real-time ",[172,8231,8233],{"href":8232},"\u002Fsolutions\u002Fscada\u002F","SCADA",", control systems, and ",[172,8236,8238],{"href":8237},"\u002Fblog\u002F2025\u002F11\u002Fbuilding-hmi-for-equipment-control\u002F","HMI"," solutions.",[15,8241,8242],{},"At its core, Sparkplug B extends MQTT 3.1.1 by adding structured topic namespace conventions, Google Protocol Buffer encoded payloads, state-aware birth and death certificates, metric aliasing for bandwidth optimization, and store-and-forward capabilities for intermittent connectivity. These additions transform MQTT from a simple messaging protocol into a complete industrial communication framework.",[494,8244,8246],{"id":8245},"the-industrial-integration-problem","The Industrial Integration Problem",[15,8248,8249,8250,8253,8254,8257,8258,8261],{},"In typical factory environments, every machine manufacturer implements MQTT differently. Consider a real-world scenario where Machine A publishes temperature data to ",[22,8251,8252],{},"factory\u002Fline1\u002Ftemp"," with a JSON payload containing the temperature value. Meanwhile, Machine B sends its data to ",[22,8255,8256],{},"sensors\u002FmachineB\u002Fenv"," with a completely different JSON structure that includes both temperature and timestamp. Machine C takes yet another approach, publishing raw numeric values to ",[22,8259,8260],{},"data\u002Fmc\u002Fstatus"," with no context or metadata.",[15,8263,8264],{},"Each device requires custom parsing logic, error handling, and documentation. Integration complexity grows exponentially with each new device type. Your development team spends weeks building and maintaining custom parsers instead of focusing on business logic.",[15,8266,8267,8271],{},[489,8268],{"alt":8269,"src":8270},"Manufacturing dashboard struggling with non-standardized MQTT data from multiple sources","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fwith-plane-mqtt.png",[1235,8272,8273],{},"Dashboard complexity increases exponentially without standardized data formats",[15,8275,8276,8277,8280],{},"With Sparkplug B standardization, all devices publish to structured topics following the format ",[22,8278,8279],{},"spBv1.0\u002FFactory\u002FDDATA\u002FLine1\u002FMachineA"," with consistent Protocol Buffer payloads. Each message contains typed metrics, timestamps, and quality indicators. Integration becomes predictable and maintainable. When you add a new device, it automatically describes its capabilities through birth certificates, eliminating the need for custom integration code.",[15,8282,8283,8287],{},[489,8284],{"alt":8285,"src":8286},"Manufacturing dashboard efficiently processing standardized Sparkplug B data","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fwith-sparkplug.png",[1235,8288,8289],{},"Standardized format enables reliable data aggregation across heterogeneous devices",[37,8291,8293],{"id":8292},"sparkplug-b-architecture-patterns","Sparkplug B Architecture Patterns",[15,8295,8296],{},"Several architectural patterns have emerged from production Sparkplug B deployments. Understanding these patterns helps you design scalable, maintainable systems.",[494,8298,8300],{"id":8299},"edge-node-architecture","Edge Node Architecture",[15,8302,8303],{},"The edge node serves as the gateway between physical devices and the MQTT broker. A single edge node typically manages multiple devices, publishing aggregate birth certificates and handling communication for all attached devices. This centralized approach simplifies device management and reduces broker connections.",[15,8305,8306],{},"Edge nodes implement store-and-forward buffering to handle temporary connectivity loss. When the broker becomes unreachable, the edge node buffers data locally. After reconnection, it publishes buffered data with historical flags set, allowing applications to distinguish between real-time and historical data.",[15,8308,8309,8310,8313],{},"The edge node monitors broker connectivity and automatically publishes ",[22,8311,8312],{},"NBIRTH"," after reconnection. It manages sequence numbers across all messages from its devices, enabling applications to detect lost messages. Many edge nodes implement local data processing, filtering, and aggregation before publishing to reduce bandwidth and broker load.",[494,8315,8317],{"id":8316},"primary-application-pattern","Primary Application Pattern",[15,8319,8320],{},"The primary application concept allows edge nodes to adapt their behavior based on application state. A designated primary application publishes STATE messages indicating its operational status. Edge nodes subscribe to these STATE messages and adjust their reporting frequency or metrics based on whether the primary application is online.",[15,8322,8323],{},"For example, an edge node might publish data every second when the primary SCADA application is connected but reduce to every 60 seconds when no primary application is available. This adaptive behavior conserves bandwidth and broker resources while ensuring data availability when needed.",[494,8325,8327],{"id":8326},"command-and-control-flow","Command and Control Flow",[15,8329,8330,8331,1289,8334,8337,8338,1987,8341,8344],{},"Sparkplug B enables bidirectional communication through ",[22,8332,8333],{},"NCMD",[22,8335,8336],{},"DCMD"," messages. Applications publish commands to specific topics, and edge nodes or devices execute the commands and respond with updated metric values in ",[22,8339,8340],{},"NDATA",[22,8342,8343],{},"DDATA"," messages.",[15,8346,8347],{},"Command messages use the same Protocol Buffer format as data messages but flow in the opposite direction. Applications might send a write command to change a setpoint, a rebirth command to request fresh birth certificates, or a custom command to trigger device-specific actions. The standardized command structure enables generic control applications that work with any Sparkplug-compliant device.",[37,8349,8351],{"id":8350},"the-mqtt-sparkplug-specification-for-iiot","The MQTT Sparkplug Specification for IIoT",[15,8353,8354],{},"Now that we have an overview of Sparkplug B and its role in standardizing data formats, it’s time to dive deeper into how this protocol structures its payloads and topics. Understanding these details will give you insight into how Sparkplug B efficiently manages data in complex industrial environments and will assist you in implementing it effectively in your own projects.",[15,8356,8357],{},"Sparkplug B utilizes Google Protocol Buffers (Protobufs) for encoding its messages. Protobufs offer a compact and fast way to serialize structured data, preserving MQTT's lightweight nature while introducing a robust framework for handling complex data.",[494,8359,8351],{"id":8360},"the-mqtt-sparkplug-specification-for-iiot-1",[15,8362,8363],{},"The Sparkplug B specification addresses critical industrial requirements that standard MQTT implementations typically handle inconsistently. The specification is built around several core concepts that work together to create a robust industrial messaging framework.",[494,8365,8367],{"id":8366},"topic-namespace-architecture","Topic Namespace Architecture",[15,8369,8370,8371,8374,8375,8377],{},"Sparkplug B enforces a hierarchical topic namespace that follows a specific pattern: ",[22,8372,8373],{},"spBv1.0\u002F{group_id}\u002F{message_type}\u002F{edge_node_id}\u002F{device_id}",". The namespace starts with the protocol version identifier ",[22,8376,253],{},", ensuring clients can identify Sparkplug messages. The group_id provides logical grouping such as factory, building, or region. The message_type specifies whether this is a birth certificate, data update, death notification, or command. The edge_node_id identifies the gateway or edge node, and optionally, a device_id can specify individual devices under that edge node.",[15,8379,8380,8381,8384],{},"For example, a temperature sensor in a manufacturing facility might publish to ",[22,8382,8383],{},"spBv1.0\u002FManufacturing\u002FDDATA\u002FGateway01\u002FTempSensor05",". This structured approach eliminates ambiguity and enables automatic topic subscription patterns.",[494,8386,8388],{"id":8387},"protocol-buffer-payloads","Protocol Buffer Payloads",[15,8390,8391,8392,8396],{},"Rather than using JSON or other text-based formats, Sparkplug B employs ",[172,8393,8395],{"href":8394},"\u002Fblog\u002F2025\u002F12\u002Fnode-red-buffer-parser-industrial-data\u002F","Google Protocol Buffers"," for message encoding. This choice delivers several advantages in industrial environments. The compact binary format produces significantly smaller messages than JSON, reducing bandwidth consumption on constrained networks. Protocol Buffers provide strongly typed data fields, eliminating parsing ambiguities. The format supports backward compatibility, allowing older clients to work with newer message versions. Finally, efficient parsing performance matters when handling thousands of messages per second.",[494,8398,8400],{"id":8399},"state-management-system","State Management System",[15,8402,8403,8404,8406,8407,8410],{},"The specification includes explicit state awareness through birth and death certificates. When an edge node or device connects to the broker, it publishes a birth certificate (",[22,8405,8312],{}," for nodes, ",[22,8408,8409],{},"DBIRTH"," for devices) that declares all available metrics, their data types, and initial values. This self-description capability means applications can discover device capabilities automatically without external configuration files.",[15,8412,8413,8414,423,8417,8420],{},"When devices disconnect, either gracefully or due to network failure, death certificates (",[22,8415,8416],{},"NDEATH",[22,8418,8419],{},"DDEATH",") signal the disconnection to all subscribers. The MQTT Last Will and Testament feature ensures death certificates publish even when devices lose connectivity unexpectedly. Sequence numbers in every message enable detection of lost messages, while timestamps provide temporal context for all data points.",[494,8422,8424],{"id":8423},"metric-definition-framework","Metric Definition Framework",[15,8426,8427],{},"Each metric in Sparkplug B carries comprehensive metadata beyond just a name and value. The specification supports a wide range of data types including various integer sizes (Int8 through Int64, both signed and unsigned), floating-point numbers (Float and Double), Boolean values, strings, timestamps, UUIDs, binary data, and complex structures like datasets and templates.",[15,8429,8430],{},"Every metric includes a timestamp indicating when the value was captured, not just when it was transmitted. Quality flags indicate whether data is historical (stored and forwarded), transient (not to be stored), or null (sensor failure). This rich metadata enables applications to make informed decisions about data processing and storage.",[494,8432,8434],{"id":8433},"message-types-and-their-purposes","Message Types and Their Purposes",[15,8436,8437,8438,8440,8441,8443,8444,8446,8447,3084,8449,3095,8451,8453,8454,1289,8456,8458],{},"Sparkplug B defines specific message types for different communication needs. ",[22,8439,8312],{}," messages announce edge node connection and available metrics. ",[22,8442,8340],{}," messages carry periodic metric updates from edge nodes. ",[22,8445,8416],{}," messages signal edge node disconnection. ",[22,8448,8409],{},[22,8450,8343],{},[22,8452,8419],{}," provide the same functions for devices under edge nodes.",[22,8455,8333],{},[22,8457,8336],{}," enable command and control, allowing applications to send instructions to nodes and devices. STATE messages, published by primary applications, indicate application health and readiness.",[37,8460,8462],{"id":8461},"sparkplug-b-vs-plain-mqtt-understanding-the-differences","Sparkplug B vs Plain MQTT: Understanding the Differences",[15,8464,8465,8466,8469,8470,8473,8474,8477],{},"While both ",[172,8467,8468],{"href":1647},"plain MQTT"," and Sparkplug B use the same MQTT transport protocol, they solve ",[309,8471,8472],{},"very different problems",".\nPlain MQTT focuses on moving messages reliably, whereas Sparkplug B defines ",[309,8475,8476],{},"how industrial data should be structured, identified, and managed"," across devices and applications.",[15,8479,8480],{},"The table below highlights the practical differences that matter when designing real-world IIoT and SCADA systems.",[42,8482,8483,8495],{},[45,8484,8485],{},[48,8486,8487,8490,8492],{},[51,8488,8489],{},"Category",[51,8491,55],{},[51,8493,8494],{},"MQTT Sparkplug B",[60,8496,8497,8509,8522,8537,8549,8562,8575,8588,8601,8614,8627,8640,8653,8666,8679,8692,8705,8718,8731,8744,8757],{},[48,8498,8499,8503,8506],{},[65,8500,8501],{},[309,8502,67],{},[65,8504,8505],{},"Messaging protocol",[65,8507,8508],{},"Industrial IoT specification built on MQTT",[48,8510,8511,8516,8519],{},[65,8512,8513],{},[309,8514,8515],{},"Primary purpose",[65,8517,8518],{},"Message transport",[65,8520,8521],{},"Standardized industrial data exchange",[48,8523,8524,8528,8531],{},[65,8525,8526],{},[309,8527,78],{},[65,8529,8530],{},"Fully custom, no enforced rules",[65,8532,8533,8534,2941],{},"Strict, standardized namespace (",[22,8535,8536],{},"spBv1.0\u002F...",[48,8538,8539,8543,8546],{},[65,8540,8541],{},[309,8542,89],{},[65,8544,8545],{},"JSON, text, or custom binary",[65,8547,8548],{},"Google Protocol Buffers (binary, compact)",[48,8550,8551,8556,8559],{},[65,8552,8553],{},[309,8554,8555],{},"Payload consistency",[65,8557,8558],{},"Varies by device and vendor",[65,8560,8561],{},"Guaranteed consistent structure",[48,8563,8564,8569,8572],{},[65,8565,8566],{},[309,8567,8568],{},"Data typing",[65,8570,8571],{},"Not enforced",[65,8573,8574],{},"Strongly typed metrics",[48,8576,8577,8582,8585],{},[65,8578,8579],{},[309,8580,8581],{},"Device discovery",[65,8583,8584],{},"Manual configuration",[65,8586,8587],{},"Automatic via NBIRTH \u002F DBIRTH",[48,8589,8590,8595,8598],{},[65,8591,8592],{},[309,8593,8594],{},"State awareness",[65,8596,8597],{},"Limited (LWT only)",[65,8599,8600],{},"Full lifecycle (BIRTH, DATA, DEATH)",[48,8602,8603,8608,8611],{},[65,8604,8605],{},[309,8606,8607],{},"Message loss detection",[65,8609,8610],{},"Not supported",[65,8612,8613],{},"Sequence numbers included",[48,8615,8616,8621,8624],{},[65,8617,8618],{},[309,8619,8620],{},"Timestamps",[65,8622,8623],{},"Optional, application-defined",[65,8625,8626],{},"Mandatory per metric",[48,8628,8629,8634,8637],{},[65,8630,8631],{},[309,8632,8633],{},"Data quality flags",[65,8635,8636],{},"Custom implementation",[65,8638,8639],{},"Built-in (historical, transient, null)",[48,8641,8642,8647,8650],{},[65,8643,8644],{},[309,8645,8646],{},"Bandwidth efficiency",[65,8648,8649],{},"Lower (JSON overhead)",[65,8651,8652],{},"Higher (protobuf + metric aliasing)",[48,8654,8655,8660,8663],{},[65,8656,8657],{},[309,8658,8659],{},"Metric aliasing",[65,8661,8662],{},"Not available",[65,8664,8665],{},"Supported",[48,8667,8668,8673,8676],{},[65,8669,8670],{},[309,8671,8672],{},"Command & control",[65,8674,8675],{},"Custom topics and logic",[65,8677,8678],{},"Standardized NCMD \u002F DCMD",[48,8680,8681,8686,8689],{},[65,8682,8683],{},[309,8684,8685],{},"Interoperability",[65,8687,8688],{},"Low (vendor-specific)",[65,8690,8691],{},"High (vendor-neutral)",[48,8693,8694,8699,8702],{},[65,8695,8696],{},[309,8697,8698],{},"Human readability",[65,8700,8701],{},"High",[65,8703,8704],{},"Low (binary encoded)",[48,8706,8707,8712,8715],{},[65,8708,8709],{},[309,8710,8711],{},"Debugging effort",[65,8713,8714],{},"Easy with basic tools",[65,8716,8717],{},"Requires Sparkplug-aware tools",[48,8719,8720,8725,8728],{},[65,8721,8722],{},[309,8723,8724],{},"Scalability",[65,8726,8727],{},"Depends on custom design",[65,8729,8730],{},"Designed for large-scale IIoT",[48,8732,8733,8738,8741],{},[65,8734,8735],{},[309,8736,8737],{},"Security",[65,8739,8740],{},"MQTT-level (TLS, ACLs)",[65,8742,8743],{},"MQTT-level (same as plain MQTT)",[48,8745,8746,8751,8754],{},[65,8747,8748],{},[309,8749,8750],{},"Learning curve",[65,8752,8753],{},"Low",[65,8755,8756],{},"Medium to high",[48,8758,8759,8764,8767],{},[65,8760,8761],{},[309,8762,8763],{},"Best fit use cases",[65,8765,8766],{},"Small systems, prototypes, simple sensors",[65,8768,8769],{},"SCADA, HMI, multi-vendor industrial systems",[37,8771,8773],{"id":8772},"using-mqtt-sparkplug-b-with-node-red","Using MQTT Sparkplug B with Node-RED",[15,8775,8776],{},"Now that we understand what Sparkplug B is and how it structures industrial data, let’s see how to use it in practice with Node-RED.",[15,8778,8779,8782],{},[172,8780,424],{"href":8781},"\u002Fnode-red\u002F"," is a popular low-code tool for building IoT and industrial data flows. It’s widely used at the edge to connect devices, process data, and integrate with MQTT brokers. With dedicated Sparkplug nodes, Node-RED makes it easy to publish and consume Sparkplug B messages without manually handling topics, protobufs, or state management.",[15,8784,8785,8786,8788],{},"To run Node-RED reliably in production, especially for industrial and edge deployments, ",[172,8787,5707],{"href":423}," provides a managed platform for deploying, scaling, and managing Node-RED instances. FlowFuse also includes a built-in MQTT broker, making it simple to get started with Sparkplug B without additional infrastructure.",[15,8790,8791],{},"[Create a free FlowFuse account]({% include \"sign-up-url.njk\" %}) to deploy Node-RED, connect devices, and start working with MQTT Sparkplug B in minutes.",[15,8793,8794],{},"In the following example, we’ll configure a Node-RED flow where a factory machine publishes temperature and humidity data using Sparkplug B, and then consumes that data downstream.",[494,8796,8798],{"id":8797},"prerequisite","Prerequisite",[15,8800,8801],{},"Before you begin, ensure you have the following:",[431,8803,8804,8813],{},[306,8805,8806,8807,8812],{},"node-red-contrib-mqtt-sparkplug-plus: Install this ",[172,8808,8811],{"href":8809,"rel":8810},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002Fnode-red-contrib-mqtt-sparkplug-plus",[176],"Node-RED package for Sparkplug B"," support via palette manager.",[306,8814,8815,8816,367],{},"MQTT Broker: An MQTT broker is required to send and receive data between clients. If you do not already have one, FlowFuse offers a built-in MQTT broker service that simplifies the process of using MQTT with Node-RED, no external setup required. To learn how to use the FlowFuse MQTT Broker and create and manage clients, refer to the ",[172,8817,8818],{"href":468},"FlowFuse MQTT documentation",[494,8820,8822],{"id":8821},"configuring-node-red-for-mqtt-sparkplug-b","Configuring Node-RED for MQTT Sparkplug B",[303,8824,8825,8828,8831,8845,8848,8851],{},[306,8826,8827],{},"Drag any mqtt sparkplug node onto the canvas.",[306,8829,8830],{},"Double-click the mqtt sparkplug node to open the configuration panel.",[306,8832,8833,8834,8836,8837,8840,8841,8844],{},"Click the \"+\" icon next to the \"Broker\" field. Enter your MQTT broker's host address (e.g., ",[22,8835,7224],{},"), specify the port number (e.g., ",[22,8838,8839],{},"1883"," for unencrypted or ",[22,8842,8843],{},"8883"," for TLS), and configure the TLS settings if required. Enter the username and password, enter a Client ID, Set the \"Keep Alive\" interval (default is 60 seconds).",[306,8846,8847],{},"Switch to the Sparkplug tab by clicking the Sparkplug option in the top-right corner.",[306,8849,8850],{},"Enter a name in the \"Name\" field (this will be the Edge Node ID). Enter the group name in the \"Group\" field. Select \"No\" for the compression setting. Enable the \"Use Alias for Metrics\" option if you prefer not to send the full metric names every time and use aliases instead.",[306,8852,8853],{},"Click \"Add\" to save the configuration.",[15,8855,8856,8860,8862],{},[489,8857],{"alt":8858,"src":8859,"title":8858},"Screenshot showing the configuration of Sparkplug broker config node","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-broker-config.png",[4121,8861],{},[1235,8863,8858],{},[494,8865,8867],{"id":8866},"sending-data-to-mqtt-with-sparkplug-b","Sending Data to MQTT with Sparkplug B",[303,8869,8870,8996,8999],{},[306,8871,8872,8873,8875,8876],{},"Drag the inject node onto the canvas. Set the ",[22,8874,616],{}," to the metrics you want to send and set the repeat interval according to your preference. This inject node could be any node that triggers the data sending. For testing purpose, you can use the following JSONata expression to simulate temperature and humidly metrics:",[619,8877,8879],{"className":621,"code":8878,"language":623,"meta":369,"style":369},"{\n    \"metrics\": [\n        {\n            \"name\": \"sensor\u002Ftemperature\",\n            \"value\": $random() * 100\n        },\n        {\n            \"name\": \"sensor\u002Fhumidity\",\n            \"value\": $random() * 100\n        }\n    ]\n}\n",[22,8880,8881,8885,8898,8903,8924,8940,8945,8949,8968,8982,8987,8992],{"__ignoreMap":369},[627,8882,8883],{"class":629,"line":630},[627,8884,634],{"class":633},[627,8886,8887,8889,8892,8894,8896],{"class":629,"line":373},[627,8888,2467],{"class":633},[627,8890,8891],{"class":642},"metrics",[627,8893,646],{"class":633},[627,8895,649],{"class":633},[627,8897,3645],{"class":633},[627,8899,8900],{"class":629,"line":659},[627,8901,8902],{"class":633},"        {\n",[627,8904,8905,8908,8911,8913,8915,8917,8920,8922],{"class":629,"line":370},[627,8906,8907],{"class":633},"            \"",[627,8909,6039],{"class":8910},"sBMFI",[627,8912,646],{"class":633},[627,8914,649],{"class":633},[627,8916,687],{"class":633},[627,8918,8919],{"class":690},"sensor\u002Ftemperature",[627,8921,646],{"class":633},[627,8923,656],{"class":633},[627,8925,8926,8928,8930,8932,8934,8937],{"class":629,"line":698},[627,8927,8907],{"class":633},[627,8929,664],{"class":8910},[627,8931,646],{"class":633},[627,8933,649],{"class":633},[627,8935,8936],{"class":2283}," $random() * ",[627,8938,8939],{"class":652},"100\n",[627,8941,8942],{"class":629,"line":564},[627,8943,8944],{"class":633},"        },\n",[627,8946,8947],{"class":629,"line":738},[627,8948,8902],{"class":633},[627,8950,8951,8953,8955,8957,8959,8961,8964,8966],{"class":629,"line":2388},[627,8952,8907],{"class":633},[627,8954,6039],{"class":8910},[627,8956,646],{"class":633},[627,8958,649],{"class":633},[627,8960,687],{"class":633},[627,8962,8963],{"class":690},"sensor\u002Fhumidity",[627,8965,646],{"class":633},[627,8967,656],{"class":633},[627,8969,8970,8972,8974,8976,8978,8980],{"class":629,"line":2399},[627,8971,8907],{"class":633},[627,8973,664],{"class":8910},[627,8975,646],{"class":633},[627,8977,649],{"class":633},[627,8979,8936],{"class":2283},[627,8981,8939],{"class":652},[627,8983,8984],{"class":629,"line":2405},[627,8985,8986],{"class":633},"        }\n",[627,8988,8989],{"class":629,"line":2413},[627,8990,8991],{"class":633},"    ]\n",[627,8993,8994],{"class":629,"line":2946},[627,8995,741],{"class":633},[306,8997,8998],{},"Drag the mqtt sparkplug device node onto the canvas.",[306,9000,9001],{},"Double-click the mqtt sparkplug device node to open the configuration panel. Add the metric names that you will be sending by clicking the bottom-left \"Add\" button. Ensure that the names match the metric names in the payload you are sending and specify the data types for each metric.",[15,9003,9004,9009,9011],{},[489,9005],{"alt":9006,"src":9007,"title":9008},"Screenshot showing the Sparkplug Device node configuration and the \"Add\" button for defining metrics","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-sparkplug-device-node.png","Screenshot showing the Sparkplug Device node configuration and the 'Add' button for defining metrics",[4121,9010],{},[1235,9012,9006],{},[303,9014,9015,9018],{"start":370},[306,9016,9017],{},"Switch to the Advanced tab by clicking the \"Advanced\" option at the top-right.",[306,9019,9020,9021,9023,9024,9026],{},"Enable the \"Send Birth Immediately\" option. This ensures that a Birth message (DBIRTH) is sent immediately upon deployment and connection to the MQTT broker. Note that enabling this option will send the ",[22,9022,8409],{}," message when the device node connects, but an ",[22,9025,8312],{}," message will be sent successful connection of mqtt sparkplug out node if you are using.",[15,9028,9029,9032,9034],{},[489,9030],{"alt":9006,"src":9031,"title":9008},"\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-spark-device-advance.png",[4121,9033],{},[1235,9035,9006],{},[303,9037,9038,9041,9044],{"start":564},[306,9039,9040],{},"Optionally, enable Store and Forward when not connected to ensure that messages are stored and sent once the connection is re-established. To use this option, make sure you have enabled it in the mqtt sparkplug broker config node and specified the destination.",[306,9042,9043],{},"Connect the inject node's output to the mqtt sparkplug device node's input.",[306,9045,9046],{},"Deploy the flow by clicking the top-right \"Deploy\" button.",[15,9048,9049,9050,9052],{},"Once you deploy the flow and all devices connect to the MQTT broker, the system automatically send a ",[22,9051,8409],{}," message as soon as each device within the node connects, signalling that the device is ready for data transmission.",[15,9054,4766,9055,2115],{},[627,9056,9057,9058,9061,9062,9065,9066,9068],{},"{\"id\":\"f2864f2b830e3590\",\"type\":\"mqtt sparkplug device\",\"z\":\"239c9025714089d3\",\"name\":\"Machine1\",\"metrics\":{\"sensor\u002Ftemperature\":{\"dataType\":\"Float\",\"name\":\"sensor\u002Ftemperature\"},\"sensor\u002Fhumidity\":{\"dataType\":\"Float\",\"name\":\"sensor\u002Fhumidity\"}},\"broker\":\"0d831bd9ba588536\",\"birthImmediately\":true,\"bufferDevice\":false,\"x\":380,\"y\":320,\"wires\":[[\"3dfc9b74f5e36bec\"]]},{\"id\":\"90cc413f58871fc1\",\"type\":\"inject\",\"z\":\"239c9025714089d3\",\"name\":\"Send Metrics\",\"props\":",[627,9059,9060],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"vt\":\"str\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"{    \"metrics\": ",[627,9063,9064],{},"        {            \"name\": \"sensor\u002Ftemperature\",            \"value\": $random()*100        },        {            \"name\": \"sensor\u002Fhumidity\",            \"value\": $random()*100        }","}\",\"payloadType\":\"jsonata\",\"x\":130,\"y\":320,\"wires\":[[\"f2864f2b830e3590\"]]},{\"id\":\"3dfc9b74f5e36bec\",\"type\":\"debug\",\"z\":\"239c9025714089d3\",\"name\":\"\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":650,\"y\":320,\"wires\":",[627,9067],{},"},{\"id\":\"0d831bd9ba588536\",\"type\":\"mqtt-sparkplug-broker\",\"name\":\"Local Host\",\"deviceGroup\":\"My Devices\",\"eonName\":\"Node-Red\",\"broker\":\"localhost\",\"port\":\"1883\",\"tls\":\"\",\"clientid\":\"\",\"usetls\":false,\"protocolVersion\":\"4\",\"keepalive\":\"60\",\"cleansession\":true,\"enableStoreForward\":false,\"compressAlgorithm\":\"\",\"aliasMetrics\":true,\"manualEoNBirth\":false,\"primaryScada\":\"\"}",[494,9070,9072],{"id":9071},"receiving-data-from-mqtt-with-sparkplug-b","Receiving Data from MQTT with Sparkplug B",[303,9074,9075,9078,9081,9095,9098,9101,9104],{},[306,9076,9077],{},"Drag the mqtt sparkplug in node onto the canvas.",[306,9079,9080],{},"Double-click the node and configure the broker settings.",[306,9082,9083,9084,9087,9088,9090,9091,9094],{},"Enter the topic in the \"Topic\" field in the format ",[22,9085,9086],{},"namespace\u002Fgroup_id\u002Fmessage_type\u002Fedge_node_id\u002F[device_id]",". Use ",[22,9089,8343],{}," for receiving metrics you are sending using device node or a wildcard like ",[22,9092,9093],{},"spBv1.0\u002Fgroup_id\u002F+\u002F+\u002F[device_id]"," to listen to all message types from a specific device.",[306,9096,9097],{},"Select the desired \"QoS\" level.",[306,9099,9100],{},"Drag a debug node onto the canvas.",[306,9102,9103],{},"Connect the mqtt sparkplug in node’s output to the debug node’s input.",[306,9105,9106],{},"Click \"Deploy\" to save and run the flow.",[15,9108,9109,9110,3095,9112,9114],{},"Now you will be able to see the ",[22,9111,8409],{},[22,9113,8343],{}," messages printed on the debug panel.",[15,9116,4766,9117,2115],{},[627,9118,9119,9120,9068],{},"{\"id\":\"a98c49d80bb5c4ee\",\"type\":\"mqtt sparkplug in\",\"z\":\"239c9025714089d3\",\"name\":\"\",\"topic\":\"spBv1.0\u002FMy Devices\u002FDDATA\u002FNode-RED\u002FMachine1\",\"qos\":\"2\",\"broker\":\"0d831bd9ba588536\",\"x\":330,\"y\":120,\"wires\":[[\"655761fb21409216\"]]},{\"id\":\"655761fb21409216\",\"type\":\"debug\",\"z\":\"239c9025714089d3\",\"name\":\"debug 1\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":800,\"y\":120,\"wires\":",[627,9121],{},[494,9123,9125],{"id":9124},"sending-commands-for-devices-and-eon-nodes","Sending Commands for devices and EoN nodes",[15,9127,9128],{},"Beyond data exchange, MQTT Sparkplug B allows you to send commands for managing devices and Edge of Network (EoN) nodes, such as initiating a device's rebirth or signalling its death.",[303,9130,9131,9134],{},[306,9132,9133],{},"Drag inject node onto the canvas.",[306,9135,2638,9136,9139],{},[22,9137,9138],{},"msg.command"," in the inject node to the desired command. For instance, you can use the following JSON object to send a command that triggers a device's death:",[619,9141,9143],{"className":621,"code":9142,"language":623,"meta":369,"style":369},"    {\n        \"device\" : {\n            \"death\" : true\n        }\n    }   \n",[22,9144,9145,9150,9164,9178,9182],{"__ignoreMap":369},[627,9146,9147],{"class":629,"line":630},[627,9148,9149],{"class":633},"    {\n",[627,9151,9152,9155,9157,9159,9162],{"class":629,"line":373},[627,9153,9154],{"class":633},"        \"",[627,9156,2528],{"class":642},[627,9158,646],{"class":633},[627,9160,9161],{"class":633}," :",[627,9163,2396],{"class":633},[627,9165,9166,9168,9171,9173,9175],{"class":629,"line":659},[627,9167,8907],{"class":633},[627,9169,9170],{"class":8910},"death",[627,9172,646],{"class":633},[627,9174,9161],{"class":633},[627,9176,9177],{"class":633}," true\n",[627,9179,9180],{"class":629,"line":370},[627,9181,8986],{"class":633},[627,9183,9184],{"class":629,"line":698},[627,9185,9186],{"class":633},"    }\n",[15,9188,9189],{},"Alternatively, to send a command that triggers a device's rebirth, use:",[619,9191,9193],{"className":621,"code":9192,"language":623,"meta":369,"style":369},"    {\n        \"device\" : {\n            \"rebirth\" : true\n        }\n    }   \n",[22,9194,9195,9199,9211,9224,9228],{"__ignoreMap":369},[627,9196,9197],{"class":629,"line":630},[627,9198,9149],{"class":633},[627,9200,9201,9203,9205,9207,9209],{"class":629,"line":373},[627,9202,9154],{"class":633},[627,9204,2528],{"class":642},[627,9206,646],{"class":633},[627,9208,9161],{"class":633},[627,9210,2396],{"class":633},[627,9212,9213,9215,9218,9220,9222],{"class":629,"line":659},[627,9214,8907],{"class":633},[627,9216,9217],{"class":8910},"rebirth",[627,9219,646],{"class":633},[627,9221,9161],{"class":633},[627,9223,9177],{"class":633},[627,9225,9226],{"class":629,"line":370},[627,9227,8986],{"class":633},[627,9229,9230],{"class":629,"line":698},[627,9231,9186],{"class":633},[303,9233,9234,9237,9240],{"start":659},[306,9235,9236],{},"Connect the output of the inject node to the input of the relevant mqtt sparkplug device node.",[306,9238,9239],{},"Deploy the flow by clicking the Deploy button at the top-right of the Node-RED interface.",[306,9241,9242],{},"Click the inject node’s button to send the command.",[15,9244,9245,9246,367],{},"In this example, we've used an inject node to manually send commands, but you can also trigger these commands based on other inputs or conditions within your flow, such as device status or sensor data. For more information on available commands and advanced configurations, refer to the ",[172,9247,9249],{"href":8809,"rel":9248},[176],"MQTT Sparkplug nodes documentation",[15,9251,4766,9252,2115],{},[627,9253,9254,9255,9258,9259,9261,9262,9265,9266,9269],{},"{\"id\":\"f2864f2b830e3590\",\"type\":\"mqtt sparkplug device\",\"z\":\"239c9025714089d3\",\"name\":\"Machine1\",\"metrics\":{\"sensor\u002Ftemperature\":{\"dataType\":\"Float\"},\"sensor\u002Fhumidity\":{\"dataType\":\"Float\"}},\"broker\":\"0d831bd9ba588536\",\"birthImmediately\":true,\"bufferDevice\":false,\"x\":440,\"y\":320,\"wires\":[[\"3dfc9b74f5e36bec\"]]},{\"id\":\"90cc413f58871fc1\",\"type\":\"inject\",\"z\":\"239c9025714089d3\",\"name\":\"Send connect command\",\"props\":",[627,9256,9257],{},"{\"p\":\"command\",\"v\":\"{\"node\":{\"connect\":true}}\",\"vt\":\"jsonata\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":170,\"y\":260,\"wires\":[[\"f2864f2b830e3590\"]]},{\"id\":\"3dfc9b74f5e36bec\",\"type\":\"debug\",\"z\":\"239c9025714089d3\",\"name\":\"\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":650,\"y\":320,\"wires\":",[627,9260],{},"},{\"id\":\"915ca0772eebee04\",\"type\":\"inject\",\"z\":\"239c9025714089d3\",\"name\":\"Send rebirth command\",\"props\":",[627,9263,9264],{},"{\"p\":\"command\",\"v\":\"{\"device\":{\"rebirth\":true}}\",\"vt\":\"json\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":160,\"y\":320,\"wires\":[[\"f2864f2b830e3590\"]]},{\"id\":\"696db58cc9eb029d\",\"type\":\"inject\",\"z\":\"239c9025714089d3\",\"name\":\"Send death command\",\"props\":",[627,9267,9268],{},"{\"p\":\"command\",\"v\":\"{\"device\":{\"death\":true}}\",\"vt\":\"json\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":160,\"y\":380,\"wires\":[[\"f2864f2b830e3590\"]]},{\"id\":\"0d831bd9ba588536\",\"type\":\"mqtt-sparkplug-broker\",\"name\":\"Local Host\",\"deviceGroup\":\"My Devices\",\"eonName\":\"Node-Red\",\"broker\":\"localhost\",\"port\":\"1883\",\"tls\":\"\",\"clientid\":\"\",\"usetls\":false,\"protocolVersion\":\"4\",\"keepalive\":\"60\",\"cleansession\":true,\"enableStoreForward\":false,\"compressAlgorithm\":\"\",\"aliasMetrics\":true,\"manualEoNBirth\":true,\"primaryScada\":\"\"}",[15,9271,9272],{},"If you need more flexibility in defining topic names when sending data, you can use the mqtt sparkplug out node. It’s quite similar to the standard mqtt out node but is designed to handle Sparkplug-encoded messages. Below is an example showing how to use the mqtt sparkplug out node with in nodes.",[15,9274,4766,9275,2115],{},[627,9276,9277,9278,9280,9281,9283,9284,9061,9286,9289],{},"{\"id\":\"bbe3765e67eed956\",\"type\":\"mqtt sparkplug in\",\"z\":\"f098830cc10afc2f\",\"name\":\"\",\"topic\":\"spBv1.0\u002F+\u002F+\u002F#\",\"qos\":\"2\",\"broker\":\"0d831bd9ba588536\",\"x\":150,\"y\":100,\"wires\":[[\"d45ff4446380beaa\"]]},{\"id\":\"3b2b9788c51d5c3b\",\"type\":\"mqtt sparkplug out\",\"z\":\"f098830cc10afc2f\",\"name\":\"\",\"topic\":\"spBv1.0\u002FMy Devices\u002FNDATA\u002FNode-Red\",\"qos\":\"\",\"retain\":\"\",\"broker\":\"0d831bd9ba588536\",\"x\":510,\"y\":200,\"wires\":",[627,9279],{},"},{\"id\":\"d45ff4446380beaa\",\"type\":\"debug\",\"z\":\"f098830cc10afc2f\",\"name\":\"\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"false\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":410,\"y\":100,\"wires\":",[627,9282],{},"},{\"id\":\"dc73048fd385783a\",\"type\":\"inject\",\"z\":\"f098830cc10afc2f\",\"name\":\"Send Metrics\",\"props\":",[627,9285,2110],{},[627,9287,9288],{},"        {            \"name\": \"sensor\u002Ftemperature\",            \"value\": $random(),            \"type\": \"Float\"        },        {            \"name\": \"sensor\u002Fhumidity\",            \"value\": $random(),            \"type\": \"Float\"        }","}\",\"payloadType\":\"jsonata\",\"x\":170,\"y\":220,\"wires\":[[\"3b2b9788c51d5c3b\"]]},{\"id\":\"0d831bd9ba588536\",\"type\":\"mqtt-sparkplug-broker\",\"name\":\"Local Host\",\"deviceGroup\":\"My Devices\",\"eonName\":\"Node-Red\",\"broker\":\"localhost\",\"port\":\"1883\",\"tls\":\"\",\"clientid\":\"\",\"usetls\":false,\"protocolVersion\":\"4\",\"keepalive\":\"60\",\"cleansession\":true,\"enableStoreForward\":false,\"compressAlgorithm\":\"\",\"aliasMetrics\":true,\"manualEoNBirth\":false,\"primaryScada\":\"\"}",[15,9291,9292,9297],{},[489,9293],{"alt":9294,"src":9295,"title":9296},"\"Images of some Sparkplug messages printed on debug panel\"","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fsparkplug-messages.png","Images of some Sparkplug messages printed on debug panel",[1235,9298,9296],{},[37,9300,9302],{"id":9301},"best-practices-for-production-deployments","Best Practices for Production Deployments",[15,9304,9305],{},"Getting Sparkplug B working is only the first step. Running it reliably in production means thinking about naming, state, performance, and failure handling from day one. The best practices below focus on the things that matter most once your system is live, keeping data trustworthy, networks efficient, and recovery predictable.",[431,9307,9308,9314,9325,9331,9341,9347,9353],{},[306,9309,9310,9313],{},[309,9311,9312],{},"Name things like you mean it","\nUse clear group, edge, and device names that match your factory or system layout. Future you will thank you.",[306,9315,9316,9319,9320,1289,9322,9324],{},[309,9317,9318],{},"Birth messages are non-negotiable","\nAlways send ",[22,9321,8312],{},[22,9323,8409],{}," on start and reconnect. If apps don’t see a birth, they don’t trust the data.",[306,9326,9327,9330],{},[309,9328,9329],{},"Alias your metrics","\nTurn on metric aliasing to cut payload size and keep networks fast and efficient.",[306,9332,9333,9336,1289,9338,9340],{},[309,9334,9335],{},"Listen for Death messages",[22,9337,8416],{},[22,9339,8419],{}," are early warning signals. Use them to detect failures instantly.",[306,9342,9343,9346],{},[309,9344,9345],{},"Buffer with intent","\nStore-and-forward is great for flaky networks, just don’t let backlogs pile up unchecked.",[306,9348,9349,9352],{},[309,9350,9351],{},"Lock down MQTT early","\nUse TLS, authentication, and topic permissions from day one. Security is easier before go-live.",[306,9354,9355,9358],{},[309,9356,9357],{},"Break it on purpose","\nRestart brokers and edge nodes during testing. A system that recovers cleanly is production-ready.",[37,9360,884],{"id":883},[15,9362,9363],{},"MQTT Sparkplug B transforms MQTT from a simple messaging protocol into a robust, standardized framework for industrial IoT. By enforcing structured topics, typed metrics, state awareness, and efficient payloads, it makes integrating heterogeneous devices predictable, scalable, and reliable.",[15,9365,9366],{},"Following best practices (clear naming, birth\u002Fdeath messages, metric aliasing, buffering, security, and deliberate testing) ensures your system runs smoothly in production and avoids costly downtime.",[15,9368,9369],{},"For teams looking to get Sparkplug B up and running quickly, [FlowFuse]({% include \"sign-up-url.njk\" %}) provides a production-ready, easy-to-use platform. With minimal setup and no advanced skills required, you can deploy, scale, and monitor industrial flows in minutes. Start building your reliable, standardized IIoT solution today.",[898,9371,9372],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":369,"searchDepth":370,"depth":370,"links":9374},[9375,9378,9383,9391,9392,9399,9400],{"id":8219,"depth":373,"text":8220,"children":9376},[9377],{"id":8245,"depth":659,"text":8246},{"id":8292,"depth":373,"text":8293,"children":9379},[9380,9381,9382],{"id":8299,"depth":659,"text":8300},{"id":8316,"depth":659,"text":8317},{"id":8326,"depth":659,"text":8327},{"id":8350,"depth":373,"text":8351,"children":9384},[9385,9386,9387,9388,9389,9390],{"id":8360,"depth":659,"text":8351},{"id":8366,"depth":659,"text":8367},{"id":8387,"depth":659,"text":8388},{"id":8399,"depth":659,"text":8400},{"id":8423,"depth":659,"text":8424},{"id":8433,"depth":659,"text":8434},{"id":8461,"depth":373,"text":8462},{"id":8772,"depth":373,"text":8773,"children":9393},[9394,9395,9396,9397,9398],{"id":8797,"depth":659,"text":8798},{"id":8821,"depth":659,"text":8822},{"id":8866,"depth":659,"text":8867},{"id":9071,"depth":659,"text":9072},{"id":9124,"depth":659,"text":9125},{"id":9301,"depth":373,"text":9302},{"id":883,"depth":373,"text":884},"2024-08-22","Learn how to implement MQTT Sparkplug B with Node-RED for standardized, reliable Industrial IoT data flows and scalable production deployments.","2025-12-22",{"keywords":9405,"excerpt":9406},"node red, mqtt sparkplug, industrial IoT",{"type":12,"value":9407},[9408],[15,9409,8216],{},"\u002Fblog\u002F2024\u002F08\u002Fusing-mqtt-sparkplugb-with-node-red",{"title":8210,"description":9402},{"loc":9410},"blog\u002F2024\u002F08\u002Fusing-mqtt-sparkplugb-with-node-red","Standardize and manage industrial IoT data with MQTT Sparkplug B",[8205,7964,402],"MQTT Sparkplug B extends plain MQTT with standardized topic namespaces, Protocol Buffer payloads, and lifecycle state messages (birth\u002Fdeath) to solve the integration chaos common in industrial IoT. This guide explains the specification and shows how to use the node-red-contrib-mqtt-sparkplug-plus package to publish and receive Sparkplug B messages in Node-RED.","qcbJeRULdsdm-dPPEZH61Qe3xnGS_7V0Mwr6lc92DvE",{"id":9419,"title":9420,"authors":9421,"body":9422,"cta":9904,"date":9907,"description":9908,"extension":386,"image":9909,"lastUpdated":7951,"meta":9910,"navigation":394,"path":9916,"seo":9917,"sitemap":9918,"stem":9919,"subtitle":9920,"tags":9921,"tldr":9922,"video":3,"__hash__":9923},"blog\u002Fblog\u002F2024\u002F08\u002Fopc-ua-to-mqtt-with-node-red.md","Bridging OPC UA Data to MQTT with Node-RED (2026)",[10],{"type":12,"value":9423,"toc":9892},[9424,9427,9430,9434,9443,9446,9449,9458,9462,9465,9467,9492,9496,9499,9516,9524,9532,9541,9549,9557,9595,9598,9602,9605,9623,9631,9670,9674,9677,9686,9694,9710,9718,9775,9779,9782,9785,9818,9826,9853,9857],[15,9425,9426],{},"Have you ever found yourself trying to connect old industrial systems with new IoT tools? This is a common scenario when trying to digitally transform while setting up your Unified Name Space. Maybe you have machinery that uses OPC UA, but your data is sent through MQTT. How do you make these systems work together smoothly?",[15,9428,9429],{},"In this guide, we'll demonstrate how to use Node-RED to bridge OPC UA data to MQTT. This integration will streamline your data flow and enhance real-time monitoring, helping you modernize your setup and improve communication between systems.",[494,9431,9433],{"id":9432},"why-bridge-opc-ua-to-mqtt","Why Bridge OPC UA to MQTT",[15,9435,9436,9440],{},[489,9437],{"alt":9438,"dataZoomable":369,"src":9439},"Diagram showing the data flow when bridging OPC UA to MQTT to enable communication between non-OPC UA compatible systems and devices","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopc-ua-to-mqtt.png",[1235,9441,9442],{},"Diagram showing the data flow when bridging OPC UA to MQTT to enable communication between non-OPC UA compatible systems and devices.",[15,9444,9445],{},"In modern industrial environments, integrating systems with different communication protocols can be a significant challenge. For example, a CNC machine on the factory floor might use OPC UA, while some cloud solutions, edge devices, and other systems, such as custom ERP solutions and IoT applications, might rely on MQTT protocol. This is where bridging OPC UA to MQTT becomes highly beneficial.",[15,9447,9448],{},"By converting OPC UA data into MQTT messages, you make the data from the CNC machine accessible to a broader range of systems that use MQTT, which is a more universally supported messaging protocol. This bridging solution simplifies the integration process, allowing diverse systems to communicate effectively without needing direct OPC UA support.",[15,9450,9451,9453,9454,367],{},[309,9452,424],{}," is perfect for this job. It can connect both OPC UA and MQTT, making it easy to transform and route data between different systems. Its flexibility and support for many protocols make it great for integrating various industrial hardware and software. For more on how Node-RED can improve industrial operations, check out ",[172,9455,9457],{"href":9456},"\u002Fblog\u002F2024\u002F07\u002Fbuilding-on-flowfuse-devices\u002F","Building on FlowFuse: Remote Device Monitoring",[37,9459,9461],{"id":9460},"bridging-opc-ua-data-to-mqtt-with-node-red","Bridging OPC UA Data to MQTT with Node-RED",[15,9463,9464],{},"In this section, I'll demonstrate how to bridge OPC UA data to MQTT using Node-RED. We will use simulated OPC UA server data from a CNC machine as an example. The goal is to show how you can efficiently transfer this data to an MQTT broker, making it accessible to various applications and systems.",[494,9466,8798],{"id":8797},[431,9468,9469,9476,9479,9486],{},[306,9470,9471,9472,367],{},"OPC UA Server: Make sure you have an OPC UA server configured and running with the necessary data. For this blog, we'll use the Prosys OPC UA Simulation Server, which simulates data from CNC machines designed for testing OPC UA client applications and learning the technology. You can download it from ",[172,9473,5668],{"href":9474,"rel":9475},"https:\u002F\u002Fprosysopc.com\u002Fproducts\u002Fopc-ua-simulation-server\u002F",[176],[306,9477,9478],{},"FlowFuse Account: A FlowFuse account lets you quickly create, deploy, and manage Node-RED instances in the cloud. [sign up now]({% include \"sign-up-url.njk\" %}?utm_campaign=60718323-BCTA&utm_source=blog&utm_medium=cta&utm_term=high_intent&utm_content=Bridging%20OPC%20UA%20Data%20to%20MQTT%20with%20Node-RED).",[306,9480,9481,9485],{},[172,9482,4061],{"href":9483,"rel":9484},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002Fnode-red-contrib-opcua",[176],": install the node-red contrib package that will enable integration of opcua in Node-RED.",[306,9487,9488,9489,367],{},"MQTT Broker: We’ll need an MQTT broker for data communication. FlowFuse offers an integrated MQTT Broker Service within Platform for easy setup. For more details, check out ",[172,9490,9491],{"href":6130},"FlowFuse's MQTT Broker Announcement",[494,9493,9495],{"id":9494},"retrieving-data-from-the-opc-ua-server","Retrieving Data from the OPC UA Server",[15,9497,9498],{},"To begin retrieving data from your OPC UA server using Node-RED, follow these steps:",[303,9500,9501,9507],{},[306,9502,2134,9503,9506],{},[309,9504,9505],{},"inject"," node onto the canvas.",[306,9508,2134,9509,9512,9513,9515],{},[309,9510,9511],{},"change"," node onto the canvas and double-click on the node to open its configuration settings. Set the ",[22,9514,4686],{}," to the node ID and datatype of the property you wish to read.",[15,9517,9518,9522],{},[489,9519],{"alt":9520,"dataZoomable":369,"src":9521},"(Left) Image of the Change node setting the 'msg.topic' to retrieve the cycle time data and (Right) the OPC UA Prosys interface.","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fchange-node-setting-nodeid-datatype.png",[1235,9523,9520],{},[303,9525,9526],{"start":373},[306,9527,2134,9528,9531],{},[309,9529,9530],{},"OpcUa-Client"," node onto the canvas. Double-click on it to open its configuration settings. Click the \"+\" icon next to the Endpoint field and enter the URL of your running OPC UA server. Configure the security policy and mode according to your server setup. If you use the Prosys OPC UA Simulation Server and have not enabled any security features, you can leave the security policy and mode as \"None.\"",[15,9533,9534,9538],{},[489,9535],{"alt":9536,"dataZoomable":369,"src":9537},"Configuring opc-ua client node with the opc ua server endpoint","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopc-ua-config.png",[1235,9539,9540],{},"Configuring opc-ua node with the opc ua server endpoint",[303,9542,9543],{"start":659},[306,9544,9545,9546,9548],{},"In the ",[309,9547,9530],{}," node settings, select the action type as \"READ.\" This instructs Node-RED to read data from the OPC UA server.",[15,9550,9551,9555],{},[489,9552],{"alt":9553,"dataZoomable":369,"src":9554},"Configuring OpcUa-Client node to select the read operation","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopc-ua-config2.png",[1235,9556,9553],{},[303,9558,9559,9562,9568,9592],{"start":370},[306,9560,9561],{},"If your OPC UA server uses security features, specify the path to your certificate files in the relevant fields. If no security is configured, this step can be skipped.",[306,9563,2134,9564,9567],{},[309,9565,9566],{},"debug"," node onto the canvas. The output will help you verify the data retrieved from the OPC UA server.",[306,9569,2179,9570,9572,9573,9575,9576,9572,9578,9580,9581,9572,9583,9585,9586,9588,9589,9591],{},[309,9571,9505],{}," node to the input of the ",[309,9574,9511],{}," node and the output of the ",[309,9577,9511],{},[309,9579,9530],{}," node. Then, connect the output of the ",[309,9582,9530],{},[309,9584,9566],{}," node. This setup ensures that when the ",[309,9587,9505],{}," node triggers, it sends data to the ",[309,9590,9530],{}," node, and the results are displayed in the Debug node.",[306,9593,9594],{},"Deploy the flow by clicking the \"Deploy\" button in the top right corner. To test the setup, press the Inject button.",[15,9596,9597],{},"You can follow the same steps to retrieve other property values from the OPC UA server. In this example, we are retrieving four simulated data properties: the cycle time, temperature, and spindle speed of the simulated CNC machine. Your setup might differ depending on the properties and data available on your OPC UA server.",[494,9599,9601],{"id":9600},"transforming-and-aggregating-data","Transforming and Aggregating Data",[15,9603,9604],{},"Once you have successfully retrieved data from your OPC UA server, the next step is to transform and aggregate this data to make it suitable for publishing to an MQTT broker. This demonstration, we will aggregate the retrieved individual property values into a single object. Depending on your specific needs, you might choose to split the object properties and send them separately or perform various calculations and transformations on the data.",[303,9606,9607,9611],{},[306,9608,2134,9609,9506],{},[309,9610,9511],{},[306,9612,9613,9614,9616,9617,4324,9619,9622],{},"Double-click on the node and set ",[22,9615,4686],{}," to the name of the property you want to set for the retrieved data. In this context, set ",[22,9618,4686],{},[22,9620,9621],{},"'cycle-time'",", which will be the key in the object that we will create.",[15,9624,9625,9628],{},[489,9626],{"alt":9627,"dataZoomable":369,"src":9521},"Setting the msg.topic with the Change node to retrieve data from the OPC UA server.",[1235,9629,9630],{},"Setting the msg.topic with the change node to retrieve data from the OPC UA server.",[303,9632,9633,9647,9661,9667],{"start":659},[306,9634,2134,9635,9637,9638,9640,9641,9643,9644,9646],{},[309,9636,3525],{}," node onto the canvas. Set the mode to manual, with the option to create ",[22,9639,616],{}," using the values of ",[22,9642,4686],{}," as keys. Set the count to 3 and ensure that the interval for all of the ",[309,9645,9505],{}," nodes triggering data retrieval is the same. This ensures that the data is collected and aggregated correctly at the same time.",[306,9648,2179,9649,9651,9652,9654,9655,9657,9658,9660],{},[309,9650,9530],{}," node (which retrieves the data) to the input of the ",[309,9653,9511],{}," node. For example, if I have set the ",[309,9656,9511],{}," node for the 'cycle-time' data property, connect it to the ",[309,9659,9530],{}," node that retrieves this data.",[306,9662,2179,9663,9572,9665,2191],{},[309,9664,9511],{},[309,9666,3525],{},[306,9668,9669],{},"Repeat this process for all of your data properties.",[494,9671,9673],{"id":9672},"sending-data-to-the-mqtt-broker","Sending Data to the MQTT Broker",[15,9675,9676],{},"Now, in this section, we will show you how to send the collected data to an MQTT broker:",[303,9678,9679,9683],{},[306,9680,2134,9681,9506],{},[309,9682,7203],{},[306,9684,9685],{},"Double-click on it and configure it with your MQTT broker details.",[15,9687,9688,9692],{},[489,9689],{"alt":9690,"dataZoomable":369,"src":9691},"Configuring the mqtt out node with broker information","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-out-node-config.png",[1235,9693,9690],{},[303,9695,9696,9701,9707],{"start":659},[306,9697,9698,9699,2191],{},"Set the topic for your data in the ",[309,9700,7203],{},[306,9702,2179,9703,9572,9705,2191],{},[309,9704,3525],{},[309,9706,7203],{},[306,9708,9709],{},"Deploy the flow. After deploying, you will see the status \"connected\" with a green dot at the bottom of each node, indicating that you have successfully connected to your MQTT broker.",[15,9711,9712,9716],{},[489,9713],{"alt":9714,"dataZoomable":369,"src":9715},"Image showing the successful bridging of OPC UA data to MQTT","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopcua-to-mqtt.gif",[1235,9717,9714],{},[15,9719,4766,9720,2115],{},[627,9721,9722,9723,9725,9726,9728,9729,9731,9732,9734,9735,9738,9739,9742,9743,9746,9747,9749,9750,9752,9753,9755,9756,9759,9760,9763,9764,9767,9768,9770,9771],{},"{\"id\":\"a099aefb08837e70\",\"type\":\"OpcUa-Client\",\"z\":\"807758ec576fbfd8\",\"endpoint\":\"9dd56eda04f5c5b5\",\"action\":\"read\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":1,\"maxMessageSize\":8192,\"receiveBufferSize\":8192,\"sendBufferSize\":8192,\"name\":\"\",\"x\":480,\"y\":320,\"wires\":[[\"f5fd1ffafdfe790f\"],",[627,9724],{},"]},{\"id\":\"1aa02b27b99dfe9d\",\"type\":\"mqtt out\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"topic\":\"\u002Fmanufacturing\u002Fcnc\",\"qos\":\"2\",\"retain\":\"true\",\"respTopic\":\"\",\"contentType\":\"\",\"userProps\":\"\",\"correl\":\"\",\"expiry\":\"\",\"broker\":\"abd4e6202945fee3\",\"x\":1390,\"y\":380,\"wires\":",[627,9727],{},"},{\"id\":\"d565ae620d90498a\",\"type\":\"OpcUa-Client\",\"z\":\"807758ec576fbfd8\",\"endpoint\":\"9dd56eda04f5c5b5\",\"action\":\"read\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":1,\"maxMessageSize\":8192,\"receiveBufferSize\":8192,\"sendBufferSize\":8192,\"name\":\"\",\"x\":480,\"y\":400,\"wires\":[[\"fc4b83a8a0be3a35\"],",[627,9730],{},"]},{\"id\":\"0e0614ada3269627\",\"type\":\"OpcUa-Client\",\"z\":\"807758ec576fbfd8\",\"endpoint\":\"9dd56eda04f5c5b5\",\"action\":\"read\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":1,\"maxMessageSize\":8192,\"receiveBufferSize\":8192,\"sendBufferSize\":8192,\"name\":\"\",\"x\":480,\"y\":480,\"wires\":[[\"e1c4fe72e4f37b6a\"],",[627,9733],{},"]},{\"id\":\"f5fd1ffafdfe790f\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"Set the topic for the data\",\"rules\":",[627,9736,9737],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"cycle-time\",\"tot\":\"str\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":730,\"y\":300,\"wires\":[[\"913e9de1324a6f21\"]]},{\"id\":\"fc4b83a8a0be3a35\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"Set the topic for the data\",\"rules\":",[627,9740,9741],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"spindle-speed\",\"tot\":\"str\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":730,\"y\":380,\"wires\":[[\"913e9de1324a6f21\"]]},{\"id\":\"e1c4fe72e4f37b6a\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"Set the topic for the data\",\"rules\":",[627,9744,9745],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"temperature\",\"tot\":\"str\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":730,\"y\":460,\"wires\":[[\"913e9de1324a6f21\"]]},{\"id\":\"913e9de1324a6f21\",\"type\":\"join\",\"z\":\"807758ec576fbfd8\",\"name\":\"Create object from those three data property \",\"mode\":\"custom\",\"build\":\"object\",\"property\":\"payload\",\"propertyType\":\"msg\",\"key\":\"topic\",\"joiner\":\"\\n\",\"joinerType\":\"str\",\"useparts\":false,\"accumulate\":false,\"timeout\":\"\",\"count\":\"3\",\"reduceRight\":false,\"reduceExp\":\"\",\"reduceInit\":\"\",\"reduceInitType\":\"\",\"reduceFixup\":\"\",\"x\":1080,\"y\":380,\"wires\":[[\"1aa02b27b99dfe9d\"]]},{\"id\":\"3339483f64116fce\",\"type\":\"mqtt in\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"topic\":\"\u002Fmanufacturing\u002Fcnc\",\"qos\":\"2\",\"datatype\":\"auto-detect\",\"broker\":\"abd4e6202945fee3\",\"nl\":false,\"rap\":true,\"rh\":0,\"inputs\":0,\"x\":170,\"y\":660,\"wires\":[[\"d881d251071bd317\"]]},{\"id\":\"d881d251071bd317\",\"type\":\"debug\",\"z\":\"807758ec576fbfd8\",\"name\":\"debug 1\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"false\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":460,\"y\":660,\"wires\":",[627,9748],{},"},{\"id\":\"55f43460af9601ec\",\"type\":\"comment\",\"z\":\"807758ec576fbfd8\",\"name\":\"Retrieving the data from mqtt\",\"info\":\"\",\"x\":320,\"y\":600,\"wires\":",[627,9751],{},"},{\"id\":\"628ab54495901021\",\"type\":\"comment\",\"z\":\"807758ec576fbfd8\",\"name\":\"Bridging OPC UA data to MQTT\",\"info\":\"\",\"x\":350,\"y\":240,\"wires\":",[627,9754],{},"},{\"id\":\"ce6b8a0e2c8a895d\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"rules\":",[627,9757,9758],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"ns=3;i=1010,datatype=float\",\"tot\":\"str\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":290,\"y\":320,\"wires\":[[\"a099aefb08837e70\"]]},{\"id\":\"50fe2b9310d3bb3f\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"rules\":",[627,9761,9762],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"ns=3;i=1011,datatype=basedatatype\",\"tot\":\"str\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":290,\"y\":400,\"wires\":[[\"d565ae620d90498a\"]]},{\"id\":\"9cf691f55748d013\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"rules\":",[627,9765,9766],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"ns=3;i=1012,datatype=float\",\"tot\":\"str\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":290,\"y\":480,\"wires\":[[\"0e0614ada3269627\"]]},{\"id\":\"de74dabc616c3094\",\"type\":\"inject\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"props\":",[627,9769,9060],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":120,\"y\":400,\"wires\":[[\"ce6b8a0e2c8a895d\",\"50fe2b9310d3bb3f\",\"9cf691f55748d013\"]]},{\"id\":\"9dd56eda04f5c5b5\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"opc.tcp:\u002F\u002FRoni:53530\u002FOPCUA\u002FSimulationServer\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"},{\"id\":\"abd4e6202945fee3\",\"type\":\"mqtt-broker\",\"name\":\"\",\"broker\":\"",[172,9772,9774],{"rel":9773},[176],"http:\u002F\u002Fbroker.hivemq.com\",\"port\":\"1883\",\"clientid\":\"\",\"autoConnect\":true,\"usetls\":false,\"protocolVersion\":\"4\",\"keepalive\":\"60\",\"cleansession\":true,\"autoUnsubscribe\":true,\"birthTopic\":\"\",\"birthQos\":\"0\",\"birthRetain\":\"false\",\"birthPayload\":\"\",\"birthMsg\":{},\"closeTopic\":\"\",\"closeQos\":\"0\",\"closeRetain\":\"false\",\"closePayload\":\"\",\"closeMsg\":{},\"willTopic\":\"\",\"willQos\":\"0\",\"willRetain\":\"false\",\"willPayload\":\"\",\"willMsg\":{},\"userProps\":\"\",\"sessionExpiry\":\"\"}",[37,9776,9778],{"id":9777},"bridging-mqtt-data-to-opc-ua","Bridging MQTT Data to OPC UA",[15,9780,9781],{},"In addition to bridging data from OPC UA to MQTT, you might also need to send data from MQTT back to an OPC UA server. This is often required in scenarios where external systems, such as Manufacturing Execution Systems (MES), need to update or control machinery settings.",[15,9783,9784],{},"For example, an MES can send commands or configuration changes via MQTT, which then need to be applied to an OPC UA-controlled machine.",[303,9786,9787,9793,9801,9807],{},[306,9788,2697,9789,9792],{},[309,9790,9791],{},"mqtt in"," node onto the Node-RED canvas and configure it with your MQTT broker details and the appropriate topic where the MES publishes commands.",[306,9794,2134,9795,9797,9798,9800],{},[309,9796,9511],{}," node onto the canvas, Set the ",[22,9799,4686],{}," to the node ID and datatype of the property you wish to update.",[306,9802,9803,9804,9806],{},"Add an ",[309,9805,9530],{}," node to the canvas and configure it with your OPC UA server. Set the action type to \"WRITE\" to send the received data.",[306,9808,2179,9809,9572,9811,9813,9814,9572,9816,2191],{},[309,9810,9791],{},[309,9812,9511],{}," node, and the output of the ",[309,9815,9511],{},[309,9817,9530],{},[15,9819,9820,9824],{},[489,9821],{"alt":9822,"dataZoomable":369,"src":9823},"Image showing the successful bridging of MQTT data to OPC UA","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-to-opcua.gif",[1235,9825,9714],{},[15,9827,4766,9828,2115],{},[627,9829,9830,9831,9833,9834,9836,9837,9840,9841,9843,9844,9846,9847,9849,9850],{},"{\"id\":\"a099aefb08837e70\",\"type\":\"OpcUa-Client\",\"z\":\"FFF0000000000001\",\"endpoint\":\"9dd56eda04f5c5b5\",\"action\":\"write\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":1,\"maxMessageSize\":8192,\"receiveBufferSize\":8192,\"sendBufferSize\":8192,\"name\":\"\",\"x\":760,\"y\":220,\"wires\":[[],",[627,9832],{},"]},{\"id\":\"628ab54495901021\",\"type\":\"comment\",\"z\":\"FFF0000000000001\",\"name\":\"Bridging MQTT to OPC UA\",\"info\":\"\",\"x\":510,\"y\":140,\"wires\":",[627,9835],{},"},{\"id\":\"ce6b8a0e2c8a895d\",\"type\":\"change\",\"z\":\"FFF0000000000001\",\"name\":\"\",\"rules\":",[627,9838,9839],{},"{\"t\":\"set\",\"p\":\"topic\",\"pt\":\"msg\",\"to\":\"ns=3;i=1010,datatype=Boolean\",\"tot\":\"str\"},{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"paylad\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":540,\"y\":220,\"wires\":[[\"a099aefb08837e70\"]]},{\"id\":\"0a89ebd0d9f6f577\",\"type\":\"mqtt in\",\"z\":\"FFF0000000000001\",\"name\":\"\",\"topic\":\"command\u002Fcnc\u002F\",\"qos\":\"2\",\"datatype\":\"auto-detect\",\"broker\":\"abd4e6202945fee3\",\"nl\":false,\"rap\":true,\"rh\":0,\"inputs\":0,\"x\":300,\"y\":220,\"wires\":[[\"ce6b8a0e2c8a895d\"]]},{\"id\":\"4cf4e425d075722a\",\"type\":\"mqtt out\",\"z\":\"FFF0000000000001\",\"name\":\"\",\"topic\":\"command\u002Fcnc\u002F\",\"qos\":\"1\",\"retain\":\"\",\"respTopic\":\"\",\"contentType\":\"\",\"userProps\":\"\",\"correl\":\"\",\"expiry\":\"\",\"broker\":\"abd4e6202945fee3\",\"x\":660,\"y\":400,\"wires\":",[627,9842],{},"},{\"id\":\"8e339e511c573905\",\"type\":\"inject\",\"z\":\"FFF0000000000001\",\"name\":\"\",\"props\":",[627,9845,2110],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"false\",\"payloadType\":\"bool\",\"x\":330,\"y\":400,\"wires\":[[\"4cf4e425d075722a\"]]},{\"id\":\"9c33cff54b0aca15\",\"type\":\"comment\",\"z\":\"FFF0000000000001\",\"name\":\"Sending Command\",\"info\":\"\",\"x\":490,\"y\":340,\"wires\":",[627,9848],{},"},{\"id\":\"9dd56eda04f5c5b5\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"opc.tcp:\u002F\u002FRoni:53530\u002FOPCUA\u002FSimulationServer\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"},{\"id\":\"abd4e6202945fee3\",\"type\":\"mqtt-broker\",\"name\":\"\",\"broker\":\"",[172,9851,9774],{"rel":9852},[176],[494,9854,9856],{"id":9855},"up-next","Up Next",[431,9858,9859,9864,9871,9878,9885],{},[306,9860,9861,9863],{},[172,9862,6334],{"href":5562},"\nLearn how to integrate MQTT with Node-RED to enhance your IoT solutions with real-time data messaging.",[306,9865,9866,9870],{},[172,9867,9869],{"href":9868},"\u002Fblog\u002F2023\u002F07\u002Fhow-to-build-a-opc-client-dashboard-in-node-red\u002F","How to Build an OPC UA Client Dashboard in Node-RED","\nFollow a step-by-step guide to create a comprehensive OPC UA client dashboard in Node-RED for effective monitoring and control.",[306,9872,9873,9877],{},[172,9874,9876],{"href":9875},"\u002Fnode-red\u002Fprotocol\u002Fopc-ua\u002F","Building a Secure OPC UA Server in Node-RED","\nExplore best practices for configuring a secure OPC UA server in Node-RED to ensure safe and reliable data exchange.",[306,9879,9880,9884],{},[172,9881,9883],{"href":9882},"\u002Fblog\u002F2023\u002F07\u002Fhow-to-deploy-a-basic-opc-ua-server-in-node-red\u002F","How to Deploy a Basic OPC UA Server in Node-RED","\nLearn how to quickly deploy a basic OPC UA server in Node-RED for testing and development purposes.",[306,9886,9887,9891],{},[172,9888,9890],{"href":9889},"\u002Fblog\u002F2023\u002F06\u002Fnode-red-as-a-no-code-ethernet_ip-to-s7-protocol-converter\u002F","Node-RED as a No-Code EtherNet\u002FIP to S7 Protocol Converter","\nDiscover how to use Node-RED to seamlessly convert EtherNet\u002FIP to S7 protocols with Node-RED.",{"title":369,"searchDepth":370,"depth":370,"links":9893},[9894,9895,9901],{"id":9432,"depth":659,"text":9433},{"id":9460,"depth":373,"text":9461,"children":9896},[9897,9898,9899,9900],{"id":8797,"depth":659,"text":8798},{"id":9494,"depth":659,"text":9495},{"id":9600,"depth":659,"text":9601},{"id":9672,"depth":659,"text":9673},{"id":9777,"depth":373,"text":9778,"children":9902},[9903],{"id":9855,"depth":659,"text":9856},{"type":914,"title":9905,"description":9906},"Connect OPC UA and MQTT with Node-RED on FlowFuse","FlowFuse makes it easy to deploy Node-RED in the cloud or at the edge and bridge industrial protocols like OPC UA and MQTT, with built-in MQTT broker support, team collaboration, and production-ready infrastructure.","2024-08-13","Learn how to bridge OPC UA data to MQTT using Node-RED for seamless industrial IoT integration and real-time data flow.","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fbrdging-opcua-to-mqtt.png",{"keywords":9911,"excerpt":9912},"opc ua gateway, opc ua example, node-red-contrib-opcua, nodered opcua, opc ua mqtt, opc ua over mqtt, opc ua to mqtt gateway, mqtt to opc ua, mqtt and opc ua, opc ua and mqtt, opc ua via mqtt, opcua to mqtt",{"type":12,"value":9913},[9914],[15,9915,9426],{},"\u002Fblog\u002F2024\u002F08\u002Fopc-ua-to-mqtt-with-node-red",{"title":9420,"description":9908},{"loc":9916},"blog\u002F2024\u002F08\u002Fopc-ua-to-mqtt-with-node-red","Connecting OPC UA Data Streams to MQTT Brokers for Enhanced IoT Communication and Monitoring",[8205,7964,402,1723,7965],"This guide demonstrates how to connect an OPC UA server to an MQTT broker using Node-RED, allowing industrial machine data to flow into modern IoT systems. It covers installing node-red-contrib-opcua, reading multiple OPC UA node values, aggregating them with a join node, and publishing the result to MQTT. A reverse bridging pattern for sending MQTT commands back to OPC UA is also covered.","1ykI1HGoZ2_Ok3cOEeLGGBNC4WqOMHPU3pfFFRiCFww",{"id":9925,"title":9926,"authors":9927,"body":9928,"cta":10544,"date":10547,"description":10548,"extension":386,"image":10549,"lastUpdated":7951,"meta":10550,"navigation":394,"path":10556,"seo":10557,"sitemap":10558,"stem":10559,"subtitle":10560,"tags":10561,"tldr":10562,"video":3,"__hash__":10563},"blog\u002Fblog\u002F2024\u002F06\u002Fhow-to-use-mqtt-in-node-red.md","Working with MQTT in Node-RED: Complete Guide (2026)",[10],{"type":12,"value":9929,"toc":10531},[9930,9933,9936,9940,9943,9962,9966,9976,9990,9998,10005,10010,10017,10052,10057,10064,10067,10082,10085,10094,10104,10108,10111,10159,10166,10170,10173,10233,10240,10245,10259,10266,10269,10313,10316,10358,10361,10365,10368,10375,10380,10387,10391,10394,10398,10407,10413,10419,10425,10431,10435,10438,10444,10450,10456,10459,10463,10466,10471,10477,10482,10488,10493,10499,10508,10511,10517,10519,10522,10525,10528],[15,9931,9932],{},"MQTT handles the messaging layer for most IoT deployments. Node-RED provides built-in nodes that connect to MQTT brokers, subscribe to topics, and publish messages, all through a visual interface.",[15,9934,9935],{},"This guide walks through the configuration steps and common patterns you'll need for working implementations.",[37,9937,9939],{"id":9938},"what-youll-need","What You'll Need",[15,9941,9942],{},"Before you start, make sure you have:",[431,9944,9945,9956],{},[306,9946,9947,9950,9951,9955],{},[309,9948,9949],{},"Node-RED Instance",": You need Node-RED running somewhere. Easiest option is FlowFuse, grab a ",[172,9952,9954],{"href":1984,"rel":9953},[176],"free trial"," and you get a cloud-hosted instance ready to go. No server setup, no port forwarding hassles.",[306,9957,9958,9961],{},[309,9959,9960],{},"MQTT Broker",": You'll need an MQTT broker to handle message routing. If you're on FlowFuse Pro tier, you get a built-in MQTT broker service, no separate setup needed.",[37,9963,9965],{"id":9964},"getting-connected","Getting Connected",[15,9967,9968,9969,1289,9972,9975],{},"Node-RED ships with MQTT nodes already installed. Open your Node-RED editor and look in the palette, you'll find ",[309,9970,9971],{},"mqtt-in",[309,9973,9974],{},"mqtt-out"," under the network section.",[180,9977,9978],{},[15,9979,9980,9981,1289,9985,9989],{},"If you're using FlowFuse's managed MQTT broker, this is straightforward. Use the ",[172,9982,9984],{"href":9983},"\u002Fnode-red\u002Fflowfuse\u002Fmqtt\u002Fmqtt-in\u002F","ff-mqtt-in",[172,9986,9988],{"href":9987},"\u002Fnode-red\u002Fflowfuse\u002Fmqtt\u002Fmqtt-out\u002F","ff-mqtt-out"," nodes instead of the standard MQTT nodes. Simply drag one onto the canvas, and the connection to FlowFuse's broker will be configured automatically.",[15,9991,9992,9993,1987,9995,9997],{},"For any other broker, drag an ",[309,9994,9971],{},[309,9996,9974],{}," node onto your workspace. Double-click it to open the configuration panel.",[15,9999,10000,10001,10004],{},"Click the pencil icon next to ",[309,10002,10003],{},"Server",". You'll see two tabs: Connection and Security.",[15,10006,10007],{},[309,10008,10009],{},"Connection Tab",[15,10011,10012],{},[489,10013],{"alt":10014,"dataZoomable":369,"src":10015,"title":10016},"MQTT broker connection configuration screen showing server address, port, and protocol settings","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fmqtt-broker-config.png","MQTT Connection Tab - Configure broker address, port, and TLS settings",[303,10018,10019,10028,10040,10046],{},[306,10020,10021,10023,10024,10027],{},[309,10022,10003],{},": Enter your broker address (",[22,10025,10026],{},"broker.hivemq.com"," for testing, or your broker's hostname)",[306,10029,10030,10033,10034,10036,10037,10039],{},[309,10031,10032],{},"Port",": Use ",[22,10035,8843],{}," for encrypted connections, ",[22,10038,8839],{}," for unencrypted",[306,10041,10042,10045],{},[309,10043,10044],{},"Enable TLS",": Check this if you're using port 8883",[306,10047,10048,10051],{},[309,10049,10050],{},"Protocol",": Leave it at MQTT 3.1.1 unless you specifically need MQTT 5 features",[15,10053,10054],{},[309,10055,10056],{},"Security Tab",[15,10058,10059],{},[489,10060],{"alt":10061,"dataZoomable":369,"src":10062,"title":10063},"MQTT broker security configuration showing username and password fields","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fmqtt-configuration-security-tab.png","MQTT Security Tab - Enter credentials using environment variables for security",[15,10065,10066],{},"Enter your username and password. For anything beyond local testing, use environment variables:",[431,10068,10069,10076],{},[306,10070,10071,10072,10075],{},"Put ",[22,10073,10074],{},"${MQTT_USER}"," in the username field",[306,10077,10071,10078,10081],{},[22,10079,10080],{},"${MQTT_PASSWORD}"," in the password field",[15,10083,10084],{},"Set these in your Node-RED settings or FlowFuse environment config",[180,10086,10087],{},[15,10088,10089,10090,10093],{},"See ",[172,10091,10092],{"href":6290},"Using Environment Variables in Node-RED"," for setup details.",[15,10095,3794,10096,10099,10100,10103],{},[309,10097,10098],{},"Add",", then ",[309,10101,10102],{},"Done",". Deploy your flow. If the node shows \"connected\" under it, you're in.",[37,10105,10107],{"id":10106},"publishing-data-to-a-topic-on-mqtt-broker","Publishing Data to a Topic on MQTT Broker",[15,10109,10110],{},"The mqtt-out node sends data from Node-RED to your MQTT broker. Configure the topic, quality of service level, and retention settings to control how your messages are delivered.",[303,10112,10113,10117,10125,10133,10146,10153],{},[306,10114,2697,10115,9506],{},[309,10116,9974],{},[306,10118,7207,10119,10121,10122,10124],{},[309,10120,9974],{}," node and select your broker from the ",[309,10123,10003],{}," dropdown.",[306,10126,10127,10128,10130,10131,367],{},"Enter your topic name in the ",[309,10129,8178],{}," field. Use forward slashes for hierarchy like ",[22,10132,8252],{},[306,10134,763,10135,4324,10137,10139,10140,10142,10143,10145],{},[309,10136,4323],{},[309,10138,4796],{}," for guaranteed delivery. Use ",[309,10141,4327],{}," if you can tolerate occasional duplicates, or ",[309,10144,2099],{}," for high-frequency data where missing readings don't matter.",[306,10147,10148,10149,10152],{},"Enable ",[309,10150,10151],{},"Retain"," if new subscribers should immediately receive the last published value.",[306,10154,10155,10156,10158],{},"Connect your data source to the mqtt-out node's input. The node expects ",[22,10157,616],{}," to contain your data.",[15,10160,10161],{},[489,10162],{"alt":10163,"dataZoomable":369,"src":10164,"title":10165},"MQTT-out node configuration panel settings","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fmqtt-out.png","MQTT-out Node Configuration",[37,10167,10169],{"id":10168},"subscribing-to-a-topic-on-mqtt-broker","Subscribing to a Topic on MQTT Broker",[15,10171,10172],{},"The mqtt-in node receives messages from topics you specify. You can subscribe to specific topics or use wildcards to monitor multiple topics at once.",[303,10174,10175,10179,10185,10216,10222,10230],{},[306,10176,2697,10177,9506],{},[309,10178,9971],{},[306,10180,7207,10181,10121,10183,10124],{},[309,10182,9971],{},[309,10184,10003],{},[306,10186,763,10187,4324,10189,10192,10193,10195,10196],{},[309,10188,8165],{},[309,10190,10191],{},"subscribe to a single topic"," and enter the topic name in the ",[309,10194,8178],{}," field. You can use:\n",[431,10197,10198,10203,10210],{},[306,10199,10200,10201],{},"Specific topics: ",[22,10202,8252],{},[306,10204,10205,10206,10209],{},"Single-level wildcard: ",[22,10207,10208],{},"factory\u002F+\u002Ftemp"," (matches any value where + appears)",[306,10211,10212,10213,10215],{},"Multi-level wildcard: ",[22,10214,1761],{}," (matches everything under factory\u002F)",[306,10217,763,10218,4324,10220,367],{},[309,10219,4323],{},[309,10221,4796],{},[306,10223,763,10224,4324,10226,10229],{},[309,10225,3820],{},[309,10227,10228],{},"auto-detect"," (it parses JSON automatically and passes through other formats as strings).",[306,10231,10232],{},"Connect the mqtt-in node's output to wherever you need the data.",[15,10234,10235],{},[489,10236],{"alt":10237,"dataZoomable":369,"src":10238,"title":10239},"MQTT-in node configuration showing subscription settings with topic field and QoS options","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fmqtt-in-config.png","MQTT-in Node Configuration",[15,10241,10242],{},[309,10243,10244],{},"For Dynamic Subscriptions:",[15,10246,10247,10248,4324,10250,10253,10254,1289,10256,10258],{},"If you need to change subscriptions at runtime based on user input or system conditions, set ",[309,10249,8165],{},[309,10251,10252],{},"dynamic"," instead. You'll control subscriptions by sending messages with ",[22,10255,4686],{},[22,10257,4643],{}," to the node's input.",[15,10260,10261],{},[489,10262],{"alt":10263,"dataZoomable":369,"src":10264,"title":10265},"MQTT-in node configured for dynamic subscription mode with empty topic field","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fmqtt-in-dynamic.png","MQTT-in Dynamic Mode",[15,10267,10268],{},"To subscribe dynamically, send a message like:",[619,10270,10272],{"className":2265,"code":10271,"language":2267,"meta":369,"style":369},"msg.topic = \"factory\u002Fline1\u002Ftemperature\";\nmsg.action = \"subscribe\";\n",[22,10273,10274,10294],{"__ignoreMap":369},[627,10275,10276,10278,10280,10283,10285,10287,10290,10292],{"class":629,"line":630},[627,10277,3554],{"class":2283},[627,10279,367],{"class":633},[627,10281,10282],{"class":2283},"topic ",[627,10284,2287],{"class":633},[627,10286,687],{"class":633},[627,10288,10289],{"class":690},"factory\u002Fline1\u002Ftemperature",[627,10291,646],{"class":633},[627,10293,2298],{"class":633},[627,10295,10296,10298,10300,10303,10305,10307,10309,10311],{"class":629,"line":373},[627,10297,3554],{"class":2283},[627,10299,367],{"class":633},[627,10301,10302],{"class":2283},"action ",[627,10304,2287],{"class":633},[627,10306,687],{"class":633},[627,10308,2619],{"class":690},[627,10310,646],{"class":633},[627,10312,2298],{"class":633},[15,10314,10315],{},"To unsubscribe:",[619,10317,10319],{"className":2265,"code":10318,"language":2267,"meta":369,"style":369},"msg.topic = \"factory\u002Fline1\u002Ftemperature\";\nmsg.action = \"unsubscribe\";\n",[22,10320,10321,10339],{"__ignoreMap":369},[627,10322,10323,10325,10327,10329,10331,10333,10335,10337],{"class":629,"line":630},[627,10324,3554],{"class":2283},[627,10326,367],{"class":633},[627,10328,10282],{"class":2283},[627,10330,2287],{"class":633},[627,10332,687],{"class":633},[627,10334,10289],{"class":690},[627,10336,646],{"class":633},[627,10338,2298],{"class":633},[627,10340,10341,10343,10345,10347,10349,10351,10354,10356],{"class":629,"line":373},[627,10342,3554],{"class":2283},[627,10344,367],{"class":633},[627,10346,10302],{"class":2283},[627,10348,2287],{"class":633},[627,10350,687],{"class":633},[627,10352,10353],{"class":690},"unsubscribe",[627,10355,646],{"class":633},[627,10357,2298],{"class":633},[15,10359,10360],{},"This is useful when users select which equipment to monitor from a dashboard, when topics depend on database queries or API responses, or when you need to add and remove subscriptions without redeploying your flow.",[37,10362,10364],{"id":10363},"deploying-the-flow","Deploying the Flow",[15,10366,10367],{},"Deploy your flow to activate the MQTT connection and start sending or receiving messages.",[303,10369,10370],{},[306,10371,3102,10372,10374],{},[309,10373,3876],{}," button at the top-right corner.",[15,10376,10377],{},[1235,10378,10379],{},"Tip: Check the node status below each MQTT node. It will display 'connected' if the connection is successful.",[15,10381,10382],{},[489,10383],{"alt":10384,"dataZoomable":369,"src":10385,"title":10386},"MQTT nodes in Node-RED editor showing green connected status indicators below each node","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fmqtt-node-status.png","MQTT Node Status - Green 'connected' indicator confirms successful broker connection",[37,10388,10390],{"id":10389},"best-practices","Best Practices",[15,10392,10393],{},"Production MQTT deployments need more than basic configuration. These practices separate hobby projects from industrial-grade systems that run 24\u002F7 without issues.",[494,10395,10397],{"id":10396},"security-first","Security First",[15,10399,10400,10403,10404,10406],{},[309,10401,10402],{},"Always use TLS encryption."," Unencrypted MQTT sends credentials and data in plain text across your network. Enable port 8883 with TLS on your broker, then check the ",[309,10405,10044],{}," box in your Node-RED broker configuration. No exceptions for production systems.",[15,10408,10409,10412],{},[309,10410,10411],{},"Never hardcode credentials."," Putting usernames and passwords directly in nodes means anyone with access to your flows can see them. Use environment variables instead:",[619,10414,10417],{"className":10415,"code":10416,"language":789},[787],"Username: ${MQTT_USER}\nPassword: ${MQTT_PASS}\n",[22,10418,10416],{"__ignoreMap":369},[15,10420,10421,10422,10424],{},"Set these in your Node-RED settings file or FlowFuse environment configuration. See ",[172,10423,10092],{"href":6290}," for the complete setup.",[15,10426,10427,10430],{},[309,10428,10429],{},"Implement access control on your broker."," Not every device needs to publish and subscribe to every topic. Configure your MQTT broker's ACL (Access Control List) to restrict clients based on their role. Sensors should only publish to their specific topics. Dashboard applications should only subscribe to what they display. This limits damage if credentials get compromised.",[494,10432,10434],{"id":10433},"choose-the-right-qos","Choose the Right QoS",[15,10436,10437],{},"QoS isn't a \"set it and forget it\" decision. Each level trades reliability against network overhead and latency.",[15,10439,10440,10443],{},[309,10441,10442],{},"QoS 0:"," Fire and forget. Use for high-frequency sensor data where missing one reading doesn't matter.",[15,10445,10446,10449],{},[309,10447,10448],{},"QoS 1:"," Guaranteed delivery, possible duplicates. Good for status updates and notifications.",[15,10451,10452,10455],{},[309,10453,10454],{},"QoS 2:"," Exactly once delivery with higher latency. Use for commands that trigger actions or critical transactions.",[15,10457,10458],{},"Match QoS to your use case. Don't default everything to QoS 2 just to be safe, you'll waste bandwidth and add latency where it doesn't help.",[494,10460,10462],{"id":10461},"design-your-topic-hierarchy-properly","Design Your Topic Hierarchy Properly",[15,10464,10465],{},"Your topic structure determines how easy it is to filter, subscribe, and scale your system. A hierarchical approach mirrors your physical setup and makes wildcards useful.",[15,10467,10468],{},[309,10469,10470],{},"Structure topics from general to specific:",[619,10472,10475],{"className":10473,"code":10474,"language":789},[787],"company\u002Flocation\u002Farea\u002Fequipment\u002Fmeasurement\n",[22,10476,10474],{"__ignoreMap":369},[15,10478,10479],{},[309,10480,10481],{},"Good hierarchy:",[619,10483,10486],{"className":10484,"code":10485,"language":789},[787],"acme\u002Fchicago\u002Fpackaging\u002Ffiller-01\u002Ftemperature\nacme\u002Fchicago\u002Fpackaging\u002Ffiller-01\u002Fpressure\nacme\u002Fdenver\u002Fassembly\u002Frobot-03\u002Ftemperature\nacme\u002Fdenver\u002Fassembly\u002Fconveyor-02\u002Fspeed\n",[22,10487,10485],{"__ignoreMap":369},[15,10489,10490],{},[309,10491,10492],{},"Poor hierarchy:",[619,10494,10497],{"className":10495,"code":10496,"language":789},[787],"temp-sensor-1\ntemp-sensor-2\npressure-sensor-1\nline1-data\n",[22,10498,10496],{"__ignoreMap":369},[15,10500,10501,10502,10504,10505,367],{},"The difference: with a proper hierarchy, you can subscribe at any level. Need all data from Chicago? Subscribe to ",[22,10503,4298],{},". Want temperature readings across all sites? Use ",[22,10506,10507],{},"acme\u002F+\u002F+\u002F+\u002Ftemperature",[15,10509,10510],{},"Flat topics force you to subscribe to dozens of individual topics and manage them manually. Hierarchical topics let the broker do the filtering.",[15,10512,10513,10516],{},[309,10514,10515],{},"Keep it simple:"," Use lowercase, separate levels with forward slashes, use hyphens within names. Topics are paths, not sentences.",[37,10518,884],{"id":883},[15,10520,10521],{},"You now know how to connect Node-RED to MQTT brokers, publish data to topics, subscribe to incoming messages, and secure your deployment with TLS and proper credentials. That's the foundation.",[15,10523,10524],{},"Go build something. Connect a sensor, route the data, display it somewhere useful. The patterns you've learned here scale from a single device to entire factory floors.",[15,10526,10527],{},"When you hit the limits of managing individual instances (tracking deployments, coordinating updates, maintaining uptime across sites), that's when tools like [FlowFuse]({% include \"sign-up-url.njk\" %}) become relevant. Until then, you have everything you need.",[898,10529,10530],{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":369,"searchDepth":370,"depth":370,"links":10532},[10533,10534,10535,10536,10537,10538,10543],{"id":9938,"depth":373,"text":9939},{"id":9964,"depth":373,"text":9965},{"id":10106,"depth":373,"text":10107},{"id":10168,"depth":373,"text":10169},{"id":10363,"depth":373,"text":10364},{"id":10389,"depth":373,"text":10390,"children":10539},[10540,10541,10542],{"id":10396,"depth":659,"text":10397},{"id":10433,"depth":659,"text":10434},{"id":10461,"depth":659,"text":10462},{"id":883,"depth":373,"text":884},{"type":914,"title":10545,"description":10546},"Run Production-Grade MQTT and Node-RED in One Platform","FlowFuse gives you hosted Node-RED and a built-in MQTT broker with access control, TLS, and managed credentials, plus remote device management and DevOps pipelines to run reliably from one device to entire factory floors. Start free today.","2024-06-05","Complete MQTT Node-RED tutorial: configure brokers, implement pub\u002Fsub messaging, use mqtt-in and mqtt-out nodes, and create dynamic subscriptions for IoT","\u002Fblog\u002F2024\u002F06\u002Fimages\u002Fworking-with-mqtt.jpg",{"keywords":10551,"excerpt":10552},"node red mqtt, mqtt node red, mqtt in node red, node red mqtt in, node red mqtt out, node red mqtt broker, mqtt broker node red, node-red-contrib-mqtt-broker, node red mqtt dynamic subscription, node red mqtt example, mqtt dynamic subscription, mqtt in\u002Fout nodes, mqtt broker setup",{"type":12,"value":10553},[10554],[15,10555,9932],{},"\u002Fblog\u002F2024\u002F06\u002Fhow-to-use-mqtt-in-node-red",{"title":9926,"description":10548},{"loc":10556},"blog\u002F2024\u002F06\u002Fhow-to-use-mqtt-in-node-red","Connect, subscribe, and publish MQTT messages in Node-RED",[8205,7964,402,7965],"Node-RED's built-in mqtt-in and mqtt-out nodes make it straightforward to connect to any MQTT broker, subscribe to topics with wildcard support, and publish data. Dynamic subscriptions, TLS security, environment-variable credentials, and a well-structured topic hierarchy are the key practices for reliable, production-grade MQTT flows.","MM_Ln2w_vqrUlQzGO9sjEvDGcCW4gg9usLAqHHMBUxk",1785528680355]