[{"data":1,"prerenderedAt":10398},["ShallowReactive",2],{"blog-\u002Fblog\u002Fopcua":3,"blog-all-for-related":4,"blog-all-opcua":5},null,[],[6,830,1469,1699,1952,2167,2696,2898,4204,5104,6172,6683,7103,8536],{"id":7,"title":8,"authors":9,"body":11,"cta":796,"date":800,"description":801,"extension":802,"image":803,"lastUpdated":3,"meta":804,"navigation":494,"path":819,"seo":820,"sitemap":821,"stem":822,"subtitle":823,"tags":824,"tldr":828,"video":3,"__hash__":829},"blog\u002Fblog\u002F2026\u002F06\u002Fopcua-to-influxdb.md","Historical Data Logging with OPC UA and InfluxDB",[10],"sumit-shinde",{"type":12,"value":13,"toc":785},"minimark",[14,18,36,47,52,55,93,109,112,116,119,170,179,182,186,189,194,244,253,263,275,279,285,311,319,368,380,396,415,424,428,435,452,656,659,702,711,720,723,727,730,751,759,762,771,775,778,781],[15,16,17],"p",{},"Industrial equipment produces data constantly: temperatures, pressures, motor speeds, tank levels, all changing by the second. Real-time values tell you what's happening now, but the history is where the value lives, spotting a degrading pump, proving a batch stayed within spec, tracing the conditions behind a fault. OPC UA gets that data out of your equipment in a vendor-neutral way, and InfluxDB stores it as timestamped history built to query at scale. In this article, you'll connect the two in FlowFuse to turn live readings into a durable record you can query, chart, and analyze.",[19,20,21],"blockquote",{},[15,22,23,27,28,35],{},[24,25,26],"strong",{},"Note:"," If you'd rather not leave FlowFuse and want a good time-series database built in, ",[29,30,34],"a",{"href":31,"rel":32},"https:\u002F\u002Fflowfuse.com\u002Fdocs\u002Fuser\u002Fff-tables\u002F",[33],"nofollow","FlowFuse Tables"," is the answer.",[15,37,38,43],{},[39,40],"img",{"alt":41,"src":42},"The finished flow on the FlowFuse canvas: inject → Read (OPC UA) → function → influxdb out","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-to-influxdb-flow.png",[44,45,46],"em",{},"The complete pipeline: an inject node triggers a read, a function node shapes the reading, and the influxdb out node stores it.",[48,49,51],"h2",{"id":50},"what-youll-need","What you'll need",[15,53,54],{},"Before building the flow, make sure you have:",[56,57,58,70,76,82],"ul",{},[59,60,61,64,65,69],"li",{},[24,62,63],{},"A FlowFuse remote instance on an edge device."," OPC UA servers and PLCs sit on the local network, so run this flow on an edge device close to the equipment. Install the ",[29,66,68],{"href":67},"\u002Fdocs\u002Fdevice-agent\u002Finstall\u002Foverview\u002F","Device Agent"," and register it as a remote instance.",[59,71,72,75],{},[24,73,74],{},"An OPC UA server to read from."," Your data source: a PLC, gateway, or device exposing tags over OPC UA. No hardware? The free Prosys OPC UA Simulation Server works for testing.",[59,77,78,81],{},[24,79,80],{},"A running InfluxDB instance."," Cloud or self-hosted. Create an organization, a bucket, and an API token with write access.",[59,83,84,87,88,92],{},[24,85,86],{},"Endpoint details for both."," The OPC UA endpoint URL (like ",[89,90,91],"code",{},"opc.tcp:\u002F\u002F192.168.1.10:4840",") plus any credentials, and your InfluxDB URL, org, bucket, and token.",[15,94,95,96,99,100,103,104,108],{},"For the OPC UA connection, this guide uses the ",[24,97,98],{},"FlowFuse Edge Certified Nodes package",", part of the ",[24,101,102],{},"FlowFuse Edge"," offering and vetted, maintained, and tested by the FlowFuse team. ",[29,105,107],{"href":106},"\u002Fcontact-us\u002F","Contact sales"," to enable it for your team. Community nodes work too, but they don't get the same vetting, maintenance, or testing, so reliability varies.",[15,110,111],{},"With those ready, the next step is installing the nodes that connect FlowFuse to OPC UA and InfluxDB.",[48,113,115],{"id":114},"installing-the-nodes","Installing the nodes",[15,117,118],{},"You'll install two packages: the InfluxDB nodes and the FlowFuse Edge Certified OPC UA nodes.",[120,121,122,125,136,148,155],"ol",{},[59,123,124],{},"Open the editor on your remote instance.",[59,126,127,128,131,132,135],{},"From the menu (top right), select ",[24,129,130],{},"Manage palette",", then switch to the ",[24,133,134],{},"Install"," tab.",[59,137,138,139,144,145,147],{},"Search for ",[24,140,141],{},[89,142,143],{},"node-red-contrib-influxdb"," and click ",[24,146,134],{},". These nodes write to and query InfluxDB.",[59,149,150,151,154],{},"Switch the catalog using the top dropdown to ",[24,152,153],{},"FlowFuse Edge Certified Nodes",". Once sales enables FlowFuse Edge Certified Nodes for your team, this catalog shows up here; restart any existing instance so it picks up the updated catalogue.",[59,156,138,157,144,162,164,165,169],{},[24,158,159],{},[89,160,161],{},"@flowfuse-certified-nodes\u002Fopcua",[24,163,134],{},". See the ",[29,166,168],{"href":167},"\u002Fnode-red\u002Fflowfuse\u002Fedge\u002Fopcua\u002F","OPC UA node documentation"," for the full node set and configuration options.",[15,171,172,176],{},[39,173],{"alt":174,"src":175},"Manage palette Install tab showing the OPC UA certified package in search results","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-manage-pallete.png",[44,177,178],{},"Install the OPC UA certified package from the FlowFuse Edge Certified Nodes catalog.",[15,180,181],{},"Both packages now appear in the palette on the left: an OPC UA group for reading your equipment, and an InfluxDB group for storing the data. Now you're ready to connect to your server and pull live values.",[48,183,185],{"id":184},"connecting-to-your-opc-ua-server","Connecting to your OPC UA server",[15,187,188],{},"With the nodes installed, you'll build the read side of the flow: define the connection, then read your tag values on a schedule.",[190,191,193],"h3",{"id":192},"define-the-connection","Define the connection",[120,195,196,203,210,216,231,234],{},[59,197,198,199,202],{},"Drag a ",[24,200,201],{},"Read"," node onto the canvas.",[59,204,205,206,209],{},"Double-click it to open its settings, then click the \"+\" next to the ",[24,207,208],{},"Endpoint"," field to add a new endpoint configuration.",[59,211,212,213,215],{},"Enter your endpoint URL, for example ",[89,214,91],{},".",[59,217,218,219,222,223,226,227,230],{},"Set the ",[24,220,221],{},"Security Policy"," and ",[24,224,225],{},"Security Mode"," to match your server. For a local test server such as the Prosys simulator with security disabled, set both to ",[89,228,229],{},"None",". On production equipment, choose the certificate-based policy and mode your server requires, and point the node at your certificate and private-key files.",[59,232,233],{},"If your server needs credentials, enable the login option on the endpoint and enter the username and password. Otherwise leave it anonymous.",[59,235,236,237,240,241,215],{},"Click ",[24,238,239],{},"Add",", then ",[24,242,243],{},"Done",[15,245,246,250],{},[39,247],{"alt":248,"src":249},"The OPC UA endpoint configuration dialog with URL, Security Policy, and Security Mode fields","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-config.png",[44,251,252],{},"Point the endpoint at your server's URL and match its Security Policy and Mode.",[19,254,255],{},[15,256,257,259,260,262],{},[24,258,26],{}," This guide uses a simulator server for convenience. On production equipment, always enable a certificate-based Security Policy and Mode rather than ",[89,261,229],{},", so the connection between FlowFuse and your OPC UA server stays encrypted and authenticated.",[19,264,265],{},[15,266,267,269,270,274],{},[24,268,26],{}," Store connection details, endpoint URLs, credentials, InfluxDB tokens, org and bucket names in environment variables rather than hardcoding them in your nodes. This keeps secrets out of your flows and lets you move the same flow between instances without editing each node. See ",[29,271,273],{"href":272},"\u002Fdocs\u002Fuser\u002Fenvvar\u002F","Using Environment Variables"," for how to set them.",[190,276,278],{"id":277},"read-the-values-on-a-schedule","Read the values on a schedule",[15,280,281,282,215],{},"The Read node takes the Node ID of the tag from the incoming message, so feed it a message carrying the tag you want and it returns the value. First you need that Node ID, something like ",[89,283,284],{},"ns=3;s=Temperature",[120,286,287,297,304],{},[59,288,289,290,292,293,296],{},"In the ",[24,291,201],{}," node, click the tree button next to the ",[24,294,295],{},"NodeId"," field. Enter the Node ID you want to drill into (a root node such as the Objects folder is the usual starting point), and the node renders your server's address space as an expandable tree. Drill down, click the tag you want, and its Node ID fills in automatically.",[59,298,299,300,303],{},"Add an ",[24,301,302],{},"inject"," node and set it to repeat at a fixed interval, say every 5 seconds, so each pulse triggers a fresh read. Wire it into the Read node.",[59,305,306,307,310],{},"Connect a ",[24,308,309],{},"debug"," node to the Read node's output, then deploy.",[15,312,313,317],{},[39,314],{"alt":315,"src":316},"Opcua read node config","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-read-node.png",[44,318,315],{},[15,320,321,322,325,326,329,330,333,334,337,338,341,342,345,346,337,349,222,352,355,356,359,360,363,364,367],{},"Each time a message arrives, the Read node returns more than just the number. The value lands in ",[89,323,324],{},"msg.payload",", and the message also carries ",[89,327,328],{},"msg.dataType"," (such as ",[89,331,332],{},"Double"," or ",[89,335,336],{},"Boolean","), ",[89,339,340],{},"msg.statusCode"," (",[89,343,344],{},"Good"," on success, or an error like ",[89,347,348],{},"BadUnknownNode",[89,350,351],{},"msg.sourceTimestamp",[89,353,354],{},"msg.serverTimestamp"," as ISO strings, and ",[89,357,358],{},"msg.nodeId"," echoing back what was read. Watch that ",[89,361,362],{},"statusCode",", it's how you tell a real ",[89,365,366],{},"0"," reading from a tag that failed to read at all.",[15,369,370,371,333,374,376,377,379],{},"To read several tags at once, pass an array of Node IDs in ",[89,372,373],{},"msg.topic",[89,375,358],{}," and the node returns an array of values in ",[89,378,324],{},", more efficient than running a separate read per tag.",[19,381,382],{},[15,383,384,387,388,391,392,395],{},[24,385,386],{},"ℹ Tip:"," If you ever need the ",[44,389,390],{},"flow itself"," to discover Node IDs while it's running, say, to enumerate tags on a server whose address space changes, there's a dedicated ",[24,393,394],{},"Browse"," node for that. It's overkill for a fixed set of tags like this one, so we'll skip it here.",[15,397,398,399,401,402,404,405,407,408,410,411,414],{},"Deploy and watch the debug output. You should see a value arriving on each interval. The value itself is in ",[89,400,324],{},", while the timestamp and quality ride along on separate properties (",[89,403,351],{},", ",[89,406,340],{},", and so on), so ",[89,409,324],{}," is just the bare reading, like ",[89,412,413],{},"42.5",". That's the shape the next step builds on.",[15,416,417,421],{},[39,418],{"alt":419,"src":420},"The debug sidebar showing a reading with msg.payload, msg.statusCode, and msg.sourceTimestamp expanded","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fread-output.png",[44,422,423],{},"Each read returns the value in msg.payload, with timestamp and quality on separate properties.",[48,425,427],{"id":426},"writing-data-to-influxdb","Writing Data to InfluxDB",[15,429,430,431,434],{},"The OPC UA Read node and InfluxDB Out node use different message formats, so add a ",[24,432,433],{},"Function"," node between them to format the data before writing it to InfluxDB.",[120,436,437,443],{},[59,438,439,440,442],{},"Drop a ",[24,441,433],{}," node after the Read node and open it.",[59,444,445,446,448,449,451],{},"Configure it to build the payload InfluxDB expects. ",[89,447,324],{}," contains the OPC UA value, and ",[89,450,351],{}," contains the timestamp from the OPC UA server:",[453,454,459],"pre",{"className":455,"code":456,"language":457,"meta":458,"style":458},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const value = msg.payload;\n\nmsg.measurement = \"equipment_readings\";\nmsg.timestamp = msg.sourceTimestamp;\n\nmsg.payload = [\n    {\n        temperature: value\n    },\n    {\n        sensor: \"tank-1\",\n        location: \"plant-floor\"\n    }\n];\n\nreturn msg;\n","javascript","",[89,460,461,489,496,521,542,547,562,568,581,587,592,610,626,632,640,645],{"__ignoreMap":458},[462,463,466,470,474,478,481,483,486],"span",{"class":464,"line":465},"line",1,[462,467,469],{"class":468},"spNyl","const",[462,471,473],{"class":472},"sTEyZ"," value ",[462,475,477],{"class":476},"sMK4o","=",[462,479,480],{"class":472}," msg",[462,482,215],{"class":476},[462,484,485],{"class":472},"payload",[462,487,488],{"class":476},";\n",[462,490,492],{"class":464,"line":491},2,[462,493,495],{"emptyLinePlaceholder":494},true,"\n",[462,497,499,502,504,507,509,512,516,519],{"class":464,"line":498},3,[462,500,501],{"class":472},"msg",[462,503,215],{"class":476},[462,505,506],{"class":472},"measurement ",[462,508,477],{"class":476},[462,510,511],{"class":476}," \"",[462,513,515],{"class":514},"sfazB","equipment_readings",[462,517,518],{"class":476},"\"",[462,520,488],{"class":476},[462,522,524,526,528,531,533,535,537,540],{"class":464,"line":523},4,[462,525,501],{"class":472},[462,527,215],{"class":476},[462,529,530],{"class":472},"timestamp ",[462,532,477],{"class":476},[462,534,480],{"class":472},[462,536,215],{"class":476},[462,538,539],{"class":472},"sourceTimestamp",[462,541,488],{"class":476},[462,543,545],{"class":464,"line":544},5,[462,546,495],{"emptyLinePlaceholder":494},[462,548,550,552,554,557,559],{"class":464,"line":549},6,[462,551,501],{"class":472},[462,553,215],{"class":476},[462,555,556],{"class":472},"payload ",[462,558,477],{"class":476},[462,560,561],{"class":472}," [\n",[462,563,565],{"class":464,"line":564},7,[462,566,567],{"class":476},"    {\n",[462,569,571,575,578],{"class":464,"line":570},8,[462,572,574],{"class":573},"swJcz","        temperature",[462,576,577],{"class":476},":",[462,579,580],{"class":472}," value\n",[462,582,584],{"class":464,"line":583},9,[462,585,586],{"class":476},"    },\n",[462,588,590],{"class":464,"line":589},10,[462,591,567],{"class":476},[462,593,595,598,600,602,605,607],{"class":464,"line":594},11,[462,596,597],{"class":573},"        sensor",[462,599,577],{"class":476},[462,601,511],{"class":476},[462,603,604],{"class":514},"tank-1",[462,606,518],{"class":476},[462,608,609],{"class":476},",\n",[462,611,613,616,618,620,623],{"class":464,"line":612},12,[462,614,615],{"class":573},"        location",[462,617,577],{"class":476},[462,619,511],{"class":476},[462,621,622],{"class":514},"plant-floor",[462,624,625],{"class":476},"\"\n",[462,627,629],{"class":464,"line":628},13,[462,630,631],{"class":476},"    }\n",[462,633,635,638],{"class":464,"line":634},14,[462,636,637],{"class":472},"]",[462,639,488],{"class":476},[462,641,643],{"class":464,"line":642},15,[462,644,495],{"emptyLinePlaceholder":494},[462,646,648,652,654],{"class":464,"line":647},16,[462,649,651],{"class":650},"s7zQu","return",[462,653,480],{"class":472},[462,655,488],{"class":476},[15,657,658],{},"The first object contains the field values, while the second contains tags used for filtering and grouping data during queries.",[120,660,661,668,675,689,699],{"start":498},[59,662,663,664,667],{},"Wire the Function node to an ",[24,665,666],{},"InfluxDB Out"," node.",[59,669,670,671,674],{},"Open the InfluxDB Out node and click the \"+\" icon next to ",[24,672,673],{},"Server"," to configure the connection. Enter your InfluxDB URL and select the appropriate version (1.x or 2.0).",[59,676,677,678,404,681,684,685,688],{},"For InfluxDB 2.0, provide your ",[24,679,680],{},"Token",[24,682,683],{},"Organization",", and ",[24,686,687],{},"Bucket",". For InfluxDB 1.x, enter the database name and any required credentials.",[59,690,691,692,695,696,698],{},"If you did not set ",[89,693,694],{},"msg.measurement"," in the Function node, specify the measurement name (for example, ",[89,697,515],{},") in the InfluxDB Out node configuration.",[59,700,701],{},"Deploy the flow.",[15,703,704,708],{},[39,705],{"alt":706,"src":707},"The influxdb node configuration with URL and version fields","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Finfluxdb-config.png",[44,709,710],{},"Configure the server connection with your InfluxDB URL and version.",[15,712,713,717],{},[39,714],{"alt":715,"src":716},"The influxdb out node configuration with token, org, and bucket fields","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Finfluxdb-write-node-config.png",[44,718,719],{},"Set the token, organization, and bucket so readings are written to the correct destination.",[15,721,722],{},"Your readings are now flowing into InfluxDB. On each interval, the Read node retrieves the OPC UA value, the Function node formats it, and the InfluxDB Out node writes the timestamped data point to your bucket.",[48,724,726],{"id":725},"verifying-your-data","Verifying your data",[15,728,729],{},"Confirm the history is actually landing before you rely on it.",[120,731,732,738,748],{},[59,733,734,735,215],{},"Open the InfluxDB UI and go to the ",[24,736,737],{},"Data Explorer",[59,739,740,741,743,744,747],{},"Select your bucket, your ",[89,742,515],{}," measurement, and the ",[89,745,746],{},"temperature"," field.",[59,749,750],{},"Set the time range to the last few minutes and run the query.",[15,752,753,757],{},[39,754],{"alt":755,"src":756},"InfluxDB Data Explorer showing the temperature filling in","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Finfluxdb-explorer.png",[44,758,755],{},[15,760,761],{},"You'll see your readings listed in a table, one row per read interval. If new rows keep appearing as time passes, your pipeline is working end to end: equipment to OPC UA to FlowFuse to InfluxDB.",[15,763,764,765,770],{},"Storing data is only half the story. The InfluxDB In node lets you query readings back from InfluxDB, whether you need the latest values, historical trends, or aggregated metrics. You can then feed the results directly into a ",[29,766,769],{"href":767,"rel":768},"https:\u002F\u002Fdashboard.flowfuse.com",[33],"FlowFuse Dashboard"," to build charts, tables, and real-time monitoring views of your OPC UA data.",[48,772,774],{"id":773},"where-to-go-from-here","Where to go from here",[15,776,777],{},"You now have a durable, queryable record of your equipment's behavior. From here you can read more tags, tag each reading with its machine or line so you can slice the data later, and build dashboards on top of InfluxDB to chart trends and spot the slow drift that real-time values hide.",[15,779,780],{},"The real payoff comes when you stop reacting to problems and start seeing them coming. A pump that's drawing a little more current each week, a tank that's taking longer to fill, a temperature that's creeping past its usual range, all of it now sits in a history you can query, instead of vanishing the moment it happens.",[782,783,784],"style",{},"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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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":458,"searchDepth":523,"depth":523,"links":786},[787,788,789,793,794,795],{"id":50,"depth":491,"text":51},{"id":114,"depth":491,"text":115},{"id":184,"depth":491,"text":185,"children":790},[791,792],{"id":192,"depth":498,"text":193},{"id":277,"depth":498,"text":278},{"id":426,"depth":491,"text":427},{"id":725,"depth":491,"text":726},{"id":773,"depth":491,"text":774},{"type":797,"title":798,"description":799},"contact","Build on a foundation you can trust","FlowFuse Edge Certified Nodes are vetted, maintained, and tested by the FlowFuse team, so your OPC UA connections stay reliable in production. Contact sales to enable them for your team.","2026-06-24","Learn how to connect OPC UA and InfluxDB in FlowFuse to log industrial equipment data as timestamped history, so you can spot trends, prove compliance, and catch failures before they happen.","md","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-to-influxdb.png",{"keywords":805,"excerpt":806},"opc ua influxdb, opc ua historical data, influxdb node-red, flowfuse opc ua, industrial data logging, opc ua time series, node-red influxdb, log opc ua data, equipment data history, iiot data logging",{"type":12,"value":807},[808,810],[15,809,17],{},[19,811,812],{},[15,813,814,27,816,35],{},[24,815,26],{},[29,817,34],{"href":31,"rel":818},[33],"\u002Fblog\u002F2026\u002F06\u002Fopcua-to-influxdb",{"title":8,"description":801},{"loc":819},"blog\u002F2026\u002F06\u002Fopcua-to-influxdb","Turn live equipment readings into a durable history you can query, chart, and analyze",[825,826,827],"post","flowfuse","opcua","Real-time OPC UA values tell you what's happening now; the history is where the value lives. This guide connects OPC UA to InfluxDB in FlowFuse to turn live equipment readings into durable, timestamped history. Install the InfluxDB and FlowFuse Edge Certified OPC UA nodes, configure an OPC UA endpoint and read tags on a schedule, shape each reading into fields and tags with a function node, set the point's timestamp from the server's sample time, and write to InfluxDB with the influxdb out node. Verify the data lands in the Data Explorer, then query it back into FlowFuse Dashboard to chart trends and catch slow drift before it becomes a fault.","H1vitrPnSOBbHUdgRAQ3bgr0P8RNKt9Emkv_VJXrbK0",{"id":831,"title":832,"authors":833,"body":834,"cta":1452,"date":1455,"description":1456,"extension":802,"image":1457,"lastUpdated":3,"meta":1458,"navigation":494,"path":1460,"seo":1461,"sitemap":1462,"stem":1463,"subtitle":1464,"tags":1465,"tldr":1467,"video":3,"__hash__":1468},"blog\u002Fblog\u002F2026\u002F06\u002Fopc-ua-security-best-practices.md","OPC UA Security: How to Establish a Defensible OPC UA Security Architecture",[10],{"type":12,"value":835,"toc":1440},[836,844,847,851,862,869,872,894,897,906,910,913,928,937,944,947,975,978,987,991,998,1001,1025,1032,1041,1059,1077,1084,1088,1091,1105,1127,1147,1165,1169,1186,1189,1212,1219,1223,1226,1229,1232,1270,1280,1302,1311,1314,1323,1327,1334,1341,1345,1352,1355,1359,1362,1380,1383,1387,1390,1437],[15,837,838,839,843],{},"In ",[29,840,842],{"href":841},"\u002Fblog\u002F2026\u002F05\u002Fopc-ua-security-attack-vectors\u002F","Part 1",", we watched how threat actors actually exploit OPC UA. None of it was broken cryptography. It was disabled trust lists, anonymous logins, dead ciphers nobody removed, and servers Shodan finds on the open internet. The protocol shipped with the tools to stop every one. The attacks worked because the tools were switched off.",[15,845,846],{},"This is the part where we switch them on, not as a checklist, but as an architecture where each decision closes a specific vector from Part 1. The order matters, because the cheapest fixes close the widest holes.",[48,848,850],{"id":849},"the-model-that-decides-everything-else","The model that decides everything else",[15,852,853,854,857,858,861],{},"Part 1 named the trap that sinks more deployments than any zero-day: OPC UA splits ",[44,855,856],{},"application"," authentication (does the server trust this client's certificate?) from ",[44,859,860],{},"user"," authentication (who is this operator, and what may they do?). Teams harden one, leave the other open, and believe they're covered.",[15,863,864,865,868],{},"The reason this confuses people is that OPC UA secures the ",[24,866,867],{},"messages themselves",", not just the transport beneath them. A transport-only scheme like TLS protects the pipe between two hosts; OPC UA signs and encrypts each message independently of the transport, so a receiver detects a tampered process value even on a hostile network and even if the transport is something other than TLS. Application authentication and message security are layers in their own right, sitting above whatever carries the bytes.",[15,870,871],{},"Two facts fall out of this, and both map straight to Part 1's attacks:",[56,873,874,884],{},[59,875,876,879,880,883],{},[24,877,878],{},"Every application instance has its own certificate",", not every host, every ",[44,881,882],{},"running process",". A Node-RED client, a SCADA server, and a historian on the same box each carry their own.",[59,885,886,889,890,893],{},[24,887,888],{},"Authentication is mutual."," Both sides present a certificate, both sides decide whether to trust. There is no \"the server has a cert, the client just connects\" shortcut like HTTPS. The machine-in-the-middle attacks CISPA demonstrated work ",[44,891,892],{},"precisely"," when that mutual check is advertised but not enforced.",[15,895,896],{},"Hold onto the second point. Almost every control below is a way of making that mutual check real instead of decorative.",[15,898,899,903],{},[39,900],{"alt":901,"src":902},"Application authentication and user authentication are two separate checks on the same OPC UA session.","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-application-vs-user-authentication.png",[44,904,905],{},"OPC UA authenticates the software and the operator as two separate checks, not one.",[48,907,909],{"id":908},"stop-accepting-inbound-connections-at-all","Stop accepting inbound connections at all",[15,911,912],{},"Part 1 opened with the worst number: 14,220 internet-exposed servers, more than half allowing unauthenticated access. The instinct is to bolt authentication onto an exposed server. The better move is to stop the server from accepting inbound connections in the first place.",[15,914,915,916,919,920,923,924,927],{},"OPC UA has a protocol feature built for exactly this, and most \"best practices\" posts never mention it: ",[24,917,918],{},"Reverse Connect",". Normally a client opens the TCP connection to a server. Reverse Connect inverts that, the ",[44,921,922],{},"server"," dials out to the client and sends a ",[89,925,926],{},"ReverseHello"," message (OPC UA Part 6), and the client establishes the secure channel over that server-initiated socket. The handshake and all mutual authentication proceed exactly as before; only the direction of the initial TCP connection flips.",[15,929,930,934],{},[39,931],{"alt":932,"src":933},"Traditional connect requires an open inbound port; Reverse Connect has the server dial out so the firewall stays closed.","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-reverse-connect-vs-traditional.png",[44,935,936],{},"Reverse Connect inverts the initial TCP connection so the firewall stays closed. Only the socket origin flips, the client still drives the OPC UA session.",[15,938,939,940,943],{},"Why this matters architecturally: the server sits in the production zone behind a firewall with ",[24,941,942],{},"no inbound ports open",". From the firewall's perspective the traffic is outbound, the one direction it already permits. A SCADA client or edge gateway in the DMZ listens on a single port; each downstream server connects out to it. You get bidirectional OPC UA communication while the production-network firewall stays completely closed to the outside.",[15,945,946],{},"This is the structural fix that makes Part 1's exposure problem disappear rather than merely guarding it. Layer it inside normal defense in depth, the zone-and-conduit segmentation IEC 62443 calls for:",[56,948,949,959,965],{},[59,950,951,954,955,958],{},[24,952,953],{},"Segment the network."," Control network separate from enterprise, firewalls between zones. A typical layout: ",[89,956,957],{},"SignAndEncrypt"," from the enterprise zone (historians, MES, ERP), through a DMZ of edge gateways and protocol bridges, down to a plant floor where PLCs and HMIs sit on isolated VLANs.",[59,960,961,964],{},[24,962,963],{},"Put a security gateway in the DMZ."," A gateway can terminate Reverse Connect on both sides and act as the single, aggregating access point to the plant, the only door, and one you control.",[59,966,967,970,971,974],{},[24,968,969],{},"Keep the single-port design as leverage, not a license."," OPC UA's standard TCP 4840 keeps firewall rules clean. Clean rules are what let you ",[44,972,973],{},"not"," expose the server, not an excuse to.",[15,976,977],{},"Vendors agree on the bottom line. Siemens, Schneider, and Rockwell all explicitly advise against putting these servers on the open internet. Reverse Connect is how you comply without losing IT\u002FOT data flow.",[15,979,980,984],{},[39,981],{"alt":982,"src":983},"A segmented network with Enterprise, DMZ, and Plant Floor zones separated by firewalls, with SignAndEncrypt links between them.","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-defense-in-depth-network-zones.png",[44,985,986],{},"OPC UA security sits inside a segmented, defense-in-depth network.",[48,988,990],{"id":989},"make-the-trust-list-actually-enforce","Make the trust list actually enforce",[15,992,993,994,997],{},"This was Part 1's ugliest vector, because the servers ",[44,995,996],{},"look"," secure, they advertise certificate authentication, they just don't enforce it. CISPA tested 48 products and found the failures clustered in trust list handling: missing support, disabled by default, insecure configuration. Here is how the trust check works, and the two settings that quietly defeat it.",[15,999,1000],{},"When a peer presents a certificate, a correct implementation validates it against three local stores:",[56,1002,1003,1009,1015],{},[59,1004,1005,1008],{},[24,1006,1007],{},"Trusted store",", certificates (or a CA root) you've explicitly chosen to trust.",[59,1010,1011,1014],{},[24,1012,1013],{},"Issuer store",", intermediate and root CA certificates plus their Certificate Revocation Lists (CRLs), used to walk and verify the chain.",[59,1016,1017,1020,1021,1024],{},[24,1018,1019],{},"Rejected store",", where unknown certificates land on first contact, ",[44,1022,1023],{},"pending an administrator's decision",". Nothing here is trusted.",[15,1026,1027,1028,1031],{},"The intended workflow is deliberate friction: an unknown peer's certificate drops into the rejected store, an administrator inspects it, and only then moves it to trusted. That manual approval ",[44,1029,1030],{},"is"," the security. Two things destroy it:",[15,1033,1034,1038],{},[39,1035],{"alt":1036,"src":1037},"Flowchart: a presented certificate is checked for trust, its chain validated, and accepted or refused, with admin approval promoting rejected certificates for the next connection.","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-certificate-trust-validation-flow.png",[44,1039,1040],{},"Trust nothing by default: certificates enter the trusted store only by explicit approval.",[120,1042,1043,1049],{},[59,1044,1045,1048],{},[24,1046,1047],{},"\"Automatically accept all certificates.\""," Almost every server has this toggle, Siemens TIA Portal, node tooling, test harnesses. It's there to get you past the handshake during commissioning, and it is the single most common reason a \"secure\" connection is actually wide open. A server set to auto-accept has, in effect, the disabled trust list from Part 1. This default is common enough that even purpose-built Node-RED OPC UA clients often ship with server certificates auto-accepted out of the box, convenient for testing, dangerous in production. Turn it off before production. Every time.",[59,1050,1051,1054,1055,1058],{},[24,1052,1053],{},"Trusting a commercial public CA's root."," If you drop a public CA into your trusted store, that CA, not you, decides which applications your systems trust. For OPC UA you want a ",[24,1056,1057],{},"company-specific CA"," whose root you control, or explicit per-application trust. Never a public one.",[15,1060,1061,1062,1064,1065,1068,1069,1072,1073,1076],{},"The concrete mechanic trips up everyone the first time, so it's worth being literal. To let a Node-RED OPC UA client talk to a Siemens S7 server over ",[89,1063,957],{},", you copy the client's certificate (in node-based tooling it's typically ",[89,1066,1067],{},"PKI\u002Fown\u002Fcerts\u002Fclient_certificate.pem",") into the ",[44,1070,1071],{},"server's"," trusted folder, and copy the server's certificate into the ",[44,1074,1075],{},"client's"," trusted store. Both ends, both directions, because authentication is mutual. Miss one side and you get the \"connection could not be established\" error that fills the Node-RED forums, almost always because one party doesn't yet trust the other.",[15,1078,1079,1080,1083],{},"The governing rule: ",[24,1081,1082],{},"trust nothing by default."," A certificate enters the trusted store only through explicit, human approval. That is the control CISPA kept finding switched off.",[48,1085,1087],{"id":1086},"force-signandencrypt-and-rip-the-deprecated-ciphers-out","Force SignAndEncrypt, and rip the deprecated ciphers out",[15,1089,1090],{},"Part 1's Secura research and the CVEs behind it all traced to one root cause: known-weak crypto left switched on in non-default configurations. You close this by removing the option, not by hoping nobody selects it.",[15,1092,1093,1096,1097,1100,1101,1104],{},[24,1094,1095],{},"Set the security mode deliberately."," Endpoints advertise a ",[44,1098,1099],{},"mode"," and a ",[44,1102,1103],{},"policy",". The mode is one of three:",[56,1106,1107,1112,1118],{},[59,1108,1109,1111],{},[89,1110,229],{},", no signing, no encryption, everything in plaintext. This is the \"None\" mode 80% of Part 1's exposed servers still offered. Disable it, or bind it to localhost-only diagnostics.",[59,1113,1114,1117],{},[89,1115,1116],{},"Sign",", every message signed but not encrypted. Integrity and authenticity without confidentiality. Use only where you've consciously decided the data is non-sensitive but you still must detect a forged value.",[59,1119,1120,1122,1123,1126],{},[89,1121,957],{},", signed ",[44,1124,1125],{},"and"," encrypted: integrity, authenticity, and confidentiality together. The answer for anything carrying process data or accepting commands.",[15,1128,1129,1132,1133,222,1136,1139,1140,1142,1143,1146],{},[24,1130,1131],{},"Then remove the dead policies."," ",[89,1134,1135],{},"Basic128Rsa15",[89,1137,1138],{},"Basic256"," are deprecated, the OPC Foundation retired them in spec 1.04 because they lean on SHA-1 and RSA key lengths that no longer meet NIST or BSI guidance, and IEC 62443 and the NIST CSF explicitly flag them. ",[89,1141,1135],{}," is the exact policy behind Part 1's CVE-2024-42512 and CODESYS's CVE-2025-1468 Bleichenbacher oracle. If a server ",[44,1144,1145],{},"only"," offers these, that's a firmware-update conversation, not a config tweak.",[15,1148,1149,1150,1153,1154,1157,1158,1161,1162,1164],{},"For anything new, ",[89,1151,1152],{},"Basic256Sha256"," is the floor; the modern policies ",[89,1155,1156],{},"Aes128_Sha256_RsaOaep"," (faster) and ",[89,1159,1160],{},"Aes256_Sha256_RsaPss"," (strongest available) are better. The trade-off is backward compatibility, older devices won't speak the newer suites, so the realistic migration is ",[89,1163,1152],{}," as the enforced minimum while you push the fleet forward and decommission the deprecated suites as you go. The point is that an attacker can't downgrade to a broken cipher you've physically removed.",[48,1166,1168],{"id":1167},"separate-who-the-software-is-from-who-the-operator-is","Separate who-the-software-is from who-the-operator-is",[15,1170,1171,1172,1175,1176,1179,1180,1182,1183,1185],{},"Application authentication, handled above, proves ",[44,1173,1174],{},"which software"," connected. It says nothing about ",[44,1177,1178],{},"who"," is driving the session. Part 1's anonymous-access vector only fully closes when you enforce both layers, and as Part 1 noted, anonymous ",[44,1181,860],{}," access is far less dangerous when ",[44,1184,856],{}," authentication is genuinely enforced, and far more dangerous when it isn't.",[15,1187,1188],{},"User authentication options, weakest to strongest:",[56,1190,1191,1197,1206],{},[59,1192,1193,1196],{},[24,1194,1195],{},"Anonymous",", acceptable only for read-only, non-sensitive dashboards. Never write access, never diagnostics.",[59,1198,1199,1202,1203,1205],{},[24,1200,1201],{},"Username \u002F password",", fine, but only over a ",[89,1204,957],{}," endpoint, or you've just shipped credentials in plaintext.",[59,1207,1208,1211],{},[24,1209,1210],{},"User X.509 certificate",", strongest, and the natural fit for machine-to-machine.",[15,1213,1214,1215,1218],{},"Then constrain what an authenticated identity can do. Implement ",[24,1216,1217],{},"role-based access control from day one."," Running every application with administrator rights is the oversized blast radius Part 1 warned about, one compromise and the attacker owns the read-and-write path to the process. Assign read, write, and browse separately, per role, least privilege. If a server can't enforce granular access itself, put a gateway in front that can.",[48,1220,1222],{"id":1221},"manage-certificates-like-infrastructure-not-a-one-time-chore","Manage certificates like infrastructure, not a one-time chore",[15,1224,1225],{},"The trust mechanics above assume certificates that are valid, unique, and revocable. At one connection, manual exchange is fine. At a hundred it collapses, and that collapse is what produces the 20-year self-signed certs and shared keys Part 1 punished.",[15,1227,1228],{},"Every instance holds an X.509 v3 Application Instance Certificate (IEC 62541 Part 2): application URI as a globally unique ID, public key, issuer identity, validity window, issuer signature. The private key stays secret on the instance, leak it and that certificate must be revoked and replaced, the precise consequence CODESYS described for the Bleichenbacher oracle.",[15,1230,1231],{},"Non-negotiables regardless of scale:",[56,1233,1234,1240,1246,1252,1258,1264],{},[59,1235,1236,1239],{},[24,1237,1238],{},"One certificate per instance."," Share a certificate and revoking it after one compromise takes down every instance that shared it.",[59,1241,1242,1245],{},[24,1243,1244],{},"2048-bit RSA minimum",", 4096-bit for long-lived (5+ year) certificates.",[59,1247,1248,1251],{},[24,1249,1250],{},"SAN must match the application URI exactly",", or validation fails in maddening, hard-to-diagnose ways.",[59,1253,1254,1257],{},[24,1255,1256],{},"Track expiry like any operational asset."," Field certs carry absurd multi-decade lifetimes precisely because nobody wants to renew. That's deferral, not security. Reminder 60 days out.",[59,1259,1260,1263],{},[24,1261,1262],{},"Handle CRLs."," A trust store without working revocation can't respond to a compromise.",[59,1265,1266,1269],{},[24,1267,1268],{},"Protect the private-key store",", read\u002Fwrite to an administrator or the application only.",[15,1271,1272,1275,1276,1279],{},[24,1273,1274],{},"Automate before it hurts."," A ",[24,1277,1278],{},"Global Discovery Server (GDS)"," with certificate management acts as your CA and directory, issuing, renewing, and revoking across the fleet over standard PKI protocols (CMP, EST) so you're not vendor-locked. It works two ways:",[56,1281,1282,1288],{},[59,1283,1284,1287],{},[24,1285,1286],{},"Pull management",", the application (usually a client) calls the GDS to request and refresh its own certificate and trust list. It owns keeping itself current.",[59,1289,1290,1293,1294,1297,1298,1301],{},[24,1291,1292],{},"Push management",", the GDS pushes new certificates and trust lists ",[44,1295,1296],{},"to"," the application (usually a server), which exposes the methods for it. Push requires an encrypted channel and a client holding the ",[89,1299,1300],{},"SecurityAdmin"," role, and the GDS will only deliver an update over a channel at least as strong as the certificate being updated, it won't push a 4096-bit cert down a 2048-bit channel.",[15,1303,1304,1308],{},[39,1305],{"alt":1306,"src":1307},"A Global Discovery Server issuing certificates two ways: applications pull their own, or the GDS pushes certificates and trust lists to servers.","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopcua-gds-push-pull-certificate-management.png",[44,1309,1310],{},"A GDS automates certificate issuance, renewal, and revocation across the fleet.",[15,1312,1313],{},"One field tip even with a GDS: keep a local rejected-certificate store on each application, so you can still see and reason about what tried to connect.",[15,1315,1316,1317,1322],{},"If you're building this on FlowFuse, the OPC UA connectivity is available as one of the Certified Nodes introduced in ",[29,1318,1321],{"href":1319,"rel":1320},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2026\u002F06\u002Fflowfuse-release-2-31\u002F",[33],"FlowFuse 2.31",", vetted and FlowFuse-supported rather than pulled unmaintained from the community registry, which is the supply-chain point above made concrete. As with any OPC UA client, confirm it's set to reject untrusted server certificates before you go to production rather than auto-accepting them.",[48,1324,1326],{"id":1325},"keep-the-audit-trail-on-and-watched","Keep the audit trail on, and watched",[15,1328,1329,1330,1333],{},"Part 1's quietest, most damning detail: most anonymously reachable servers also had auditing ",[44,1331,1332],{},"disabled",", so an attacker connected, read the plant, and left no trace. A silent denial-of-service and a client-side compromise both get worse when nothing is watching.",[15,1335,1336,1337,1340],{},"OPC UA emits rich audit events for security-relevant operations. Turn them on, then make sure something ",[44,1338,1339],{},"collects and watches"," them, events nobody reads are theatre. This is what turns an undetected man-in-the-middle into an alert and a silent DoS into an incident with a timeline.",[48,1342,1344],{"id":1343},"patch-the-stack-and-especially-the-gateways","Patch the stack, and especially the gateways",[15,1346,1347,1348,1351],{},"Part 1 closed on a supply-chain truth: one flaw in a shared OPC UA library or sample propagates into every product built on it, and integration servers are rich targets because vulnerabilities ",[44,1349,1350],{},"chain",", Team82 strung five bugs together to own a Softing gateway.",[15,1353,1354],{},"So architecture doesn't end at configuration. Track CVEs for your specific stack and gateways. Subscribe to the OPC Foundation security bulletins and your vendors' advisories. Patch the integration servers stitching systems together with the same urgency as the servers themselves, owning one reaches everything behind it. And because the client trusts the server, a client fed bad data by a rogue server is its own vector (Part 1's client-side RCE): client-side updates matter as much as server-side.",[48,1356,1358],{"id":1357},"test-what-you-think-you-built","Test what you think you built",[15,1360,1361],{},"The step everyone skips. Verify configuration matches policy:",[56,1363,1364,1371,1377],{},[59,1365,1366,1367,1370],{},"Connect ",[44,1368,1369],{},"without"," a valid certificate, does the server actually reject it, or is auto-accept still on?",[59,1372,1373,1374,1376],{},"Read and write ",[44,1375,1369],{}," authorization, does RBAC actually deny it?",[59,1378,1379],{},"Point a security testing tool at your endpoints and confirm the advertised modes match the enforced ones.",[15,1381,1382],{},"A trust store you've never tested is a hypothesis, not a control, and Part 1 is a catalogue of deployments where the hypothesis was wrong.",[48,1384,1386],{"id":1385},"the-blueprint-in-one-breath","The blueprint, in one breath",[15,1388,1389],{},"Every vector in Part 1 had the same root cause: a tool OPC UA handed you that nobody switched on. The architecture is switching them on, in the order of biggest hole for least effort:",[120,1391,1392,1398,1404,1410,1416,1422,1427,1432],{},[59,1393,1394,1397],{},[24,1395,1396],{},"Reverse Connect + segmentation",", the server stops accepting inbound connections; the firewall stays closed.",[59,1399,1400,1403],{},[24,1401,1402],{},"Enforcing trust list, auto-accept off, company CA",", the mutual check becomes real instead of decorative.",[59,1405,1406,1409],{},[24,1407,1408],{},"SignAndEncrypt, deprecated ciphers removed",", no cipher to downgrade to.",[59,1411,1412,1415],{},[24,1413,1414],{},"User auth + RBAC on top of application auth",", both layers, least privilege.",[59,1417,1418,1421],{},[24,1419,1420],{},"One cert per instance, GDS-managed lifecycle",", valid, unique, revocable, at scale.",[59,1423,1424],{},[24,1425,1426],{},"Auditing on and watched.",[59,1428,1429],{},[24,1430,1431],{},"Stack and gateways patched.",[59,1433,1434],{},[24,1435,1436],{},"Tested against the policy, not the assumption.",[15,1438,1439],{},"OPC UA shipped with the strongest security model in industrial protocols. Part 1 showed what it looks like switched off. This is what it looks like switched on, and where FlowFuse fits is making it the default rather than the project: data pulled off exposed, internet-facing servers into a managed, segmented architecture where Reverse Connect, enforced trust, and least-privilege access are how the system is built, not a hardening pass you hope someone remembers to run.",{"title":458,"searchDepth":523,"depth":523,"links":1441},[1442,1443,1444,1445,1446,1447,1448,1449,1450,1451],{"id":849,"depth":491,"text":850},{"id":908,"depth":491,"text":909},{"id":989,"depth":491,"text":990},{"id":1086,"depth":491,"text":1087},{"id":1167,"depth":491,"text":1168},{"id":1221,"depth":491,"text":1222},{"id":1325,"depth":491,"text":1326},{"id":1343,"depth":491,"text":1344},{"id":1357,"depth":491,"text":1358},{"id":1385,"depth":491,"text":1386},{"type":797,"title":1453,"description":1454},"Make the secure setup the default, not the project","Everything above is an architecture you can configure by hand, but it's easier when the platform starts you in the right place. FlowFuse connects your OPC UA servers and lets you build dashboards and logic on that data with low-code, with an AI copilot that builds the flows for you from a prompt. Its OPC UA connectivity ships as a Certified Node, vetted and supported rather than pulled unmaintained from the community registry, with secure trust handling built in rather than bolted on. Talk to our team about your OT connectivity.","2026-06-05","Turn every OPC UA attack vector into a configuration decision you control: Reverse Connect to keep the firewall closed, enforced trust lists, SignAndEncrypt, GDS certificate management, RBAC, and the field anti-patterns that quietly undo all of it.","\u002Fblog\u002F2026\u002F06\u002Fimages\u002Fopc-ua-security.png",{"keywords":1459},"opc ua security, opc ua security architecture, opc ua reverse connect, opc ua certificate management, opc ua trust list, opc ua gds, opc ua signandencrypt, opc ua rbac, defensible opc ua, opc ua best practices, industrial security, iiot security","\u002Fblog\u002F2026\u002F06\u002Fopc-ua-security-best-practices",{"title":832,"description":1456},{"loc":1460},"blog\u002F2026\u002F06\u002Fopc-ua-security-best-practices","Part 1 showed how attackers walk in. This is the blueprint that locks every door behind them.",[825,827,1466],"security","A defensible OPC UA architecture is a handful of decisions, each closing a known attack vector. Use Reverse Connect and network segmentation so the server accepts no inbound connections and the firewall stays closed. Force SignAndEncrypt with a modern policy and remove the deprecated Basic128Rsa15 and Basic256 ciphers. Make the trust list enforce and turn off 'auto-accept all certificates.' Issue one certificate per instance from a company CA, automated through a GDS at scale. Layer user authentication and RBAC on top of application authentication. Keep auditing on and watched, patch the stack and gateways, then test that what you configured is what is actually running.","YjKpDHEEJ1-BHG4D4qCl25pLS8DNtJ9U_xghKTSpraE",{"id":1470,"title":1471,"authors":1472,"body":1473,"cta":1679,"date":1682,"description":1683,"extension":802,"image":1684,"lastUpdated":3,"meta":1685,"navigation":494,"path":1690,"seo":1691,"sitemap":1692,"stem":1693,"subtitle":1694,"tags":1695,"tldr":1697,"video":3,"__hash__":1698},"blog\u002Fblog\u002F2026\u002F05\u002Fopc-ua-security-attack-vectors.md","OPC UA Security: How Threat Actors Exploit Industrial Protocol Vulnerabilities",[10],{"type":12,"value":1474,"toc":1669},[1475,1478,1481,1485,1488,1491,1500,1504,1513,1516,1519,1524,1530,1533,1536,1540,1543,1551,1555,1561,1569,1572,1576,1584,1589,1592,1613,1617,1620,1633,1637,1646,1655,1659,1662],[15,1476,1477],{},"Threat actors don't break OPC UA's cryptography. They walk through the security it left switched off. The attacks that work in the field are disabled trust lists, anonymous logins left on, dead ciphers nobody removed, and servers sitting on the open internet. This post breaks down how attackers actually exploit OPC UA, vector by vector.",[15,1479,1480],{},"That's the irony. Unlike most industrial protocols, OPC UA ships with real security: authentication, signing, and encryption built into the spec. It's what finally let your Siemens PLC, your Allen-Bradley controller, and your SCADA system speak the same language. But \"built in\" and \"turned on\" are different things, and attackers live in that gap.",[48,1482,1484],{"id":1483},"why-attackers-target-opc-ua","Why attackers target OPC UA",[15,1486,1487],{},"The OPC server sits at a dangerous spot in the stack. It talks to PLCs, HMIs, and robotic arms, then exposes everything through one interface. For an attacker, that's the appeal: compromise the server and you don't get one device, you get the read-and-write path to the physical process.",[15,1489,1490],{},"That changes the attacker's goal. In IT, the aim is usually to take over the machine. In OT, the more alarming prospect is the physical one: because the OPC server issues the commands that run the plant, blinding the operator or freezing the server can create a safety problem, not just a data breach.",[15,1492,1493,1494,1499],{},"The scale is real. ",[29,1495,1498],{"href":1496,"rel":1497},"https:\u002F\u002Fclaroty.com\u002Fteam82\u002Fresearch\u002Fopc-ua-deep-dive-a-complete-guide-to-the-opc-ua-attack-surface",[33],"Claroty's Team82"," has disclosed more than two dozen OPC UA vulnerabilities since 2020, and its exploit framework has helped find close to 50 across clients, servers, and gateways.",[48,1501,1503],{"id":1502},"the-exposure-problem","The exposure problem",[15,1505,1506,1507,1512],{},"Before any clever exploit, there's the basic question of who can reach the server. ",[29,1508,1511],{"href":1509,"rel":1510},"https:\u002F\u002Fwww.bitsight.com\u002Fblog\u002Fopc-ua-server-internet-device-exposures-in-2025",[33],"Bitsight's TRACE research team",", in a year-long scan through June 2025, found 14,220 internet-exposed OPC UA devices across 99 countries. Over half (51.74%) allowed unauthenticated access. Among the devices that reported their supported security modes, 80.26% supported an unencrypted \"None\" mode that transmits data in plaintext. Most anonymously accessible servers also had auditing disabled, so an attacker connects, reads the plant, and leaves no trail.",[15,1514,1515],{},"None of this is a flaw in OPC UA itself. The protocol offers strong authentication and encryption; these are deployment and configuration choices made by asset owners.",[15,1517,1518],{},"Anonymous access, as Bitsight senior security research scientist Vasco Pinto frames it, is what makes the exposure dangerous:",[19,1520,1521],{},[15,1522,1523],{},"This configuration represents a significant security risk, as it allows anyone to access server information and potentially read operational data without authentication.",[15,1525,1526],{},[29,1527,1529],{"href":1509,"rel":1528},[33],"Bitsight TRACE",[15,1531,1532],{},"Major OT vendors, including Siemens, Schneider Electric, and Rockwell Automation, all explicitly advise against putting these servers on the open internet. Thousands remain there anyway.",[15,1534,1535],{},"The lesson from OT researchers is blunt: attackers often don't need an exploit. Unauthenticated, internet-facing servers are the entry point, and Shodan does the recon for free.",[48,1537,1539],{"id":1538},"anonymous-and-weak-authentication","Anonymous and weak authentication",[15,1541,1542],{},"If anonymous login is enabled, the server simply doesn't authenticate the user, and combined with internet exposure, there's no attack to speak of. The attacker just connects.",[15,1544,1545,1546,857,1548,1550],{},"There's a trap here too. OPC UA separates ",[44,1547,856],{},[44,1549,860],{}," authentication (who is the user?). Anonymous user access is far less risky when application authentication is enforced, but dangerous when it isn't. Many deployments disable the wrong layer and assume they're still covered.",[48,1552,1554],{"id":1553},"broken-certificate-validation","Broken certificate validation",[15,1556,1557,1558,1560],{},"This one's the worst, because the servers ",[44,1559,996],{}," secure. They advertise certificate-based authentication. They just don't enforce it.",[15,1562,1563,1568],{},[29,1564,1567],{"href":1565,"rel":1566},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2104.06051",[33],"CISPA researchers Alessandro Erba, Anne Müller, and Nils Ole Tippenhauer"," systematically tested 48 OPC UA products and libraries. They found 38 of the 48 carried one or more security issues, and 7 didn't support the protocol's security features at all. The failures cluster around certificate and trust list handling: missing trust list support, trust lists disabled by default, and insecure trust list configuration. The researchers were careful to locate the problem in implementations and configuration rather than the protocol's design, though they argued the standard contributes by permitting these insecure options in the first place.",[15,1570,1571],{},"What does that buy an attacker? A machine-in-the-middle position. A third party inserts itself between two legitimate entities, intercepting and tampering with data while neither side notices, blinding maintenance staff to the real state of the plant. The operator's screen says everything is normal. It isn't. The researchers proved it: their attack framework, which implements Rogue Server, Rogue Client, and Middleperson modes against real implementations, could steal exchanged credentials, eavesdrop on process data, and manipulate the physical process through sensor and actuator values.",[48,1573,1575],{"id":1574},"weak-legacy-crypto-left-switched-on","Weak legacy crypto left switched on",[15,1577,1578,1579,577],{},"OPC UA didn't build on TLS. It implemented its own cryptographic transport layer, which is exactly why Secura's Tom Tervoort, the researcher behind Zerologon, went after it ",[29,1580,1583],{"href":1581,"rel":1582},"https:\u002F\u002Fwww.darkreading.com\u002Fvulnerabilities-threats\u002Futilities-factories-encryption-holes-industrial-protocol",[33],"at DEF CON 33 in 2025",[19,1585,1586],{},[15,1587,1588],{},"That makes it an interesting research target for me, especially because they're not relying on an existing standard protocol like TLS. They implemented their own cryptographic protocol.",[15,1590,1591],{},"Tom Tervoort, Secura",[15,1593,1594,1595,1600,1601,1606,1607,1612],{},"His work produced three CVEs, all credited to him in the vendor advisories, and by his own account at the talk the underlying issues affected at least seven products. ",[29,1596,1599],{"href":1597,"rel":1598},"https:\u002F\u002Ffiles.opcfoundation.org\u002FSecurityBulletins\u002FOPC%20Foundation%20Security%20Bulletin%20CVE-2024-42513.pdf",[33],"CVE-2024-42513"," lets an unauthorized attacker bypass application authentication in the OPC UA .NET Standard Stack when HTTPS endpoints are enabled with a security policy other than None, which the OPC Foundation classifies as CWE-305 and rates medium severity. ",[29,1602,1605],{"href":1603,"rel":1604},"https:\u002F\u002Ffiles.opcfoundation.org\u002FSecurityBulletins\u002FOPC%20Foundation%20Security%20Bulletin%20CVE-2024-42512.pdf",[33],"CVE-2024-42512"," targets the deprecated Basic128Rsa15 policy, which uses RSA with PKCS#1 v1.5 padding. The OPC Foundation classifies it as an observable timing discrepancy (CWE-208) with confidentiality impact and rates it medium severity, noting that Basic128Rsa15 is disabled by default, so most users are unaffected. CODESYS, assessing the same weakness in its own server as ",[29,1608,1611],{"href":1609,"rel":1610},"https:\u002F\u002Fcertvde.com\u002Fen\u002Fadvisories\u002FVDE-2025-022\u002F",[33],"CVE-2025-1468",", describes the consequence more bluntly: an unauthenticated attacker exploiting the Bleichenbacher padding oracle (a decades-old attack that recovers RSA-encrypted secrets by watching how a server responds to malformed padding) could compromise the server certificate's private key, then bypass application authentication or decrypt traffic. The common thread is old, known-weak crypto that should have been retired but lingers in non-default configurations.",[48,1614,1616],{"id":1615},"denial-of-service-against-the-process","Denial of service against the process",[15,1618,1619],{},"Not every attack reads or steals. Some just stop the plant. Flooding or crashing the OPC server kills the SCADA workstation's real-time view and command path.",[15,1621,1622,1623,1628,1629,1632],{},"This is where OPC UA research began. In 2018, ",[29,1624,1627],{"href":1625,"rel":1626},"https:\u002F\u002Fics-cert.kaspersky.com\u002Fpublications\u002Freports\u002F2018\u002F05\u002F10\u002Fopc-ua-security-analysis\u002F",[33],"Kaspersky ICS CERT"," reported 17 zero-day vulnerabilities in the OPC Foundation's products, spanning denial of service and remote code execution, plus several flaws in commercial applications built on the stack. All were reported and fixed by the end of March 2018. It's worth noting the OPC Foundation's own response: it reviewed the findings and pointed out that eight of the 17 sat in an ANSI-C ",[44,1630,1631],{},"sample server application"," shipped as example code on GitHub rather than in the production stack, and that many third-party flaws came from developers misusing the stack's API. The researchers also pinned down the realistic threat model in interviews: exploitation usually needs local network access, and they said they had never seen a configuration allowing direct internet attacks. The broader lesson holds regardless: because a single flaw in a shared OPC UA library or sample can propagate into every product built on it, one bug scales across the supply chain.",[48,1634,1636],{"id":1635},"client-and-gateway-exploitation","Client and gateway exploitation",[15,1638,1639,1640,1645],{},"Servers aren't the only target. The client trusts the server, and that trust is exploitable. ",[29,1641,1644],{"href":1642,"rel":1643},"https:\u002F\u002Fclaroty.com\u002Fteam82\u002Fresearch\u002Fopc-ua-deep-dive-series-part-8-gaining-client-side-remote-code-execution",[33],"Team82 demonstrated client-side remote code execution"," by exploiting the client's trust in data it receives from the server. Stand up a rogue server and you can reach back into the clients connecting to it.",[15,1647,1648,1649,1654],{},"Integration servers, the gateways stitching multiple OPC UA systems together, are richer still, because vulnerabilities chain. ",[29,1650,1653],{"href":1651,"rel":1652},"https:\u002F\u002Fclaroty.com\u002Fteam82\u002Fresearch\u002Fopc-ua-deep-dive-series-part-9-chaining-vulnerabilities-to-exploit-softing-opc-ua-integration-server",[33],"In the Softing Secure Integration Server",", researchers chained four new bugs with a fifth to reach full remote code execution. No single flaw was catastrophic; strung together, they owned the box.",[48,1656,1658],{"id":1657},"the-pattern","The pattern",[15,1660,1661],{},"The vulnerabilities threat actors exploit in OPC UA are rarely clever zero days. They're disabled trust lists, anonymous logins, stale ciphers, exposed servers, and trusted clients fed bad data. The protocol gives you the tools to close every one. The question is whether they're switched on.",[15,1663,1664,1665,1668],{},"That's an architecture problem, and it's where we're headed next. In the follow-up, ",[44,1666,1667],{},"How to Establish a Defensible OPC UA Security Architecture",", we'll turn these attack vectors into a concrete blueprint for building OPC UA deployments that hold up.",{"title":458,"searchDepth":523,"depth":523,"links":1670},[1671,1672,1673,1674,1675,1676,1677,1678],{"id":1483,"depth":491,"text":1484},{"id":1502,"depth":491,"text":1503},{"id":1538,"depth":491,"text":1539},{"id":1553,"depth":491,"text":1554},{"id":1574,"depth":491,"text":1575},{"id":1615,"depth":491,"text":1616},{"id":1635,"depth":491,"text":1636},{"id":1657,"depth":491,"text":1658},{"type":797,"title":1680,"description":1681},"Connect your plant without opening it up","FlowFuse helps you move industrial data off exposed, internet-facing servers and into a managed, secure architecture. Talk to our team about your OT connectivity.","2026-05-29","Most OPC UA breaches don't crack the protocol's encryption. They walk through disabled trust lists, anonymous logins, stale ciphers, and servers left on the open internet. This post breaks down how attackers actually exploit OPC UA, vector by vector, drawing on research from Claroty, Bitsight, CISPA, Secura, and Kaspersky.","\u002Fblog\u002F2026\u002F05\u002Fimages\u002Fopcua-security-blog.png",{"excerpt":1686},{"type":12,"value":1687},[1688],[15,1689,1477],{},"\u002Fblog\u002F2026\u002F05\u002Fopc-ua-security-attack-vectors",{"title":1471,"description":1683},{"loc":1690},"blog\u002F2026\u002F05\u002Fopc-ua-security-attack-vectors","The attacks that work in the field aren't broken cryptography, they're security that was never switched on",[1696,826,827],"posts","OPC UA ships with real authentication, signing, and encryption, but attackers rarely touch it. They exploit the gap between 'built in' and 'turned on': anonymous access, trust lists that don't enforce certificates, deprecated ciphers nobody removed, and internet-exposed servers Shodan finds for free. The protocol gives you the tools to close every vector. The question is whether they're switched on.","TKc82UJPjRQQWCDijeIZJBWXP6VLpUjJe_fO1Bgd_Lg",{"id":1700,"title":1701,"authors":1702,"body":1703,"cta":1935,"date":1939,"description":1940,"extension":802,"image":1941,"lastUpdated":3,"meta":1942,"navigation":494,"path":1944,"seo":1945,"sitemap":1946,"stem":1947,"subtitle":1948,"tags":1949,"tldr":3,"video":3,"__hash__":1951},"blog\u002Fblog\u002F2026\u002F03\u002Fwhy-opcua-is-not-replacing-modbus-yet.md","Why OPC UA Is Not Replacing Modbus (Yet)",[10],{"type":12,"value":1704,"toc":1925},[1705,1710,1715,1718,1726,1729,1740,1743,1747,1750,1753,1756,1765,1768,1772,1775,1778,1781,1784,1787,1790,1793,1797,1800,1803,1806,1809,1812,1816,1819,1822,1825,1828,1831,1834,1838,1841,1844,1847,1850,1853,1856,1860,1863,1866,1869,1872,1875,1878,1882,1885,1888,1891,1894,1897,1900,1903,1907,1910,1913,1916,1919,1922],[15,1706,1707],{},[24,1708,1709],{},"Everyone in industrial automation agrees: OPC UA is the future. The specs are richer. The security is real. The semantic modeling is genuinely elegant. The industry consortia say so. The whitepapers say so. Vendors say so constantly, especially the ones selling OPC UA stacks.",[15,1711,1712],{},[24,1713,1714],{},"Modbus is still winning.",[15,1716,1717],{},"Not in keynotes. Not in roadmaps. On the factory floor, in new device datasheets, in RFQs sent out this quarter, Modbus keeps showing up where OPC UA was supposed to have taken over by now.",[15,1719,1720,1721,1725],{},"In January, we wrote about ",[29,1722,1724],{"href":1723},"\u002Fblog\u002F2026\u002F01\u002Fwhy-modbus-still-exist\u002F","why Modbus refuses to die",", the installed base, the zero-cost implementation, the vendor neutrality, the brutal simplicity that makes it work at 3 AM when nothing else will. That piece hit a nerve. The responses fell into two camps: engineers who nodded along because they live this every day, and architects who pushed back insisting OPC UA adoption is accelerating.",[15,1727,1728],{},"Both camps are right. And that's exactly the problem.",[15,1730,1731,1732,1735,1736,1739],{},"OPC UA isn't losing because it's a bad protocol. It's losing ground in places it should dominate because the gap between what OPC UA ",[44,1733,1734],{},"can"," do and what most facilities ",[44,1737,1738],{},"need"," done remains wider than the standards bodies want to admit. Capability isn't the same as adoption. A Ferrari doesn't win in a parking lot.",[15,1741,1742],{},"This isn't a eulogy for OPC UA. It's a sober look at the structural reasons why a protocol with every technical advantage on paper hasn't delivered the displacement its advocates have been predicting for fifteen years, and what would actually need to change for the \"yet\" in that title to disappear.",[48,1744,1746],{"id":1745},"the-promise-vs-the-reality","The Promise vs. The Reality",[15,1748,1749],{},"OPC UA was ratified in 2008. That's eighteen years ago. The pitch was compelling: a unified, secure, semantically rich protocol that would finally bring industrial automation into the modern era. The OPC Foundation had vendor backing. The specification was thorough. The vision was clear.",[15,1751,1752],{},"Optimistic predictions followed. The expectation in many quarters was that by the mid-2010s OPC UA would be the dominant machine-level protocol, that Modbus would be a legacy concern by 2020, and that the transition would be essentially complete by the middle of this decade. Those expectations reflected genuine enthusiasm for the protocol's capabilities, not sourced forecasts, but they shaped investment decisions and roadmaps across the industry nonetheless.",[15,1754,1755],{},"None of that happened.",[15,1757,1758,1759,1764],{},"The ",[29,1760,1763],{"href":1761,"rel":1762},"https:\u002F\u002Fwww.futuremarketreport.com\u002Findustry-report\u002Fmodbus-communication-module-market",[33],"Modbus TCP market was valued at $1.35 billion in 2024 and is projected to reach $2.55 billion by 2032",". That isn't legacy drag. That's active investment. New Modbus devices are being designed, manufactured, purchased, and installed in 2026, not as fallback options, but as deliberate first choices. Meanwhile, OPC UA adoption, while genuinely growing, remains concentrated in specific layers of the automation stack: SCADA systems, MES integrations, and IT\u002FOT gateways. At the field device level, Modbus still dominates.",[15,1766,1767],{},"The gap between expectation and reality isn't a failure of OPC UA's design. The protocol does what it promises. The gap exists because adoption in industrial automation doesn't follow software industry timelines. A protocol doesn't win by being technically superior. It wins by becoming the path of least resistance across every layer of the ecosystem simultaneously: device manufacturers, integrators, maintenance teams, procurement departments, and plant managers all have to move together. That has never happened with OPC UA, and understanding why requires looking at each layer honestly.",[48,1769,1771],{"id":1770},"the-complexity-tax-nobody-talks-about","The Complexity Tax Nobody Talks About",[15,1773,1774],{},"OPC UA's biggest competitor isn't Modbus. It's its own specification.",[15,1776,1777],{},"The full OPC UA specification runs across fourteen separate documents. A developer picking up Modbus for the first time can read the entire protocol specification over a weekend and ship a working implementation by Monday. A developer picking up OPC UA faces months of study before they can confidently build something production-ready.",[15,1779,1780],{},"This isn't an unfair criticism. It's the honest cost of doing more. Modbus reads and writes registers. OPC UA models information, manages sessions, handles subscriptions, enforces security policies, and describes data with rich metadata. That capability has a price, paid in implementation time, developer hours, and operational complexity.",[15,1782,1783],{},"For device manufacturers, the math is punishing. A Modbus RTU interface costs roughly $5 to $10 in silicon and a few days of firmware work. A proper OPC UA server, implemented correctly with certificate management, secure channels, and a meaningful information model, requires a capable processor, sufficient memory, and weeks of engineering time. For a sensor company shipping into a price-sensitive market, that difference doesn't show up as a line item in the spec sheet. It shows up in whether the product gets built at all.",[15,1785,1786],{},"Certificate management alone has quietly killed more OPC UA deployments than any technical limitation. Certificates expire. They need to be provisioned, rotated, and trusted across every client and server. In an IT environment with dedicated security teams, this is manageable. In a plant where the automation engineer also handles PLC programming, HMI design, and network troubleshooting, it becomes an ongoing burden that nobody budgeted for and nobody wants to own.",[15,1788,1789],{},"The OPC Foundation recognized this. Companion specifications like OPC UA FX and the Field Level Communications initiative are genuine attempts to bring the protocol closer to the field device layer. Progress is real but slow, and in the meantime, device manufacturers continue defaulting to Modbus because it ships today without a compliance checklist.",[15,1791,1792],{},"Complexity isn't a dealbreaker when the problem demands it. Nobody complains that OPC UA is too complex when it's modeling an entire production line in a SCADA system. The complexity tax only becomes fatal when the problem is simple and a simpler tool is sitting right there, already understood by the team, already working.",[48,1794,1796],{"id":1795},"the-skills-gap-on-the-floor","The Skills Gap on the Floor",[15,1798,1799],{},"Protocols don't run themselves. People configure them, troubleshoot them, and fix them at 2 AM when production is down. And the people doing that work in most manufacturing facilities today learned Modbus, not OPC UA.",[15,1801,1802],{},"This isn't a generational complaint. It's a workforce reality with direct operational consequences. The automation technician who has spent fifteen years on a plant floor can read a Modbus register map the way a mechanic reads an engine. They know register 40023 on device 12 is the motor temperature. They know what value triggers an alarm. They know how to pull up a protocol analyzer and spot the problem in minutes.",[15,1804,1805],{},"Ask that same technician to troubleshoot an OPC UA subscription that stopped delivering updates and the confidence evaporates. Is it a certificate issue? A session timeout? A misconfigured sampling interval? A namespace problem? The diagnostic path is longer, the tooling is more complex, and the required knowledge base is fundamentally different. The problem gets escalated, production stays down longer, and the experience gets filed away as evidence that OPC UA is unreliable. The protocol isn't unreliable. The skills to operate it confidently just aren't evenly distributed yet.",[15,1807,1808],{},"Training helps but doesn't solve the structural problem. OPC UA expertise is concentrated in system integrators and automation vendors, not in the maintenance teams who keep plants running day to day. Facilities that have gone deep on OPC UA often find themselves dependent on a small number of people who truly understand the stack, creating exactly the kind of single point of failure that conservative plant managers spend their careers avoiding.",[15,1810,1811],{},"The skills gap will close eventually. Engineering curricula are adding industrial networking content. Younger engineers are entering the field with broader protocol exposure. But eventually in industrial automation means a decade, not a release cycle. The plants being designed today will be maintained by the workforce that exists today, and that workforce is fluent in Modbus in a way it simply isn't in OPC UA yet.",[48,1813,1815],{"id":1814},"the-hardware-reality","The Hardware Reality",[15,1817,1818],{},"Modbus RTU was designed in 1979 for the hardware constraints of 1979, worth noting that Modbus TCP, the networked variant that dominates modern installations, didn't arrive until 1999. But the original serial protocol's frugality is what set the expectation, and the ecosystem never abandoned it.",[15,1820,1821],{},"A bare-minimum Modbus RTU slave implementation can run on an 8-bit microcontroller with around 10KB of flash and 1.5KB of RAM. A robust, production-grade implementation with full error handling and edge-case coverage needs more, typically several times that, but the floor is still extremely low compared to almost any alternative. Device manufacturers building sensors, meters, drives, and actuators work within tight BOM constraints where every dollar multiplies across thousands of units. Modbus fits inside the microcontroller they were already using. It adds no hardware cost and minimal firmware complexity.",[15,1823,1824],{},"OPC UA has a different story. A properly implemented OPC UA server needs a real processor capable of running a TCP\u002FIP stack, handling cryptographic operations, and managing runtime memory requirements. Lightweight stacks like open62541 have brought the floor down meaningfully, a constrained OPC UA server can run in under 100KB of flash with careful implementation, but that still represents a significant step up from a Modbus RTU slave, and a full-featured server with a rich information model typically requires several hundred kilobytes of RAM or more.",[15,1826,1827],{},"The OPC Foundation's work on OPC UA FX targets exactly this problem, aiming to bring the protocol down to devices with 256KB of flash and 64KB of RAM. That's genuine progress. It's also still an order of magnitude more resource-intensive than a minimal Modbus implementation on equivalent hardware, and FX-capable devices are only beginning to reach the market.",[15,1829,1830],{},"For established device categories the cost difference compounds quickly. A manufacturer selling thousands of flow meters into water treatment, oil and gas, and chemical processing isn't just buying components. They're buying tooling, certifications, and support infrastructure built around specific hardware platforms. Changing the processor family to support OPC UA means requalifying the entire product, retesting for environmental and EMC compliance, and retraining field service teams. The protocol upgrade triggers a full product redesign, and the business case rarely pencils out when the existing Modbus version is selling reliably into a market that hasn't asked for OPC UA.",[15,1832,1833],{},"Until OPC UA can run comfortably on the same class of hardware Modbus runs on today, at comparable cost and without requiring a platform redesign, the field device market will continue defaulting to Modbus. Not because engineers prefer old technology, but because the economics of building physical hardware into conservative industrial markets leave very little room for protocol idealism.",[48,1835,1837],{"id":1836},"where-opc-ua-actually-wins","Where OPC UA Actually Wins",[15,1839,1840],{},"This isn't a one-sided argument. OPC UA dominates in specific contexts and deserves the credit it gets there. Conflating the two is how bad architecture decisions get made in both directions.",[15,1842,1843],{},"At the SCADA and MES layer, OPC UA is the right answer. When you need to aggregate data from hundreds of heterogeneous devices and feed it into manufacturing execution systems, historian databases, and enterprise analytics platforms, Modbus gives you registers with no context. OPC UA gives you structured, self-describing data with units, ranges, relationships, and meaning baked in. At scale, that semantic layer saves thousands of engineering hours.",[15,1845,1846],{},"Security requirements close the conversation quickly. The moment a system needs to be accessible from outside the plant network, Modbus is disqualified. Not because it can't be hardened with compensating controls, but because its security model is nonexistent by design. OPC UA with TLS encryption, certificate-based authentication, and role-based access control provides the foundation connected industrial systems actually need.",[15,1848,1849],{},"Large equipment builders and machine OEMs increasingly ship with OPC UA as the primary integration interface, for good reason. A packaging line, CNC machining center, or industrial robot is a complex asset with hundreds of meaningful data points. OPC UA companion specifications from industry groups like OMAC, EUROMAP, and the VDMA define standardized information models for entire equipment categories. A machine built to the PackML OPC UA companion spec integrates with any PackML-aware SCADA system without custom mapping work. That interoperability has real commercial value.",[15,1851,1852],{},"Greenfield installations with modern hardware and no legacy constraints are where arguments for Modbus at the field level are weakest. When the BOM can absorb the hardware cost and the team has OPC UA skills, there is no compelling reason to default to a register-based polling protocol from 1979.",[15,1854,1855],{},"The pattern is consistent. OPC UA wins where complexity is justified by the problem, where security is non-negotiable, and where people and hardware resources exist to implement it properly. Those conditions describe the upper layers of the automation stack and modern greenfield projects. They do not yet describe the majority of the field device layer, and that distinction is exactly why the \"yet\" still belongs in this article's title.",[48,1857,1859],{"id":1858},"the-gateway-middle-ground","The Gateway Middle Ground",[15,1861,1862],{},"The industry didn't wait for OPC UA to win. It built a workaround and quietly made it the standard architecture.",[15,1864,1865],{},"Edge gateways now sit at the boundary between the field device layer and everything above it, speaking Modbus to the equipment that has always spoken Modbus and presenting OPC UA, MQTT, or REST to the systems that need structured, secure data. It isn't a temporary fix pending full OPC UA adoption. For most facilities, it is the architecture, and it works well enough that the pressure to replace Modbus at the source has largely evaporated.",[15,1867,1868],{},"This reflects how industrial modernization actually happens. Plants don't replace working equipment to adopt better protocols. They add intelligence at the edge and leave the field devices alone. A Modbus temperature transmitter installed in 2008 keeps transmitting exactly as it always has. The gateway reads its registers, maps the raw value to a properly typed OPC UA node with engineering units and metadata attached, and publishes it upstream. The transmitter never knows the difference. The SCADA system gets clean, contextualized data. Nobody touched the wiring.",[15,1870,1871],{},"The business case is straightforward. Replacing field devices across a large facility to gain native OPC UA at the source costs millions of dollars, requires production downtime, and delivers no improvement in the process being controlled. Adding an edge gateway costs thousands, takes days to deploy, and delivers the same data quality improvement. The ROI calculation ends quickly.",[15,1873,1874],{},"FlowFuse is built around exactly this architecture. Node-RED flows running on the edge read Modbus registers from legacy field devices, apply context and normalization, and publish structured data over MQTT or OPC UA to cloud systems, historians, and analytics platforms. The Modbus equipment keeps running. The modern data infrastructure gets what it needs. The migration happens at the connectivity layer rather than the device layer, which is the only migration path that makes economic sense for most operational facilities.",[15,1876,1877],{},"The gateway middle ground isn't a compromise born of failure. It's a pragmatic recognition that the automation stack has always been heterogeneous and always will be. New protocols don't replace old ones in industrial environments. They get added on top, and the translation layer between them becomes the most important piece of architecture in the building.",[48,1879,1881],{"id":1880},"what-would-actually-accelerate-opc-ua-adoption","What Would Actually Accelerate OPC UA Adoption",[15,1883,1884],{},"Diagnosing why OPC UA hasn't replaced Modbus is useful. Identifying what would actually change the trajectory is more useful. Not wishlist thinking, but a realistic assessment of the specific friction points that, if addressed, would move the needle in ways that eighteen years of industry advocacy has not.",[15,1886,1887],{},"The most immediate lever is simplification at the implementation level. Device manufacturers make platform decisions years before products ship. Every year that lightweight OPC UA profiles remain incomplete or poorly supported by silicon vendors is another product generation that defaults to Modbus. Finalizing FX profiles, getting them supported in major embedded toolchains, and making reference implementations genuinely production-ready would lower the barrier in ways that specification documents alone cannot.",[15,1889,1890],{},"Certificate management needs to be solved, not documented. The current approach requires automation engineers to operate like IT security professionals in environments where that expertise simply does not exist. Automated certificate lifecycle management, built into OPC UA servers and clients by default, would remove one of the most common reasons deployments stall or fail after going live. Several vendors are working on this. It needs to become a baseline expectation, not a premium feature.",[15,1892,1893],{},"Open source needs to catch up. Modbus has dozens of mature, well-documented stacks across every embedded platform imaginable. OPC UA open source options have improved, open62541 in particular has become a credible foundation, but the ecosystem remains thinner and less consistent in quality and maintenance overall. A developer evaluating both protocols reaches for the option with better community support and lower risk of hitting an undocumented edge case six months before launch. Closing that gap requires sustained investment from the OPC Foundation, major vendors, and the broader industrial open source community.",[15,1895,1896],{},"Interoperability between vendor implementations remains more aspirational than actual. Passing certification does not guarantee seamless interoperability across every feature combination two products might use together. Tightening conformance requirements and expanding interoperability testing infrastructure would give integrators the confidence that OPC UA devices from different manufacturers actually work together reliably, the way Modbus devices have for forty years.",[15,1898,1899],{},"Finally, the total cost of ownership narrative needs to be addressed honestly. OPC UA advocates often present the protocol's benefits without fully accounting for implementation costs, support burden, and skills investment. Facilities that have been oversold and then struggled become skeptics who push back on the next modernization proposal. Engineers trust data and specifics. Give them that.",[15,1901,1902],{},"None of these changes are impossible. Some are already in progress. But progress in industrial standards moves at the pace of the least motivated stakeholder, and the least motivated stakeholders are the ones who have something that works today.",[48,1904,1906],{"id":1905},"conclusion-the-yet-has-a-deadline-but-nobody-knows-it","Conclusion: The \"Yet\" Has a Deadline, But Nobody Knows It",[15,1908,1909],{},"OPC UA will win. That part isn't in dispute.",[15,1911,1912],{},"The semantic modeling is too useful to ignore forever. The security requirements of connected industrial systems are too real to patch around indefinitely. The demand for self-describing, context-rich data will only grow as analytics, AI, and remote operations become standard expectations. The protocol that delivers all of that is OPC UA, not Modbus.",[15,1914,1915],{},"But winning eventually and winning now are two entirely different things. Fieldbus was supposed to replace 4-20mA. It did, mostly, over thirty years. Industrial Ethernet was supposed to eliminate serial communication. Serial communication is still everywhere. Better technology wins in industrial automation on a timeline set by depreciation schedules, workforce transitions, and the risk tolerance of people whose primary job is keeping production running. Those timelines are measured in decades and they do not compress because a standards body publishes a roadmap.",[15,1917,1918],{},"The \"yet\" in this article's title has a deadline. The honest answer, based on everything the industry has demonstrated about how protocol transitions actually unfold, is that it is further away than the whitepapers suggest and closer than the Modbus installed base makes it feel.",[15,1920,1921],{},"Plan accordingly. Build the gateway layer. Invest in OPC UA skills before you need them urgently. Specify OPC UA where the problem justifies it today. And stop expecting the field device layer to look like the SCADA layer anytime soon.",[15,1923,1924],{},"Modbus will be there when you get back.",{"title":458,"searchDepth":523,"depth":523,"links":1926},[1927,1928,1929,1930,1931,1932,1933,1934],{"id":1745,"depth":491,"text":1746},{"id":1770,"depth":491,"text":1771},{"id":1795,"depth":491,"text":1796},{"id":1814,"depth":491,"text":1815},{"id":1836,"depth":491,"text":1837},{"id":1858,"depth":491,"text":1859},{"id":1880,"depth":491,"text":1881},{"id":1905,"depth":491,"text":1906},{"type":1936,"title":1937,"description":1938},"demo","Bridge Modbus and OPC UA Without Ripping Out Your Infrastructure","FlowFuse connects your legacy Modbus devices to modern SCADA, cloud, and analytics systems using Node-RED at the edge. No hardware replacement. No production downtime. Just the data your modern systems need from the equipment already running your plant.","2026-03-30","OPC UA has every technical advantage. Modbus is still winning. Here's why the replacement hasn't happened and what would actually change that.","\u002Fblog\u002F2026\u002F03\u002Fimages\u002Fopcua-is-not-replacing-modbus-yet.png",{"keywords":1943},"opc ua, modbus, industrial automation, protocol comparison, field devices, scada, mes, industrial protocols, gateway architecture, edge computing, node-red, mqtt, industrial security, certificate management, interoperability","\u002Fblog\u002F2026\u002F03\u002Fwhy-opcua-is-not-replacing-modbus-yet",{"title":1701,"description":1940},{"loc":1944},"blog\u002F2026\u002F03\u002Fwhy-opcua-is-not-replacing-modbus-yet","Why your next device will still ship with Modbus, and what OPC UA needs to fix before that changes",[826,827,1950],"modbus","zGoIYxHV6dJg57-_1G-lzhSBh_imALBtvUBEN9IDzsU",{"id":1953,"title":1954,"authors":1955,"body":1956,"cta":2149,"date":2152,"description":2153,"extension":802,"image":3,"lastUpdated":3,"meta":2154,"navigation":494,"path":2160,"seo":2161,"sitemap":2162,"stem":2163,"subtitle":2164,"tags":2165,"tldr":3,"video":3,"__hash__":2166},"blog\u002Fblog\u002F2026\u002F01\u002Feliminate-opc-ua-bottleneck-ai-agents.md","Agentic AI Reads OPC UA Servers So You Don't Have To",[10],{"type":12,"value":1957,"toc":2143},[1958,1961,1968,1971,1974,1977,1982,1989,2000,2003,2010,2013,2017,2020,2023,2029,2032,2035,2038,2041,2044,2047,2051,2054,2057,2060,2068,2071,2079,2084,2087,2093,2097,2100,2120,2123,2127,2130,2133,2136],[15,1959,1960],{},"OPC UA servers store everything. Finding anything takes hours.",[15,1962,1963,1964,1967],{},"Your historian has six months of production data across 847 variables. Wednesday's batch failed quality checks. The root cause is in there, a sensor drift, a temperature anomaly, something that happened before the failure became visible. But variables are named ",[89,1965,1966],{},"ns=2;s=Device1.PLC.DB1.Temp_Sensor_3",". The namespace structure was designed for PLC efficiency, not human investigation.",[15,1969,1970],{},"So you click through hierarchies. Cross-reference documentation that's two firmware versions out of date. Export data to Excel. Build correlation matrices. Check timing against process logs. Four hours later, you find it.",[15,1972,1973],{},"OPC UA gave machines a common language. It solved connectivity. But it created an accessibility problem: the data infrastructure that captures everything makes finding specific answers remarkably slow.",[15,1975,1976],{},"The solution isn't better visualization or more dashboards. It's removing humans from the navigation process entirely. AI agents can browse OPC UA servers, pull historian data, run correlations, and surface answers while you're still typing the question.",[1978,1979,1981],"h1",{"id":1980},"why-investigation-remains-the-bottleneck","Why Investigation Remains the Bottleneck",[15,1983,1984,1985,1988],{},"Implementation problems in industrial IoT are largely solved. Teams connect devices, configure historians, and establish data flows with impressive efficiency, especially on platforms like FlowFuse. The wheels fall off when someone actually needs to ",[44,1986,1987],{},"use"," that data.",[15,1990,1991,1992,1995,1996,1999],{},"Your monitoring dashboard flags a reject rate spike on Line 3. That's the easy part, alerts work. But dashboards show you ",[44,1993,1994],{},"symptoms",", not ",[44,1997,1998],{},"causes",". Finding the cause means reconstructing what happened in the hours leading up to the spike. Which of the seventy-three variables on Line 3 changed? What correlations exist between the temperature sensors and quality metrics? How does this week's pattern compare to normal operations?",[15,2001,2002],{},"Every operational question follows this pattern. Why did energy consumption spike Tuesday? Which sensor readings predict motor failures? What operating conditions maximize packaging throughput? The questions change. The investigative workflow doesn't, navigate namespaces, extract data, analyze patterns, interpret results. Manual. Every. Single. Time.",[15,2004,2005,2006,2009],{},"Here's what makes this a systemic crisis rather than an annoyance: the data exists. The infrastructure works. But converting data into operational intelligence requires hours of skilled labor ",[44,2007,2008],{},"per question",". So people stop asking questions. They stick to pre-configured dashboards showing metrics someone decided to monitor six months ago. They don't explore. They don't investigate unexpected patterns. They definitely don't do the kind of exploratory analysis that actually drives improvement.",[15,2011,2012],{},"The standard solutions miss the fundamental problem. Hiring more analysts scales linearly at best, you get three people doing manual work instead of one. Building more dashboards only helps when you already know what to monitor. Neither solves for the unexpected question, the one-off investigation, the \"something doesn't look right\" hunch that requires pulling data you've never looked at before.",[48,2014,2016],{"id":2015},"what-ai-changes","What AI Changes",[15,2018,2019],{},"The value proposition is straightforward: Replace manual investigation workflows with automated execution.",[15,2021,2022],{},"Thursday afternoon, Line 3's reject rate spikes. The traditional approach takes six hours minimum if the data's clean and you know exactly where to look: Pull historian data for fifty variables that might matter. Build correlation matrices in Excel. Analyze sensor drift patterns. Cross-reference timing against process logs. Compare current performance against last month's baseline. Pull in a colleague to verify you didn't miss something obvious.",[15,2024,2025,2026],{},"Ask an AI agent: ",[44,2027,2028],{},"\"What changed in Line 3 before Thursday's spike?\"",[15,2030,2031],{},"The agent queries your historian across relevant subsystems. Runs timing correlations against the reject rate increase. Identifies statistical anomalies in sensor data. Tests relationships between variables. Flags causation with confidence intervals. Five minutes later you're reviewing root cause analysis, not building it from scratch.",[15,2033,2034],{},"This efficiency compounds across every investigative use case:",[15,2036,2037],{},"Predictive analysis that would take weeks becomes instant queries. Understanding how motor current relates to product quality typically requires extracting time-series data from your historian, cleaning datasets, running statistical tests, validating correlations, interpreting significance, three months of dedicated work. The agent returns correlation matrices with confidence intervals and outlier analysis while you're finishing your coffee.",[15,2039,2040],{},"Compliance documentation that takes weeks to compile generates on demand. Audits need complete OPC UA server documentation, node hierarchies, relationship mappings, system architecture, operational ranges calculated from historical performance. Manually, that's weeks of browsing address spaces and organizing specifications. The agent generates it directly from live server metadata and your historical data. Infrastructure changes next quarter? Regenerate the documentation instead of manually updating deprecated specs.",[15,2042,2043],{},"Pattern recognition at scale becomes feasible. Agents analyze patterns across days, weeks, months of continuous operation, patterns humans miss because they require simultaneous analysis of thousands of variables. \"Show me every instance where Variable_A spiked within ten minutes of Variable_B changing\" becomes a query you actually ask instead of a question you abandon because the manual investigation would take too long.",[15,2045,2046],{},"The mechanical work executes automatically: namespace navigation, data retrieval, correlation testing, anomaly detection. Your time goes to what requires actual judgment, interpreting analytical findings against operational knowledge, deciding whether to adjust processes or schedule maintenance. Questions you'd previously skip because investigation overhead exceeded potential value become queries worth asking.",[48,2048,2050],{"id":2049},"the-technology-behind-it","The Technology Behind It",[15,2052,2053],{},"FlowFuse makes this work through a straightforward architectural approach that connects AI reasoning to industrial data systems.",[15,2055,2056],{},"As an industrial data platform, FlowFuse already handles connectivity to OPC UA servers, historians, and other industrial systems. The new capability comes from MCP nodes that expose this connectivity through the Model Context Protocol, a standardized interface that lets AI systems interact with any data source using common operations like browse, read, query, and analyze.",[15,2058,2059],{},"Here's how it flows: You ask your AI agent a question in natural language. The agent translates that into MCP operations, browse this namespace, retrieve these variables, analyze this time range. FlowFuse receives those operations and executes them against your actual infrastructure, handling all the OPC UA protocol complexity, session management, and security. The agent gets back structured data, interprets it, and gives you an answer.",[15,2061,2062,2066],{},[39,2063],{"alt":2064,"dataZoomable":458,"src":2065},"High-level architecture diagram showing the interaction between Al agents and industrial systems via the FlowFuse Platform.","\u002Fblog\u002F2026\u002F01\u002Fimages\u002Fai-mcp-opcua.png",[44,2067,2064],{},[15,2069,2070],{},"The architecture separates concerns cleanly. AI handles the reasoning, figuring out what data matters and how to interpret it. FlowFuse handles the execution, dealing with industrial protocols, data access, and system integration. Neither tries to do the other's job.",[15,2072,2073,2074],{},"For teams building their own integrations, the implementation details are documented here: ",[29,2075,2078],{"href":2076,"rel":2077},"https:\u002F\u002Fflowfuse.com\u002Fblog\u002F2025\u002F10\u002Fbuilding-mcp-server-using-flowfuse\u002F",[33],"Building MCP Server Using FlowFuse",[15,2080,2081],{},[24,2082,2083],{},"Watch It Work",[15,2085,2086],{},"The video below shows an AI agent generating complete OPC UA server documentation on request, finishing in minutes what typically requires weeks of manual effort.",[2088,2089],"lite-youtube",{"videoid":2090,"style":2091,"title":2092},"agxAw4B91Nw","width: 100%; aspect-ratio: 16\u002F9; background-image: url('\u002Fblog\u002F2026\u002F01\u002Fimages\u002Fai-opcua-document-generation.jpg'); background-size: cover; background-position: center;","AI Agent Generating OPC UA Documentation",[48,2094,2096],{"id":2095},"what-this-unlocks","What This Unlocks",[15,2098,2099],{},"Connecting agents to OPC UA infrastructure delivers capabilities manual investigation can't match at scale.",[56,2101,2102,2108,2114],{},[59,2103,2104,2107],{},[24,2105,2106],{},"Autonomous navigation across address spaces."," Agents read node hierarchies, examine metadata, DisplayNames, EngineeringUnits, data types, access levels, follow references between nodes, build structural understanding of systems. You describe what you need, agent locates relevant nodes. No memorizing namespace paths or node IDs. Looking for a pump's discharge pressure sensor buried five levels deep in your hierarchy? Agent finds it by understanding equipment relationships, not because someone documented the exact path.",[59,2109,2110,2113],{},[24,2111,2112],{},"Automated data analysis across historians."," Agents pull historical data, run statistical tests, calculate correlations, detect anomalies, compare time periods, validate significance. Ask \"How does ambient temperature affect motor current draw on Line 2?\" and get months of historian data analyzed, variables correlated, confounding factors accounted for, confidence intervals calculated. Manual approach means days of Excel work: extraction, cleaning, statistical analysis, validation. Agent returns analyzed results in minutes while you're still drinking your coffee.",[59,2115,2116,2119],{},[24,2117,2118],{},"Pattern recognition at operational scale."," Agents analyze patterns across days, weeks, months of continuous operation, patterns humans miss because they require simultaneous analysis of thousands of variables. \"Show me every instance where Variable_A spiked within ten minutes of Variable_B changing\" becomes a query you actually ask instead of a question you abandon. Finding subtle leading indicators of equipment degradation across hundreds of sensors? Agent correlates every variable combination, identifies statistically significant patterns, surfaces predictions. Doing this manually would take months of dedicated work. Nobody attempts it because nobody has months to spare.",[15,2121,2122],{},"Investigation capabilities that previously required dedicated data science teams become natural language queries. Complex analyses finish in minutes instead of weeks. Questions you'd skip because the investigation wasn't worth the effort become routine operational intelligence you actually use.",[48,2124,2126],{"id":2125},"the-bigger-picture","The Bigger Picture",[15,2128,2129],{},"The value in industrial data was never about collection, it was always about the questions that data could answer. Those questions just cost too much time to pursue. When investigation drops from hours to minutes, the economics change completely. Different questions become worth asking. Documentation stays current because updating it is on-demand instead of weeks of work. Pattern analysis across thousands of variables becomes routine instead of heroic.",[15,2131,2132],{},"This isn't about replacing people with automation. It's about making the data infrastructure you already built actually useful for the decisions it was meant to inform. Your team still interprets results, makes judgment calls, and takes action. The AI just handles the mechanical work of data access and analysis.",[15,2134,2135],{},"And it's not limited to OPC UA. FlowFuse's MCP approach works the same way across any industrial system, MQTT brokers, Modbus devices, SQL databases, REST APIs, whatever protocols you're running. Same natural language interface, same investigation capabilities, different underlying systems. The infrastructure you have becomes the infrastructure you can actually use.",[15,2137,2138,2139,215],{},"For a complete guide to connecting PLCs via OPC UA, EtherNet\u002FIP, Siemens S7, and Modbus to MQTT, cloud, and enterprise systems, see the ",[29,2140,2142],{"href":2141},"\u002Flanding\u002Fplc\u002F","FlowFuse PLC integration overview",{"title":458,"searchDepth":523,"depth":523,"links":2144},[2145,2146,2147,2148],{"id":2015,"depth":491,"text":2016},{"id":2049,"depth":491,"text":2050},{"id":2095,"depth":491,"text":2096},{"id":2125,"depth":491,"text":2126},{"type":797,"title":2150,"description":2151},"Turn Your Industrial Data Into Instant Answers","If you want a single platform to reliably connect OPC UA servers, devices, and data systems, and make that data usable by both people and AI, FlowFuse provides the foundation.","2026-01-30","Learn how agentic AI transforms OPC UA server investigations, automating data access, analysis, and root cause detection to turn hours of manual work into minutes.",{"keywords":2155,"excerpt":2156},"OPC UA, AI Agents, MCP, FlowFuse, Industrial IoT, Root Cause Analysis, Node-RED.",{"type":12,"value":2157},[2158],[15,2159,1960],{},"\u002Fblog\u002F2026\u002F01\u002Feliminate-opc-ua-bottleneck-ai-agents",{"title":1954,"description":2153},{"loc":2160},"blog\u002F2026\u002F01\u002Feliminate-opc-ua-bottleneck-ai-agents","Why manual OPC UA investigation is the bottleneck, and how agentic AI eliminates it",[826,827],"VxJeoHGoGtEptK3nRE7Wa0k0DU6JmL4SZYKCtQ8YI48",{"id":2168,"title":2169,"authors":2170,"body":2171,"cta":2671,"date":2674,"description":2675,"extension":802,"image":2676,"lastUpdated":2677,"meta":2678,"navigation":494,"path":2686,"seo":2687,"sitemap":2688,"stem":2689,"subtitle":2690,"tags":2691,"tldr":2693,"video":2694,"__hash__":2695},"blog\u002Fblog\u002F2026\u002F01\u002Fopcua-vs-mqtt.md","MQTT vs OPC UA: Why This Question Never Has a Straight Answer",[10],{"type":12,"value":2172,"toc":2651},[2173,2176,2179,2182,2185,2188,2191,2195,2198,2202,2208,2213,2216,2224,2227,2247,2250,2255,2268,2271,2274,2278,2281,2284,2289,2292,2298,2301,2306,2309,2312,2317,2355,2358,2363,2366,2369,2373,2376,2379,2382,2385,2393,2396,2400,2409,2412,2415,2418,2422,2425,2429,2432,2435,2438,2442,2445,2448,2451,2454,2458,2461,2464,2467,2471,2474,2477,2480,2483,2487,2490,2493,2496,2500,2503,2506,2509,2513,2516,2519,2526,2529,2532,2535,2538,2541,2545,2548,2551,2554,2559,2562,2567,2570,2575,2578,2583,2586,2594,2600,2603,2606,2610,2613,2631,2634,2637,2640,2643,2646],[15,2174,2175],{},"The question itself is broken.",[15,2177,2178],{},"MQTT moves messages. OPC UA defines meaning. They operate at different layers of the stack. Comparing them is like comparing TCP to JSON.",[15,2180,2181],{},"Yet the debate persists. Vendors position them as competitors. Consultants bill by the complexity. Your procurement department demands a choice.",[15,2183,2184],{},"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,2186,2187],{},"The persistent debate exists because the distinction between their purposes remains unclear to many decision-makers.",[15,2189,2190],{},"This article explains what each does, where they differ, and how to decide based on requirements instead of marketing.",[48,2192,2194],{"id":2193},"what-each-actually-does","What Each Actually Does",[15,2196,2197],{},"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.",[190,2199,2201],{"id":2200},"mqtt-the-minimalist-messenger","MQTT: The Minimalist Messenger",[15,2203,2204,2205],{},"MQTT is a publish-subscribe messaging protocol designed in 1999 for satellite oil pipeline monitoring. It does exactly one thing: ",[44,2206,2207],{},"move small messages between devices over unreliable networks with minimal overhead.",[15,2209,2210],{},[24,2211,2212],{},"The entire protocol is remarkably compact:",[15,2214,2215],{},"Publishers send messages to named topics. Subscribers express interest in topic patterns. A broker routes messages from publishers to matching subscribers. That's it.",[453,2217,2222],{"className":2218,"code":2220,"language":2221},[2219],"language-text","Device A publishes: \"factory\u002Fline3\u002Ftemperature\" → 72.4\nDevice B subscribes: \"factory\u002Fline3\u002F#\"\nBroker delivers: Device B receives 72.4\n","text",[89,2223,2220],{"__ignoreMap":458},[15,2225,2226],{},"MQTT's three quality-of-service levels handle network reality:",[56,2228,2229,2235,2241],{},[59,2230,2231,2234],{},[24,2232,2233],{},"QoS 0",": Fire and forget. Message might arrive. Might not. Zero guarantees.",[59,2236,2237,2240],{},[24,2238,2239],{},"QoS 1",": At least once delivery. Message arrives one or more times. Duplicates possible.",[59,2242,2243,2246],{},[24,2244,2245],{},"QoS 2",": Exactly once delivery between client and broker, using a four-way handshake.",[15,2248,2249],{},"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,2251,2252],{},[24,2253,2254],{},"What MQTT doesn't provide:",[15,2256,2257,2258,222,2261,222,2264,2267],{},"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. ",[89,2259,2260],{},"factory\u002Fline3\u002Ftemp",[89,2262,2263],{},"factory\u002Fline3\u002Ftemperature",[89,2265,2266],{},"line3\u002Ffactory\u002Ftemp"," are entirely different topics with no semantic relationship.",[15,2269,2270],{},"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,2272,2273],{},"MQTT is deliberately minimal. This simplicity at the transport layer enables its flexibility and efficiency.",[190,2275,2277],{"id":2276},"opc-ua-the-semantic-framework","OPC UA: The Semantic Framework",[15,2279,2280],{},"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,2282,2283],{},"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,2285,2286],{},[24,2287,2288],{},"At its core is the address space, a hierarchical graph of nodes:",[15,2290,2291],{},"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.",[453,2293,2296],{"className":2294,"code":2295,"language":2221},[2219],"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",[89,2297,2295],{"__ignoreMap":458},[15,2299,2300],{},"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,2302,2303],{},[24,2304,2305],{},"Companion specifications extend this model for specific industries:",[15,2307,2308],{},"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,2310,2311],{},"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,2313,2314],{},[24,2315,2316],{},"OPC UA provides multiple interaction patterns:",[56,2318,2319,2325,2331,2337,2343,2349],{},[59,2320,2321,2324],{},[24,2322,2323],{},"Data access",": Read\u002Fwrite variables synchronously",[59,2326,2327,2330],{},[24,2328,2329],{},"Subscriptions",": Monitor variables, receive change notifications",[59,2332,2333,2336],{},[24,2334,2335],{},"Methods",": Execute operations on server objects (start motor, set recipe)",[59,2338,2339,2342],{},[24,2340,2341],{},"Events",": Structured alarm and event notifications",[59,2344,2345,2348],{},[24,2346,2347],{},"Historical access",": Time-series query interface",[59,2350,2351,2354],{},[24,2352,2353],{},"PubSub"," (Part 14): Publish address space updates to message brokers, including MQTT",[15,2356,2357],{},"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,2359,2360],{},[24,2361,2362],{},"The tradeoff is implementation complexity:",[15,2364,2365],{},"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,2367,2368],{},"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.",[190,2370,2372],{"id":2371},"the-layer-mismatch","The Layer Mismatch",[15,2374,2375],{},"Think about the OSI model, that seven-layer networking abstraction everyone learns and immediately forgets:",[15,2377,2378],{},"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,2380,2381],{},"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,2383,2384],{},"Comparing them is comparing different architectural concerns:",[56,2386,2387,2390],{},[59,2388,2389],{},"MQTT answers: \"How do I efficiently move this message from publisher to subscriber?\"",[59,2391,2392],{},"OPC UA answers: \"What does this data represent, and how does it relate to other data?\"",[15,2394,2395],{},"They're not competing solutions to the same problem. They're solving different problems that happen to intersect in industrial automation architectures.",[190,2397,2399],{"id":2398},"the-convergence","The Convergence",[15,2401,2402,2403,2408],{},"OPC UA ",[29,2404,2407],{"href":2405,"rel":2406},"https:\u002F\u002Freference.opcfoundation.org\u002FCore\u002FPart14\u002Fv104\u002Fdocs\u002F",[33],"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,2410,2411],{},"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,2413,2414],{},"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,2416,2417],{},"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?\"",[48,2419,2421],{"id":2420},"where-they-actually-differ","Where They Actually Differ",[15,2423,2424],{},"Understanding real differences requires moving past marketing claims to examine what each technology optimizes for and what constraints it accepts as tradeoffs.",[190,2426,2428],{"id":2427},"network-assumptions","Network Assumptions",[15,2430,2431],{},"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,2433,2434],{},"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,2436,2437],{},"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.",[190,2439,2441],{"id":2440},"discovery-and-configuration","Discovery and Configuration",[15,2443,2444],{},"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,2446,2447],{},"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,2449,2450],{},"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,2452,2453],{},"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.",[190,2455,2457],{"id":2456},"state-and-synchronization","State and Synchronization",[15,2459,2460],{},"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,2462,2463],{},"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,2465,2466],{},"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.",[190,2468,2470],{"id":2469},"security-models","Security Models",[15,2472,2473],{},"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,2475,2476],{},"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,2478,2479],{},"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,2481,2482],{},"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.",[190,2484,2486],{"id":2485},"bandwidth-and-overhead","Bandwidth and Overhead",[15,2488,2489],{},"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,2491,2492],{},"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,2494,2495],{},"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.",[190,2497,2499],{"id":2498},"scalability-patterns","Scalability Patterns",[15,2501,2502],{},"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,2504,2505],{},"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,2507,2508],{},"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.",[48,2510,2512],{"id":2511},"the-unified-namespace-question","The Unified Namespace Question",[15,2514,2515],{},"\"Just use Unified Namespace\" appears in every MQTT versus OPC UA discussion, framed as the answer that makes protocol choice irrelevant.",[15,2517,2518],{},"It is not sufficient.",[15,2520,2521,2525],{},[29,2522,2524],{"href":2523},"\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,2527,2528],{},"But UNS doesn't eliminate protocol choice. It relocates it.",[15,2530,2531],{},"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,2533,2534],{},"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,2536,2537],{},"The question changes from \"MQTT or OPC UA for everything?\" to \"MQTT or OPC UA for this specific connection?\"",[15,2539,2540],{},"UNS is valuable architecture. It's not a protocol substitute.",[190,2542,2544],{"id":2543},"how-to-actually-decide","How to Actually Decide",[15,2546,2547],{},"Most protocol comparisons start with feature matrices. Yours should start with data flow diagrams.",[15,2549,2550],{},"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,2552,2553],{},"Consider four factors for each data flow:",[15,2555,2556],{},[24,2557,2558],{},"1. Semantic requirements",[15,2560,2561],{},"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,2563,2564],{},[24,2565,2566],{},"2. Network constraints",[15,2568,2569],{},"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,2571,2572],{},[24,2573,2574],{},"3. Native protocol support",[15,2576,2577],{},"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,2579,2580],{},[24,2581,2582],{},"4. Scale characteristics",[15,2584,2585],{},"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,2587,2588,2589,2593],{},"For example, you're connecting 50 CNC machines, 500 environmental sensors, ",[29,2590,2592],{"href":2591},"\u002Fsolutions\u002Fmes\u002F","MES",", predictive maintenance, and cloud analytics.",[453,2595,2598],{"className":2596,"code":2597,"language":2221},[2219],"- 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",[89,2599,2597],{"__ignoreMap":458},[15,2601,2602],{},"Four data flows, two protocols, zero false choices. The architecture reflects requirements, not vendor marketing.",[15,2604,2605],{},"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.",[48,2607,2609],{"id":2608},"moving-forward","Moving Forward",[15,2611,2612],{},"The persistence of this debate reveals something: we're still thinking protocol-first instead of problem-first.",[15,2614,2615,2616,2620,2621,2625,2626,2630],{},"Stop asking \"which protocol?\" Start mapping your actual data flows and constraints. That pipeline sensor? ",[29,2617,2619],{"href":2618},"\u002Fblog\u002F2024\u002F06\u002Fhow-to-use-mqtt-in-node-red\u002F","MQTT",". That machine coordination? ",[29,2622,2624],{"href":2623},"\u002Fblog\u002F2025\u002F07\u002Freading-and-writing-plc-data-using-opc-ua\u002F","OPC UA",". That edge-to-cloud telemetry? ",[29,2627,2629],{"href":2628},"\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,2632,2633],{},"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,2635,2636],{},"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,2638,2639],{},"The right question isn't \"MQTT or OPC UA?\"",[15,2641,2642],{},"It's \"MQTT where? OPC UA where? Both where?\"",[15,2644,2645],{},"Answer that based on your requirements, not vendor marketing.",[15,2647,2648,2649,215],{},"For a practical guide to connecting PLCs via both OPC UA and MQTT in FlowFuse, alongside EtherNet\u002FIP, Siemens S7, and Modbus, see the ",[29,2650,2142],{"href":2141},{"title":458,"searchDepth":523,"depth":523,"links":2652},[2653,2659,2667,2670],{"id":2193,"depth":491,"text":2194,"children":2654},[2655,2656,2657,2658],{"id":2200,"depth":498,"text":2201},{"id":2276,"depth":498,"text":2277},{"id":2371,"depth":498,"text":2372},{"id":2398,"depth":498,"text":2399},{"id":2420,"depth":491,"text":2421,"children":2660},[2661,2662,2663,2664,2665,2666],{"id":2427,"depth":498,"text":2428},{"id":2440,"depth":498,"text":2441},{"id":2456,"depth":498,"text":2457},{"id":2469,"depth":498,"text":2470},{"id":2485,"depth":498,"text":2486},{"id":2498,"depth":498,"text":2499},{"id":2511,"depth":491,"text":2512,"children":2668},[2669],{"id":2543,"depth":498,"text":2544},{"id":2608,"depth":491,"text":2609},{"type":797,"title":2672,"description":2673},"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":2679,"excerpt":2680},"MQTT vs OPC UA, MQTT protocol, OPC UA protocol, industrial communication, IIoT architecture, OPC UA PubSub, MQTT Sparkplug",{"type":12,"value":2681},[2682,2684],[15,2683,2175],{},[15,2685,2178],{},"\u002Fblog\u002F2026\u002F01\u002Fopcua-vs-mqtt",{"title":2169,"description":2675},{"loc":2686},"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",[826,827,2692],"mqtt","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":2697,"title":2698,"authors":2699,"body":2700,"cta":2878,"date":2881,"description":2882,"extension":802,"image":2883,"lastUpdated":3,"meta":2884,"navigation":494,"path":2890,"seo":2891,"sitemap":2892,"stem":2893,"subtitle":2894,"tags":2895,"tldr":3,"video":2896,"__hash__":2897},"blog\u002Fblog\u002F2026\u002F01\u002Fkepware-opcua-better-alternative.md","Beyond Kepware: Why Modern Industrial Connectivity Demands a Second Look",[10],{"type":12,"value":2701,"toc":2872},[2702,2705,2708,2711,2715,2718,2721,2724,2727,2730,2733,2736,2739,2742,2745,2749,2752,2755,2758,2761,2764,2767,2770,2773,2776,2779,2782,2786,2789,2792,2798,2804,2810,2816,2822,2825,2828,2831,2834,2838,2841,2844,2847,2850,2853,2856,2859,2862,2865],[15,2703,2704],{},"Kepware isn't chosen, it's assumed. It appears in budgets like line items for electricity or insurance. No one questions it. No one compares it. It just... goes in.",[15,2706,2707],{},"And that's exactly the problem. You've been paying luxury car prices, often well into six figures, for a data shuttle bus. Reliable? Sure. But while Kepware moves your data, it also moves your money straight into per-tag, per-connection licensing fees that explode as you scale. Worse, you don't control your own data. And now, with TPG's $600 million acquisition closing in early 2026, you're betting on a company mid-transition, mid-uncertainty, mid-everything.",[15,2709,2710],{},"The question isn't whether Kepware works. It's whether you can afford to keep not asking better questions.",[48,2712,2714],{"id":2713},"why-you-picked-kepware-and-why-that-made-sense","Why You Picked Kepware (And Why That Made Sense)",[15,2716,2717],{},"Before we talk about why Kepware shouldn't be your next choice, let's acknowledge why it was your last one. Because the logic that got you here wasn't wrong, it was just incomplete.",[15,2719,2720],{},"You didn't choose Kepware. Kepware chose you.",[15,2722,2723],{},"Your integrator spec'd it. The equipment vendor had already validated it. Your boss signed off without discussion because \"everyone uses Kepware.\" When you're staring down a plant expansion deadline with production breathing down your neck, safe beats optimal every time.",[15,2725,2726],{},"And Kepware was safe. Until the bills started compounding.",[15,2728,2729],{},"$15,000 for the initial license seemed reasonable. Then came additional tags for the new production line. New drivers for equipment you hadn't planned for. A redundant server because IT flagged single points of failure. Eighteen months later, you're at 20x annually, and nobody remembers approving half of it.",[15,2731,2732],{},"Here's what actually happened: Kepware didn't win on technical merit. It won on timing and driver ubiquity.",[15,2734,2735],{},"In the early 2000s, industrial connectivity was genuinely hard. Proprietary PLC protocols. Sparse documentation. Vendors actively hostile to third-party integration. Kepware invested aggressively in driver development, by 2010, if a PLC existed in North America, Kepware almost certainly supported it. That created a network effect system integrators couldn't ignore. Standardization followed. Equipment vendors tested against it. PTC's $100 million acquisition in 2016 cemented the strategy.",[15,2737,2738],{},"You didn't get tricked. Lock-in happened through entirely normal operations.",[15,2740,2741],{},"But here's what the sales process never highlights: escalating switching costs aren't a side effect. They're the business model.",[15,2743,2744],{},"Your goal was never \"buy Kepware.\" Your goal was to move OT data where it matters, fast, reliably, without unnecessary drama.",[48,2746,2748],{"id":2747},"kepware-pricing-explained-how-costs-escalate-as-you-scale","Kepware Pricing Explained: How Costs Escalate as You Scale",[15,2750,2751],{},"The ROI spreadsheet your vendor showed you was accurate. It just ended when the story was just beginning.",[15,2753,2754],{},"You approved Kepware because the first-year quote made sense: base license, sufficient tags for operations, drivers for your PLCs. Number aligned with budget. Decision closed.",[15,2756,2757],{},"Then your plant didn't stop.",[15,2759,2760],{},"New production line? More tags needed. Different PLC brand? New driver license. Maintenance kicks in at 18-20%, calculated not on your starting point, but on everything you've added since. IT finally gets redundancy approved. Operations wants visualization. Kepware doesn't do that, so you're buying elsewhere. New vendor. New purchase order.",[15,2762,2763],{},"Year two: more equipment, more expansion. Your historian works with Kepware. Your analytics tool doesn't. Middleware required. Management wants remote access. Cloud gateway added. Every item individually justified. Every purchase properly approved. All operationally necessary.",[15,2765,2766],{},"Year three: you're maintaining the entire accumulated infrastructure. Tag costs scaled with production capacity. Integration expenses compounded with each system added.",[15,2768,2769],{},"What wasn't emphasized during procurement: Kepware moves data. Full stop. You still need separate systems for storage (historian), translation (middleware), visualization (dashboards), and processing (analytics). The purchase order said \"connectivity.\" The actual infrastructure required five different vendors.",[15,2771,2772],{},"The pricing model punishes scale. More capacity needs more tags. More tags mean higher licensing. Higher licensing means steeper maintenance. Your costs climb while the underlying technology expenses, bandwidth, compute, storage, have been dropping for years.",[15,2774,2775],{},"Per-tag pricing doesn't match infrastructure reality. It matches what the market has tolerated. The actual cost of transmitting ten thousand data points versus one thousand? Essentially identical. Cloud providers know this. Modern software companies abandoned this model. The technology doesn't require metered billing, it just permits it.",[15,2777,2778],{},"Kepware charges per-tag because nobody's forced them to change.",[15,2780,2781],{},"You thought you bought connectivity. What you actually got was a billing structure that monetizes your success. Every expansion. Every new line. Every added system. Kepware extracts revenue from it. This isn't a partnership, it's value extraction wearing an enterprise license agreement.",[48,2783,2785],{"id":2784},"why-kepware-makes-less-sense-in-2026","Why Kepware Makes Less Sense in 2026",[15,2787,2788],{},"Five years ago, questioning Kepware meant gambling with production reliability. The alternatives weren't proven.",[15,2790,2791],{},"Today they are. And fundamental shifts made the old calculation obsolete.",[15,2793,2794,2797],{},[24,2795,2796],{},"Protocol secrecy collapsed."," Kepware's advantage rested entirely on PLC manufacturers hiding their communication protocols. Documentation was unavailable. Reverse engineering was mandatory. Now every significant protocol specification is publicly published. Manufacturers provide detailed technical guides. Industry bodies standardized everything. What once demanded rare expertise is now freely available knowledge. The technical moat largely dried up. The pricing hasn't acknowledged it.",[15,2799,2800,2803],{},[24,2801,2802],{},"Infrastructure economics flipped."," Handling 50,000 tags used to mean purchasing dedicated servers, implementing redundant hardware, staffing IT personnel. Real capital expenditure. Today that same capacity runs on $200 monthly cloud compute. The underlying cost dropped 90%. Kepware's licensing model operates as though nothing changed.",[15,2805,2806,2809],{},[24,2807,2808],{},"Complexity barriers vanished."," Configuring Kepware required certified specialists. Three-day deployments minimum. Formal training requirements. Troubleshooting demanded protocol knowledge most engineers lacked. Modern platforms offer drag-and-drop setup, automatic device discovery, visual configuration. What took specialists three days, operations teams complete in two hours. The complexity that forced expensive integrator relationships disappeared.",[15,2811,2812,2815],{},[24,2813,2814],{},"Fragmented purchases became unified platforms."," Kepware moved data. Full stop. You still needed separate historians, visualization tools, cloud gateways, middleware, analytics platforms. Five vendors. Five contracts. Five integration projects. Modern platforms ship unified, not assembled from parts, designed as integrated systems. The integration tax evaporated.",[15,2817,2818,2821],{},[24,2819,2820],{},"And private equity bought Kepware for $600 million."," TPG's deal closes early 2026. Private equity doesn't maintain operations, it maximizes returns. That often means price increases, forced product bundles, or operational restructuring designed to extract more from existing customers. It's the same playbook every time.",[15,2823,2824],{},"You're not evaluating Kepware as it is. You're evaluating what it becomes under new ownership carrying $600 million in return expectations.",[15,2826,2827],{},"The window's narrow. Before new pricing hits. Before renewals reflect new ownership. While you control the timing instead of reacting to changes forced on you.",[15,2829,2830],{},"The safe choice five years ago became the risky bet today. Alternatives matured. Economics shifted fundamentally. Ownership transferred.",[15,2832,2833],{},"Evaluate now, or negotiate from weakness later.",[48,2835,2837],{"id":2836},"the-bottom-line","The Bottom Line",[15,2839,2840],{},"You didn't select Kepware after rigorous evaluation. You selected it because it was the path of least resistance.",[15,2842,2843],{},"Least resistance meant proven reliability. Integrator familiarity. Budget pre-approval. Zero pushback.",[15,2845,2846],{},"But resistance-free had costs. Not just licensing, per-tag economics that scale against you. Integration overhead that multiplies vendor relationships. Lock-in that monetizes every operational expansion.",[15,2848,2849],{},"And now adds new risk: private equity ownership with $600 million in performance expectations.",[15,2851,2852],{},"The fundamentals shifted. Protocols became open. Infrastructure costs dropped 90%. Modern platforms integrated what previously required assembly. The technical and economic moats that justified Kepware as default evaporated.",[15,2854,2855],{},"You're not constrained by technology. You're constrained by inertia.",[15,2857,2858],{},"Kepware functions reliably. That's not disputed. But reliability alone doesn't justify paying 2015 prices for 2026 infrastructure when alternatives provide more capability at lower total cost.",[15,2860,2861],{},"Evaluate alternatives now from strength. Or negotiate renewals later from weakness under new ownership terms.",[15,2863,2864],{},"Kepware won through early dominance and ecosystem lock-in. That's separate from being the right architecture for current operations.",[15,2866,2867,2868,2871],{},"See ",[29,2869,2870],{"href":2141},"how FlowFuse connects any PLC to MQTT, OPC UA, cloud, and enterprise systems",", without per-tag licensing or proprietary lock-in.",{"title":458,"searchDepth":523,"depth":523,"links":2873},[2874,2875,2876,2877],{"id":2713,"depth":491,"text":2714},{"id":2747,"depth":491,"text":2748},{"id":2784,"depth":491,"text":2785},{"id":2836,"depth":491,"text":2837},{"type":797,"title":2879,"description":2880},"Evaluate Your Options Before New Ownership Does It For You","FlowFuse connects your PLCs, historians, and cloud systems without per-tag penalties or vendor lock-in. See how teams are cutting Kepware costs while gaining more capability, before your next renewal.","2026-01-16","Kepware became the default when industrial connectivity was hard. Today, its pricing model, scaling costs, and private-equity ownership make it a growing risk. Here's why it's time to re-evaluate.","\u002Fblog\u002F2026\u002F01\u002Fimages\u002Fkepware-alternative.png",{"keywords":2885,"excerpt":2886},"kepware alternatives, opc ua server, industrial connectivity, per-tag pricing, plc data integration, industrial middleware, ot-it convergence",{"type":12,"value":2887},[2888],[15,2889,2704],{},"\u002Fblog\u002F2026\u002F01\u002Fkepware-opcua-better-alternative",{"title":2698,"description":2882},{"loc":2890},"blog\u002F2026\u002F01\u002Fkepware-opcua-better-alternative","Why per-tag pricing, scale penalties, and private-equity ownership change the risk equation",[826,827],"rWcfYX_0_8U","m0V02doIljCqBepr5NN9zOJTmj7EQzy0RqB9GB1e54k",{"id":2899,"title":2900,"authors":2901,"body":2902,"cta":3,"date":4184,"description":4185,"extension":802,"image":4186,"lastUpdated":3,"meta":4187,"navigation":494,"path":4195,"seo":4196,"sitemap":4197,"stem":4198,"subtitle":4199,"tags":4200,"tldr":4201,"video":4202,"__hash__":4203},"blog\u002Fblog\u002F2025\u002F08\u002Fadvanced-opcua-real-time-subscriptions-alarms-historical-data.md","OPC UA Tutorial: Advanced Monitoring with Subscriptions, Alarms, and Historical Data",[10],{"type":12,"value":2903,"toc":4163},[2904,2911,2914,2917,2921,2924,2949,2953,2956,2973,2978,2981,2984,2988,2991,2994,2997,3001,3004,3009,3018,3036,3060,3063,3067,3070,3073,3179,3182,3208,3211,3214,3220,3223,3227,3230,3236,3242,3245,3249,3252,3255,3259,3277,3280,3300,3304,3307,3318,3401,3409,3431,3434,3437,3440,3443,3447,3450,3496,3510,3513,3517,3520,3523,3527,3530,3541,3676,3684,3706,3709,3713,3716,3721,3854,3859,3993,3998,4135,4138,4141,4145,4148,4151,4157,4160],[15,2905,2906,2907,2910],{},"In our ",[29,2908,2909],{"href":2623},"previous tutorial",", we covered OPC UA basics, connecting to servers, reading tags, and writing values. Now it's time for the features that make OPC UA truly powerful in production.",[15,2912,2913],{},"Polling for data every few seconds works fine for demos, but real systems need better. They need instant updates when values change. They need alarms that fire immediately when something goes wrong. They need access to historical data for troubleshooting. And they need to trigger complex operations without juggling dozens of write commands.",[15,2915,2916],{},"This guide shows you how to build all of that using advanced OPC UA features in FlowFuse Node-RED.",[48,2918,2920],{"id":2919},"what-youll-learn","What You'll Learn",[15,2922,2923],{},"This guide covers four powerful OPC UA features:",[56,2925,2926,2931,2937,2943],{},[59,2927,2928,2930],{},[24,2929,2329],{},": Get real-time updates without constant polling",[59,2932,2933,2936],{},[24,2934,2935],{},"Events & Alarms",": Capture and handle equipment alerts as they happen",[59,2938,2939,2942],{},[24,2940,2941],{},"Historical Data",": Query past values for trending and analysis",[59,2944,2945,2948],{},[24,2946,2947],{},"Method Calls",": Execute functions directly on your equipment",[48,2950,2952],{"id":2951},"prerequisites","Prerequisites",[15,2954,2955],{},"To follow this guide, you'll need:",[56,2957,2958,2965,2968],{},[59,2959,2960,2961,2964],{},"FlowFuse running instance with the ",[89,2962,2963],{},"node-red-contrib-opcua"," nodes installed",[59,2966,2967],{},"A working OPC UA server connection",[59,2969,2970,2971],{},"The basics from our ",[29,2972,2909],{"href":2623},[19,2974,2975],{},[15,2976,2977],{},"Managing and scaling Node-RED instances is easy with FlowFuse, offering DevOps pipelines, audit logs, snapshots, high availability, and much more. [Start your free trial today!]({% include \"sign-up-url.njk\" %})",[15,2979,2980],{},"Before proceeding, check which features your OPC UA server supports, most handle subscriptions and events, but historical data and methods vary by vendor.",[15,2982,2983],{},"Let's get started.",[48,2985,2987],{"id":2986},"real-time-monitoring-with-subscriptions","Real-Time Monitoring with Subscriptions",[15,2989,2990],{},"OPC UA subscriptions monitor values on the server side and notify you only when they change. This is fundamentally different from polling, where you repeatedly ask for values whether they've changed or not.",[15,2992,2993],{},"Consider a pressure sensor that spikes from 5 to 20 bar and back to 5 bar in one second. With 2-second polling, you miss this critical event entirely. With subscriptions, the server captures it and notifies you immediately.",[15,2995,2996],{},"The efficiency gains are significant too. Monitoring 100 tags with polling means 100 requests every 2 seconds, consuming bandwidth even when nothing changes. Subscriptions send updates only when values actually change, reducing network traffic and server load.",[190,2998,3000],{"id":2999},"setting-up-subscriptions","Setting Up Subscriptions",[15,3002,3003],{},"To create your first subscription:",[120,3005,3006],{},[59,3007,3008],{},"Drag an Inject node onto your canvas. This will trigger the subscription to start.",[19,3010,3011],{},[15,3012,3013,3014,215],{},"Note: This article uses Inject nodes for manual triggering to illustrate key concepts. In production, it is advisable to create interactive dashboards with FlowFuse Dashboard to enable effective monitoring and control. For more information on designing operator interfaces, please refer to ",[29,3015,3017],{"href":3016},"\u002Fblog\u002F2023\u002F07\u002Fhow-to-build-a-opc-client-dashboard-in-node-red\u002F","this article",[120,3019,3020,3027,3030,3033],{"start":491},[59,3021,3022,3023,3026],{},"Add an OpcUa-Item node. Double-click it and enter the NodeId of the tag you want to monitor, like ",[89,3024,3025],{},"ns=2;i=2007",". Select the correct data type for your tag.",[59,3028,3029],{},"Place an OpcUa-Client node on the canvas. Open its Configuration, select your OPC UA server endpoint configuration, and change the Action dropdown to \"SUBSCRIBE\". Set the interval to how often you want updates.",[59,3031,3032],{},"Connect the Inject output to the OpcUa-Item input. Connect the OpcUa-Item output to the OpcUa-Client input. Add a Debug node and connect the OpcUa-Client output to the Debug input.",[59,3034,3035],{},"Deploy your flow and click the Inject button.",[15,3037,3038,3039,3059],{},"{% renderFlow 300 %}\n",[462,3040,3041,3042,3045,3046,3048,3049,3051,3052,3055,3056,3058],{},"{\"id\":\"c62e8dab346d62bb\",\"type\":\"inject\",\"z\":\"7008401a.b94db\",\"name\":\"\",\"props\":",[462,3043,3044],{},"{\"p\":\"topic\",\"vt\":\"str\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":490,\"y\":740,\"wires\":[[\"cce9159a656858b9\"]]},{\"id\":\"cce9159a656858b9\",\"type\":\"OpcUa-Item\",\"z\":\"7008401a.b94db\",\"item\":\"ns=3;i=1003\",\"datatype\":\"Int32\",\"value\":\"\",\"name\":\"\",\"x\":700,\"y\":740,\"wires\":[[\"042a5d016ce879c6\"]]},{\"id\":\"1c1d56834b8d3373\",\"type\":\"debug\",\"z\":\"7008401a.b94db\",\"name\":\"Result\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":1130,\"y\":720,\"wires\":",[462,3047],{},"},{\"id\":\"bccca1356626f117\",\"type\":\"debug\",\"z\":\"7008401a.b94db\",\"name\":\"Errors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":1130,\"y\":760,\"wires\":",[462,3050],{},"},{\"id\":\"042a5d016ce879c6\",\"type\":\"OpcUa-Client\",\"z\":\"7008401a.b94db\",\"endpoint\":\"\",\"action\":\"subscribe\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":\"2\",\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":1,\"maxMessageSize\":8192,\"receiveBufferSize\":8192,\"sendBufferSize\":8192,\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":940,\"y\":740,\"wires\":[[\"1c1d56834b8d3373\"],",[462,3053,3054],{},"\"bccca1356626f117\"",",",[462,3057],{},"]}","\n{% endrenderFlow %}",[15,3061,3062],{},"When clicked, the OpcUa-Item node sends the tag to the OpcUa-Client and creates the subscription. The node’s status will update to “subscribed” once the subscription is active. When values change, they appear in the debug panel. If no value changes occur within the interval time, the status will show “keep alive” to confirm that the connection is still active.",[190,3064,3066],{"id":3065},"subscribing-to-multiple-tags","Subscribing to Multiple Tags",[15,3068,3069],{},"To monitor multiple tags, simply create multiple OpcUa-Item nodes and connect them all to the OpcUa-Client node. Each item node should have its own NodeId configured. When you trigger the flow, all tags start updating simultaneously.",[15,3071,3072],{},"For many tags, you can also use a Function node to subscribe to multiple tags at once. Connect the Function node directly to the OpcUa-Client node (no OpcUa-Item node needed). Use the \"multiple\" topic with the following code:",[453,3074,3076],{"className":455,"code":3075,"language":457,"meta":458,"style":458},"msg.topic = \"multiple\";\nmsg.payload = [\n    { nodeId: \"ns=3;i=1007\" },\n    { nodeId: \"ns=3;i=1002\" },\n    { nodeId: \"ns=3;i=1001\" }\n];\nreturn msg;\n",[89,3077,3078,3098,3110,3130,3147,3165,3171],{"__ignoreMap":458},[462,3079,3080,3082,3084,3087,3089,3091,3094,3096],{"class":464,"line":465},[462,3081,501],{"class":472},[462,3083,215],{"class":476},[462,3085,3086],{"class":472},"topic ",[462,3088,477],{"class":476},[462,3090,511],{"class":476},[462,3092,3093],{"class":514},"multiple",[462,3095,518],{"class":476},[462,3097,488],{"class":476},[462,3099,3100,3102,3104,3106,3108],{"class":464,"line":491},[462,3101,501],{"class":472},[462,3103,215],{"class":476},[462,3105,556],{"class":472},[462,3107,477],{"class":476},[462,3109,561],{"class":472},[462,3111,3112,3115,3118,3120,3122,3125,3127],{"class":464,"line":498},[462,3113,3114],{"class":476},"    {",[462,3116,3117],{"class":573}," nodeId",[462,3119,577],{"class":476},[462,3121,511],{"class":476},[462,3123,3124],{"class":514},"ns=3;i=1007",[462,3126,518],{"class":476},[462,3128,3129],{"class":476}," },\n",[462,3131,3132,3134,3136,3138,3140,3143,3145],{"class":464,"line":523},[462,3133,3114],{"class":476},[462,3135,3117],{"class":573},[462,3137,577],{"class":476},[462,3139,511],{"class":476},[462,3141,3142],{"class":514},"ns=3;i=1002",[462,3144,518],{"class":476},[462,3146,3129],{"class":476},[462,3148,3149,3151,3153,3155,3157,3160,3162],{"class":464,"line":544},[462,3150,3114],{"class":476},[462,3152,3117],{"class":573},[462,3154,577],{"class":476},[462,3156,511],{"class":476},[462,3158,3159],{"class":514},"ns=3;i=1001",[462,3161,518],{"class":476},[462,3163,3164],{"class":476}," }\n",[462,3166,3167,3169],{"class":464,"line":549},[462,3168,637],{"class":472},[462,3170,488],{"class":476},[462,3172,3173,3175,3177],{"class":464,"line":564},[462,3174,651],{"class":650},[462,3176,480],{"class":472},[462,3178,488],{"class":476},[15,3180,3181],{},"Below is the complete flow monitoring multiple tags:",[15,3183,3038,3184,3059],{},[462,3185,3186,3187,3189,3190,3192,3193,3195,3196,3055,3199,3201,3202,3204,3205,3207],{},"{\"id\":\"93d8a766.c57aa8\",\"type\":\"function\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"NodeId Array\",\"func\":\"msg.payload = ",[462,3188],{},";\\nmsg.payload.push({ nodeId: \"ns=3;i=1001\"});\\nmsg.payload.push({ nodeId: \"ns=3;i=1002\"});\\nmsg.payload.push({ nodeId: \"ns=3;i=1003\"});\\nreturn msg;\",\"outputs\":1,\"timeout\":\"\",\"noerr\":0,\"initialize\":\"\",\"finalize\":\"\",\"libs\":",[462,3191],{},",\"x\":430,\"y\":400,\"wires\":[[\"ba45b808.7ff578\"]]},{\"id\":\"2d805dd3.473632\",\"type\":\"inject\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Subscribe multiple\",\"props\":",[462,3194,3044],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"multiple\",\"x\":230,\"y\":400,\"wires\":[[\"93d8a766.c57aa8\"]]},{\"id\":\"ba45b808.7ff578\",\"type\":\"OpcUa-Client\",\"z\":\"58b3ba58c45b22dd\",\"endpoint\":\"\",\"action\":\"subscribe\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":\"2\",\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":620,\"y\":400,\"wires\":[[\"8d7ef05fbd80d2f9\"],",[462,3197,3198],{},"\"591cb7f46dd507af\"",[462,3200],{},"]},{\"id\":\"8d7ef05fbd80d2f9\",\"type\":\"debug\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Result\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":790,\"y\":380,\"wires\":",[462,3203],{},"},{\"id\":\"591cb7f46dd507af\",\"type\":\"debug\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Errors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":790,\"y\":420,\"wires\":",[462,3206],{},"}",[15,3209,3210],{},"This subscribes to all tags in the array with a single request.",[15,3212,3213],{},"When using the \"multiple\" topic, each value update arrives in OPC UA's DataValue format. Here's what you'll see in the debug panel:",[453,3215,3218],{"className":3216,"code":3217,"language":2221},[2219],"{\n    value: {\n        dataType: \"Double\",\n        value: 23.5\n    },\n    statusCode: {\n        value: 0,  \u002F\u002F 0 = Good\n        description: \"Good\"\n    },\n    serverTimestamp: \"2025-07-24T11:12:45.640Z\",\n    sourceTimestamp: \"2025-07-24T10:33:17.697Z\"\n}\n",[89,3219,3217],{"__ignoreMap":458},[15,3221,3222],{},"Subscribing to multiple tags with OpcUa-Item nodes returns just the value.",[190,3224,3226],{"id":3225},"stopping-subscriptions","Stopping Subscriptions",[15,3228,3229],{},"To stop receiving updates and free up server resources, you have two options:",[15,3231,3232,3235],{},[24,3233,3234],{},"UNSUBSCRIBE",": Removes specific monitored items from the subscription but keeps the subscription alive. Use this when you want to stop monitoring certain tags while keeping others active.",[15,3237,3238,3241],{},[24,3239,3240],{},"DELETESUBSCRIPTION",": Completely removes the subscription and all its monitored items. Use this when you're done monitoring and want to clean up all resources.",[15,3243,3244],{},"To use either action, change the OpcUa-Client node's Action dropdown to \"unsubscribe\" or \"deletesubscription\".",[48,3246,3248],{"id":3247},"events-and-alarms","Events and Alarms",[15,3250,3251],{},"OPC UA events and alarms go beyond simple value monitoring. While subscriptions tell you \"the temperature is 95°C\", events tell you \"high temperature alarm triggered at 14:32:15 on Tank 3\".",[15,3253,3254],{},"Events capture the full context of what happened, when it happened, and what needs attention. Alarms are a special type of event that requires acknowledgment - perfect for critical situations that need human intervention.",[190,3256,3258],{"id":3257},"setting-up-event-monitoring","Setting Up Event Monitoring",[120,3260,3261,3264,3271,3274],{},[59,3262,3263],{},"Add an Inject node to trigger the event subscription.",[59,3265,3266,3267,3270],{},"Add an OpcUa-Event node and configure the Source node to the event source. For server-wide events, use ",[89,3268,3269],{},"ns=0;i=2253"," (the Server object).",[59,3272,3273],{},"Add an OpcUa-Client node with Action set to \"EVENTS\".",[59,3275,3276],{},"Connect the Inject output to the OpcUa-Item node input. Connect the OpcUa-Item output to the OpcUa-Client input. Add a Debug node and connect the OpcUa-Client output to the Debug input.",[15,3278,3279],{},"Deploy and trigger the flow. The debug panel will show events as they occur on your server.",[15,3281,3038,3282,3059],{},[462,3283,3284,3285,3288,3289,3055,3292,3294,3295,3297,3298,3207],{},"{\"id\":\"d72f52a6.35fa3\",\"type\":\"OpcUa-Event\",\"z\":\"5d665294.f65f14\",\"root\":\"ns=0;i=2253\",\"activatecustomevent\":false,\"eventtype\":\"i=2041\",\"customeventtype\":\"\",\"name\":\"All events\",\"x\":400,\"y\":120,\"wires\":[[\"ae628046.ca67c\"]]},{\"id\":\"96c3ea4c.7897e8\",\"type\":\"inject\",\"z\":\"5d665294.f65f14\",\"name\":\"Subscribe events\",\"props\":",[462,3286,3287],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"vt\":\"str\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":\"\",\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":220,\"y\":120,\"wires\":[[\"d72f52a6.35fa3\"]]},{\"id\":\"ae628046.ca67c\",\"type\":\"OpcUa-Client\",\"z\":\"5d665294.f65f14\",\"endpoint\":\"\",\"action\":\"events\",\"deadbandvalue\":\"\",\"time\":\"2\",\"timeUnit\":\"s\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"Prosys events\",\"x\":580,\"y\":120,\"wires\":[[\"67203130.a7a05\"],",[462,3290,3291],{},"\"1a7bf6600cc8bec0\"",[462,3293],{},"]},{\"id\":\"67203130.a7a05\",\"type\":\"debug\",\"z\":\"5d665294.f65f14\",\"name\":\"Result\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":750,\"y\":100,\"wires\":",[462,3296],{},"},{\"id\":\"1a7bf6600cc8bec0\",\"type\":\"debug\",\"z\":\"5d665294.f65f14\",\"name\":\"Errrors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":750,\"y\":140,\"wires\":",[462,3299],{},[190,3301,3303],{"id":3302},"acknowledging-events","Acknowledging Events",[15,3305,3306],{},"When alarms trigger, operators often need to acknowledge them to indicate they've seen the issue. Here's how to send acknowledgments back to the OPC UA server:",[120,3308,3309,3312,3315],{},[59,3310,3311],{},"Add an Inject node to manually trigger the acknowledgment.",[59,3313,3314],{},"Add a Function node to prepare the acknowledgment message.",[59,3316,3317],{},"In the Function node, add the following code. Comments within the code explain what needs to be replaced.",[453,3319,3321],{"className":455,"code":3320,"language":457,"meta":458,"style":458},"msg.topic = \"ns=6;s=MyLevel.Alarm\";        \u002F\u002F The alarm's NodeId\nmsg.conditionId = \"ns=6;s=MyLevel.Alarm\u002F0:EventId\";  \u002F\u002F NodeId + \"\u002F0:EventId\"\nmsg.comment = \"Acknowledged via Node-RED\";  \u002F\u002F Your acknowledgment message\nreturn msg;\n",[89,3322,3323,3347,3370,3393],{"__ignoreMap":458},[462,3324,3325,3327,3329,3331,3333,3335,3338,3340,3343],{"class":464,"line":465},[462,3326,501],{"class":472},[462,3328,215],{"class":476},[462,3330,3086],{"class":472},[462,3332,477],{"class":476},[462,3334,511],{"class":476},[462,3336,3337],{"class":514},"ns=6;s=MyLevel.Alarm",[462,3339,518],{"class":476},[462,3341,3342],{"class":476},";",[462,3344,3346],{"class":3345},"sHwdD","        \u002F\u002F The alarm's NodeId\n",[462,3348,3349,3351,3353,3356,3358,3360,3363,3365,3367],{"class":464,"line":491},[462,3350,501],{"class":472},[462,3352,215],{"class":476},[462,3354,3355],{"class":472},"conditionId ",[462,3357,477],{"class":476},[462,3359,511],{"class":476},[462,3361,3362],{"class":514},"ns=6;s=MyLevel.Alarm\u002F0:EventId",[462,3364,518],{"class":476},[462,3366,3342],{"class":476},[462,3368,3369],{"class":3345},"  \u002F\u002F NodeId + \"\u002F0:EventId\"\n",[462,3371,3372,3374,3376,3379,3381,3383,3386,3388,3390],{"class":464,"line":498},[462,3373,501],{"class":472},[462,3375,215],{"class":476},[462,3377,3378],{"class":472},"comment ",[462,3380,477],{"class":476},[462,3382,511],{"class":476},[462,3384,3385],{"class":514},"Acknowledged via Node-RED",[462,3387,518],{"class":476},[462,3389,3342],{"class":476},[462,3391,3392],{"class":3345},"  \u002F\u002F Your acknowledgment message\n",[462,3394,3395,3397,3399],{"class":464,"line":523},[462,3396,651],{"class":650},[462,3398,480],{"class":472},[462,3400,488],{"class":476},[120,3402,3403,3406],{"start":523},[59,3404,3405],{},"Add an OpcUa-Client node and configure it with your OPC UA server endpoint. Open the node’s configuration and set the Action dropdown to \"ACKNOWLEDGE\".",[59,3407,3408],{},"Connect the Inject output to the Function input. Connect the Function output to the OpcUa-Client input.",[15,3410,3038,3411,3059],{},[462,3412,3413,3414,3416,3417,3419,3420,3422,3423,3425,3426,3055,3429,3058],{},"{\"id\":\"99a5c133.d9bdb\",\"type\":\"inject\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Acknowledge event\",\"props\":",[462,3415,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":\"\",\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":210,\"y\":300,\"wires\":[[\"cf182b3.04017d8\"]]},{\"id\":\"cf182b3.04017d8\",\"type\":\"function\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"AlarmID and EventID\",\"func\":\"msg.topic = \"ns=6;s=MyLevel.Alarm\";\\nmsg.conditionId = \"ns=6;s=MyLevel.Alarm\u002F0:EventId\";\\nmsg.comment = \"Node-RED OPCUA Ack\";\\nreturn msg;\",\"outputs\":1,\"timeout\":\"\",\"noerr\":0,\"initialize\":\"\",\"finalize\":\"\",\"libs\":",[462,3418],{},",\"x\":430,\"y\":300,\"wires\":[[\"af39662a.1fd078\"]]},{\"id\":\"39a1c77b1fb33695\",\"type\":\"debug\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Result\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":810,\"y\":280,\"wires\":",[462,3421],{},"},{\"id\":\"e50779c74918b1b9\",\"type\":\"debug\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Errrors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":810,\"y\":320,\"wires\":",[462,3424],{},"},{\"id\":\"af39662a.1fd078\",\"type\":\"OpcUa-Client\",\"z\":\"58b3ba58c45b22dd\",\"endpoint\":\"\",\"action\":\"acknowledge\",\"deadbandtype\":\"a\",\"deadbandvalue\":\"5\",\"time\":\"1\",\"timeUnit\":\"s\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"OPC UA Client\",\"x\":640,\"y\":300,\"wires\":[[\"39a1c77b1fb33695\"],",[462,3427,3428],{},"\"e50779c74918b1b9\"",[462,3430],{},[15,3432,3433],{},"Deploy the flow. When you click the Inject button, it sends the acknowledgment to the server. The alarm state changes to \"Event: \u003Calarm's NodeId> Acknowledged\" and operators know someone has seen the issue.",[48,3435,2947],{"id":3436},"method-calls",[15,3438,3439],{},"OPC UA methods let you execute functions directly on your equipment. Instead of writing multiple values to trigger an action, you call a method with parameters, like calling a function in code.",[15,3441,3442],{},"Methods are ideal for complex operations like starting batch processes, resetting counters, or triggering calibration routines. They encapsulate the logic on the server side, making your Node-RED flows simpler and more reliable.",[190,3444,3446],{"id":3445},"calling-methods","Calling Methods",[15,3448,3449],{},"To call a method on your OPC UA server:",[120,3451,3452,3455,3466,3493],{},[59,3453,3454],{},"Add an Inject node to trigger the method call.",[59,3456,3457,3458,3461,3462,3465],{},"Add an OpcUa-Method node and double-click it. Select your OPC UA endpoint, then enter the Object ID (like ",[89,3459,3460],{},"ns=6;s=MyDevice",") and Method ID (like ",[89,3463,3464],{},"ns=6;s=MyMethod",").",[59,3467,3468,3469],{},"In the Arguments section, enter each argument's name, type, and value. For example:",[56,3470,3471,3482],{},[59,3472,3473,3474,3477,3478,3481],{},"Name: ",[89,3475,3476],{},"Operator",", Type: ",[89,3479,3480],{},"String",", Value: \"sin\"",[59,3483,3473,3484,3477,3487,3489,3490],{},[89,3485,3486],{},"Value",[89,3488,332],{},", Value: ",[89,3491,3492],{},"3.3",[59,3494,3495],{},"Connect the Inject output to the OpcUa-Method input. Add a Debug node to see the result.",[15,3497,3038,3498,3059],{},[462,3499,3500,3501,3503,3504,3506,3507,3509],{},"{\"id\":\"9b199c7f.82f47\",\"type\":\"OpcUa-Method\",\"z\":\"4d24eae5.3b9b24\",\"endpoint\":\"\",\"objectId\":\"ns=6;s=MyDevice\",\"methodId\":\"ns=6;s=MyMethod\",\"name\":\"Prosys MyMethod(sin, 3.3)\",\"inputArguments\":",[462,3502],{},",\"arg0name\":\"Operator\",\"arg0type\":\"String\",\"arg0typeid\":\"\",\"arg0value\":\"sin\",\"arg1name\":\"Value\",\"arg1type\":\"Double\",\"arg1typeid\":\"\",\"arg1value\":\"3.3\",\"arg2name\":\"\",\"arg2type\":\"\",\"arg2typeid\":\"\",\"arg2value\":\"\",\"out0name\":\"\",\"out0type\":\"\",\"out0typeid\":\"\",\"out0value\":\"\",\"x\":760,\"y\":120,\"wires\":[[\"aad9fc2a.a94b4\"]]},{\"id\":\"aad9fc2a.a94b4\",\"type\":\"debug\",\"z\":\"4d24eae5.3b9b24\",\"name\":\"\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"true\",\"targetType\":\"full\",\"x\":970,\"y\":120,\"wires\":",[462,3505],{},"},{\"id\":\"6188d1de770fbb95\",\"type\":\"inject\",\"z\":\"4d24eae5.3b9b24\",\"name\":\"Call Method\",\"props\":",[462,3508],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":530,\"y\":120,\"wires\":[[\"9b199c7f.82f47\"]]}",[15,3511,3512],{},"Deploy and click the Inject button. The method executes on the server and the node status changes to \"Method Executed\". The result appears in the debug panel.",[48,3514,3516],{"id":3515},"historical-data-access","Historical Data Access",[15,3518,3519],{},"OPC UA Historical Access lets you query past values from your equipment. Instead of just seeing current temperature, you can ask \"what was the temperature yesterday at 3 PM?\" or \"show me all pressure values from the last shift.\"",[15,3521,3522],{},"This is essential for troubleshooting, compliance reporting, and trend analysis. However, not all OPC UA servers support historical data, check your server documentation first. Also, not all tags are configured for history, verify that the \"Historizing\" attribute is set to true for your tag.",[190,3524,3526],{"id":3525},"reading-historical-values","Reading Historical Values",[15,3528,3529],{},"To query historical data from your server:",[120,3531,3532,3535,3538],{},[59,3533,3534],{},"Add an Inject node to trigger the historical read.",[59,3536,3537],{},"Add a Function node to prepare the query parameters.",[59,3539,3540],{},"In the Function node, add this code:",[453,3542,3544],{"className":455,"code":3543,"language":457,"meta":458,"style":458},"msg.topic = \"NodeId ns=6;s=MyLevel\"; \u002F\u002F Replace with your NodeId\nmsg.aggregate = \"raw\"; \u002F\u002F Or use: \"min\", \"max\", \"ave\", \"interpolative\"\nmsg.start = new Date(Date.now() - 60 * 60 * 1000); \u002F\u002F 1 hour ago\nmsg.end = new Date(); \u002F\u002F Now\nreturn msg;\n",[89,3545,3546,3568,3591,3645,3668],{"__ignoreMap":458},[462,3547,3548,3550,3552,3554,3556,3558,3561,3563,3565],{"class":464,"line":465},[462,3549,501],{"class":472},[462,3551,215],{"class":476},[462,3553,3086],{"class":472},[462,3555,477],{"class":476},[462,3557,511],{"class":476},[462,3559,3560],{"class":514},"NodeId ns=6;s=MyLevel",[462,3562,518],{"class":476},[462,3564,3342],{"class":476},[462,3566,3567],{"class":3345}," \u002F\u002F Replace with your NodeId\n",[462,3569,3570,3572,3574,3577,3579,3581,3584,3586,3588],{"class":464,"line":491},[462,3571,501],{"class":472},[462,3573,215],{"class":476},[462,3575,3576],{"class":472},"aggregate ",[462,3578,477],{"class":476},[462,3580,511],{"class":476},[462,3582,3583],{"class":514},"raw",[462,3585,518],{"class":476},[462,3587,3342],{"class":476},[462,3589,3590],{"class":3345}," \u002F\u002F Or use: \"min\", \"max\", \"ave\", \"interpolative\"\n",[462,3592,3593,3595,3597,3600,3602,3605,3609,3612,3614,3617,3620,3623,3627,3630,3632,3634,3637,3640,3642],{"class":464,"line":498},[462,3594,501],{"class":472},[462,3596,215],{"class":476},[462,3598,3599],{"class":472},"start ",[462,3601,477],{"class":476},[462,3603,3604],{"class":476}," new",[462,3606,3608],{"class":3607},"s2Zo4"," Date",[462,3610,3611],{"class":472},"(Date",[462,3613,215],{"class":476},[462,3615,3616],{"class":3607},"now",[462,3618,3619],{"class":472},"() ",[462,3621,3622],{"class":476},"-",[462,3624,3626],{"class":3625},"sbssI"," 60",[462,3628,3629],{"class":476}," *",[462,3631,3626],{"class":3625},[462,3633,3629],{"class":476},[462,3635,3636],{"class":3625}," 1000",[462,3638,3639],{"class":472},")",[462,3641,3342],{"class":476},[462,3643,3644],{"class":3345}," \u002F\u002F 1 hour ago\n",[462,3646,3647,3649,3651,3654,3656,3658,3660,3663,3665],{"class":464,"line":523},[462,3648,501],{"class":472},[462,3650,215],{"class":476},[462,3652,3653],{"class":472},"end ",[462,3655,477],{"class":476},[462,3657,3604],{"class":476},[462,3659,3608],{"class":3607},[462,3661,3662],{"class":472},"()",[462,3664,3342],{"class":476},[462,3666,3667],{"class":3345}," \u002F\u002F Now\n",[462,3669,3670,3672,3674],{"class":464,"line":544},[462,3671,651],{"class":650},[462,3673,480],{"class":472},[462,3675,488],{"class":476},[120,3677,3678,3681],{"start":523},[59,3679,3680],{},"Add an OpcUa-Client node. Open its configuration and set the Action dropdown to \"HISTORY\".",[59,3682,3683],{},"Connect the Inject output to the Function input. Connect the Function output to the OpcUa-Client input. Add a Debug node to see the historical values.",[15,3685,3038,3686,3059],{},[462,3687,3688,3689,3055,3692,3694,3695,3697,3698,3700,3701,3703,3704,3207],{},"{\"id\":\"0c43bd35230132af\",\"type\":\"OpcUa-Client\",\"z\":\"58b3ba58c45b22dd\",\"endpoint\":\"\",\"action\":\"history\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"securitymode\":\"None\",\"securitypolicy\":\"None\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":620,\"y\":140,\"wires\":[[\"532ae640b386e34e\"],",[462,3690,3691],{},"\"24678e079b08c81d\"",[462,3693],{},"]},{\"id\":\"5d8f9b5854a12919\",\"type\":\"inject\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Get Historical Data\",\"props\":",[462,3696],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"x\":270,\"y\":140,\"wires\":[[\"9c071e5a8e543eba\"]]},{\"id\":\"9c071e5a8e543eba\",\"type\":\"function\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"\",\"func\":\"msg.topic = \"ns=3;i=1001\";\\nmsg.aggregate = \"ave\";  \u002F\u002F Try: \"min\", \"max\", \"ave\", \"interpolative\"\\nmsg.start = new Date(Date.now() - 60 * 60 * 1000); \u002F\u002F 1 hour ago\\nmsg.end = new Date(); \u002F\u002F Now\\nmsg.interval = 300000;  \u002F\u002F Required for aggregates: 5-minute intervals\\nreturn msg;\",\"outputs\":1,\"timeout\":0,\"noerr\":0,\"initialize\":\"\",\"finalize\":\"\",\"libs\":",[462,3699],{},",\"x\":440,\"y\":140,\"wires\":[[\"0c43bd35230132af\"]]},{\"id\":\"532ae640b386e34e\",\"type\":\"debug\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Result\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":790,\"y\":120,\"wires\":",[462,3702],{},"},{\"id\":\"24678e079b08c81d\",\"type\":\"debug\",\"z\":\"58b3ba58c45b22dd\",\"name\":\"Errrors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":790,\"y\":160,\"wires\":",[462,3705],{},[15,3707,3708],{},"Deploy and click the Inject button. The debug panel shows all stored values for that tag within your time range.",[190,3710,3712],{"id":3711},"advanced-historical-queries","Advanced Historical Queries",[15,3714,3715],{},"While all historized tags support raw data, aggregate support varies by tag type. Analog values typically support aggregates like min, max, and ave, while discrete tags may only support raw.",[15,3717,3718],{},[24,3719,3720],{},"Working with Aggregates:",[453,3722,3724],{"className":455,"code":3723,"language":457,"meta":458,"style":458},"msg.topic = \"ns=6;s=MyLevel\";\nmsg.aggregate = \"ave\";  \u002F\u002F Options: \"min\", \"max\", \"ave\", \"interpolative\"\nmsg.start = new Date(Date.now() - 60 * 60 * 1000); \u002F\u002F 1 hour ago\nmsg.end = new Date(); \u002F\u002F Now\nmsg.interval = 300000;  \u002F\u002F Required for aggregates: 5-minute intervals\nreturn msg;\n",[89,3725,3726,3745,3767,3807,3827,3846],{"__ignoreMap":458},[462,3727,3728,3730,3732,3734,3736,3738,3741,3743],{"class":464,"line":465},[462,3729,501],{"class":472},[462,3731,215],{"class":476},[462,3733,3086],{"class":472},[462,3735,477],{"class":476},[462,3737,511],{"class":476},[462,3739,3740],{"class":514},"ns=6;s=MyLevel",[462,3742,518],{"class":476},[462,3744,488],{"class":476},[462,3746,3747,3749,3751,3753,3755,3757,3760,3762,3764],{"class":464,"line":491},[462,3748,501],{"class":472},[462,3750,215],{"class":476},[462,3752,3576],{"class":472},[462,3754,477],{"class":476},[462,3756,511],{"class":476},[462,3758,3759],{"class":514},"ave",[462,3761,518],{"class":476},[462,3763,3342],{"class":476},[462,3765,3766],{"class":3345},"  \u002F\u002F Options: \"min\", \"max\", \"ave\", \"interpolative\"\n",[462,3768,3769,3771,3773,3775,3777,3779,3781,3783,3785,3787,3789,3791,3793,3795,3797,3799,3801,3803,3805],{"class":464,"line":498},[462,3770,501],{"class":472},[462,3772,215],{"class":476},[462,3774,3599],{"class":472},[462,3776,477],{"class":476},[462,3778,3604],{"class":476},[462,3780,3608],{"class":3607},[462,3782,3611],{"class":472},[462,3784,215],{"class":476},[462,3786,3616],{"class":3607},[462,3788,3619],{"class":472},[462,3790,3622],{"class":476},[462,3792,3626],{"class":3625},[462,3794,3629],{"class":476},[462,3796,3626],{"class":3625},[462,3798,3629],{"class":476},[462,3800,3636],{"class":3625},[462,3802,3639],{"class":472},[462,3804,3342],{"class":476},[462,3806,3644],{"class":3345},[462,3808,3809,3811,3813,3815,3817,3819,3821,3823,3825],{"class":464,"line":523},[462,3810,501],{"class":472},[462,3812,215],{"class":476},[462,3814,3653],{"class":472},[462,3816,477],{"class":476},[462,3818,3604],{"class":476},[462,3820,3608],{"class":3607},[462,3822,3662],{"class":472},[462,3824,3342],{"class":476},[462,3826,3667],{"class":3345},[462,3828,3829,3831,3833,3836,3838,3841,3843],{"class":464,"line":544},[462,3830,501],{"class":472},[462,3832,215],{"class":476},[462,3834,3835],{"class":472},"interval ",[462,3837,477],{"class":476},[462,3839,3840],{"class":3625}," 300000",[462,3842,3342],{"class":476},[462,3844,3845],{"class":3345},"  \u002F\u002F Required for aggregates: 5-minute intervals\n",[462,3847,3848,3850,3852],{"class":464,"line":549},[462,3849,651],{"class":650},[462,3851,480],{"class":472},[462,3853,488],{"class":476},[15,3855,3856],{},[24,3857,3858],{},"Hourly Averages for the Last Day:",[453,3860,3862],{"className":455,"code":3861,"language":457,"meta":458,"style":458},"msg.topic = \"ns=3;s=Temperature\";\nmsg.aggregate = \"ave\";\nmsg.start = new Date(Date.now() - 24*60*60*1000);  \u002F\u002F 24 hours ago\nmsg.end = new Date();\nmsg.interval = 3600000;  \u002F\u002F 1-hour intervals\nreturn msg;\n",[89,3863,3864,3882,3900,3949,3967,3985],{"__ignoreMap":458},[462,3865,3866,3868,3870,3872,3874,3876,3878,3880],{"class":464,"line":465},[462,3867,501],{"class":472},[462,3869,215],{"class":476},[462,3871,3086],{"class":472},[462,3873,477],{"class":476},[462,3875,511],{"class":476},[462,3877,284],{"class":514},[462,3879,518],{"class":476},[462,3881,488],{"class":476},[462,3883,3884,3886,3888,3890,3892,3894,3896,3898],{"class":464,"line":491},[462,3885,501],{"class":472},[462,3887,215],{"class":476},[462,3889,3576],{"class":472},[462,3891,477],{"class":476},[462,3893,511],{"class":476},[462,3895,3759],{"class":514},[462,3897,518],{"class":476},[462,3899,488],{"class":476},[462,3901,3902,3904,3906,3908,3910,3912,3914,3916,3918,3920,3922,3924,3927,3930,3933,3935,3937,3939,3942,3944,3946],{"class":464,"line":498},[462,3903,501],{"class":472},[462,3905,215],{"class":476},[462,3907,3599],{"class":472},[462,3909,477],{"class":476},[462,3911,3604],{"class":476},[462,3913,3608],{"class":3607},[462,3915,3611],{"class":472},[462,3917,215],{"class":476},[462,3919,3616],{"class":3607},[462,3921,3619],{"class":472},[462,3923,3622],{"class":476},[462,3925,3926],{"class":3625}," 24",[462,3928,3929],{"class":476},"*",[462,3931,3932],{"class":3625},"60",[462,3934,3929],{"class":476},[462,3936,3932],{"class":3625},[462,3938,3929],{"class":476},[462,3940,3941],{"class":3625},"1000",[462,3943,3639],{"class":472},[462,3945,3342],{"class":476},[462,3947,3948],{"class":3345},"  \u002F\u002F 24 hours ago\n",[462,3950,3951,3953,3955,3957,3959,3961,3963,3965],{"class":464,"line":523},[462,3952,501],{"class":472},[462,3954,215],{"class":476},[462,3956,3653],{"class":472},[462,3958,477],{"class":476},[462,3960,3604],{"class":476},[462,3962,3608],{"class":3607},[462,3964,3662],{"class":472},[462,3966,488],{"class":476},[462,3968,3969,3971,3973,3975,3977,3980,3982],{"class":464,"line":544},[462,3970,501],{"class":472},[462,3972,215],{"class":476},[462,3974,3835],{"class":472},[462,3976,477],{"class":476},[462,3978,3979],{"class":3625}," 3600000",[462,3981,3342],{"class":476},[462,3983,3984],{"class":3345},"  \u002F\u002F 1-hour intervals\n",[462,3986,3987,3989,3991],{"class":464,"line":549},[462,3988,651],{"class":650},[462,3990,480],{"class":472},[462,3992,488],{"class":476},[15,3994,3995],{},[24,3996,3997],{},"Peak Detection:",[453,3999,4001],{"className":455,"code":4000,"language":457,"meta":458,"style":458},"\u002F\u002F Find maximum values in 15-minute windows\nmsg.topic = \"ns=3;s=Pressure\";\nmsg.aggregate = \"max\";\nmsg.start = new Date().setHours(0,0,0,0);  \u002F\u002F Midnight today\nmsg.end = new Date();\nmsg.interval = 900000;  \u002F\u002F 15-minute intervals\nreturn msg;\n",[89,4002,4003,4008,4027,4046,4091,4109,4127],{"__ignoreMap":458},[462,4004,4005],{"class":464,"line":465},[462,4006,4007],{"class":3345},"\u002F\u002F Find maximum values in 15-minute windows\n",[462,4009,4010,4012,4014,4016,4018,4020,4023,4025],{"class":464,"line":491},[462,4011,501],{"class":472},[462,4013,215],{"class":476},[462,4015,3086],{"class":472},[462,4017,477],{"class":476},[462,4019,511],{"class":476},[462,4021,4022],{"class":514},"ns=3;s=Pressure",[462,4024,518],{"class":476},[462,4026,488],{"class":476},[462,4028,4029,4031,4033,4035,4037,4039,4042,4044],{"class":464,"line":498},[462,4030,501],{"class":472},[462,4032,215],{"class":476},[462,4034,3576],{"class":472},[462,4036,477],{"class":476},[462,4038,511],{"class":476},[462,4040,4041],{"class":514},"max",[462,4043,518],{"class":476},[462,4045,488],{"class":476},[462,4047,4048,4050,4052,4054,4056,4058,4060,4062,4064,4067,4070,4072,4074,4076,4078,4080,4082,4084,4086,4088],{"class":464,"line":523},[462,4049,501],{"class":472},[462,4051,215],{"class":476},[462,4053,3599],{"class":472},[462,4055,477],{"class":476},[462,4057,3604],{"class":476},[462,4059,3608],{"class":3607},[462,4061,3662],{"class":472},[462,4063,215],{"class":476},[462,4065,4066],{"class":3607},"setHours",[462,4068,4069],{"class":472},"(",[462,4071,366],{"class":3625},[462,4073,3055],{"class":476},[462,4075,366],{"class":3625},[462,4077,3055],{"class":476},[462,4079,366],{"class":3625},[462,4081,3055],{"class":476},[462,4083,366],{"class":3625},[462,4085,3639],{"class":472},[462,4087,3342],{"class":476},[462,4089,4090],{"class":3345},"  \u002F\u002F Midnight today\n",[462,4092,4093,4095,4097,4099,4101,4103,4105,4107],{"class":464,"line":544},[462,4094,501],{"class":472},[462,4096,215],{"class":476},[462,4098,3653],{"class":472},[462,4100,477],{"class":476},[462,4102,3604],{"class":476},[462,4104,3608],{"class":3607},[462,4106,3662],{"class":472},[462,4108,488],{"class":476},[462,4110,4111,4113,4115,4117,4119,4122,4124],{"class":464,"line":549},[462,4112,501],{"class":472},[462,4114,215],{"class":476},[462,4116,3835],{"class":472},[462,4118,477],{"class":476},[462,4120,4121],{"class":3625}," 900000",[462,4123,3342],{"class":476},[462,4125,4126],{"class":3345},"  \u002F\u002F 15-minute intervals\n",[462,4128,4129,4131,4133],{"class":464,"line":564},[462,4130,651],{"class":650},[462,4132,480],{"class":472},[462,4134,488],{"class":476},[15,4136,4137],{},"The historical data returns with timestamps and quality codes. Use this for shift reports, compliance documentation, or troubleshooting equipment issues that happened hours or days ago.",[15,4139,4140],{},"You've now mastered the advanced features that make OPC UA essential for industrial systems. With subscriptions, you're monitoring values in real-time without wasting bandwidth. With events and alarms, you're capturing critical alerts the moment they happen. With method calls, you're executing complex operations with a single command. And with historical access, you have the data trail needed for analysis and compliance.",[48,4142,4144],{"id":4143},"scale-your-opc-ua-implementation","Scale Your OPC UA Implementation",[15,4146,4147],{},"Managing OPC UA flows across multiple sites? FlowFuse helps teams deploy Node-RED to hundreds of edge devices with one click, monitor everything from a central dashboard, and roll back instantly if something goes wrong. Built-in team collaboration, audit logs, and enterprise security keep your industrial data safe.",[15,4149,4150],{},"Following our managed MQTT broker, we've now added database services built right into the platform, plus new AI features that make building flows faster than ever.",[15,4152,4153,4154,4156],{},"Connecting PLCs beyond OPC UA? FlowFuse also supports Siemens S7, EtherNet\u002FIP, Modbus TCP\u002FRTU, and MQTT, see the ",[29,4155,2142],{"href":2141}," for all supported protocols and use cases.",[15,4158,4159],{},"[Get started free]({% include \"sign-up-url.njk\" %}) and scale and manage your Node-RED deployments today.",[782,4161,4162],{},"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 pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":458,"searchDepth":523,"depth":523,"links":4164},[4165,4166,4167,4172,4176,4179,4183],{"id":2919,"depth":491,"text":2920},{"id":2951,"depth":491,"text":2952},{"id":2986,"depth":491,"text":2987,"children":4168},[4169,4170,4171],{"id":2999,"depth":498,"text":3000},{"id":3065,"depth":498,"text":3066},{"id":3225,"depth":498,"text":3226},{"id":3247,"depth":491,"text":3248,"children":4173},[4174,4175],{"id":3257,"depth":498,"text":3258},{"id":3302,"depth":498,"text":3303},{"id":3436,"depth":491,"text":2947,"children":4177},[4178],{"id":3445,"depth":498,"text":3446},{"id":3515,"depth":491,"text":3516,"children":4180},[4181,4182],{"id":3525,"depth":498,"text":3526},{"id":3711,"depth":498,"text":3712},{"id":4143,"depth":491,"text":4144},"2025-08-14","Learn advanced OPC UA techniques in Node-RED: real-time subscriptions, alarm handling, historical data queries, and method calls for production-ready industrial systems.","\u002Fblog\u002F2025\u002F08\u002Fimages\u002Fadvanced-opcua-real-time-subscriptions-alarms-historical-data.png",{"keywords":4188,"excerpt":4189},"OPC UA subscriptions Node-RED, OPC UA events alarms, OPC UA historical data, OPC UA method calls, real-time monitoring OPC UA, industrial automation advanced, OPC UA HA redundancy, OPC UA performance optimization",{"type":12,"value":4190},[4191],[15,4192,2906,4193,2910],{},[29,4194,2909],{"href":2623},"\u002Fblog\u002F2025\u002F08\u002Fadvanced-opcua-real-time-subscriptions-alarms-historical-data",{"title":2900,"description":4185},{"loc":4195},"blog\u002F2025\u002F08\u002Fadvanced-opcua-real-time-subscriptions-alarms-historical-data","Master advanced OPC UA features in Node-RED for production-ready industrial automation",[826,827],"Polling OPC UA tags every few seconds misses critical events and wastes bandwidth; OPC UA subscriptions solve this by monitoring values server-side and pushing notifications only when they change. This advanced tutorial covers four production-ready OPC UA features in Node-RED: subscriptions for instant value updates, event and alarm handling, historical data queries, and method calls for triggering complex equipment operations.","NtA5KIaE3R4","-b9u-3FHDPIoUfRcKPv03NE8U3JF-ryulYMHT1exCrM",{"id":4205,"title":4206,"authors":4207,"body":4208,"cta":3,"date":5086,"description":5087,"extension":802,"image":5088,"lastUpdated":3,"meta":5089,"navigation":494,"path":5095,"seo":5096,"sitemap":5097,"stem":5098,"subtitle":5099,"tags":5100,"tldr":5102,"video":3,"__hash__":5103},"blog\u002Fblog\u002F2025\u002F07\u002Freading-and-writing-plc-data-using-opc-ua.md","OPC UA Tutorial: Connect and Exchange Data with Industrial Equipment",[10],{"type":12,"value":4209,"toc":5060},[4210,4213,4218,4221,4234,4258,4262,4265,4269,4272,4276,4279,4283,4286,4290,4293,4297,4300,4304,4307,4310,4313,4316,4324,4327,4330,4333,4337,4340,4345,4370,4383,4386,4389,4419,4435,4443,4451,4454,4458,4461,4499,4502,4510,4524,4528,4531,4535,4538,4618,4625,4633,4636,4642,4666,4670,4673,4682,4692,4739,4742,4765,4769,4772,4776,4779,4867,4873,4896,4900,4903,4985,4988,5014,5018,5021,5028,5031,5045,5051,5054],[15,4211,4212],{},"If you’ve ever tried to connect industrial equipment from different vendors, you know how frustrating it can be, a mess of incompatible protocols, proprietary software, and confusing drivers. Your Siemens PLC speaks one language, your Allen-Bradley controller another, and that Modbus sensor? Yet another protocol entirely.",[15,4214,4215],{},[24,4216,4217],{},"OPC UA changes that.",[15,4219,4220],{},"OPC UA (Open Platform Communications Unified Architecture) is the industry-standard protocol that eliminates this chaos. Also known as OPC Unified Architecture or IEC 62541, it provides a universal language for secure communication between PLCs, SCADA systems, HMIs, and enterprise applications ,regardless of the manufacturer.",[15,4222,4223,4224,4227,4228,222,4231,577],{},"This hands-on guide walks you through building your first ",[24,4225,4226],{},"OPC UA integration"," using ",[24,4229,4230],{},"Node-RED",[24,4232,4233],{},"FlowFuse",[56,4235,4236,4242,4247,4252],{},[59,4237,4238,4241],{},[24,4239,4240],{},"Connect"," to any OPC UA server, Kepware, MatrikonOPC, or built-in PLC servers",[59,4243,4244,4246],{},[24,4245,394],{}," available tags and discover Node IDs from your equipment",[59,4248,4249,4251],{},[24,4250,201],{}," real-time values from PLCs, sensors, and industrial devices",[59,4253,4254,4257],{},[24,4255,4256],{},"Write"," control signals and setpoints back to your systems",[48,4259,4261],{"id":4260},"why-opc-ua","Why OPC UA?",[15,4263,4264],{},"If you have worked with industrial equipment, you know the pain. Every PLC vendor uses a different protocol. Your Siemens S7-1500 requires TIA Portal and PROFINET drivers. The Allen-Bradley ControlLogix needs RSLinx and EtherNet\u002FIP. A Modbus temperature sensor needs yet another tool. Before long, you are juggling a dozen different software packages, each with its own licensing, training, and maintenance overhead.",[190,4266,4268],{"id":4267},"breaking-the-cycle","Breaking the Cycle",[15,4270,4271],{},"OPC UA eliminates this fragmentation. Instead of relying on vendor-specific protocols, it provides a universal language for all your equipment. Here is why it is becoming the industry standard:",[190,4273,4275],{"id":4274},"universal-connectivity","Universal Connectivity",[15,4277,4278],{},"Connect to any modern PLC using a single protocol. Leading manufacturers like Siemens, Rockwell, Schneider, and ABB now embed OPC UA servers directly into their controllers. One client, all your equipment.",[190,4280,4282],{"id":4281},"information-not-just-data","Information, Not Just Data",[15,4284,4285],{},"Reading a temperature value from OPC UA does not just give you \"42.5\", it gives the full context: 42.5 °C, measured at 14:32:15.625 with \"Good\" quality, from \"Tank_01\u002FTemperature\", and includes alarm limits (10 °C \u002F 80 °C). This context reduces guesswork and helps prevent costly mistakes.",[190,4287,4289],{"id":4288},"security-built-for-industry","Security Built for Industry",[15,4291,4292],{},"While protocols like Modbus transmit everything in plain text, OPC UA uses enterprise-grade security. It supports X.509 certificates, 256-bit encryption, and robust user authentication to safeguard critical infrastructure from cyber threats.",[190,4294,4296],{"id":4295},"future-proof-investment","Future-Proof Investment",[15,4298,4299],{},"OPC UA is the foundation of Industry 4.0 initiatives around the world. It is not just another protocol, it is the one major vendors are standardizing on. Choosing OPC UA today ensures long-term compatibility and ROI.",[48,4301,4303],{"id":4302},"getting-started","Getting Started",[15,4305,4306],{},"Now that you understand why OPC UA is widely adopted, let’s explore how to implement it using FlowFuse Node-RED.",[15,4308,4309],{},"This next section walks you through exactly what you need to get started with a working setup, whether for prototyping or production.",[190,4311,4312],{"id":50},"What You’ll Need",[15,4314,4315],{},"Before diving into the flow-building process, make sure you have the following:",[56,4317,4318,4321],{},[59,4319,4320],{},"An OPC UA server (like Kepware, MatrikonOPC, or built into your PLC)",[59,4322,4323],{},"A FlowFuse Node-RED instance running on your edge device.",[15,4325,4326],{},"For production OPC UA deployments, we recommend using FlowFuse. When connecting to industrial systems, you need more than just Node-RED, you need team collaboration so multiple engineers can work on flows safely, audit logs for compliance tracking, high availability to prevent downtime, and remote device management for edge deployments.",[15,4328,4329],{},"FlowFuse provides these enterprise features plus automatic backups, one-click rollbacks, environment variables for different sites, and DevOps pipelines for testing changes before they reach production.",[15,4331,4332],{},"[Get started →]({% include \"sign-up-url.njk\" %})",[190,4334,4336],{"id":4335},"installing-opc-ua-support-in-flowfuse","Installing OPC UA Support in FlowFuse",[15,4338,4339],{},"To work with OPC UA in FlowFuse Node-RED, you will first need to install the required nodes.",[4341,4342,4344],"h4",{"id":4343},"install-the-opc-ua-node-package","Install the OPC UA Node Package",[120,4346,4347,4353,4358,4366],{},[59,4348,4349,4350,215],{},"Open the ",[24,4351,4352],{},"FlowFuse Node-RED editor",[59,4354,4355,4356,215],{},"Click the menu in the top-right and choose ",[24,4357,130],{},[59,4359,4360,4361,4363,4364,215],{},"Navigate to the ",[24,4362,134],{}," tab and search for ",[89,4365,2963],{},[59,4367,236,4368,215],{},[24,4369,134],{},[15,4371,4372,4373,404,4376,684,4379,4382],{},"Once installed, you will find new nodes for OPC UA communication in your palette, including ",[24,4374,4375],{},"Client",[24,4377,4378],{},"Item",[24,4380,4381],{},"Browser"," and other OPC UA nodes.",[190,4384,4385],{"id":184},"Connecting to Your OPC UA Server",[15,4387,4388],{},"To begin accessing industrial data, create a client connection using the OPC UA Client node.",[120,4390,4391,4397,4400,4407,4413],{},[59,4392,4393,4394,202],{},"Drag an ",[24,4395,4396],{},"OPC UA Client",[59,4398,4399],{},"Double-click to configure it.",[59,4401,4402,4403,4406],{},"Click the ",[24,4404,4405],{},"+"," icon to create a new endpoint configuration.",[59,4408,4409,4410],{},"Enter your OPC UA server address, for example: ",[89,4411,4412],{},"opc.tcp:\u002F\u002F192.168.0.10:4840",[59,4414,4415,4416,4418],{},"Set the security mode to ",[24,4417,229],{}," (you can add security later).",[19,4420,4421],{},[15,4422,4423,4426,4427,4430,4431,4434],{},[24,4424,4425],{},"Security Note:"," This tutorial uses ",[24,4428,4429],{},"\"None\""," for the security setting to keep things simple.\nIn production environments, always use appropriate security, typically ",[24,4432,4433],{},"\"Sign & Encrypt\""," with certificates.",[120,4436,4437],{"start":549},[59,4438,236,4439,240,4441,215],{},[24,4440,239],{},[24,4442,243],{},[15,4444,4445,4449],{},[39,4446],{"alt":4447,"dataZoomable":458,"src":4448},"OPC UA endpoint configuration","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-endpoint-config.png",[44,4450,4447],{},[15,4452,4453],{},"With the connection now defined, you’re ready to explore what tags are available.",[190,4455,4457],{"id":4456},"browsing-tags-optional","Browsing Tags (Optional)",[15,4459,4460],{},"If you do not already know the Node IDs of the tags you want to access, use the OPC UA Browser node to explore the tag structure.",[120,4462,4463,4474,4480,4493,4496],{},[59,4464,4393,4465,404,4468,684,4471,202],{},[24,4466,4467],{},"Inject",[24,4469,4470],{},"OPC UA Browser",[24,4472,4473],{},"Debug",[59,4475,4476,4477,4479],{},"Connect the output of the Inject node to the input of the ",[24,4478,4381],{}," node, then connect the Browser's output to the Debug node.",[59,4481,289,4482,4484,4485,4488,4489,4492],{},[24,4483,4381],{}," node, set the topic to ",[89,4486,4487],{},"ns=0;i=85"," (the root ",[44,4490,4491],{},"Objects"," folder).",[59,4494,4495],{},"Configure the Inject node to send a timestamp.",[59,4497,4498],{},"Deploy the flow and click the Inject node.",[15,4500,4501],{},"Tag information will be printed to the debug sidebar. You can now identify the exact Node IDs to use in your reads or writes.",[15,4503,4504,4508],{},[39,4505],{"alt":4506,"dataZoomable":458,"src":4507},"OPC UA Browser node","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-browser.png",[44,4509,4506],{},[15,4511,3038,4512,3059],{},[462,4513,4514,4515,4517,4518,4520,4521,4523],{},"{\"id\":\"c3a8303048e6588f\",\"type\":\"OpcUa-Browser\",\"z\":\"f66e9c91c269e7fb\",\"endpoint\":\"c0f8c79fc00845c8\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"ns=0;i=85\",\"items\":",[462,4516],{},",\"name\":\"\",\"x\":510,\"y\":300,\"wires\":[[\"3428199852f9fcdc\"]]},{\"id\":\"1549f797c58ba667\",\"type\":\"inject\",\"z\":\"f66e9c91c269e7fb\",\"name\":\"\",\"props\":",[462,4519,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":280,\"y\":300,\"wires\":[[\"c3a8303048e6588f\"]]},{\"id\":\"3428199852f9fcdc\",\"type\":\"debug\",\"z\":\"f66e9c91c269e7fb\",\"name\":\"debug 1\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"false\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":740,\"y\":300,\"wires\":",[462,4522],{},"},{\"id\":\"c0f8c79fc00845c8\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"}",[190,4525,4527],{"id":4526},"reading-tag-values","Reading Tag Values",[15,4529,4530],{},"Once you know the Node IDs, you can start reading data from your industrial equipment through the OPC UA server.",[4341,4532,4534],{"id":4533},"reading-a-single-tag","Reading a Single Tag",[15,4536,4537],{},"Here’s how to read a single value in real time:",[120,4539,4540,4545,4577,4585,4603,4606],{},[59,4541,4393,4542,4544],{},[24,4543,4467],{}," node onto the canvas (this will trigger the read operation).",[59,4546,299,4547,4550,4551,4570,4573],{},[24,4548,4549],{},"OPC UA Item"," node and configure:",[56,4552,4553,4562],{},[59,4554,4555,4558,4559,3639],{},[24,4556,4557],{},"Node ID",": Enter the tag’s identifier (e.g., ",[89,4560,4561],{},"ns=3;i=1003",[59,4563,4564,4567,4568,3639],{},[24,4565,4566],{},"Data Type",": Select the appropriate type (e.g., ",[89,4569,336],{},[4571,4572],"br",{},[39,4574],{"alt":4575,"dataZoomable":458,"src":4576},"OPC UA Item node configuration","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-item-node.png",[59,4578,4579,4580,4582,4583,667],{},"Connect the output of the ",[24,4581,4467],{}," node to the input of the ",[24,4584,4378],{},[59,4586,299,4587,4589,4590,4593,4594,215,4597,4599],{},[24,4588,4396],{}," node and set its ",[24,4591,4592],{},"Action"," to ",[89,4595,4596],{},"read",[4571,4598],{},[39,4600],{"alt":4601,"dataZoomable":458,"src":4602},"OPC UA Client node configured for reading","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-client-read-node.png",[59,4604,4605],{},"Select the endpoint configuration you created earlier.",[59,4607,4579,4608,4582,4610,4612,4613,4615,4616,667],{},[24,4609,4378],{},[24,4611,4375],{}," node, then connect the ",[24,4614,4375],{}," node's top output to a ",[24,4617,4473],{},[19,4619,4620],{},[15,4621,1758,4622,4624],{},[24,4623,4396],{}," node has three outputs: the top carries the data payload, the middle indicates connection status, and the bottom provides raw responses for debugging.",[120,4626,4627],{"start":564},[59,4628,4629,4630,4632],{},"Deploy the flow and click the ",[24,4631,4467],{}," button to trigger the read.",[15,4634,4635],{},"You should see the tag value appear in the debug panel. This confirms that communication is working correctly.",[15,4637,4638,4639,4641],{},"You can also pass the Node ID dynamically using ",[89,4640,373],{}," from the Inject node if you prefer not to use an Item node.",[15,4643,3038,4644,3059],{},[462,4645,4646,4647,3055,4650,4653,4654,4656,4657,4659,4660,4662,4663,4665],{},"{\"id\":\"d128582dda7adbed\",\"type\":\"OpcUa-Client\",\"z\":\"ead97ed756a13a15\",\"endpoint\":\"a4df18253e5a79a0\",\"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,\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":580,\"y\":240,\"wires\":[[\"3fc16bf912f16169\"],",[462,4648,4649],{},"\"17724a6889ec7378\"",[462,4651,4652],{},"\"c6b0f16ef7371699\"","]},{\"id\":\"3fc16bf912f16169\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Tag Value\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":740,\"y\":200,\"wires\":",[462,4655],{},"},{\"id\":\"2691196551812a21\",\"type\":\"OpcUa-Item\",\"z\":\"ead97ed756a13a15\",\"item\":\"ns=3;i=1001\",\"datatype\":\"Boolean\",\"value\":\"\",\"name\":\"OPC UA Item Node\",\"x\":370,\"y\":240,\"wires\":[[\"d128582dda7adbed\"]]},{\"id\":\"96d17841a7f13ac4\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Read tag\",\"props\":",[462,4658,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":200,\"y\":200,\"wires\":[[\"2691196551812a21\"]]},{\"id\":\"17724a6889ec7378\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Errors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":730,\"y\":240,\"wires\":",[462,4661],{},"},{\"id\":\"c6b0f16ef7371699\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Raw Respons\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":760,\"y\":280,\"wires\":",[462,4664],{},"},{\"id\":\"a4df18253e5a79a0\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"opc.tcp:\u002F\u002F192.168.0.10:4840\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"}",[4341,4667,4669],{"id":4668},"reading-multiple-tags","Reading Multiple Tags",[15,4671,4672],{},"Batch reading improves performance when you need multiple data points from your equipment",[120,4674,4675],{},[59,4676,4393,4677,4589,4679,4681],{},[24,4678,4396],{},[24,4680,4592],{}," to \"READ MULTIPLE\".",[15,4683,4684,4688,4690],{},[39,4685],{"alt":4686,"dataZoomable":458,"src":4687},"Screenshot showing OPC UA Client node with \"READ MULTIPLE\" action selected","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fread-multiple.png",[4571,4689],{},[44,4691,4686],{},[120,4693,4694,4697,4702,4707,4710,4713,4721,4723,4726,4733],{"start":491},[59,4695,4696],{},"Select the endpoint configuration.",[59,4698,299,4699,4701],{},[24,4700,4549],{}," node for each tag you want to read.",[59,4703,299,4704,4706],{},[24,4705,4467],{}," node for each Item node to trigger it.",[59,4708,4709],{},"Connect each Inject node to its corresponding Item node.",[59,4711,4712],{},"Wire all Item nodes into the OPC UA Client node.",[59,4714,4715,4716,4718,4719,667],{},"Add a ",[24,4717,4473],{}," node to the top output of the ",[24,4720,4375],{},[59,4722,701],{},[59,4724,4725],{},"Click each Inject node once, the client node will store the tag definitions.",[59,4727,4728,4729,4732],{},"Send a message with ",[89,4730,4731],{},"msg.topic = \"readmultiple\""," to trigger the actual read.",[59,4734,4735,4736,215],{},"To clear stored items, send ",[89,4737,4738],{},"msg.topic = \"clearitems\"",[15,4740,4741],{},"You now have a flexible setup for reading multiple values from your PLC on demand.",[15,4743,3038,4744,3059],{},[462,4745,4746,4747,3055,4750,4753,4754,4756,4757,4759,4760,4762,4763,3207],{},"{\"id\":\"6f5e2b1cbce15025\",\"type\":\"OpcUa-Client\",\"z\":\"ead97ed756a13a15\",\"endpoint\":\"\",\"action\":\"readmultiple\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":580,\"y\":500,\"wires\":[[\"28b575f06bbbe7a7\"],",[462,4748,4749],{},"\"139d346aab204f2f\"",[462,4751,4752],{},"\"3497d5566fb78f5f\"","]},{\"id\":\"4daa958d34c648c5\",\"type\":\"OpcUa-Item\",\"z\":\"ead97ed756a13a15\",\"item\":\"ns=5;s=Counter1\",\"datatype\":\"Int32\",\"value\":\"\",\"name\":\"\",\"x\":380,\"y\":480,\"wires\":[[\"6f5e2b1cbce15025\"]]},{\"id\":\"baa2733ca1fcb69d\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Add item\",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":200,\"y\":480,\"wires\":[[\"4daa958d34c648c5\"]]},{\"id\":\"dfd96a4dfe6330af\",\"type\":\"OpcUa-Item\",\"z\":\"ead97ed756a13a15\",\"item\":\"ns=5;s=Random1\",\"datatype\":\"Double\",\"value\":\"\",\"name\":\"\",\"x\":380,\"y\":520,\"wires\":[[\"6f5e2b1cbce15025\"]]},{\"id\":\"b8d5e40a98b1fb9f\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Add item\",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":200,\"y\":520,\"wires\":[[\"dfd96a4dfe6330af\"]]},{\"id\":\"3f63c46f499c3bca\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Read multiple items\",\"props\":",[462,4755,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"readmultiple\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":370,\"y\":440,\"wires\":[[\"6f5e2b1cbce15025\"]]},{\"id\":\"75c7927996cf44c2\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Clear nodeId array\",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"clearitems\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":370,\"y\":560,\"wires\":[[\"6f5e2b1cbce15025\"]]},{\"id\":\"28b575f06bbbe7a7\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Tag Value\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":760,\"y\":460,\"wires\":",[462,4758],{},"},{\"id\":\"139d346aab204f2f\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Errors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":750,\"y\":500,\"wires\":",[462,4761],{},"},{\"id\":\"3497d5566fb78f5f\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Raw Response\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":780,\"y\":540,\"wires\":",[462,4764],{},[190,4766,4768],{"id":4767},"writing-values","Writing Values",[15,4770,4771],{},"In addition to reading data, OPC UA also allows you to write control signals or parameters to your equipment.",[4341,4773,4775],{"id":4774},"writing-a-single-tag","Writing a Single Tag",[15,4777,4778],{},"To write a single value:",[120,4780,4781,4786,4822,4830,4850,4852,4862],{},[59,4782,4393,4783,4785],{},[24,4784,4467],{}," node onto the canvas (used to trigger the write operation).",[59,4787,299,4788,4550,4790,4811,4813,4817,4819],{},[24,4789,4549],{},[56,4791,4792,4797,4806],{},[59,4793,4794,4796],{},[24,4795,4557],{},": Enter the target identifier.",[59,4798,4799,4801,4802,404,4804,3465],{},[24,4800,4566],{},": Choose the appropriate type (e.g., ",[89,4803,336],{},[89,4805,332],{},[59,4807,4808,4810],{},[24,4809,3486],{},": Enter the value to write.",[4571,4812],{},[39,4814],{"alt":4815,"dataZoomable":458,"src":4816},"Screenshot showing OPC UA Item node configuration for write operation","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-item-node-write.png",[4571,4818],{},[44,4820,4821],{},"OPC UA Item node configured for a write operation",[59,4823,4824,4825,4827,4828,667],{},"Connect the ",[24,4826,4467],{}," node to the ",[24,4829,4378],{},[59,4831,299,4832,4589,4834,4593,4836,215,4839,4841,4845,4847],{},[24,4833,4396],{},[24,4835,4592],{},[89,4837,4838],{},"WRITE",[4571,4840],{},[39,4842],{"alt":4843,"dataZoomable":458,"src":4844},"Screenshot showing OPC UA Client node with \"WRITE\" action selected","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-client-write-ops.png",[4571,4846],{},[44,4848,4849],{},"OPC UA Client node with \"WRITE\" action selected",[59,4851,4605],{},[59,4853,4824,4854,4827,4856,4612,4858,4615,4860,667],{},[24,4855,4378],{},[24,4857,4375],{},[24,4859,4375],{},[24,4861,4473],{},[59,4863,4629,4864,4866],{},[24,4865,4467],{}," button to trigger the write.",[15,4868,4869,4870,215],{},"The OPC UA Client node will confirm the operation with a status like ",[24,4871,4872],{},"\"values written\"",[15,4874,3038,4875,3059],{},[462,4876,4877,4878,3055,4881,4884,4885,4887,4888,4890,4891,4893,4894,3207],{},"{\"id\":\"c922a70d48ecba6f\",\"type\":\"OpcUa-Client\",\"z\":\"ead97ed756a13a15\",\"endpoint\":\"\",\"action\":\"write\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":520,\"y\":480,\"wires\":[[\"7eb010a4671ac181\"],",[462,4879,4880],{},"\"392bb1fd60c29baf\"",[462,4882,4883],{},"\"e9d279677dbc87e8\"","]},{\"id\":\"5ff1e3c2d5977a34\",\"type\":\"OpcUa-Item\",\"z\":\"ead97ed756a13a15\",\"item\":\"ns=5;s=Counter1\",\"datatype\":\"Int32\",\"value\":\"20\",\"name\":\"\",\"x\":340,\"y\":480,\"wires\":[[\"c922a70d48ecba6f\"]]},{\"id\":\"8cdd141dbdb350c7\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Write\",\"props\":",[462,4886,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":190,\"y\":480,\"wires\":[[\"5ff1e3c2d5977a34\"]]},{\"id\":\"7eb010a4671ac181\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Tag Value\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":680,\"y\":440,\"wires\":",[462,4889],{},"},{\"id\":\"392bb1fd60c29baf\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Errors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":670,\"y\":480,\"wires\":",[462,4892],{},"},{\"id\":\"e9d279677dbc87e8\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Raw Response\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":700,\"y\":520,\"wires\":",[462,4895],{},[4341,4897,4899],{"id":4898},"writing-multiple-tags","Writing Multiple Tags",[15,4901,4902],{},"To write multiple values at once, follow this pattern:",[120,4904,4905,4925,4928,4941,4948,4962,4968,4974,4980],{},[59,4906,299,4907,4589,4909,4593,4911,215,4914,4916,4920,4922],{},[24,4908,4396],{},[24,4910,4592],{},[89,4912,4913],{},"WRITE MULTIPLE",[4571,4915],{},[39,4917],{"alt":4918,"dataZoomable":458,"src":4919},"Screenshot showing OPC UA Client node with \"WRITE MULTIPLE\" action selected","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fopcua-client-write-multiple.png",[4571,4921],{},[44,4923,4924],{},"OPC UA Client node configured for writing multiple values",[59,4926,4927],{},"Select the appropriate endpoint configuration.",[59,4929,4930,4931,4933,4934,404,4936,684,4938,4940],{},"Add multiple ",[24,4932,4549],{}," nodes, each configured with a ",[24,4935,4557],{},[24,4937,4566],{},[24,4939,3486],{}," to be written.",[59,4942,299,4943,4945,4946,667],{},[24,4944,4467],{}," node for each ",[24,4947,4378],{},[59,4949,4950,4951,4953,4954,4956,4957,4959,4960,667],{},"Connect each ",[24,4952,4467],{}," node to its corresponding ",[24,4955,4378],{}," node, then connect all ",[24,4958,4378],{}," nodes to the ",[24,4961,4375],{},[59,4963,4715,4964,4718,4966,667],{},[24,4965,4473],{},[24,4967,4375],{},[59,4969,4970,4971,4973],{},"Deploy the flow and trigger all ",[24,4972,4467],{}," nodes to load the values.",[59,4975,4976,4977,215],{},"To execute the write operation, send a message with ",[89,4978,4979],{},"msg.topic = \"writemultiple\"",[59,4981,4982,4983,215],{},"To clear the stored items, send a message with ",[89,4984,4738],{},[15,4986,4987],{},"This setup allows you to prepare multiple tag values and write them all at once, giving you precise control through a single command.",[15,4989,3038,4990,3059],{},[462,4991,4992,4993,3055,4996,4999,5000,5002,5003,5005,5006,5008,5009,5011,5012,3207],{},"{\"id\":\"ed421a9.d6319e8\",\"type\":\"OpcUa-Client\",\"z\":\"ead97ed756a13a15\",\"endpoint\":\"\",\"action\":\"writemultiple\",\"deadbandtype\":\"a\",\"deadbandvalue\":1,\"time\":10,\"timeUnit\":\"s\",\"certificate\":\"n\",\"localfile\":\"\",\"localkeyfile\":\"\",\"useTransport\":false,\"maxChunkCount\":\"\",\"maxMessageSize\":\"\",\"receiveBufferSize\":\"\",\"sendBufferSize\":\"\",\"setstatusandtime\":false,\"keepsessionalive\":false,\"name\":\"\",\"x\":560,\"y\":420,\"wires\":[[\"b0788fb9285c48ea\"],",[462,4994,4995],{},"\"bde690208cbf2c4c\"",[462,4997,4998],{},"\"0883826b4a0ca030\"","]},{\"id\":\"96bd763.14a9308\",\"type\":\"OpcUa-Item\",\"z\":\"ead97ed756a13a15\",\"item\":\"ns=3;i=1007\",\"datatype\":\"Double\",\"value\":\"1.0\",\"name\":\"\",\"x\":360,\"y\":400,\"wires\":[[\"ed421a9.d6319e8\"]]},{\"id\":\"d8a68c7a.a73008\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Add item\",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":180,\"y\":400,\"wires\":[[\"96bd763.14a9308\"]]},{\"id\":\"8ae51c8c.20bd3\",\"type\":\"OpcUa-Item\",\"z\":\"ead97ed756a13a15\",\"item\":\"ns=3;i=1008\",\"datatype\":\"Int32\",\"value\":\"50\",\"name\":\"\",\"x\":360,\"y\":440,\"wires\":[[\"ed421a9.d6319e8\"]]},{\"id\":\"1335adce.7f46ba\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Add item\",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":180,\"y\":440,\"wires\":[[\"8ae51c8c.20bd3\"]]},{\"id\":\"2c050a3d.91f496\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Write multiple items\",\"props\":",[462,5001,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"writemultiple\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":350,\"y\":360,\"wires\":[[\"ed421a9.d6319e8\"]]},{\"id\":\"690e4f9f.faeca\",\"type\":\"inject\",\"z\":\"ead97ed756a13a15\",\"name\":\"Clear nodeId array\",\"props\":",[462,5004,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":false,\"onceDelay\":0.1,\"topic\":\"clearitems\",\"payload\":\"\",\"payloadType\":\"str\",\"x\":350,\"y\":480,\"wires\":[[\"ed421a9.d6319e8\"]]},{\"id\":\"b0788fb9285c48ea\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Tag Value\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":740,\"y\":380,\"wires\":",[462,5007],{},"},{\"id\":\"bde690208cbf2c4c\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Errors\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":730,\"y\":420,\"wires\":",[462,5010],{},"},{\"id\":\"0883826b4a0ca030\",\"type\":\"debug\",\"z\":\"ead97ed756a13a15\",\"name\":\"Raw Response\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":760,\"y\":460,\"wires\":",[462,5013],{},[48,5015,5017],{"id":5016},"whats-next","What’s Next",[15,5019,5020],{},"You’ve now mastered the fundamentals of OPC UA integration, connecting to servers, browsing tags, and reading or writing data. These core building blocks lay the foundation for powerful industrial automation.",[15,5022,5023,5024,5027],{},"In real deployments, you will want more than Inject nodes and debug panels. With ",[24,5025,5026],{},"FlowFuse Dashboard 2.0",", you can build full operator interfaces, live gauges, control buttons, trend charts, fully connected to your OPC UA data.",[15,5029,5030],{},"This guide covered the basics, but OPC UA offers far more. In the next article, we will explore:",[56,5032,5033,5036,5039,5042],{},[59,5034,5035],{},"Subscriptions for real-time monitoring without polling",[59,5037,5038],{},"Events and alarms directly from equipment",[59,5040,5041],{},"Historical data queries for trend analysis",[59,5043,5044],{},"Method calls to execute functions on your devices",[15,5046,5047,5048,5050],{},"When it is time to move beyond prototypes, ",[24,5049,4233],{}," delivers what industrial systems truly need, remote device management, instant rollbacks with full version control, built-in team collaboration, and high availability you can trust.",[15,5052,5053],{},"If you’re ready to simplify your OPC UA integration and scale industrial workflows with Node-RED, [start your free trial]({% include \"sign-up-url.njk\" %}) of FlowFuse today.",[15,5055,5056,5057,5059],{},"OPC UA is one of several protocols FlowFuse uses to connect PLCs to MQTT, cloud platforms, and enterprise systems. See the ",[29,5058,2142],{"href":2141}," for EtherNet\u002FIP, Siemens S7, Modbus, and more.",{"title":458,"searchDepth":523,"depth":523,"links":5061},[5062,5069,5085],{"id":4260,"depth":491,"text":4261,"children":5063},[5064,5065,5066,5067,5068],{"id":4267,"depth":498,"text":4268},{"id":4274,"depth":498,"text":4275},{"id":4281,"depth":498,"text":4282},{"id":4288,"depth":498,"text":4289},{"id":4295,"depth":498,"text":4296},{"id":4302,"depth":491,"text":4303,"children":5070},[5071,5072,5075,5076,5077,5081],{"id":50,"depth":498,"text":4312},{"id":4335,"depth":498,"text":4336,"children":5073},[5074],{"id":4343,"depth":523,"text":4344},{"id":184,"depth":498,"text":4385},{"id":4456,"depth":498,"text":4457},{"id":4526,"depth":498,"text":4527,"children":5078},[5079,5080],{"id":4533,"depth":523,"text":4534},{"id":4668,"depth":523,"text":4669},{"id":4767,"depth":498,"text":4768,"children":5082},[5083,5084],{"id":4774,"depth":523,"text":4775},{"id":4898,"depth":523,"text":4899},{"id":5016,"depth":491,"text":5017},"2025-07-16","OPC UA tutorial: Connect Node-RED to industrial PLCs step-by-step. Configure Kepware endpoints, read\u002Fwrite Siemens S7 tags, browse Allen-Bradley data. Free guide.","blog\u002F2025\u002F07\u002Fimages\u002Fopcua-tutorial.png",{"keywords":5090,"excerpt":5091},"OPC UA Node-RED tutorial, connect PLC to Node-RED, OPC UA example, Node-RED industrial IoT, OPC UA browser Node-RED, read PLC data Node-RED, OPC UA client configuration, Kepware Node-RED, OPC UA port 4840, industrial automation tutorial",{"type":12,"value":5092},[5093],[15,5094,4212],{},"\u002Fblog\u002F2025\u002F07\u002Freading-and-writing-plc-data-using-opc-ua",{"title":4206,"description":5087},{"loc":5095},"blog\u002F2025\u002F07\u002Freading-and-writing-plc-data-using-opc-ua","A practical guide to accessing industrial data through OPC UA server gateways",[826,827,5101],"plc","OPC UA is the industry-standard protocol that provides a universal language for connecting PLCs, SCADA systems, HMIs, and enterprise applications from any vendor. This hands-on tutorial shows how to use Node-RED and FlowFuse to connect to any OPC UA server, browse available tags, and read and write real-time values from industrial equipment using the OPC UA Browser node for discovering Node IDs.","HmqpYuVb_fVnQD0uk4EXLMYTz-sUmN_pDO9PUfSoy1E",{"id":5105,"title":5106,"authors":5107,"body":5108,"cta":3,"date":6151,"description":6152,"extension":802,"image":6153,"lastUpdated":6154,"meta":6155,"navigation":494,"path":6163,"seo":6164,"sitemap":6165,"stem":6166,"subtitle":6167,"tags":6168,"tldr":6170,"video":3,"__hash__":6171},"blog\u002Fblog\u002F2025\u002F07\u002Fconnect-legacy-equipment-serial-flowfuse.md","Node-RED Serial Port Tutorial: Connect RS232\u002FRS485 Manufacturing Equipment (2026)",[10],{"type":12,"value":5109,"toc":6135},[5110,5117,5120,5124,5127,5130,5134,5137,5169,5176,5180,5186,5247,5251,5254,5277,5281,5284,5290,5293,5295,5298,5329,5333,5339,5372,5380,5432,5439,5448,5452,5459,5462,5485,5488,5495,5500,5504,5507,5536,5539,5548,5554,5743,5746,5794,5811,5815,5829,5838,5841,5871,5874,5888,5891,5895,5898,5908,5914,5917,5928,5931,5934,5958,5961,5983,5986,6098,6101,6104,6110,6114,6117,6120,6132],[15,5111,5112,5113,5116],{},"Many factories rely on machines, both new and old, that communicate via traditional serial interfaces such as ",[24,5114,5115],{},"RS-232, RS-422, or RS-485",". These machines remain reliable but can be challenging to integrate with modern systems due to their connectivity style.",[15,5118,5119],{},"This guide shows you how to use FlowFuse (Node-RED with enterprise capabilities) to connect manufacturing equipment, collect data, and enable real-time monitoring, without modifying your original hardware.",[48,5121,5123],{"id":5122},"making-sense-of-serial-communication","Making Sense of Serial Communication",[15,5125,5126],{},"Before diving into the wiring and flow configuration, it helps to understand how serial communication works, and why it is still relevant in industrial settings.",[15,5128,5129],{},"Serial ports move data one bit at a time, like passing beads on a string. This may sound old-fashioned, but it remains one of the most reliable and predictable ways to connect machines.",[190,5131,5133],{"id":5132},"data-direction-which-way-does-it-flow","Data Direction: Which Way Does It Flow?",[15,5135,5136],{},"Not all serial connections behave the same. The direction of data flow is defined by its duplex mode:",[56,5138,5139,5145,5155],{},[59,5140,5141,5144],{},[24,5142,5143],{},"Simplex",": One-way only. Like a speaker giving a lecture, the machine talks, you just listen. This is common for devices like weight scales or scanners that only output data.",[59,5146,5147,5150,5151,5154],{},[24,5148,5149],{},"Half-Duplex",": Data can flow in both directions, but only one side can transmit at a time. This is like using a walkie-talkie. It is the most common operational mode for ",[24,5152,5153],{},"RS-485"," (using two wires), where multiple devices share the same communication line.",[59,5156,5157,5160,5161,5164,5165,5168],{},[24,5158,5159],{},"Full-Duplex",": Two-way, simultaneous communication. This is like a phone call, both sides can talk and listen at once. This is the typical mode for ",[24,5162,5163],{},"RS-232"," (using separate transmit and receive lines) and ",[24,5166,5167],{},"RS-422",", which is designed for full-duplex, multi-drop scenarios (one sender, multiple listeners).",[15,5170,5171,5172,5175],{},"Across industrial environments, serial interfaces like ",[24,5173,5174],{},"RS-232, RS-422, and RS-485"," remain prevalent for device communication, depending on the wiring and number of connected devices.",[190,5177,5179],{"id":5178},"data-format-how-is-it-structured","Data Format: How Is It Structured?",[15,5181,5182,5183,577],{},"Machines are picky, they expect data to arrive in a specific format. Here are the key pieces that make up a serial data ",[24,5184,5185],{},"frame",[5187,5188,5189,5203],"table",{},[5190,5191,5192],"thead",{},[5193,5194,5195,5200],"tr",{},[5196,5197,5199],"th",{"align":5198},"left","Setting",[5196,5201,5202],{"align":5198},"What It Means",[5204,5205,5206,5217,5227,5237],"tbody",{},[5193,5207,5208,5214],{},[5209,5210,5211],"td",{"align":5198},[24,5212,5213],{},"Baud Rate",[5209,5215,5216],{"align":5198},"Speed of transmission (e.g., 9600 or 115200)",[5193,5218,5219,5224],{},[5209,5220,5221],{"align":5198},[24,5222,5223],{},"Data Bits",[5209,5225,5226],{"align":5198},"The actual data, usually 7 or 8 bits",[5193,5228,5229,5234],{},[5209,5230,5231],{"align":5198},[24,5232,5233],{},"Parity",[5209,5235,5236],{"align":5198},"Optional error check, even, odd, or none",[5193,5238,5239,5244],{},[5209,5240,5241],{"align":5198},[24,5242,5243],{},"Stop Bits",[5209,5245,5246],{"align":5198},"Marks the end of each message",[190,5248,5250],{"id":5249},"interface-types-how-devices-physically-connect","Interface Types: How Devices Physically Connect",[15,5252,5253],{},"Different machines use different physical standards. The most common are:",[56,5255,5256,5261,5266,5271],{},[59,5257,5258,5260],{},[24,5259,5163],{},": Typically full-duplex and one-to-one. Good for short-distance device communication.",[59,5262,5263,5265],{},[24,5264,5167],{},": Full-duplex, multi-drop (one sender, multiple receivers). Used for longer distances than RS-232.",[59,5267,5268,5270],{},[24,5269,5153],{},": Typically half-duplex and multi-device. Ideal for networks and even longer cable runs.",[59,5272,5273,5276],{},[24,5274,5275],{},"USB (via adapter)",": Most modern PCs and gateways use USB-to-Serial adapters to talk to RS-232\u002F422\u002F485 devices.",[48,5278,5280],{"id":5279},"setting-up-serial-communication-with-flowfuse","Setting Up Serial Communication with FlowFuse",[15,5282,5283],{},"Now that you understand how serial communication works and what kind of interfaces your machine might use, the next step is to put that knowledge into practice.",[15,5285,5286,5287,5289],{},"Using ",[24,5288,4233],{},", you can easily establish serial communication, process the data, and integrate it into dashboards or automated workflows, all without modifying the original hardware.",[15,5291,5292],{},"Let's walk through how to set this up.",[190,5294,2952],{"id":2951},[15,5296,5297],{},"Before we start, ensure the following prerequisites are met:",[56,5299,5300,5306,5317],{},[59,5301,5302,5305],{},[24,5303,5304],{},"Hardware Connection:"," The machine must be physically connected to your system using a serial interface.",[59,5307,5308,5311,5312,215],{},[24,5309,5310],{},"Node-RED Instance:"," Make sure you have an instance of Node-RED up and running. The quickest way to do this is via FlowFuse. If you don't have an account, check out our ",[29,5313,5316],{"href":5314,"rel":5315},"https:\u002F\u002Fapp.flowfuse.com\u002F",[33],"free trial",[59,5318,5319,5322,5323,5328],{},[24,5320,5321],{},"Serialport Node:"," Install the ",[29,5324,5327],{"href":5325,"rel":5326},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002Fnode-red-node-serialport",[33],"node-red-node-serialport"," package if it is not already available in your palette.",[190,5330,5332],{"id":5331},"configuring-the-serial-port-node","Configuring the Serial Port Node",[15,5334,5335,5336,5338],{},"After installing the ",[89,5337,5327],{}," package, follow these steps to configure serial communication in your Node-RED flow:",[120,5340,5341,5347,5350,5357],{},[59,5342,198,5343,5346],{},[24,5344,5345],{},"Serial In"," node from the Node-RED palette onto the canvas.",[59,5348,5349],{},"Double-click the node to open the configuration dialog.",[59,5351,5352,5353,5356],{},"Click the pencil icon next to the ",[24,5354,5355],{},"Serial Port"," field to add a new port configuration.",[59,5358,5359,5360,5363,5364,5367,5368,5371],{},"Enter the serial port path (e.g., ",[89,5361,5362],{},"\u002Fdev\u002FttyUSB0"," on Linux or ",[89,5365,5366],{},"COM3"," on Windows). You can also click the ",[24,5369,5370],{},"search"," option to list available ports.",[15,5373,5374,5378],{},[39,5375],{"alt":5376,"dataZoomable":458,"src":5377},"Screenshot of Node-RED serial port node configuration showing available serial ports after clicking the search option.","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fsearching-path.gif",[44,5379,5376],{},[120,5381,5382,5397,5427],{"start":549},[59,5383,218,5384,404,5387,404,5390,684,5393,5396],{},[24,5385,5386],{},"baud rate",[24,5388,5389],{},"data bits",[24,5391,5392],{},"stop bits",[24,5394,5395],{},"parity"," according to your machine's specifications. These values must match the device exactly, or communication will fail or result in corrupted data.",[59,5398,5399,5400,5403,5404,333,5407,5410,5411,5414,5415,5418,5419,5421,5425],{},"Optionally, define an ",[24,5401,5402],{},"input delimiter",", such as ",[89,5405,5406],{},"\\n",[89,5408,5409],{},"\\r",", to segment incoming messages if your device sends data in lines or chunks.\nIf the output is fixed-length, you can configure it to wait for a specific number of characters. You can also set a ",[24,5412,5413],{},"timeout"," to receive data at regular intervals.\nLater in the output section, you can choose to ",[24,5416,5417],{},"add characters"," back to the message, such as restoring the line break.",[4571,5420],{},[39,5422],{"alt":5423,"dataZoomable":458,"src":5424},"Screenshot of input and output settings in the Node-RED serial port node, showing options like delimiter, character count, and timeout.","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Finput-output-serial-node.png",[44,5426,5423],{},[59,5428,236,5429,5431],{},[24,5430,243],{}," to save the configuration.",[15,5433,5434,5435,5438],{},"Once the serial port is correctly configured and the device is connected, the ",[24,5436,5437],{},"serial in"," node will show a \"connected\" status below the node with a small green square.",[15,5440,5441,5445,5447],{},[39,5442],{"alt":5443,"dataZoomable":458,"src":5444},"Screenshot of the Serial In node in Node-RED showing a green square that indicates a successful connection to the serial port.","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fserial-port-node-status.png",[44,5446,5443],{},"\n{data-zoomable}",[190,5449,5451],{"id":5450},"writing-to-serial-port","Writing to Serial Port",[15,5453,5454,5455,5458],{},"To send data to a machine, use the ",[24,5456,5457],{},"serial out"," node in Node-RED. This is often necessary to trigger actions such as starting a process, requesting a reading, or changing an internal state.",[15,5460,5461],{},"Follow these steps to send a command:",[120,5463,5464,5468,5474,5479],{},[59,5465,4393,5466,202],{},[24,5467,302],{},[59,5469,218,5470,5473],{},[24,5471,5472],{},"payload type"," appropriate to your machine's requirements. This could be a string, number, raw buffer, or JSON object.",[59,5475,4715,5476,5478],{},[24,5477,5457],{}," node and select the configured serial port.",[59,5480,4824,5481,4827,5483,667],{},[24,5482,302],{},[24,5484,5457],{},[15,5486,5487],{},"Once deployed, clicking the inject button will send the specified data to the machine via the serial interface.",[15,5489,5490,5491,5494],{},"In this guide, we are using a real machine connected via a serial interface. The machine is programmed to simulate a production process when it receives the ",[89,5492,5493],{},"\"START\""," command (sent as a string). Once triggered, it begins incrementing the count of good and defect products and sends this data back over the same serial connection.",[15,5496,5497,5498,667],{},"The next section demonstrates how to read and process this simulated production data using the ",[24,5499,5437],{},[190,5501,5503],{"id":5502},"reading-and-processing-serial-data","Reading and Processing Serial Data",[15,5505,5506],{},"Follow these steps to read and handle the serial data:",[120,5508,5509,5514,5522],{},[59,5510,198,5511,5513],{},[24,5512,5437],{}," node onto the canvas and configure it to use the same serial port.",[59,5515,4715,5516,5518,5519,5521],{},[24,5517,309],{}," node and connect it to the output of the ",[24,5520,5437],{}," node. This helps you inspect the raw payload and confirm that data is being received correctly.",[59,5523,5524,5525,404,5528,5531,5532,5535],{},"Once you confirm the format of the incoming data, use any of the ",[24,5526,5527],{},"change",[24,5529,5530],{},"JSON",", or ",[24,5533,5534],{},"function"," node to parse and convert it into a structured format, here we have used function.",[15,5537,5538],{},"In our case, the machine sends production data every 2 seconds in the following format:",[15,5540,5541,5545],{},[39,5542],{"alt":5543,"dataZoomable":458,"src":5544},"Screenshot of Node-RED debug panel showing production data sent from the machine every 2 seconds","\u002Fblog\u002F2025\u002F07\u002Fimages\u002Fdebug-panel-output.png",[44,5546,5547],{},"Screenshot of Node-RED debug panel showing production data sent from the machine every 2 seconds.",[15,5549,5550,5551,5553],{},"To convert this string into a structured JSON object, you can use a ",[24,5552,5534],{}," node with the following code:",[453,5555,5557],{"className":455,"code":5556,"language":457,"meta":458,"style":458},"let parts = msg.payload.trim().split(' ');\nlet result = {};\n\nparts.forEach(part => {\n    let [key, value] = part.split(':');\n    result[key.trim()] = parseInt(value);\n});\n\nmsg.payload = result;\nreturn msg;\n",[89,5558,5559,5599,5611,5615,5637,5677,5708,5716,5720,5735],{"__ignoreMap":458},[462,5560,5561,5564,5567,5569,5571,5573,5575,5577,5580,5582,5584,5587,5589,5592,5595,5597],{"class":464,"line":465},[462,5562,5563],{"class":468},"let",[462,5565,5566],{"class":472}," parts ",[462,5568,477],{"class":476},[462,5570,480],{"class":472},[462,5572,215],{"class":476},[462,5574,485],{"class":472},[462,5576,215],{"class":476},[462,5578,5579],{"class":3607},"trim",[462,5581,3662],{"class":472},[462,5583,215],{"class":476},[462,5585,5586],{"class":3607},"split",[462,5588,4069],{"class":472},[462,5590,5591],{"class":476},"'",[462,5593,5594],{"class":476}," '",[462,5596,3639],{"class":472},[462,5598,488],{"class":476},[462,5600,5601,5603,5606,5608],{"class":464,"line":491},[462,5602,5563],{"class":468},[462,5604,5605],{"class":472}," result ",[462,5607,477],{"class":476},[462,5609,5610],{"class":476}," {};\n",[462,5612,5613],{"class":464,"line":498},[462,5614,495],{"emptyLinePlaceholder":494},[462,5616,5617,5620,5622,5625,5627,5631,5634],{"class":464,"line":523},[462,5618,5619],{"class":472},"parts",[462,5621,215],{"class":476},[462,5623,5624],{"class":3607},"forEach",[462,5626,4069],{"class":472},[462,5628,5630],{"class":5629},"sHdIc","part",[462,5632,5633],{"class":468}," =>",[462,5635,5636],{"class":476}," {\n",[462,5638,5639,5642,5645,5648,5650,5653,5655,5658,5661,5663,5665,5667,5669,5671,5673,5675],{"class":464,"line":544},[462,5640,5641],{"class":468},"    let",[462,5643,5644],{"class":476}," [",[462,5646,5647],{"class":472},"key",[462,5649,3055],{"class":476},[462,5651,5652],{"class":472}," value",[462,5654,637],{"class":476},[462,5656,5657],{"class":476}," =",[462,5659,5660],{"class":472}," part",[462,5662,215],{"class":476},[462,5664,5586],{"class":3607},[462,5666,4069],{"class":573},[462,5668,5591],{"class":476},[462,5670,577],{"class":514},[462,5672,5591],{"class":476},[462,5674,3639],{"class":573},[462,5676,488],{"class":476},[462,5678,5679,5682,5685,5687,5689,5691,5694,5696,5699,5701,5704,5706],{"class":464,"line":549},[462,5680,5681],{"class":472},"    result",[462,5683,5684],{"class":573},"[",[462,5686,5647],{"class":472},[462,5688,215],{"class":476},[462,5690,5579],{"class":3607},[462,5692,5693],{"class":573},"()] ",[462,5695,477],{"class":476},[462,5697,5698],{"class":3607}," parseInt",[462,5700,4069],{"class":573},[462,5702,5703],{"class":472},"value",[462,5705,3639],{"class":573},[462,5707,488],{"class":476},[462,5709,5710,5712,5714],{"class":464,"line":564},[462,5711,3207],{"class":476},[462,5713,3639],{"class":472},[462,5715,488],{"class":476},[462,5717,5718],{"class":464,"line":570},[462,5719,495],{"emptyLinePlaceholder":494},[462,5721,5722,5724,5726,5728,5730,5733],{"class":464,"line":583},[462,5723,501],{"class":472},[462,5725,215],{"class":476},[462,5727,556],{"class":472},[462,5729,477],{"class":476},[462,5731,5732],{"class":472}," result",[462,5734,488],{"class":476},[462,5736,5737,5739,5741],{"class":464,"line":589},[462,5738,651],{"class":650},[462,5740,480],{"class":472},[462,5742,488],{"class":476},[15,5744,5745],{},"This transforms the string into a JSON object like:",[453,5747,5751],{"className":5748,"code":5749,"language":5750,"meta":458,"style":458},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"GOOD\": 214,\n  \"DEFECT\": 22\n}\n","json",[89,5752,5753,5758,5775,5789],{"__ignoreMap":458},[462,5754,5755],{"class":464,"line":465},[462,5756,5757],{"class":476},"{\n",[462,5759,5760,5763,5766,5768,5770,5773],{"class":464,"line":491},[462,5761,5762],{"class":476},"  \"",[462,5764,5765],{"class":468},"GOOD",[462,5767,518],{"class":476},[462,5769,577],{"class":476},[462,5771,5772],{"class":3625}," 214",[462,5774,609],{"class":476},[462,5776,5777,5779,5782,5784,5786],{"class":464,"line":498},[462,5778,5762],{"class":476},[462,5780,5781],{"class":468},"DEFECT",[462,5783,518],{"class":476},[462,5785,577],{"class":476},[462,5787,5788],{"class":3625}," 22\n",[462,5790,5791],{"class":464,"line":523},[462,5792,5793],{"class":476},"}\n",[19,5795,5796],{},[15,5797,5798,5801,5802,5804,5805,5810],{},[24,5799,5800],{},"Tip",": You do not need to know JavaScript to use the ",[24,5803,5534],{}," node.\nIf you are using FlowFuse, the built-in ",[29,5806,5809],{"href":5807,"rel":5808},"https:\u002F\u002Fwww.google.com\u002Fsearch?q=\u002Fdocs\u002Fuser\u002Fexpert\u002F",[33],"FlowFuse Assistant"," can help you write function code using natural language. Simply provide a sample of the data received from your machine and describe the output you expect, the Assistant will generate the function for you.",[190,5812,5814],{"id":5813},"handling-request-response-serial-communication","Handling Request-Response Serial Communication",[15,5816,5817,5818,404,5820,684,5822,5824,5825,5828],{},"Not all machines stream data continuously. Some expect a request command, and only then respond with data. In these cases, using a combination of ",[24,5819,302],{},[24,5821,5457],{},[24,5823,5437],{}," nodes can become tricky, especially if you need to match each request with exactly one response. That's where the ",[24,5826,5827],{},"serial request"," node becomes useful.",[15,5830,1758,5831,5833,5834,5837],{},[24,5832,5827],{}," node handles this entire pattern for you. Internally, it combines the logic of sending a message and waiting for a single reply, working in a ",[24,5835,5836],{},"first-in, first-out"," manner. This means it will only send the next request after receiving a response (or timeout) for the previous one, making it ideal for synchronous devices.",[15,5839,5840],{},"To use it:",[120,5842,5843,5848,5851,5863],{},[59,5844,198,5845,5847],{},[24,5846,5827],{}," node from the palette.",[59,5849,5850],{},"Double-click to configure the port, use the same path and settings as your other serial nodes.",[59,5852,5853,5854,5856,5857,333,5860,215],{},"Connect it to an ",[24,5855,302],{}," node configured with the command your machine expects, such as ",[89,5858,5859],{},"\"READ\"",[89,5861,5862],{},"\"STATUS\"",[59,5864,5865,5866,333,5868,5870],{},"On the output side, connect a ",[24,5867,309],{},[24,5869,5534],{}," node to handle the response.",[15,5872,5873],{},"Each time you trigger the inject, the command will be sent over the serial port, and the response will be delivered to the output, ready to be parsed just like before. This approach is clean, predictable, and removes the guesswork from matching writes with reads.",[15,5875,5876,5877,5879,5880,5883,5884,5887],{},"The output message includes ",[89,5878,324],{}," containing the response (if any), ",[89,5881,5882],{},"msg.status"," with the result status, and ",[89,5885,5886],{},"msg.port"," for reference.",[15,5889,5890],{},"This node is especially useful for polling machines that respond with production counts, part IDs, temperature readings, or system status, but only when asked.",[190,5892,5894],{"id":5893},"dynamically-managing-serial-ports","Dynamically Managing Serial Ports",[15,5896,5897],{},"In a perfect setup, the serial device is connected, the port is stable, and everything just works. But in practice, hardware is not always so predictable.",[15,5899,5900,5901,5904,5905,5907],{},"For example, You might disconnect and reconnect a USB-to-serial adapter, and now the device shows up as ",[89,5902,5903],{},"\u002Fdev\u002FttyUSB1"," instead of ",[89,5906,5362],{},". Or maybe you need to temporarily release the serial port to flash new firmware onto an Arduino. In some environments, the port assignment could change on every reboot, making it difficult to hardcode anything.",[15,5909,5910,5911,667],{},"Rather than redeploying or editing your flow every time, Node-RED gives you a more flexible option: the ",[24,5912,5913],{},"serial control",[15,5915,5916],{},"This node lets your flow adjust serial communication settings on the fly. You can:",[56,5918,5919,5922,5925],{},[59,5920,5921],{},"Stop the serial connection when needed.",[59,5923,5924],{},"Start it again later.",[59,5926,5927],{},"Even switch to a different port entirely, without touching the Node-RED editor.",[15,5929,5930],{},"All of this happens by sending a simple message to the control node.",[15,5932,5933],{},"To stop communication:",[453,5935,5937],{"className":5748,"code":5936,"language":5750,"meta":458,"style":458},"{ \"enabled\": false }\n",[89,5938,5939],{"__ignoreMap":458},[462,5940,5941,5944,5946,5949,5951,5953,5956],{"class":464,"line":465},[462,5942,5943],{"class":476},"{",[462,5945,511],{"class":476},[462,5947,5948],{"class":468},"enabled",[462,5950,518],{"class":476},[462,5952,577],{"class":476},[462,5954,5955],{"class":476}," false",[462,5957,3164],{"class":476},[15,5959,5960],{},"To start it again:",[453,5962,5964],{"className":5748,"code":5963,"language":5750,"meta":458,"style":458},"{ \"enabled\": true }\n",[89,5965,5966],{"__ignoreMap":458},[462,5967,5968,5970,5972,5974,5976,5978,5981],{"class":464,"line":465},[462,5969,5943],{"class":476},[462,5971,511],{"class":476},[462,5973,5948],{"class":468},[462,5975,518],{"class":476},[462,5977,577],{"class":476},[462,5979,5980],{"class":476}," true",[462,5982,3164],{"class":476},[15,5984,5985],{},"And if the port changes or needs reconfiguration, you can send everything in one message:",[453,5987,5989],{"className":5748,"code":5988,"language":5750,"meta":458,"style":458},"{\n  \"serialport\": \"\u002Fdev\u002FttyUSB1\",\n  \"serialbaud\": 9600,\n  \"databits\": 8,\n  \"parity\": \"none\",\n  \"stopbits\": 1,\n  \"enabled\": true\n}\n",[89,5990,5991,5995,6014,6030,6046,6065,6081,6094],{"__ignoreMap":458},[462,5992,5993],{"class":464,"line":465},[462,5994,5757],{"class":476},[462,5996,5997,5999,6002,6004,6006,6008,6010,6012],{"class":464,"line":491},[462,5998,5762],{"class":476},[462,6000,6001],{"class":468},"serialport",[462,6003,518],{"class":476},[462,6005,577],{"class":476},[462,6007,511],{"class":476},[462,6009,5903],{"class":514},[462,6011,518],{"class":476},[462,6013,609],{"class":476},[462,6015,6016,6018,6021,6023,6025,6028],{"class":464,"line":498},[462,6017,5762],{"class":476},[462,6019,6020],{"class":468},"serialbaud",[462,6022,518],{"class":476},[462,6024,577],{"class":476},[462,6026,6027],{"class":3625}," 9600",[462,6029,609],{"class":476},[462,6031,6032,6034,6037,6039,6041,6044],{"class":464,"line":523},[462,6033,5762],{"class":476},[462,6035,6036],{"class":468},"databits",[462,6038,518],{"class":476},[462,6040,577],{"class":476},[462,6042,6043],{"class":3625}," 8",[462,6045,609],{"class":476},[462,6047,6048,6050,6052,6054,6056,6058,6061,6063],{"class":464,"line":544},[462,6049,5762],{"class":476},[462,6051,5395],{"class":468},[462,6053,518],{"class":476},[462,6055,577],{"class":476},[462,6057,511],{"class":476},[462,6059,6060],{"class":514},"none",[462,6062,518],{"class":476},[462,6064,609],{"class":476},[462,6066,6067,6069,6072,6074,6076,6079],{"class":464,"line":549},[462,6068,5762],{"class":476},[462,6070,6071],{"class":468},"stopbits",[462,6073,518],{"class":476},[462,6075,577],{"class":476},[462,6077,6078],{"class":3625}," 1",[462,6080,609],{"class":476},[462,6082,6083,6085,6087,6089,6091],{"class":464,"line":564},[462,6084,5762],{"class":476},[462,6086,5948],{"class":468},[462,6088,518],{"class":476},[462,6090,577],{"class":476},[462,6092,6093],{"class":476}," true\n",[462,6095,6096],{"class":464,"line":570},[462,6097,5793],{"class":476},[15,6099,6100],{},"This is especially useful when your flow needs to recover automatically, for example, after a USB reconnection, or if you want to let a user select the correct port from a dashboard interface.",[15,6102,6103],{},"Each time a message is received, the node also outputs the current port configuration. This allows you to log or verify changes as part of your flow, making it easy to track what the system is doing behind the scenes.",[15,6105,6106,6107,6109],{},"In short, the ",[24,6108,5913],{}," node adds a layer of resilience and flexibility that is often essential in real-world deployments, where devices come and go, ports are never quite consistent, and downtime is not an option.",[48,6111,6113],{"id":6112},"key-takeaways","Key Takeaways",[15,6115,6116],{},"Manufacturing floors often bring together a mix of old and new machines. Among them, many still operate on traditional communication methods that are reliable but difficult to integrate with modern systems. These machines continue to perform their core functions well, but without connectivity, they remain isolated from digital workflows.",[15,6118,6119],{},"With FlowFuse and Node-RED, you can bridge that gap, bringing equipment online without changing or replacing existing hardware. From data collection to triggering actions and monitoring performance, your machines can become part of a connected and intelligent system.",[15,6121,6122,6123,6127,6128,6131],{},"Whether you're in textiles, precision engineering, or ",[29,6124,6126],{"href":6125},"\u002Findustries\u002Fautomotive\u002F","automotive manufacturing",", FlowFuse helps you unlock the full potential of your existing equipment. No rip-and-replace needed, just smarter connections. ",[29,6129,6130],{"href":106},"Get in touch with us"," and start building your serial integration flow today.",[782,6133,6134],{},"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 .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}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":458,"searchDepth":523,"depth":523,"links":6136},[6137,6142,6150],{"id":5122,"depth":491,"text":5123,"children":6138},[6139,6140,6141],{"id":5132,"depth":498,"text":5133},{"id":5178,"depth":498,"text":5179},{"id":5249,"depth":498,"text":5250},{"id":5279,"depth":491,"text":5280,"children":6143},[6144,6145,6146,6147,6148,6149],{"id":2951,"depth":498,"text":2952},{"id":5331,"depth":498,"text":5332},{"id":5450,"depth":498,"text":5451},{"id":5502,"depth":498,"text":5503},{"id":5813,"depth":498,"text":5814},{"id":5893,"depth":498,"text":5894},{"id":6112,"depth":491,"text":6113},"2025-07-09","Learn how to connect manufacturing equipment using serial interfaces like RS-232\u002F422\u002F485 in Node-RED with FlowFuse. Enable monitoring, data collection, and automation, no hardware changes required","blog\u002F2025\u002F07\u002Fimages\u002Fconnect-serial-port-node-red-ff.png","2026-06-03",{"keywords":6156,"excerpt":6157},"node-red, serial communication, rs232, rs485, rs422, modbus, industrial automation, flowfuse, legacy equipment, machine data collection, manufacturing connectivity, serial port integration, factory floor monitoring, serial devices, equipment integration",{"type":12,"value":6158},[6159],[15,6160,5112,6161,5116],{},[24,6162,5115],{},"\u002Fblog\u002F2025\u002F07\u002Fconnect-legacy-equipment-serial-flowfuse",{"title":5106,"description":6152},{"loc":6163},"blog\u002F2025\u002F07\u002Fconnect-legacy-equipment-serial-flowfuse","Learn how to bring serial-connected equipment online using Node-RED and FlowFuse",[826,827,6169],"how-to","Many factory machines communicate via RS-232, RS-422, or RS-485 serial interfaces and can be integrated with modern systems using Node-RED and FlowFuse without any hardware modifications. This guide covers serial communication fundamentals, installing the node-red-contrib-serialport nodes, and building flows to collect and monitor data from legacy equipment in real time.","Yqu_YEoJ5IZNNbdOoxMxpkuuP2iX4vxrWZW1rWoJgec",{"id":6173,"title":6174,"authors":6175,"body":6176,"cta":6661,"date":6665,"description":6666,"extension":802,"image":6667,"lastUpdated":6154,"meta":6668,"navigation":494,"path":6674,"seo":6675,"sitemap":6676,"stem":6677,"subtitle":6678,"tags":6679,"tldr":6681,"video":3,"__hash__":6682},"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":6177,"toc":6649},[6178,6181,6184,6188,6197,6200,6203,6212,6216,6219,6223,6250,6254,6257,6272,6280,6288,6297,6304,6312,6348,6351,6355,6358,6376,6384,6424,6428,6431,6441,6449,6465,6473,6531,6535,6538,6541,6573,6581,6609,6613],[15,6179,6180],{},"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,6182,6183],{},"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.",[190,6185,6187],{"id":6186},"why-bridge-opc-ua-to-mqtt","Why Bridge OPC UA to MQTT",[15,6189,6190,6194],{},[39,6191],{"alt":6192,"dataZoomable":458,"src":6193},"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",[44,6195,6196],{},"Diagram showing the data flow when bridging OPC UA to MQTT to enable communication between non-OPC UA compatible systems and devices.",[15,6198,6199],{},"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,6201,6202],{},"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,6204,6205,6207,6208,215],{},[24,6206,4230],{}," 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 ",[29,6209,6211],{"href":6210},"\u002Fblog\u002F2024\u002F07\u002Fbuilding-on-flowfuse-devices\u002F","Building on FlowFuse: Remote Device Monitoring",[48,6213,6215],{"id":6214},"bridging-opc-ua-data-to-mqtt-with-node-red","Bridging OPC UA Data to MQTT with Node-RED",[15,6217,6218],{},"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.",[190,6220,6222],{"id":6221},"prerequisite","Prerequisite",[56,6224,6225,6233,6236,6243],{},[59,6226,6227,6228,215],{},"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 ",[29,6229,6232],{"href":6230,"rel":6231},"https:\u002F\u002Fprosysopc.com\u002Fproducts\u002Fopc-ua-simulation-server\u002F",[33],"here",[59,6234,6235],{},"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).",[59,6237,6238,6242],{},[29,6239,2963],{"href":6240,"rel":6241},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002Fnode-red-contrib-opcua",[33],": install the node-red contrib package that will enable integration of opcua in Node-RED.",[59,6244,6245,6246,215],{},"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 ",[29,6247,6249],{"href":6248},"\u002Fblog\u002F2024\u002F10\u002Fannouncement-mqtt-broker\u002F","FlowFuse's MQTT Broker Announcement",[190,6251,6253],{"id":6252},"retrieving-data-from-the-opc-ua-server","Retrieving Data from the OPC UA Server",[15,6255,6256],{},"To begin retrieving data from your OPC UA server using Node-RED, follow these steps:",[120,6258,6259,6264],{},[59,6260,6261,6262,202],{},"Drag the ",[24,6263,302],{},[59,6265,6261,6266,6268,6269,6271],{},[24,6267,5527],{}," node onto the canvas and double-click on the node to open its configuration settings. Set the ",[89,6270,373],{}," to the node ID and datatype of the property you wish to read.",[15,6273,6274,6278],{},[39,6275],{"alt":6276,"dataZoomable":458,"src":6277},"(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",[44,6279,6276],{},[120,6281,6282],{"start":491},[59,6283,6261,6284,6287],{},[24,6285,6286],{},"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,6289,6290,6294],{},[39,6291],{"alt":6292,"dataZoomable":458,"src":6293},"Configuring opc-ua client node with the opc ua server endpoint","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopc-ua-config.png",[44,6295,6296],{},"Configuring opc-ua node with the opc ua server endpoint",[120,6298,6299],{"start":498},[59,6300,289,6301,6303],{},[24,6302,6286],{}," node settings, select the action type as \"READ.\" This instructs Node-RED to read data from the OPC UA server.",[15,6305,6306,6310],{},[39,6307],{"alt":6308,"dataZoomable":458,"src":6309},"Configuring OpcUa-Client node to select the read operation","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopc-ua-config2.png",[44,6311,6308],{},[120,6313,6314,6317,6322,6345],{"start":523},[59,6315,6316],{},"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.",[59,6318,6261,6319,6321],{},[24,6320,309],{}," node onto the canvas. The output will help you verify the data retrieved from the OPC UA server.",[59,6323,4579,6324,4582,6326,6328,6329,4582,6331,6333,6334,4582,6336,6338,6339,6341,6342,6344],{},[24,6325,302],{},[24,6327,5527],{}," node and the output of the ",[24,6330,5527],{},[24,6332,6286],{}," node. Then, connect the output of the ",[24,6335,6286],{},[24,6337,309],{}," node. This setup ensures that when the ",[24,6340,302],{}," node triggers, it sends data to the ",[24,6343,6286],{}," node, and the results are displayed in the Debug node.",[59,6346,6347],{},"Deploy the flow by clicking the \"Deploy\" button in the top right corner. To test the setup, press the Inject button.",[15,6349,6350],{},"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.",[190,6352,6354],{"id":6353},"transforming-and-aggregating-data","Transforming and Aggregating Data",[15,6356,6357],{},"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.",[120,6359,6360,6364],{},[59,6361,6261,6362,202],{},[24,6363,5527],{},[59,6365,6366,6367,6369,6370,4593,6372,6375],{},"Double-click on the node and set ",[89,6368,373],{}," to the name of the property you want to set for the retrieved data. In this context, set ",[89,6371,373],{},[89,6373,6374],{},"'cycle-time'",", which will be the key in the object that we will create.",[15,6377,6378,6381],{},[39,6379],{"alt":6380,"dataZoomable":458,"src":6277},"Setting the msg.topic with the Change node to retrieve data from the OPC UA server.",[44,6382,6383],{},"Setting the msg.topic with the change node to retrieve data from the OPC UA server.",[120,6385,6386,6401,6415,6421],{"start":498},[59,6387,6261,6388,6391,6392,6394,6395,6397,6398,6400],{},[24,6389,6390],{},"join"," node onto the canvas. Set the mode to manual, with the option to create ",[89,6393,324],{}," using the values of ",[89,6396,373],{}," as keys. Set the count to 3 and ensure that the interval for all of the ",[24,6399,302],{}," nodes triggering data retrieval is the same. This ensures that the data is collected and aggregated correctly at the same time.",[59,6402,4579,6403,6405,6406,6408,6409,6411,6412,6414],{},[24,6404,6286],{}," node (which retrieves the data) to the input of the ",[24,6407,5527],{}," node. For example, if I have set the ",[24,6410,5527],{}," node for the 'cycle-time' data property, connect it to the ",[24,6413,6286],{}," node that retrieves this data.",[59,6416,4579,6417,4582,6419,667],{},[24,6418,5527],{},[24,6420,6390],{},[59,6422,6423],{},"Repeat this process for all of your data properties.",[190,6425,6427],{"id":6426},"sending-data-to-the-mqtt-broker","Sending Data to the MQTT Broker",[15,6429,6430],{},"Now, in this section, we will show you how to send the collected data to an MQTT broker:",[120,6432,6433,6438],{},[59,6434,6261,6435,202],{},[24,6436,6437],{},"mqtt out",[59,6439,6440],{},"Double-click on it and configure it with your MQTT broker details.",[15,6442,6443,6447],{},[39,6444],{"alt":6445,"dataZoomable":458,"src":6446},"Configuring the mqtt out node with broker information","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-out-node-config.png",[44,6448,6445],{},[120,6450,6451,6456,6462],{"start":498},[59,6452,6453,6454,667],{},"Set the topic for your data in the ",[24,6455,6437],{},[59,6457,4579,6458,4582,6460,667],{},[24,6459,6390],{},[24,6461,6437],{},[59,6463,6464],{},"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,6466,6467,6471],{},[39,6468],{"alt":6469,"dataZoomable":458,"src":6470},"Image showing the successful bridging of OPC UA data to MQTT","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fopcua-to-mqtt.gif",[44,6472,6469],{},[15,6474,6475,6476,3059],{},"{% renderFlow %}\n",[462,6477,6478,6479,6481,6482,6484,6485,6487,6488,6490,6491,6494,6495,6498,6499,6502,6503,6505,6506,6508,6509,6511,6512,6515,6516,6519,6520,6523,6524,6526,6527],{},"{\"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\"],",[462,6480],{},"]},{\"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\":",[462,6483],{},"},{\"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\"],",[462,6486],{},"]},{\"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\"],",[462,6489],{},"]},{\"id\":\"f5fd1ffafdfe790f\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"Set the topic for the data\",\"rules\":",[462,6492,6493],{},"{\"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\":",[462,6496,6497],{},"{\"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\":",[462,6500,6501],{},"{\"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\":",[462,6504],{},"},{\"id\":\"55f43460af9601ec\",\"type\":\"comment\",\"z\":\"807758ec576fbfd8\",\"name\":\"Retrieving the data from mqtt\",\"info\":\"\",\"x\":320,\"y\":600,\"wires\":",[462,6507],{},"},{\"id\":\"628ab54495901021\",\"type\":\"comment\",\"z\":\"807758ec576fbfd8\",\"name\":\"Bridging OPC UA data to MQTT\",\"info\":\"\",\"x\":350,\"y\":240,\"wires\":",[462,6510],{},"},{\"id\":\"ce6b8a0e2c8a895d\",\"type\":\"change\",\"z\":\"807758ec576fbfd8\",\"name\":\"\",\"rules\":",[462,6513,6514],{},"{\"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\":",[462,6517,6518],{},"{\"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\":",[462,6521,6522],{},"{\"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\":",[462,6525,3287],{},",\"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\":\"",[29,6528,6530],{"rel":6529},[33],"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\":\"\"}",[48,6532,6534],{"id":6533},"bridging-mqtt-data-to-opc-ua","Bridging MQTT Data to OPC UA",[15,6536,6537],{},"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,6539,6540],{},"For example, an MES can send commands or configuration changes via MQTT, which then need to be applied to an OPC UA-controlled machine.",[120,6542,6543,6549,6557,6562],{},[59,6544,4393,6545,6548],{},[24,6546,6547],{},"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.",[59,6550,6261,6551,6553,6554,6556],{},[24,6552,5527],{}," node onto the canvas, Set the ",[89,6555,373],{}," to the node ID and datatype of the property you wish to update.",[59,6558,299,6559,6561],{},[24,6560,6286],{}," node to the canvas and configure it with your OPC UA server. Set the action type to \"WRITE\" to send the received data.",[59,6563,4579,6564,4582,6566,6568,6569,4582,6571,667],{},[24,6565,6547],{},[24,6567,5527],{}," node, and the output of the ",[24,6570,5527],{},[24,6572,6286],{},[15,6574,6575,6579],{},[39,6576],{"alt":6577,"dataZoomable":458,"src":6578},"Image showing the successful bridging of MQTT data to OPC UA","\u002Fblog\u002F2024\u002F08\u002Fimages\u002Fmqtt-to-opcua.gif",[44,6580,6469],{},[15,6582,6475,6583,3059],{},[462,6584,6585,6586,6588,6589,6591,6592,6595,6596,6598,6599,6602,6603,6605,6606],{},"{\"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\":[[],",[462,6587],{},"]},{\"id\":\"628ab54495901021\",\"type\":\"comment\",\"z\":\"FFF0000000000001\",\"name\":\"Bridging MQTT to OPC UA\",\"info\":\"\",\"x\":510,\"y\":140,\"wires\":",[462,6590],{},"},{\"id\":\"ce6b8a0e2c8a895d\",\"type\":\"change\",\"z\":\"FFF0000000000001\",\"name\":\"\",\"rules\":",[462,6593,6594],{},"{\"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\":",[462,6597],{},"},{\"id\":\"8e339e511c573905\",\"type\":\"inject\",\"z\":\"FFF0000000000001\",\"name\":\"\",\"props\":",[462,6600,6601],{},"{\"p\":\"payload\"}",",\"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\":",[462,6604],{},"},{\"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\":\"",[29,6607,6530],{"rel":6608},[33],[190,6610,6612],{"id":6611},"up-next","Up Next",[56,6614,6615,6622,6628,6635,6642],{},[59,6616,6617,6621],{},[29,6618,6620],{"href":6619},"\u002Fnode-red\u002Fprotocol\u002Fmqtt\u002F","Using MQTT with Node-RED","\nLearn how to integrate MQTT with Node-RED to enhance your IoT solutions with real-time data messaging.",[59,6623,6624,6627],{},[29,6625,6626],{"href":3016},"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.",[59,6629,6630,6634],{},[29,6631,6633],{"href":6632},"\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.",[59,6636,6637,6641],{},[29,6638,6640],{"href":6639},"\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.",[59,6643,6644,6648],{},[29,6645,6647],{"href":6646},"\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":458,"searchDepth":523,"depth":523,"links":6650},[6651,6652,6658],{"id":6186,"depth":498,"text":6187},{"id":6214,"depth":491,"text":6215,"children":6653},[6654,6655,6656,6657],{"id":6221,"depth":498,"text":6222},{"id":6252,"depth":498,"text":6253},{"id":6353,"depth":498,"text":6354},{"id":6426,"depth":498,"text":6427},{"id":6533,"depth":491,"text":6534,"children":6659},[6660],{"id":6611,"depth":498,"text":6612},{"type":6662,"title":6663,"description":6664},"sign-up","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":6669,"excerpt":6670},"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":6671},[6672],[15,6673,6180],{},"\u002Fblog\u002F2024\u002F08\u002Fopc-ua-to-mqtt-with-node-red",{"title":6174,"description":6666},{"loc":6674},"blog\u002F2024\u002F08\u002Fopc-ua-to-mqtt-with-node-red","Connecting OPC UA Data Streams to MQTT Brokers for Enhanced IoT Communication and Monitoring",[1696,6680,2692,827,6169],"node-red","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":6684,"title":6685,"authors":6686,"body":6688,"cta":3,"date":7088,"description":7089,"extension":802,"image":7090,"lastUpdated":3,"meta":7091,"navigation":494,"path":7096,"seo":7097,"sitemap":7098,"stem":7099,"subtitle":7100,"tags":7101,"tldr":3,"video":3,"__hash__":7102},"blog\u002Fblog\u002F2024\u002F02\u002Fconnect-node-red-to-kepware-opc.md","Connect Node-RED to KepserverEX OPC server.",[6687],"grey-dziuba",{"type":12,"value":6689,"toc":7074},[6690,6693,6697,6706,6710,6722,6726,6730,6740,6746,6749,6755,6764,6769,6773,6780,6783,6791,6801,6807,6834,6841,6847,6851,6878,6884,6893,6899,6915,6921,6925,6932,6938,6942,6945,6951,6954,6960,6978,6981,6987,6991,7002,7009,7015,7018,7024,7031,7046,7056,7060],[15,6691,6692],{},"KepserverEX, often referred to as Kepware, is an OPC server that has been the important tool many manufacturing companies have used on their digital transformation journey.  It plays an important role for many to extract data from PLCs, Programmable Logic Controllers, without having to directly interact with them.",[48,6694,6696],{"id":6695},"ptcs-kepserverex","PTC's KepserverEX",[15,6698,6699,6700,6705],{},"PTC's ",[29,6701,6704],{"href":6702,"rel":6703},"https:\u002F\u002Fwww.ptc.com\u002Fen\u002Fproducts\u002Fkepware\u002Fkepserverex-ppc",[33],"KEPServerEX"," is a versatile connectivity platform designed to securely manage, monitor, and control diverse automation devices and software applications. Central to its functionality is the OPC standard, which enables universal communication across industrial hardware and software, facilitating data exchange. This makes KEPServerEX particularly valuable in a variety of use cases, such as real-time data monitoring, machine-to-machine (M2M) communication, and industrial Internet of Things (IIoT) applications. It serves as a critical bridge in the automation and controls engineering space, offering a robust solution for integrating disparate systems, thereby enhancing operational efficiency and enabling data-driven decision-making. Integrating KEPServerEX with Node-RED extends this functionality, by allowing bidirectional communication for sending, storing, and or manipulating data.",[190,6707,6709],{"id":6708},"scope","Scope",[15,6711,6712,6713,6716,6717,6721],{},"The goal of this blog is for a quick start guide on the configuration for collecting data from a KepserverEX OPC server.  We are going to be leveraging the ",[29,6714,2963],{"href":6240,"rel":6715},[33]," node.  We will assume that you already have ",[29,6718,6720],{"href":6702,"rel":6719},[33],"KepserverEX"," install and ready for the integration. We will be using Basic256Sha256 security in this guide with anonymous authentication.  Assumptions of the installation include allowing Default configuration of the installation of KepserverEX 6.15 and allowing dynamic tag addressing.",[190,6723,6725],{"id":6724},"configure-connection-from-node-red-to-kepserver","Configure Connection from Node-RED to Kepserver",[4341,6727,6729],{"id":6728},"step-1-kepserverex","Step 1: KepserverEX",[15,6731,6732,6733,6736,6737],{},"The first thing we need to do is check our ",[24,6734,6735],{},"OPC UA Configuration Manager"," for the security requirements for our environment.  In the tray at the bottom, click on the KepserverEX symbol and select ",[24,6738,6739],{},"OPC UA Configuration",[15,6741,6742],{},[39,6743],{"alt":6744,"src":6745},"kepware tray","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fkepserverex-tray.png",[15,6747,6748],{},"If your Node-RED instance lives on the same server that your KepserverEX is on, pick accordingly or click add if you need to define by ip address. This is for setting different credential requirements for localhost vs remote host access.  Also note, that if you have multiple network adapters, make sure to select the adapter that is in use.",[15,6750,6751],{},[39,6752],{"alt":6753,"src":6754},"kepware endpoint definition","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fkep-endpoint-definition.png",[15,6756,6757,6758,6760,6761,215],{},"We are testing locally on the server, so we will use the one selected for loopback addressing.  We will be leaving the OPC server port as default and select ",[24,6759,1152],{}," with ",[24,6762,6763],{},"Sign and Encrypt",[15,6765,236,6766,215],{},[24,6767,6768],{},"OK",[4341,6770,6772],{"id":6771},"step-2-node-red","Step 2:  Node-RED",[15,6774,6775,6776,6779],{},"Next, navigate to your Node-RED instance and install the ",[29,6777,2963],{"href":6240,"rel":6778},[33]," node if you haven't already done so.",[15,6781,6782],{},"Import the flow below into your Node-RED environment.",[6784,6785],"iframe",{"width":6786,"height":6787,"src":6788,"allow":6789,"style":6790},"100%","225px","https:\u002F\u002Fflows.nodered.org\u002Fflow\u002F04a84fe5b0db7cda9e74ba811e7b0ca5\u002Fshare?height=250","clipboard-read; clipboard-write","border: none;",[15,6792,6793,6794,6796,6797,6800],{},"Next, let's configure the ",[24,6795,4396],{},".  Click the ",[24,6798,6799],{},"pencil"," to add a new OPCUA-Endpoint.",[15,6802,6803],{},[39,6804],{"alt":6805,"src":6806},"kepware node-red encrypted opc ua node","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fopcua-endpoint-node-red-encrypted.png",[15,6808,6809,6810,6813,6814,6817,6818,6820,6821,6824,6825,6827,6828,240,6831,215],{},"For the endpoint, ",[24,6811,6812],{},"copy"," the endpoint definition from the KepserverEX OPC UA Configuration Manager.  In our example, it is ",[89,6815,6816],{},"opc.tcp:\u002F\u002F127.0.0.1:49320",", and paste it into the Endpoint.  For SecurityPolicy select ",[24,6819,1152],{},". For SecurityMode, select ",[24,6822,6823],{},"Sign&Encrypt",".  Lastly, we will be selecting ",[24,6826,1195],{},".  Click ",[24,6829,6830],{},"Update",[24,6832,6833],{},"Deploy",[15,6835,6836,6837,6840],{},"Trigger the flow by ",[24,6838,6839],{},"clicking"," on the inject node.  The server may not connect at this time, and it is expected.",[15,6842,6843],{},[39,6844],{"alt":6845,"src":6846},"kepware node-red invalid endpoint","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fnode-red-opc-ua-invalid-endpoint.png",[4341,6848,6850],{"id":6849},"step-3-kepserverex","Step 3: KepserverEX",[15,6852,6853,6854,6857,6858,6861,6862,6865,6866,6868,6869,6872,6873,6827,6876,215],{},"Moving back over to KepserverEX,  Click on the tray again in the bottom of the screen and select ",[24,6855,6856],{},"Configuration",", then select ",[24,6859,6860],{},"Edit"," from the file menu, then ",[24,6863,6864],{},"Properties",".  Next, Select ",[24,6867,2624],{}," and ensure that ",[24,6870,6871],{},"Allow Anonymous login"," is set to ",[24,6874,6875],{},"Yes",[24,6877,6768],{},[15,6879,6880],{},[39,6881],{"alt":6882,"src":6883},"kepware node-red anonymous login","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fnode-red-kepware-anonymous-login.png",[15,6885,6886,6887,6889,6890,135],{},"Select the tray at the bottom of the screen again, and select ",[24,6888,6739],{},". Select the ",[24,6891,6892],{},"Trusted Clients",[15,6894,6895],{},[39,6896],{"alt":6897,"src":6898},"kepware node-red trusted client before","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fkepserverex-trusted-client-before.png",[15,6900,6901,6902,6905,6906,6909,6910],{},"Now select the ",[24,6903,6904],{},"NodeOPCUA-Client"," and then ",[24,6907,6908],{},"click"," Trust.  ",[44,6911,6912],{},[24,6913,6914],{},"If you don't have the client option, trigger the inject node again from the Node-RED flow and check the logs",[15,6916,6917],{},[39,6918],{"alt":6919,"src":6920},"kepware node-red trusted client after","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fkepserverex-trusted-client-after.png",[4341,6922,6924],{"id":6923},"step-4-node-red","Step 4: Node-RED",[15,6926,6927,6928,6931],{},"Lastly,  Navigate back to Node-RED and ",[24,6929,6930],{},"trigger"," the inject node.  This node will now browse the project from the KepserverEX and display all of the existing tags.",[15,6933,6934],{},[39,6935],{"alt":6936,"src":6937},"kepware node-red browsed tags","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fkepware-opc-browsed-tags-node-red.png",[190,6939,6941],{"id":6940},"read-tags","Read Tags",[15,6943,6944],{},"We will be leveraging the default Simulated Examples for reading tags from KepserverEX.  Let's move on to the next set of flows.",[15,6946,6947],{},[39,6948],{"alt":6949,"src":6950},"kepware node-red read tags","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fnode-red-kepware-read-tag.png",[15,6952,6953],{},"Edit the OPCUa-Item node and note the item.",[453,6955,6958],{"className":6956,"code":6957,"language":2221},[2219],"ns=2;s=Simulation Examples.Functions.Ramp1\n",[89,6959,6957],{"__ignoreMap":458},[15,6961,6962,6963,6966,6967,6970,6971,6974,6975,6977],{},"Let's break down the syntax,  ns stands for namespace that will coincide with the project.  In this case, it is namespace 2.  Once the namespace has been selected, we are use ",[24,6964,6965],{},"Dynamic Addressing"," to select the tag through the variable ",[24,6968,6969],{},"s",", which stands for string type of NodeId. ",[24,6972,6973],{},"Click"," Done.  Now let's ",[24,6976,6930],{}," the Read inject node and view the debug output.",[15,6979,6980],{},"The debug node is set to show a complete msg object.  Note the payload as the value of the variable.",[15,6982,6983],{},[39,6984],{"alt":6985,"src":6986},"kepware node-red read tags output","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fnode-red-debug-output-opc.png",[190,6988,6990],{"id":6989},"write-tag","Write Tag",[15,6992,6993,6994,6997,6998,7001],{},"Writing a tag is a similar process.  The only difference is that a variable is set in the ",[24,6995,6996],{},"OPCUa-Item"," node and the ",[24,6999,7000],{},"OPCUa-Client"," action is set to Write.",[15,7003,7004,7005,7008],{},"In this example, we created a new variable in KepserverEX under ",[24,7006,7007],{},"Simulation Examples > Functions"," called myInt of Date Type Long.",[15,7010,7011],{},[39,7012],{"alt":7013,"src":7014},"kepware node-red write tags","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fnode-red-kepware-write-tag.png",[15,7016,7017],{},"View the OPCUa-Item node and note the item.",[453,7019,7022],{"className":7020,"code":7021,"language":2221},[2219],"ns=2;s=Simulation Examples.Functions.myInt\n",[89,7023,7021],{"__ignoreMap":458},[15,7025,7026,7028,7029],{},[24,7027,6973],{}," Done and ",[24,7030,6833],{},[15,7032,7033,7034,7037,7038,7041,7042,7045],{},"Open up the ",[24,7035,7036],{},"Quick Client"," within KepserverEX and navigate to the address of ",[24,7039,7040],{},"Simulation Examples.Functions"," and look for myInt.  It should by default, be 0.  ",[24,7043,7044],{},"Trigger"," the inject node within Node-RED to see the Value change within the Quick Client.",[15,7047,7048,7052],{},[39,7049],{"alt":7050,"src":7051},"kepware node-red write tags output","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fnode-red-debug-output-write-opc.png",[39,7053],{"alt":7054,"src":7055},"kepware node-red quick client","\u002Fblog\u002F2024\u002F02\u002Fimages\u002Fkepware-quick-client.png",[190,7057,7059],{"id":7058},"conclusion","Conclusion",[15,7061,7062,7063,7067,7068,7073],{},"This guide was designed to help you easily connect your Node-RED instance to KepserverEX with security.  For more examples of how to do more advanced configuration, please watch the past ",[29,7064,7066],{"href":7065},"\u002Fwebinars\u002F2023\u002Fgetting-started-opcua-node-red\u002F","webinar"," going over these ",[29,7069,7072],{"href":7070,"rel":7071},"https:\u002F\u002Fgithub.com\u002Fmikakaraila\u002Fnode-red-contrib-opcua\u002Ftree\u002Fmaster\u002Fexamples",[33],"examples"," in detail.",{"title":458,"searchDepth":523,"depth":523,"links":7075},[7076],{"id":6695,"depth":491,"text":6696,"children":7077},[7078,7079,7085,7086,7087],{"id":6708,"depth":498,"text":6709},{"id":6724,"depth":498,"text":6725,"children":7080},[7081,7082,7083,7084],{"id":6728,"depth":523,"text":6729},{"id":6771,"depth":523,"text":6772},{"id":6849,"depth":523,"text":6850},{"id":6923,"depth":523,"text":6924},{"id":6940,"depth":498,"text":6941},{"id":6989,"depth":498,"text":6990},{"id":7058,"depth":498,"text":7059},"2024-02-12","Follow a step-by-step guide to seamlessly integrate Node-RED with PTC's Kepware OPC server, enabling efficient data extraction from PLCs.","blog\u002F2024\u002F02\u002Fimages\u002Fnode-red-to-kepware.png",{"excerpt":7092},{"type":12,"value":7093},[7094],[15,7095,6692],{},"\u002Fblog\u002F2024\u002F02\u002Fconnect-node-red-to-kepware-opc",{"title":6685,"description":7089},{"loc":7096},"blog\u002F2024\u002F02\u002Fconnect-node-red-to-kepware-opc","Step by step guide to connect to PTC's Kepware OPC server.",[1696,826,827],"QvoiQtUHBurcwXXfsWgu4r32ilUdFO86uBnbj5mFQY8",{"id":7104,"title":7105,"authors":7106,"body":7108,"cta":8512,"date":8515,"description":8516,"extension":802,"image":8517,"lastUpdated":6154,"meta":8518,"navigation":494,"path":8528,"seo":8529,"sitemap":8530,"stem":8531,"subtitle":8532,"tags":8533,"tldr":8534,"video":3,"__hash__":8535},"blog\u002Fblog\u002F2023\u002F07\u002Fhow-to-build-a-opc-client-dashboard-in-node-red.md","How to Build an OPC UA Client Dashboard in Node-RED - Part 3 (2026)",[7107],"richard-meyer",{"type":12,"value":7109,"toc":8501},[7110,7121,7129,7132,7136,7143,7164,7167,7174,7178,7190,7193,7199,7206,7224,7227,7231,7234,7248,7251,7255,7258,7264,7267,7412,7418,7424,7435,7442,7448,7451,7457,7460,7466,7484,7490,7496,7502,7515,7534,7537,7542,7545,7555,7559,7562,7569,7791,7800,7810,7828,7847,7858,7865,7884,7891,7897,7904,7911,7914,7920,7924,7927,7934,7960,7976,7979,7993,8003,8016,8033,8036,8042,8046,8049,8055,8115,8129,8145,8160,8167,8181,8184,8187,8193,8197,8200,8207,8220,8222,8225,8228,8231],[15,7111,7112,7113,7116,7117,7120],{},"This article is the third and final part of our OPC UA content series. In the ",[29,7114,7115],{"href":6639},"first article",", we cover some OPC UA fundamentals and walk through an example OPC UA Server flow. In the ",[29,7118,7119],{"href":6632},"second article",", we built a SSL-secured OPC UA server using data from an Allen Bradley PLC as a source.\nIn this article, we show how to build an OPC Client in Node-RED that communicates with a 3rd party OPC UA Server and utilizes an interactive dashboard.",[15,7122,7123,7124,7128],{},"This article will requires the ",[29,7125,7127],{"href":6230,"rel":7126},[33],"Prosys OPC UA Simulation Server",", an application designed for testing OPC UA client applications and learning the technology.  It’s a free cross-platform application that supports Windows, Linux, and MacOS.  This article will use the Windows version.",[15,7130,7131],{},"Note: full source code for the OPC Client Dashboard is included at the end of the article.",[48,7133,7135],{"id":7134},"custom-nodes-used-assumptions","Custom Nodes Used & Assumptions",[15,7137,7138,7139,7142],{},"Several custom nodes are required in order to properly deploy this flow.  For more detailed information on how to install a custom node, follow the instructions from an ",[29,7140,7141],{"href":6646},"earlier article"," where the process on installing custom nodes is explained in detail.",[56,7144,7145,7152,7157],{},[59,7146,7147],{},[29,7148,7151],{"href":7149,"rel":7150},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002F@flowfuse\u002Fnode-red-dashboard",[33],"@flowfuse\u002Fnode-red-dashboard",[59,7153,7154],{},[29,7155,2963],{"href":6240,"rel":7156},[33],[59,7158,7159],{},[29,7160,7163],{"href":7161,"rel":7162},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002F@flowfuse\u002Fnode-red-dashboard-2-ui-led",[33],"@flowfuse\u002Fnode-red-dashboard-2-ui-led",[15,7165,7166],{},"As this is not a production application, no security will be utilized, and it is assumed that the OPC UA Server is running on the same network as the Node-RED OPC Client.",[15,7168,7169,7170,215],{},"Is it also assumed that the end user of this article has familiarization with dashboards.  There are many dashboard basic guides available on our FlowFuse website, For more infomation go to ",[29,7171,7173],{"href":7172},"\u002Fblog\u002Fdashboard\u002F","Node-RED Dashboard 2.0 guides",[48,7175,7177],{"id":7176},"install-and-deploy-the-prosys-opc-ua-simulation-server","Install and Deploy the Prosys OPC UA Simulation Server",[15,7179,7180,7181,7186,7187,215],{},"The Prosys OPC UA Simulation Server is ",[29,7182,7185],{"href":7183,"rel":7184},"https:\u002F\u002Fprosysopc.com\u002Fproducts\u002Fopc-ua-simulation-server\u002Fevaluate\u002F",[33],"free to download",", but requires a sign-up process.  Download and install the server, then run the application.  Once the application is started, the first thing you should do is go to ",[89,7188,7189],{},"options -> switch to expert mode",[15,7191,7192],{},"This will give us access to the address space tab, which we will need to develop our client application in Node-RED.",[15,7194,7195],{},[39,7196],{"alt":7197,"dataZoomable":458,"src":7198},"expert-mode.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fexpert-mode.png",[15,7200,7201,7202,7205],{},"When the application is run, an endpoint url will be displayed on the ",[89,7203,7204],{},"status"," tab, along with an indication that the server is currently running.",[15,7207,7208,7212,7213,7216,7217,7220,7221,215],{},[39,7209],{"alt":7210,"dataZoomable":458,"src":7211},"opc-endpoint-url.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopc-endpoint-url.png","\nCopy the connection endpoint, but be warned that you will likely need to replace the computer name (in my case ",[89,7214,7215],{},"DESKTOP-0K0483A",", with the actual IP address of the machine running the server.  The IP address of the machine on my local network is ",[89,7218,7219],{},"192.168.0.141",", which changes my UA TCP endpoint address to ",[89,7222,7223],{},"opc.tcp:\u002F\u002F192.168.0.141:53530\u002FOPCUA\u002FSimulationServer",[15,7225,7226],{},"Now the simulation server is set up and we are ready to start developing the OPC Client application.",[48,7228,7230],{"id":7229},"objectives-of-the-node-red-opc-client-dashboard-application","Objectives of the Node-RED OPC Client Dashboard Application",[15,7232,7233],{},"The goal is not to develop a production-level application, rather, it’s to show a variety of features that one can utilize to demonstrate common OPC UA Client application capabilities in Node-RED, while also demonstrating a variety of methods to visualize the results in a dashboard.  There are 4 main objectives of the Node-RED OPC Client Dashboard application. They are:",[120,7235,7236,7239,7242,7245],{},[59,7237,7238],{},"Browse hierarchical server address space structure & display on a dashboard",[59,7240,7241],{},"Read OPC UA values from various namespaces, showing a variety of datatypes and different ways they can be visualized",[59,7243,7244],{},"Write OPC UA values back to the OPC UA server directly from the OPC UA Client dashboard",[59,7246,7247],{},"Read alarms & events from the OPC UA Server and display them on the dashboard",[15,7249,7250],{},"Rather than building the flow step-by-step, the flow source code will be presented for each objective, and a the flow will be explained so that it is understood what is happening in each section of code.",[48,7252,7254],{"id":7253},"browse-hierarchical-server-address-space-structure-with-opc-ua-browser-node","Browse Hierarchical Server Address Space Structure With OPC UA Browser Node",[15,7256,7257],{},"The first flow will browse the hierarchical OPC UA Server address space structure and display it on the dashboard.",[15,7259,7260],{},[39,7261],{"alt":7262,"dataZoomable":458,"src":7263},"image-20230727-085611.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fimage-20230727-085611.png",[15,7265,7266],{},"You can import this flow into Node-RED using the code below:",[15,7268,6475,7269,3059],{},[462,7270,7271,7272,7275,7276,7278,7279,7281,7282,7292,7293,7295,7296,7304,7305,7313,7314,7316,7317,7320,7321,7329,7330,7338,7339,7346,7347,7350,7351,7353,7354,7356,7357,7359,7360,7372,7373,7381,7382,7391,7392,7397,7398,7402,7403,7407,7408,7411],{},"{\"id\":\"ca62be3e01388319\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Browse Hierarchical Address Space Structure & Display on Dashboard\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,7273,7274],{},"\"6b17b2da2b942bb4\",\"61797eccf2785257\",\"4d92d940177b6ee3\",\"68a113d5893b7c01\",\"d0c969b6a59fac3a\",\"639da01fc957e547\",\"29437ca7222d9a64\",\"49983d5da0958bf2\",\"49040d0cf1144f0a\",\"e7c55f412ef86543\",\"de21b7ad98a05833\",\"2d56e9a431c21a3b\",\"ac95bd0e2b304eec\",\"6fdabcc2950ccf4e\",\"1c49fa5142d2cf17\",\"335878527020598c\",\"7b208f2e8cba6205\",\"52dd2e5dcddad58f\",\"a5acdccfd2033aec\",\"157322c9c360446d\",\"78a012e5db377fd9\"",",\"x\":94,\"y\":139,\"w\":1172,\"h\":422},{\"id\":\"6b17b2da2b942bb4\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,7277],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":550,\"y\":280,\"wires\":[[\"4d92d940177b6ee3\",\"d0c969b6a59fac3a\",\"639da01fc957e547\"]]},{\"id\":\"61797eccf2785257\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Get Base Folder Structure\",\"props\":",[462,7280,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":true,\"onceDelay\":\"0.3\",\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":280,\"y\":280,\"wires\":[[\"6b17b2da2b942bb4\"]]},{\"id\":\"4d92d940177b6ee3\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Simulation Folder\",\"rules\":",[462,7283,7284,7285,7288,7289,7291],{},"{\"t\":\"set\",\"p\":\"Objects.Simulation.nodeId\",\"pt\":\"flow\",\"to\":\"payload",[462,7286,7287],{},"2",".item.nodeId\",\"tot\":\"msg\"},{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"payload",[462,7290,7287],{},".item.browseName.name\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":830,\"y\":220,\"wires\":[[\"335878527020598c\"]]},{\"id\":\"68a113d5893b7c01\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Display on Dashboard\",\"info\":\"\",\"x\":1140,\"y\":180,\"wires\":",[462,7294],{},"},{\"id\":\"d0c969b6a59fac3a\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"MyObjects Folder\",\"rules\":",[462,7297,7298,7299,7288,7302,7291],{},"{\"t\":\"set\",\"p\":\"Objects.MyObjects.nodeId\",\"pt\":\"flow\",\"to\":\"payload",[462,7300,7301],{},"4",[462,7303,7301],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":830,\"y\":340,\"wires\":[[\"52dd2e5dcddad58f\"]]},{\"id\":\"639da01fc957e547\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"StaticData Folder\",\"rules\":",[462,7306,7307,7308,7288,7311,7291],{},"{\"t\":\"set\",\"p\":\"Objects.StaticData.nodeId\",\"pt\":\"flow\",\"to\":\"payload",[462,7309,7310],{},"3",[462,7312,7310],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":830,\"y\":280,\"wires\":[[\"7b208f2e8cba6205\"]]},{\"id\":\"29437ca7222d9a64\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,7315],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":550,\"y\":440,\"wires\":[[\"49040d0cf1144f0a\",\"e7c55f412ef86543\"]]},{\"id\":\"49983d5da0958bf2\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Get StaticData Folder Structure\",\"props\":",[462,7318,7319],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"v\":\"Objects.StaticData.nodeId\",\"vt\":\"flow\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":true,\"onceDelay\":\"0.3\",\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":270,\"y\":440,\"wires\":[[\"29437ca7222d9a64\"]]},{\"id\":\"49040d0cf1144f0a\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"AnalogItemArrays Folder\",\"rules\":",[462,7322,7323,7324,7288,7327,7291],{},"{\"t\":\"set\",\"p\":\"Objects.StaticData.AnalogItemArrays.nodeId\",\"pt\":\"flow\",\"to\":\"payload",[462,7325,7326],{},"1",[462,7328,7326],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":850,\"y\":460,\"wires\":[[\"157322c9c360446d\"]]},{\"id\":\"e7c55f412ef86543\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"StaticArrayVariables Folder\",\"rules\":",[462,7331,7332,7333,7288,7336,7291],{},"{\"t\":\"set\",\"p\":\"Objects.StaticData.StaticArrayVariables.nodeId\",\"pt\":\"flow\",\"to\":\"payload",[462,7334,7335],{},"6",[462,7337,7335],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":860,\"y\":400,\"wires\":[[\"a5acdccfd2033aec\"]]},{\"id\":\"de21b7ad98a05833\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"MyDevice Object\",\"rules\":",[462,7340,7341,7342,7288,7344,7291],{},"{\"t\":\"set\",\"p\":\"Objects.MyObjects.MyDevice.nodeId\",\"pt\":\"flow\",\"to\":\"payload",[462,7343,366],{},[462,7345,366],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":830,\"y\":520,\"wires\":[[\"78a012e5db377fd9\"]]},{\"id\":\"2d56e9a431c21a3b\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Get MyObjects Object Structure\",\"props\":",[462,7348,7349],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"v\":\"Objects.MyObjects.nodeId\",\"vt\":\"flow\"}",",\"repeat\":\"\",\"crontab\":\"\",\"once\":true,\"onceDelay\":\"0.5\",\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":270,\"y\":520,\"wires\":[[\"ac95bd0e2b304eec\"]]},{\"id\":\"ac95bd0e2b304eec\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,7352],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":550,\"y\":520,\"wires\":[[\"de21b7ad98a05833\"]]},{\"id\":\"6fdabcc2950ccf4e\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Store & Parse nodeId & browseName\",\"info\":\"\",\"x\":850,\"y\":180,\"wires\":",[462,7355],{},"},{\"id\":\"1c49fa5142d2cf17\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"name\":\"Global Address Space Folder Browse\",\"info\":\"\",\"x\":410,\"y\":220,\"wires\":",[462,7358],{},"},{\"id\":\"335878527020598c\",\"type\":\"ui-template\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"group\":\"ef9998baf5f61e8a\",\"page\":\"\",\"ui\":\"\",\"name\":\"Simulation\",\"order\":1,\"width\":0,\"height\":0,\"head\":\"\",\"format\":\"",[7361,7362,7363,7364,7367,7368,7371],"template",{},"\\n    \u003Cdiv class=\"inline-content\">\\n        ",[15,7365,7366],{},"Namespace 3","\\n        \u003Cv-icon color=\"black\" icon=\"mdi-folder\" size=\"large\"> ",[7369,7370],"binding",{"value":324},"\\n    \\n","\",\"storeOutMessages\":true,\"passthru\":true,\"resendOnRefresh\":true,\"templateScope\":\"local\",\"className\":\"\",\"x\":1110,\"y\":220,\"wires\":[[]]},{\"id\":\"7b208f2e8cba6205\",\"type\":\"ui-template\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"group\":\"ef9998baf5f61e8a\",\"page\":\"\",\"ui\":\"\",\"name\":\"StaticData\",\"order\":2,\"width\":0,\"height\":0,\"head\":\"\",\"format\":\"",[7361,7374,7363,7375,7378,7379,7371],{},[15,7376,7377],{},"Namespace 5","\\n        \u003Cv-icon color=\"black\" icon=\"mdi-folder-arrow-down\" size=\"large\"> ",[7369,7380],{"value":324},"\",\"storeOutMessages\":true,\"passthru\":true,\"resendOnRefresh\":true,\"templateScope\":\"local\",\"className\":\"\",\"x\":1110,\"y\":280,\"wires\":[[]]},{\"id\":\"52dd2e5dcddad58f\",\"type\":\"ui-template\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"group\":\"ef9998baf5f61e8a\",\"page\":\"\",\"ui\":\"\",\"name\":\"MyObjects\",\"order\":5,\"width\":0,\"height\":0,\"head\":\"\",\"format\":\"",[7361,7383,7384,7385,7388,7389,7371],{},"\\n    ",[15,7386,7387],{},"Namespace 6","\\n    \u003Cdiv class=\"inline-content\">\\n        \u003Cv-icon color=\"black\" icon=\"mdi-folder\" size=\"large\"> ",[7369,7390],{"value":324},"\",\"storeOutMessages\":true,\"passthru\":true,\"resendOnRefresh\":true,\"templateScope\":\"local\",\"className\":\"\",\"x\":1110,\"y\":340,\"wires\":[[]]},{\"id\":\"a5acdccfd2033aec\",\"type\":\"ui-template\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"group\":\"ef9998baf5f61e8a\",\"page\":\"\",\"ui\":\"\",\"name\":\"StaticArrayVariables\",\"order\":3,\"width\":0,\"height\":0,\"head\":\"\",\"format\":\"",[7361,7393,7394,7395,7371],{},"\\n    \u003Cdiv class=\"d-flex align-center ml-3\">\\n        \u003Cv-icon color=\"black\" icon=\"mdi-folder\" size=\"large\"> ",[7369,7396],{"value":324},"\",\"storeOutMessages\":true,\"passthru\":true,\"resendOnRefresh\":true,\"templateScope\":\"local\",\"className\":\"\",\"x\":1140,\"y\":400,\"wires\":[[]]},{\"id\":\"157322c9c360446d\",\"type\":\"ui-template\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"group\":\"ef9998baf5f61e8a\",\"page\":\"\",\"ui\":\"\",\"name\":\"AnalogItemArrays\",\"order\":4,\"width\":0,\"height\":0,\"head\":\"\",\"format\":\"",[7361,7399,7394,7400,7371],{},[7369,7401],{"value":324},"\",\"storeOutMessages\":true,\"passthru\":true,\"resendOnRefresh\":true,\"templateScope\":\"local\",\"className\":\"\",\"x\":1130,\"y\":460,\"wires\":[[]]},{\"id\":\"78a012e5db377fd9\",\"type\":\"ui-template\",\"z\":\"5b972161c4e0464e\",\"g\":\"ca62be3e01388319\",\"group\":\"ef9998baf5f61e8a\",\"page\":\"\",\"ui\":\"\",\"name\":\"MyDevice\",\"order\":6,\"width\":0,\"height\":0,\"head\":\"\",\"format\":\"",[7361,7404,7394,7405,7371],{},[7369,7406],{"value":324},"\",\"storeOutMessages\":true,\"passthru\":true,\"resendOnRefresh\":true,\"templateScope\":\"local\",\"className\":\"\",\"x\":1100,\"y\":520,\"wires\":[[]]},{\"id\":\"53f4394dbf12c6b7\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"opc.tcp:\u002F\u002F192.168.56.1:53530\u002FOPCUA\u002FSimulationServer\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"},{\"id\":\"ef9998baf5f61e8a\",\"type\":\"ui-group\",\"name\":\" Address Space Folder Structure\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"2\",\"height\":\"1\",\"order\":1,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"44d3feb2a1143d7b\",\"type\":\"ui-page\",\"name\":\"OPC UA\",\"ui\":\"5355e0c476f9da3b\",\"path\":\"\u002Fopcua\",\"icon\":\"home\",\"layout\":\"grid\",\"theme\":\"61eee6fc60281b9b\",\"order\":1,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"5355e0c476f9da3b\",\"type\":\"ui-base\",\"name\":\"My Dashboard\",\"path\":\"\u002Fdashboard\",\"includeClientData\":true,\"acceptsClientConfig\":",[462,7409,7410],{},"\"ui-notification\",\"ui-control\"",",\"showPathInSidebar\":false,\"navigationStyle\":\"default\"},{\"id\":\"61eee6fc60281b9b\",\"type\":\"ui-theme\",\"name\":\"Default Theme\",\"colors\":{\"surface\":\"#0094ce\",\"primary\":\"#0094ce\",\"bgPage\":\"#eeeeee\",\"groupBg\":\"#ffffff\",\"groupOutline\":\"#cccccc\"},\"sizes\":{\"pagePadding\":\"12px\",\"groupGap\":\"12px\",\"groupBorderRadius\":\"4px\",\"widgetGap\":\"12px\"}}",[15,7413,7414,7415,135],{},"To understand what is going on in this flow, we must refer back to the OPC UA Simulation Server ",[89,7416,7417],{},"Address Space",[15,7419,7420,7421,7423],{},"When we browse the OPC Server base folder structure in Node-RED, we will be browsing everything included under the ",[89,7422,4491],{}," tree.",[15,7425,7426,7430,7431,7434],{},[39,7427],{"alt":7428,"dataZoomable":458,"src":7429},"address-space.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Faddress-space.png","\nIn our flow, we get the base folder structure by using an OPC-UA Browser node, as shown, with an endpoint that points to our OPC UA Server endpoint url we grabbed earlier in this article.  It is also worth noting we leave the ",[89,7432,7433],{},"Topic"," blank.  By doing this, we will browse the entire folder structure by default.",[15,7436,7437,7441],{},[39,7438],{"alt":7439,"dataZoomable":458,"src":7440},"image-20230727-090252.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fimage-20230727-090252.png","\nThe configuration of the endpoint properties includes no security credentials, as shown below.",[15,7443,7444],{},[39,7445],{"alt":7446,"dataZoomable":458,"src":7447},"endpoint-configure.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fendpoint-configure.png",[15,7449,7450],{},"Using the output of a debug node, we get from the OPC UA Browser yield a payload with an array of 5 objects.",[15,7452,7453],{},[39,7454],{"alt":7455,"dataZoomable":458,"src":7456},"address-debug.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Faddress-debug.png",[15,7458,7459],{},"Each object returned represents the 5 objects that are in our OPC UA Server Objects tree.",[15,7461,7462],{},[39,7463],{"alt":7464,"dataZoomable":458,"src":7465},"browse-payload-1.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fbrowse-payload-1.png",[15,7467,7468,7469,404,7472,684,7475,7478,7479,222,7482,215],{},"However, of those 5 objects, only 3 of them are folders that contain actual OPC values.  ",[89,7470,7471],{},"MyObjects",[89,7473,7474],{},"Simulation",[89,7476,7477],{},"StaticData",".  We can ignore ",[89,7480,7481],{},"Aliases",[89,7483,673],{},[15,7485,7486],{},[39,7487],{"alt":7488,"dataZoomable":458,"src":7489},"address-space-folders-only.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Faddress-space-folders-only.png",[15,7491,7492,7493,7495],{},"So looking deeper into the payload of our global browse from the ",[89,7494,4506],{},", we can drill down into the details and see how they correlate with the folders in the server.",[15,7497,7498],{},[39,7499],{"alt":7500,"dataZoomable":458,"src":7501},"browse-node.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fbrowse-node.png",[15,7503,7504,7505,7507,7508,7510,7511,7514],{},"As shown above, element 2 in the array returned from the global browse corresponds to the ",[89,7506,7474],{}," folder.  And we are interested in two important values in this data-structure - the ",[89,7509,295],{},", which is topic an OPC Client uses to point specific OPC values, and the ",[89,7512,7513],{},"browseName",", which is the name we see visually when we try to identify an OPC topic.  We can now use this logic to parse out this useful information using a change node.",[15,7516,7517,7521,7522,222,7525,7527,7528,7530,7531,7533],{},[39,7518],{"alt":7519,"dataZoomable":458,"src":7520},"simulation-folder.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fsimulation-folder.png","\nThis change node is grabbing the ",[89,7523,7524],{},"nodeId",[89,7526,7513],{}," .  The ",[89,7529,7524],{}," is stored in a context variable for later use, while the ",[89,7532,7513],{}," is used as the payload to be displayed on our dashboard.",[15,7535,7536],{},"The rest of the flow follows this same pattern, to end up with a folder structure that we can display on our dashboard that matches the structure on our OPC Server",[56,7538,7539],{},[59,7540,7541],{},"note - to make the flow more manageable, not all browsable folders were included in the dashboard, as this flow is just meant to serve as an example, rather than be a 1:1 copy of everything in the server.",[15,7543,7544],{},"If you deploy the flow and pull up the dashboard, it results in the following output -",[15,7546,7547,7551,7552,7554],{},[39,7548],{"alt":7549,"dataZoomable":458,"src":7550},"address-space-dashboard.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Faddress-space-dashboard.png","\nShowing side-by-side with the server, you can see that we successfully browsed a portion of the address space and displayed the values on the dashboard.  Admittedly, a lot of work for not much pay-off, but it’s a worthwhile exercise in understanding how to browse topics using the ",[89,7553,4470],{}," node.  The browser node is best used for reading OPC UA values, which will be covered next.",[48,7556,7558],{"id":7557},"read-opc-ua-values-using-opc-ua-browser-node","Read OPC UA Values Using OPC UA Browser Node",[15,7560,7561],{},"The next set of flows read OPC UA values from the server and displays them on the dashboard.",[15,7563,7564,7568],{},[39,7565],{"alt":7566,"dataZoomable":458,"src":7567},"read-opc-values.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fread-opc-values.png","\nYou can import these flows into Node-RED using the code below:",[15,7570,6475,7571,3059],{},[462,7572,7271,7573,7275,7575,7278,7577,7281,7579,7292,7585,7295,7587,7304,7593,7313,7599,7316,7601,7320,7603,7329,7609,7338,7615,7346,7621,7350,7623,7353,7625,7356,7627,7359,7629,7372,7635,7381,7641,7391,7647,7397,7651,7402,7655,7407,7659,7661,7662,7665,7666,7668,7669,7672,7673,7675,7676,7682,7683,7686,7687,7691,7692,7696,7697,7701,7702,7704,7705,7707,7708,7710,7711,7714,7715,7717,7718,7720,7721,7723,7724,7727,7728,7730,7731,7734,7735,7737,7738,7741,7742,7744,7745,7751,7752,7754,7755,7757,7758,7761,7762,7766,7767,7769,7770,7772,7773,7775,7776,7778,7779,7781,7782,7784,7785,7787,7788,7790],{},[462,7574,7274],{},[462,7576],{},[462,7578,3287],{},[462,7580,7284,7581,7288,7583,7291],{},[462,7582,7287],{},[462,7584,7287],{},[462,7586],{},[462,7588,7298,7589,7288,7591,7291],{},[462,7590,7301],{},[462,7592,7301],{},[462,7594,7307,7595,7288,7597,7291],{},[462,7596,7310],{},[462,7598,7310],{},[462,7600],{},[462,7602,7319],{},[462,7604,7323,7605,7288,7607,7291],{},[462,7606,7326],{},[462,7608,7326],{},[462,7610,7332,7611,7288,7613,7291],{},[462,7612,7335],{},[462,7614,7335],{},[462,7616,7341,7617,7288,7619,7291],{},[462,7618,366],{},[462,7620,366],{},[462,7622,7349],{},[462,7624],{},[462,7626],{},[462,7628],{},[7361,7630,7363,7631,7367,7633,7371],{},[15,7632,7366],{},[7369,7634],{"value":324},[7361,7636,7363,7637,7378,7639,7371],{},[15,7638,7377],{},[7369,7640],{"value":324},[7361,7642,7384,7643,7388,7645,7371],{},[15,7644,7387],{},[7369,7646],{"value":324},[7361,7648,7394,7649,7371],{},[7369,7650],{"value":324},[7361,7652,7394,7653,7371],{},[7369,7654],{"value":324},[7361,7656,7394,7657,7371],{},[7369,7658],{"value":324},[462,7660,7410],{},",\"showPathInSidebar\":false,\"navigationStyle\":\"default\"},{\"id\":\"61eee6fc60281b9b\",\"type\":\"ui-theme\",\"name\":\"Default Theme\",\"colors\":{\"surface\":\"#0094ce\",\"primary\":\"#0094ce\",\"bgPage\":\"#eeeeee\",\"groupBg\":\"#ffffff\",\"groupOutline\":\"#cccccc\"},\"sizes\":{\"pagePadding\":\"12px\",\"groupGap\":\"12px\",\"groupBorderRadius\":\"4px\",\"widgetGap\":\"12px\"}},{\"id\":\"8557072f05e4bda0\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Read Simulation Values & Display on Dashboard\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,7663,7664],{},"\"9659d40ac9063764\",\"9f5b597ec8179fb4\",\"a8d919f497fcff04\",\"13f5c98b7fd5f5da\",\"ec5dca5eb9d4971b\",\"1780cb86597d3c67\",\"1a2fcac87247cda4\",\"4d9b758e39555124\",\"da468bc150517fa6\",\"82aa12173dd7bbca\",\"57d8777e34b55b7b\",\"10877909d1daf6fe\",\"c4d4a3b0df372e4c\",\"b0cf511f824f2a86\",\"f2efc6b419414c9a\"",",\"x\":94,\"y\":599,\"w\":1372,\"h\":302},{\"id\":\"9659d40ac9063764\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,7667],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":570,\"y\":760,\"wires\":[[\"ec5dca5eb9d4971b\"]]},{\"id\":\"9f5b597ec8179fb4\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Update Simulation Values @ 1 second\",\"props\":",[462,7670,7671],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"v\":\"Objects.Simulation.nodeId\",\"vt\":\"flow\"}",",\"repeat\":\"1\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":300,\"y\":760,\"wires\":[[\"9659d40ac9063764\"]]},{\"id\":\"a8d919f497fcff04\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Read Simulation Values\",\"info\":\"\",\"x\":460,\"y\":720,\"wires\":",[462,7674],{},"},{\"id\":\"13f5c98b7fd5f5da\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Get Counter Value\",\"rules\":",[462,7677,7678,7679,7681],{},"{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"payload",[462,7680,7326],{},".item.value\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1070,\"y\":680,\"wires\":[[\"10877909d1daf6fe\"]]},{\"id\":\"ec5dca5eb9d4971b\",\"type\":\"switch\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"empty check\",\"property\":\"payload\",\"propertyType\":\"msg\",\"rules\":",[462,7684,7685],{},"{\"t\":\"nempty\"}",",\"checkall\":\"true\",\"repair\":false,\"outputs\":1,\"x\":790,\"y\":760,\"wires\":[[\"13f5c98b7fd5f5da\",\"1780cb86597d3c67\",\"1a2fcac87247cda4\",\"4d9b758e39555124\"]]},{\"id\":\"1780cb86597d3c67\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Get Random Number Value\",\"rules\":",[462,7688,7678,7689,7681],{},[462,7690,7287],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1100,\"y\":740,\"wires\":[[\"c4d4a3b0df372e4c\"]]},{\"id\":\"1a2fcac87247cda4\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Get Sawtooth Value\",\"rules\":",[462,7693,7678,7694,7681],{},[462,7695,7310],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1080,\"y\":800,\"wires\":[[\"b0cf511f824f2a86\"]]},{\"id\":\"4d9b758e39555124\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Get Sawtooth Value\",\"rules\":",[462,7698,7678,7699,7681],{},[462,7700,7301],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1080,\"y\":860,\"wires\":[[\"f2efc6b419414c9a\"]]},{\"id\":\"da468bc150517fa6\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Discard Empty Datasets\",\"info\":\"\",\"x\":780,\"y\":720,\"wires\":",[462,7703],{},"},{\"id\":\"82aa12173dd7bbca\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Parse Simulation Values\",\"info\":\"\",\"x\":1070,\"y\":640,\"wires\":",[462,7706],{},"},{\"id\":\"57d8777e34b55b7b\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Display on Dashboard\",\"info\":\"\",\"x\":1340,\"y\":640,\"wires\":",[462,7709],{},"},{\"id\":\"10877909d1daf6fe\",\"type\":\"ui-gauge\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"name\":\"Counter\",\"group\":\"af263064820fb7d0\",\"order\":0,\"width\":3,\"height\":3,\"gtype\":\"gauge-half\",\"gstyle\":\"needle\",\"title\":\"gauge\",\"units\":\"units\",\"icon\":\"\",\"prefix\":\"\",\"suffix\":\"\",\"segments\":",[462,7712,7713],{},"{\"from\":\"0\",\"color\":\"#5cd65c\"},{\"from\":\"15\",\"color\":\"#ffc800\"},{\"from\":\"30\",\"color\":\"#ea5353\"}",",\"min\":0,\"max\":\"30\",\"sizeThickness\":16,\"sizeGap\":4,\"sizeKeyThickness\":8,\"styleRounded\":true,\"styleGlow\":false,\"className\":\"\",\"x\":1320,\"y\":680,\"wires\":",[462,7716],{},"},{\"id\":\"c4d4a3b0df372e4c\",\"type\":\"ui-text\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"group\":\"af263064820fb7d0\",\"order\":0,\"width\":0,\"height\":0,\"name\":\"Random Number\",\"label\":\"Random Number\",\"format\":\"",[7369,7719],{"value":324},"\",\"layout\":\"row-spread\",\"style\":false,\"font\":\"\",\"fontSize\":16,\"color\":\"#717171\",\"className\":\"\",\"x\":1350,\"y\":740,\"wires\":",[462,7722],{},"},{\"id\":\"b0cf511f824f2a86\",\"type\":\"ui-chart\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"group\":\"af263064820fb7d0\",\"name\":\"\",\"label\":\"Sawtooth\",\"order\":9007199254740991,\"chartType\":\"line\",\"category\":\"Sawtooth\",\"categoryType\":\"str\",\"xAxisProperty\":\"\",\"xAxisPropertyType\":\"msg\",\"xAxisType\":\"time\",\"yAxisProperty\":\"\",\"ymin\":\"\",\"ymax\":\"\",\"action\":\"append\",\"pointShape\":\"line\",\"pointRadius\":4,\"showLegend\":true,\"removeOlder\":1,\"removeOlderUnit\":\"60\",\"removeOlderPoints\":\"\",\"colors\":",[462,7725,7726],{},"\"#1f77b4\",\"#aec7e8\",\"#ff7f0e\",\"#2ca02c\",\"#98df8a\",\"#d62728\",\"#ff9896\",\"#9467bd\",\"#c5b0d5\"",",\"width\":\"3\",\"height\":\"4\",\"className\":\"\",\"x\":1320,\"y\":800,\"wires\":[[]]},{\"id\":\"f2efc6b419414c9a\",\"type\":\"ui-chart\",\"z\":\"5b972161c4e0464e\",\"g\":\"8557072f05e4bda0\",\"group\":\"af263064820fb7d0\",\"name\":\"\",\"label\":\"Sinusoid\",\"order\":9007199254740991,\"chartType\":\"line\",\"category\":\"Sawtooth\",\"categoryType\":\"str\",\"xAxisProperty\":\"\",\"xAxisPropertyType\":\"msg\",\"xAxisType\":\"time\",\"yAxisProperty\":\"\",\"ymin\":\"\",\"ymax\":\"\",\"action\":\"append\",\"pointShape\":\"line\",\"pointRadius\":4,\"showLegend\":true,\"removeOlder\":1,\"removeOlderUnit\":\"60\",\"removeOlderPoints\":\"\",\"colors\":",[462,7729,7726],{},",\"width\":\"3\",\"height\":\"4\",\"className\":\"\",\"x\":1320,\"y\":860,\"wires\":[[]]},{\"id\":\"af263064820fb7d0\",\"type\":\"ui-group\",\"name\":\"Simulation values\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"3\",\"height\":\"1\",\"order\":2,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"5afdbddf71507886\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Read StaticData Values & Display on Dashboard\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,7732,7733],{},"\"e998aa804042128b\",\"6c9b7d4d195a1e9a\",\"cd097b744d0ec625\",\"18d21607c87ab153\",\"7b5143c4960f92a1\",\"0625b0cf6f546a4a\",\"9d899fbb4d1648b3\",\"6e1edc31687dde54\",\"051e1f282076fed2\",\"de2a1c3e380f743b\",\"c74606c48ccf5a40\",\"053bda13f2a2eabe\",\"277dcf430dc86996\",\"d708e6264cec0070\"",",\"x\":84,\"y\":939,\"w\":1382,\"h\":202},{\"id\":\"e998aa804042128b\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,7736],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":630,\"y\":1020,\"wires\":[[\"7b5143c4960f92a1\"]]},{\"id\":\"6c9b7d4d195a1e9a\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Update AnalogItemArrays Values @ 1 second\",\"props\":",[462,7739,7740],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"v\":\"Objects.StaticData.AnalogItemArrays.nodeId\",\"vt\":\"flow\"}",",\"repeat\":\"1\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":320,\"y\":1020,\"wires\":[[\"e998aa804042128b\"]]},{\"id\":\"cd097b744d0ec625\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Read StaticData Values\",\"info\":\"\",\"x\":520,\"y\":980,\"wires\":",[462,7743],{},"},{\"id\":\"18d21607c87ab153\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Get ByteAnalogItemArray Value\",\"rules\":",[462,7746,7747,7748,7750],{},"{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"$string(payload",[462,7749,366],{},".item.value)\\t\",\"tot\":\"jsonata\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1070,\"y\":1020,\"wires\":[[\"277dcf430dc86996\"]]},{\"id\":\"7b5143c4960f92a1\",\"type\":\"switch\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"empty check\",\"property\":\"payload\",\"propertyType\":\"msg\",\"rules\":",[462,7753,7685],{},",\"checkall\":\"true\",\"repair\":false,\"outputs\":1,\"x\":830,\"y\":1020,\"wires\":[[\"18d21607c87ab153\"]]},{\"id\":\"0625b0cf6f546a4a\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,7756],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":630,\"y\":1100,\"wires\":[[\"051e1f282076fed2\"]]},{\"id\":\"9d899fbb4d1648b3\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Update StaticArrayVariables Values @1 second\",\"props\":",[462,7759,7760],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"v\":\"Objects.StaticData.StaticArrayVariables.nodeId\",\"vt\":\"flow\"}",",\"repeat\":\"1\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":320,\"y\":1100,\"wires\":[[\"0625b0cf6f546a4a\"]]},{\"id\":\"6e1edc31687dde54\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Get BooleanArray Value\",\"rules\":",[462,7763,7678,7764,7681],{},[462,7765,366],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1050,\"y\":1100,\"wires\":[[\"d708e6264cec0070\"]]},{\"id\":\"051e1f282076fed2\",\"type\":\"switch\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"empty check\",\"property\":\"payload\",\"propertyType\":\"msg\",\"rules\":",[462,7768,7685],{},",\"checkall\":\"true\",\"repair\":false,\"outputs\":1,\"x\":830,\"y\":1100,\"wires\":[[\"6e1edc31687dde54\"]]},{\"id\":\"de2a1c3e380f743b\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Discard Empty Datasets\",\"info\":\"\",\"x\":820,\"y\":980,\"wires\":",[462,7771],{},"},{\"id\":\"c74606c48ccf5a40\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Parse StaticData Values\",\"info\":\"\",\"x\":1070,\"y\":980,\"wires\":",[462,7774],{},"},{\"id\":\"053bda13f2a2eabe\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"name\":\"Display on Dashboard\",\"info\":\"\",\"x\":1340,\"y\":980,\"wires\":",[462,7777],{},"},{\"id\":\"277dcf430dc86996\",\"type\":\"ui-text\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"group\":\"3d4f386e812e8b5f\",\"order\":0,\"width\":0,\"height\":0,\"name\":\"\",\"label\":\"ByteAnalogItemArray\",\"format\":\"",[7369,7780],{"value":324},"\",\"layout\":\"row-spread\",\"style\":false,\"font\":\"\",\"fontSize\":16,\"color\":\"#717171\",\"className\":\"\",\"x\":1340,\"y\":1020,\"wires\":",[462,7783],{},"},{\"id\":\"d708e6264cec0070\",\"type\":\"ui-text\",\"z\":\"5b972161c4e0464e\",\"g\":\"5afdbddf71507886\",\"group\":\"3d4f386e812e8b5f\",\"order\":0,\"width\":0,\"height\":0,\"name\":\"\",\"label\":\"BooleanArray\",\"format\":\"",[7369,7786],{"value":324},"\",\"layout\":\"row-spread\",\"style\":false,\"font\":\"\",\"fontSize\":16,\"color\":\"#717171\",\"className\":\"\",\"x\":1320,\"y\":1100,\"wires\":",[462,7789],{},"},{\"id\":\"3d4f386e812e8b5f\",\"type\":\"ui-group\",\"name\":\"StaticData Values\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"4\",\"height\":\"1\",\"order\":3,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"}",[15,7792,7793,7794,7796,7797,7799],{},"The values are derived from the ",[89,7795,7524],{}," values we stored in memory in our previous flow, via our ",[89,7798,5527],{}," nodes in the previous flow.",[15,7801,7802,7806,7807,7809],{},[39,7803],{"alt":7804,"dataZoomable":458,"src":7805},"flow-context-nodeid.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fflow-context-nodeid.png","\nAs stated earlier, you reference a OPC UA topic by its ",[89,7808,7524],{},".  So we will use these node IDs to read actual values from our OPC nodes.",[15,7811,7812,7813,7815,7816,7818,7819,7821,7822,7824,7825,7827],{},"In our first flow, we want to read the values in the ",[89,7814,7474],{}," folder at a 1 second interval.  So we use an ",[89,7817,302],{}," node with a ",[89,7820,373],{}," that references the ",[89,7823,7524],{}," corresponding to the ",[89,7826,7474],{}," folder.",[15,7829,7830,7834,7835,7837,7838,7840,7841,7843,7844,7846],{},[39,7831],{"alt":7832,"dataZoomable":458,"src":7833},"simulation-injection.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fsimulation-injection.png","\nThat ",[89,7836,373],{}," tells the ",[89,7839,4470],{}," node what ",[89,7842,7524],{}," to browse.  If we look at the debug output of the browser ",[89,7845,324],{},", we can see that it produces an array of 7 objects, and an empty set array.",[15,7848,7849,7853,7854,7857],{},[39,7850],{"alt":7851,"dataZoomable":458,"src":7852},"simulation-debug.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fsimulation-debug.png","\nIf we allow that empty array to be passed, that means all values will be reset to 0 on each read.  So to prevent that from happening, we use a ",[89,7855,7856],{},"switch"," node to filter out the empty set.",[15,7859,7860,7864],{},[39,7861],{"alt":7862,"dataZoomable":458,"src":7863},"empty-check.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fempty-check.png","\nNow only non-empty payloads will be passed, preventing the values being reset to 0 on each read.",[15,7866,7867,7868,7870,7871,7873,7874,7877,7878,7881,7882,7827],{},"Now we can actually read the values.  To do this, we use a ",[89,7869,5527],{}," node again, referencing the non-empty payload and drilling down to the ",[89,7872,5703],{}," that corresponds to the ",[89,7875,7876],{},"name"," of the node we want to read.  In this case, we’re getting the value of the node ",[89,7879,7880],{},"Counter"," located in the ",[89,7883,7474],{},[15,7885,7886,7890],{},[39,7887],{"alt":7888,"dataZoomable":458,"src":7889},"get-counter-value.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fget-counter-value.png","\nGoing back to our OPC Server, we can see that exactly where that value is derived below -",[15,7892,7893],{},[39,7894],{"alt":7895,"dataZoomable":458,"src":7896},"sim-counter-server.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fsim-counter-server.png",[15,7898,7899,7900,7903],{},"Now we add a ",[89,7901,7902],{},"gauge"," dashboard node to visualize the counter on the dashboard.  In the OPC Server, it is shown that the counter increments in a range of 0-30 in 1 count increments.",[15,7905,7906,7910],{},[39,7907],{"alt":7908,"dataZoomable":458,"src":7909},"counter-properties.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fcounter-propertie.png","\nNow that we’ve gone through the full process of reading an OPC UA value and displaying it on the dashboard, we can apply the same logic other values published by the OPC UA Server, which are repeated in the remaining parts of the flow.",[15,7912,7913],{},"The end result on the dashboard now looks like this -",[15,7915,7916],{},[39,7917],{"alt":7918,"dataZoomable":458,"src":7919},"opc-read-dashboard.gif","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopc-read-dashboard.gif",[48,7921,7923],{"id":7922},"write-opc-ua-values-to-server-using-opcua-item-and-opc-ua-client-nodes","Write OPC UA Values To Server Using OpcUa-Item and Opc-Ua-Client Nodes",[15,7925,7926],{},"The next flow writes OPC UA values to the server using dashboard UI elements.",[15,7928,7929,7933],{},[39,7930],{"alt":7931,"dataZoomable":458,"src":7932},"write-mydevice.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fwrite-mydevice.png","\nYou can import this flow into Node-RED using the code below:",[15,7935,6475,7936,3059],{},[462,7937,7938,7939,7942,7943,7945,7946,7948,7949,7951,7952,7954,7955,7957,7958,7411],{},"{\"id\":\"3de6c861611c3afa\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Write Mydevices values to OPC UA Server\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,7940,7941],{},"\"a66583d91b581cd8\",\"3e8cb6e199012155\",\"9fa33d1c9c621611\",\"fb7f57b4da5883ae\",\"9c5ff104eb9c8b10\",\"77bcb828bec95336\",\"afa83dbb46449d4a\",\"fa08f0ed04296363\",\"9f591797b56c565d\"",",\"x\":94,\"y\":1439,\"w\":792,\"h\":182},{\"id\":\"a66583d91b581cd8\",\"type\":\"OpcUa-Item\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"item\":\"ns=6;s=MySwitch\",\"datatype\":\"Boolean\",\"value\":\"\",\"name\":\"Toggle MySwitch\",\"x\":470,\"y\":1520,\"wires\":[[\"3e8cb6e199012155\"]]},{\"id\":\"3e8cb6e199012155\",\"type\":\"OpcUa-Client\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"endpoint\":\"53f4394dbf12c6b7\",\"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\":\"Write MySwitch\",\"x\":720,\"y\":1520,\"wires\":[[],",[462,7944],{},"]},{\"id\":\"9fa33d1c9c621611\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"name\":\"Dashboard Input\",\"info\":\"\",\"x\":200,\"y\":1480,\"wires\":",[462,7947],{},"},{\"id\":\"fb7f57b4da5883ae\",\"type\":\"OpcUa-Item\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"item\":\"ns=6;s=MyLevel\",\"datatype\":\"Double\",\"value\":\"\",\"name\":\"Modify MyLevel\",\"x\":460,\"y\":1580,\"wires\":[[\"9c5ff104eb9c8b10\"]]},{\"id\":\"9c5ff104eb9c8b10\",\"type\":\"OpcUa-Client\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"endpoint\":\"53f4394dbf12c6b7\",\"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\":\"Write MyLevel\",\"x\":720,\"y\":1580,\"wires\":[[],",[462,7950],{},"]},{\"id\":\"77bcb828bec95336\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"name\":\"Call OPC UA Item\",\"info\":\"\",\"x\":470,\"y\":1480,\"wires\":",[462,7953],{},"},{\"id\":\"afa83dbb46449d4a\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"name\":\"Write OPC UA Item to Client\",\"info\":\"\",\"x\":740,\"y\":1480,\"wires\":",[462,7956],{},"},{\"id\":\"fa08f0ed04296363\",\"type\":\"ui-switch\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"name\":\"\",\"label\":\"Toggle MySwitch\",\"group\":\"ec0ecb26fde8db3e\",\"order\":0,\"width\":0,\"height\":0,\"passthru\":false,\"topic\":\"topic\",\"topicType\":\"msg\",\"style\":\"\",\"className\":\"\",\"onvalue\":\"true\",\"onvalueType\":\"bool\",\"onicon\":\"\",\"oncolor\":\"\",\"offvalue\":\"false\",\"offvalueType\":\"bool\",\"officon\":\"\",\"offcolor\":\"\",\"x\":210,\"y\":1520,\"wires\":[[\"a66583d91b581cd8\"]]},{\"id\":\"9f591797b56c565d\",\"type\":\"ui-slider\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"group\":\"ec0ecb26fde8db3e\",\"name\":\"\",\"label\":\"Modify MyLevel\",\"tooltip\":\"\",\"order\":0,\"width\":0,\"height\":0,\"passthru\":false,\"outs\":\"all\",\"topic\":\"topic\",\"topicType\":\"msg\",\"thumbLabel\":true,\"min\":\"0\",\"max\":\"100\",\"step\":1,\"className\":\"\",\"x\":200,\"y\":1580,\"wires\":[[\"fb7f57b4da5883ae\"]]},{\"id\":\"53f4394dbf12c6b7\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"opc.tcp:\u002F\u002F192.168.56.1:53530\u002FOPCUA\u002FSimulationServer\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"},{\"id\":\"ec0ecb26fde8db3e\",\"type\":\"ui-group\",\"name\":\"MyDevice Status & Control\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"3\",\"height\":\"1\",\"order\":4,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"44d3feb2a1143d7b\",\"type\":\"ui-page\",\"name\":\"OPC UA\",\"ui\":\"5355e0c476f9da3b\",\"path\":\"\u002Fopcua\",\"icon\":\"home\",\"layout\":\"grid\",\"theme\":\"61eee6fc60281b9b\",\"order\":1,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"5355e0c476f9da3b\",\"type\":\"ui-base\",\"name\":\"My Dashboard\",\"path\":\"\u002Fdashboard\",\"includeClientData\":true,\"acceptsClientConfig\":",[462,7959,7410],{},[15,7961,7962,7963,7966,7967,7970,7971,7973,7974,215],{},"We have two values to write, a boolean value corresponding to the node object ",[89,7964,7965],{},"MySwitch",", and an integer value corresponding to the object ",[89,7968,7969],{},"MyLevel",". Therefore, we will use a toggle switch to toggle the ",[89,7972,7965],{},", and a slider to modify ",[89,7975,7969],{},[15,7977,7978],{},"There’s no need to modify the toggle switch properties, other than giving it a name.  The slider needs to have the range modified to match the range of the level, which is 0-100%.",[15,7980,7981,7985,7986,7989,7990,7992],{},[39,7982],{"alt":7983,"dataZoomable":458,"src":7984},"level-range.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Flevel-range.png","\nFor the ",[89,7987,7988],{},"OpcUa-Item"," nodes, copy the ",[89,7991,295],{}," corresponding to each device,",[15,7994,7995,7999,8000,8002],{},[39,7996],{"alt":7997,"dataZoomable":458,"src":7998},"copy-node-id.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fcopy-node-id.png","\nand paste it into ",[89,8001,7988],{}," node.  You must also ensure the data-type matches with the value you’re writing to.",[15,8004,8005,8009,8010,8013,8014,215],{},[39,8006],{"alt":8007,"dataZoomable":458,"src":8008},"opcua-item.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopcua-item.png","\nThe ",[89,8011,8012],{},"Opc-Ua-Client"," needs to have an endpoint and the action changed to ",[89,8015,4838],{},[15,8017,8018,8022,8023,222,8025,8027,8028,8030,8031,667],{},[39,8019],{"alt":8020,"dataZoomable":458,"src":8021},"client-node.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fclient-node.png","\nThe process is the same for ",[89,8024,7965],{},[89,8026,7969],{},", the only difference being what ",[89,8029,295],{}," is referenced in the  ",[89,8032,7988],{},[15,8034,8035],{},"When deployed, you can confirm values are being written to from the client to the server from the dashboard.",[15,8037,8038],{},[39,8039],{"alt":8040,"dataZoomable":458,"src":8041},"opc-write.gif","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopc-write.gif",[48,8043,8045],{"id":8044},"read-alarms-events-from-opc-ua-server-using-opcua-event-and-opc-ua-client-nodes","Read Alarms & Events from OPC UA Server Using OpcUa-Event and Opc-Ua-Client Nodes",[15,8047,8048],{},"Our last flow we’ll show how to read OPC UA Alarms & Events.",[15,8050,8051,7933],{},[39,8052],{"alt":8053,"dataZoomable":458,"src":8054},"opc-event-flow.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopc-event-flow.png",[15,8056,6475,8057,3059],{},[462,8058,8059,8060,8063,8064,8066,8067,8069,8070,8072,8073,8076,8077,8080,8081,8084,8085,8087,8088,8090,8091,8093,8094,8096,8097,8099,8100,8102,8103,8105,8106,8108,8109,8111,8112,8114],{},"{\"id\":\"a6e9abacd0bdf3b6\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Read Alarms & Events From OPC UA Server\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,8061,8062],{},"\"90fb4ca64a642edf\",\"b76f64786bc681c3\",\"71e24b671bc03fb8\",\"c7438df35b506470\",\"c7e8919b636cb51d\",\"5952b86dae22b056\",\"04992b24a3836f19\",\"325068cb935cd6d1\",\"5b4d1bd8b342fc05\",\"ba1ea89438335cb8\",\"d662d662c5ccb9c1\",\"1e3956200997581f\",\"0b8ac86e5e4f9f8d\",\"62b2e14ce0429eef\"",",\"x\":94,\"y\":1679,\"w\":1352,\"h\":282},{\"id\":\"90fb4ca64a642edf\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Call OPC UA Item\",\"info\":\"\",\"x\":470,\"y\":1820,\"wires\":",[462,8065],{},"},{\"id\":\"b76f64786bc681c3\",\"type\":\"OpcUa-Event\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"root\":\"ns=6;s=MyLevel.Alarm\",\"activatecustomevent\":false,\"eventtype\":\"i=2041\",\"customeventtype\":\"\",\"name\":\"MyLevel Alarms\",\"x\":500,\"y\":1860,\"wires\":[[\"c7438df35b506470\"]]},{\"id\":\"71e24b671bc03fb8\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Trigger Alarm Event Capture\",\"props\":",[462,8068,3287],{},",\"repeat\":\"\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":260,\"y\":1860,\"wires\":[[\"b76f64786bc681c3\"]]},{\"id\":\"c7438df35b506470\",\"type\":\"OpcUa-Client\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"endpoint\":\"53f4394dbf12c6b7\",\"action\":\"events\",\"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\":\"Get MyLevel Events\",\"x\":720,\"y\":1860,\"wires\":[[\"c7e8919b636cb51d\",\"5952b86dae22b056\",\"04992b24a3836f19\"],",[462,8071],{},"]},{\"id\":\"c7e8919b636cb51d\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Event Text\",\"rules\":",[462,8074,8075],{},"{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"payload.Message.text\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":990,\"y\":1800,\"wires\":[[\"d662d662c5ccb9c1\",\"1e3956200997581f\"]]},{\"id\":\"5952b86dae22b056\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Event Time\",\"rules\":",[462,8078,8079],{},"{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"payload.Time\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":990,\"y\":1860,\"wires\":[[\"0b8ac86e5e4f9f8d\"]]},{\"id\":\"04992b24a3836f19\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Event Severity\",\"rules\":",[462,8082,8083],{},"{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"payload.Severity\",\"tot\":\"msg\"}",",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1000,\"y\":1920,\"wires\":[[\"62b2e14ce0429eef\"]]},{\"id\":\"325068cb935cd6d1\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Parse Event Dataset\",\"info\":\"\",\"x\":990,\"y\":1760,\"wires\":",[462,8086],{},"},{\"id\":\"5b4d1bd8b342fc05\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Get OPC Events from Client\",\"info\":\"\",\"x\":720,\"y\":1820,\"wires\":",[462,8089],{},"},{\"id\":\"ba1ea89438335cb8\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"name\":\"Display Events on Dashboard\",\"info\":\"\",\"x\":1240,\"y\":1720,\"wires\":",[462,8092],{},"},{\"id\":\"d662d662c5ccb9c1\",\"type\":\"ui-notification\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"ui\":\"5355e0c476f9da3b\",\"position\":\"center center\",\"colorDefault\":true,\"color\":\"#000000\",\"displayTime\":\"3\",\"showCountdown\":true,\"outputs\":1,\"allowDismiss\":true,\"dismissText\":\"Close\",\"raw\":false,\"className\":\"\",\"name\":\"Event Notification\",\"x\":1230,\"y\":1800,\"wires\":[[]]},{\"id\":\"1e3956200997581f\",\"type\":\"ui-text\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"group\":\"ec0ecb26fde8db3e\",\"order\":0,\"width\":0,\"height\":0,\"name\":\"\",\"label\":\"Latest MyLevel Event\",\"format\":\"",[7369,8095],{"value":324},"\",\"layout\":\"row-spread\",\"style\":false,\"font\":\"\",\"fontSize\":16,\"color\":\"#717171\",\"className\":\"\",\"x\":1240,\"y\":1840,\"wires\":",[462,8098],{},"},{\"id\":\"0b8ac86e5e4f9f8d\",\"type\":\"ui-text\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"group\":\"ec0ecb26fde8db3e\",\"order\":0,\"width\":0,\"height\":0,\"name\":\"\",\"label\":\"Latest MyLevel Event Timestamp\",\"format\":\"",[7369,8101],{"value":324},"\",\"layout\":\"row-spread\",\"style\":false,\"font\":\"\",\"fontSize\":16,\"color\":\"#717171\",\"className\":\"\",\"x\":1280,\"y\":1880,\"wires\":",[462,8104],{},"},{\"id\":\"62b2e14ce0429eef\",\"type\":\"ui-text\",\"z\":\"5b972161c4e0464e\",\"g\":\"a6e9abacd0bdf3b6\",\"group\":\"ec0ecb26fde8db3e\",\"order\":0,\"width\":0,\"height\":0,\"name\":\"\",\"label\":\"Latest MyLevel Event Severity\",\"format\":\"",[7369,8107],{"value":324},"\",\"layout\":\"row-spread\",\"style\":false,\"font\":\"\",\"fontSize\":16,\"color\":\"#717171\",\"className\":\"\",\"x\":1270,\"y\":1920,\"wires\":",[462,8110],{},"},{\"id\":\"53f4394dbf12c6b7\",\"type\":\"OpcUa-Endpoint\",\"endpoint\":\"opc.tcp:\u002F\u002F192.168.56.1:53530\u002FOPCUA\u002FSimulationServer\",\"secpol\":\"None\",\"secmode\":\"None\",\"none\":true,\"login\":false,\"usercert\":false,\"usercertificate\":\"\",\"userprivatekey\":\"\"},{\"id\":\"5355e0c476f9da3b\",\"type\":\"ui-base\",\"name\":\"My Dashboard\",\"path\":\"\u002Fdashboard\",\"includeClientData\":true,\"acceptsClientConfig\":",[462,8113,7410],{},",\"showPathInSidebar\":false,\"navigationStyle\":\"default\"},{\"id\":\"ec0ecb26fde8db3e\",\"type\":\"ui-group\",\"name\":\"MyDevice Status & Control\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"3\",\"height\":\"1\",\"order\":4,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"44d3feb2a1143d7b\",\"type\":\"ui-page\",\"name\":\"OPC UA\",\"ui\":\"5355e0c476f9da3b\",\"path\":\"\u002Fopcua\",\"icon\":\"home\",\"layout\":\"grid\",\"theme\":\"61eee6fc60281b9b\",\"order\":1,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"61eee6fc60281b9b\",\"type\":\"ui-theme\",\"name\":\"Default Theme\",\"colors\":{\"surface\":\"#0094ce\",\"primary\":\"#0094ce\",\"bgPage\":\"#eeeeee\",\"groupBg\":\"#ffffff\",\"groupOutline\":\"#cccccc\"},\"sizes\":{\"pagePadding\":\"12px\",\"groupGap\":\"12px\",\"groupBorderRadius\":\"4px\",\"widgetGap\":\"12px\"}}",[15,8116,8117,8118,8121,8122,8124,8125,8128],{},"We use an inject node to trigger the ",[89,8119,8120],{},"OpcUa-Event"," node.  In the properties of the event node, we get the ",[89,8123,295],{}," from the ",[89,8126,8127],{},"MyLevelAlarm"," event from the OPC Server -",[15,8130,8131,8135,8136,8138,8139,8141,8142,215],{},[39,8132],{"alt":8133,"dataZoomable":458,"src":8134},"mylevel-event.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fmylevel-event.png","\nAnd copy that ",[89,8137,295],{}," into the ",[89,8140,8120],{}," node.  Event type will be ",[89,8143,8144],{},"BaseEvent (all)",[15,8146,8147,8151,8152,8154,8155,4593,8157,215],{},[39,8148],{"alt":8149,"dataZoomable":458,"src":8150},"event-node-properties.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fevent-node-properties.png","\nIn the ",[89,8153,8012],{}," node, we set the ",[89,8156,4592],{},[89,8158,8159],{},"EVENTS",[15,8161,8162,8166],{},[39,8163],{"alt":8164,"dataZoomable":458,"src":8165},"client-events.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fclient-events.png","\nIf we stick a debug node on the output of the client event, we can see how the OPC Server annunciates events.",[15,8168,8169,8173,8174,8176,8177,8180],{},[39,8170],{"alt":8171,"dataZoomable":458,"src":8172},"event-debug.png","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fevent-debug.png","\nEvery time ",[89,8175,7969],{}," exceeds certain thresholds (10%, 30%, 70% and 90%) it will flag a ",[89,8178,8179],{},"Level Exceeded"," alarm.   The event is timestamped and assigned a severity level, which we will record and put onto the dashboard.",[15,8182,8183],{},"To make things simple, we’ll only track the last event.  But in a production system, you’d likely want to store these events in a relational database (historian) to keep an alarm history.  We’ll also include a notification pop-up when an alarm occurs to notify someone monitoring the dashboard a new alarm has occurred.",[15,8185,8186],{},"Adding alarms and events to our dashboard creates the following result -",[15,8188,8189],{},[39,8190],{"alt":8191,"dataZoomable":458,"src":8192},"opc-event.gif","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopc-event.gif",[48,8194,8196],{"id":8195},"using-flowfuse-to-enhance-your-node-red-application-security-scalability-and-robustness","Using FlowFuse to Enhance Your Node-RED Application: Security, Scalability, and Robustness",[15,8198,8199],{},"So, you've successfully built your Node-RED application, congratulations! But now, how do you ensure its security, scalability, and ease of collaboration? What if you want to invite your team to work on the application simultaneously or access it remotely?",[15,8201,8202,8203,8206],{},"Enter ",[29,8204,4233],{"href":8205},"\u002F",", a cloud-based platform designed to add production-grade features to your Node-RED applications. With FlowFuse, you can seamlessly integrate advanced security measures, scale your application as needed, and collaborate effortlessly with your team. It simplifies management and deployment, turning your Node-RED project into a robust, scalable solution.",[15,8208,8209,8210,8214,8215,8219],{},"If you're interested in learning how to use Node-RED for professional use cases, check out our eBook: ",[29,8211,8213],{"href":8212},"\u002Febooks\u002Fbeginner-guide-to-a-professional-nodered\u002F","Ultimate Beginner's Guide to Professionals",". For additional resources, visit our ",[29,8216,8218],{"href":8217},"\u002Fnode-red\u002Fcore-nodes\u002F","Node-RED Learning Resources section",", where you can explore integrations with different protocols, messaging services, databases, hardware, and much more.",[48,8221,7059],{"id":7058},[15,8223,8224],{},"In this final article, we went over building a OPC UA Client dashboard that can browse the address space, read values from an OPC Server, write values to an OPC Server, and get events from an OPC Server.",[15,8226,8227],{},"This flow provides examples that can serve as a foundation for an interactive OPC Client application built in Node-RED.  This now concludes the OPC UA Series.",[15,8229,8230],{},"full source code for this project -",[15,8232,6475,8233,3059],{},[462,8234,7271,8235,7275,8237,7278,8239,7281,8241,7292,8247,7295,8249,7304,8255,7313,8261,7316,8263,7320,8265,7329,8271,7338,8277,7346,8283,7350,8285,7353,8287,7356,8289,7359,8291,7372,8297,7381,8303,7391,8309,7397,8313,7402,8317,7407,8321,7661,8323,7665,8325,7668,8327,7672,8329,7675,8331,7682,8335,7686,8337,7691,8341,7696,8345,7701,8349,7704,8351,7707,8353,7710,8355,7714,8357,7717,8359,7720,8361,7723,8363,7727,8365,7730,8367,7734,8369,7737,8371,7741,8373,7744,8375,7751,8379,7754,8381,7757,8383,7761,8385,7766,8389,7769,8391,7772,8393,7775,8395,7778,8397,7781,8399,7784,8401,7787,8403,8405,8406,8409,8410,8412,8413,8416,8417,8419,8420,8424,8425,8427,8428,8432,8433,8435,8436,8438,8439,8441,8442,8445,8446,8448,8449,8452,8453,8455,8456,7942,8458,7945,8460,7948,8462,7951,8464,7954,8466,8468,8469,8063,8471,8066,8473,8069,8475,8072,8477,8076,8479,8080,8481,8084,8483,8087,8485,8090,8487,8093,8489,8096,8491,8099,8493,8102,8495,8105,8497,8108,8499,3207],{},[462,8236,7274],{},[462,8238],{},[462,8240,3287],{},[462,8242,7284,8243,7288,8245,7291],{},[462,8244,7287],{},[462,8246,7287],{},[462,8248],{},[462,8250,7298,8251,7288,8253,7291],{},[462,8252,7301],{},[462,8254,7301],{},[462,8256,7307,8257,7288,8259,7291],{},[462,8258,7310],{},[462,8260,7310],{},[462,8262],{},[462,8264,7319],{},[462,8266,7323,8267,7288,8269,7291],{},[462,8268,7326],{},[462,8270,7326],{},[462,8272,7332,8273,7288,8275,7291],{},[462,8274,7335],{},[462,8276,7335],{},[462,8278,7341,8279,7288,8281,7291],{},[462,8280,366],{},[462,8282,366],{},[462,8284,7349],{},[462,8286],{},[462,8288],{},[462,8290],{},[7361,8292,7363,8293,7367,8295,7371],{},[15,8294,7366],{},[7369,8296],{"value":324},[7361,8298,7363,8299,7378,8301,7371],{},[15,8300,7377],{},[7369,8302],{"value":324},[7361,8304,7384,8305,7388,8307,7371],{},[15,8306,7387],{},[7369,8308],{"value":324},[7361,8310,7394,8311,7371],{},[7369,8312],{"value":324},[7361,8314,7394,8315,7371],{},[7369,8316],{"value":324},[7361,8318,7394,8319,7371],{},[7369,8320],{"value":324},[462,8322,7410],{},[462,8324,7664],{},[462,8326],{},[462,8328,7671],{},[462,8330],{},[462,8332,7678,8333,7681],{},[462,8334,7326],{},[462,8336,7685],{},[462,8338,7678,8339,7681],{},[462,8340,7287],{},[462,8342,7678,8343,7681],{},[462,8344,7310],{},[462,8346,7678,8347,7681],{},[462,8348,7301],{},[462,8350],{},[462,8352],{},[462,8354],{},[462,8356,7713],{},[462,8358],{},[7369,8360],{"value":324},[462,8362],{},[462,8364,7726],{},[462,8366,7726],{},[462,8368,7733],{},[462,8370],{},[462,8372,7740],{},[462,8374],{},[462,8376,7747,8377,7750],{},[462,8378,366],{},[462,8380,7685],{},[462,8382],{},[462,8384,7760],{},[462,8386,7678,8387,7681],{},[462,8388,366],{},[462,8390,7685],{},[462,8392],{},[462,8394],{},[462,8396],{},[7369,8398],{"value":324},[462,8400],{},[7369,8402],{"value":324},[462,8404],{},"},{\"id\":\"3d4f386e812e8b5f\",\"type\":\"ui-group\",\"name\":\"StaticData Values\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"4\",\"height\":\"1\",\"order\":3,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"25f95391088d4a08\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Read MyDevice Values & Display on Dashboard\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,8407,8408],{},"\"bfe4274963a84e2e\",\"0662c62c7f0cfac0\",\"249c223139c5779e\",\"efb293f13af17dc1\",\"507d2c11c7586957\",\"3b7695a52a1bf6e0\",\"594ec38acadc9673\",\"d4e2915ba92db8a6\",\"85619f0eab615ac7\",\"cd4941a8db3edcb6\",\"ad91d2ca81697fc2\"",",\"x\":94,\"y\":1179,\"w\":1292,\"h\":182},{\"id\":\"bfe4274963a84e2e\",\"type\":\"OpcUa-Browser\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"endpoint\":\"53f4394dbf12c6b7\",\"item\":\"\",\"datatype\":\"\",\"topic\":\"\",\"items\":",[462,8411],{},",\"name\":\"OPC Client Namespace Browse\",\"x\":590,\"y\":1280,\"wires\":[[\"507d2c11c7586957\"]]},{\"id\":\"0662c62c7f0cfac0\",\"type\":\"inject\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Read MyDevice Values @ 1 second\",\"props\":",[462,8414,8415],{},"{\"p\":\"payload\"},{\"p\":\"topic\",\"v\":\"Objects.MyObjects.MyDevice.nodeId\",\"vt\":\"flow\"}",",\"repeat\":\"1\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"payload\":\"\",\"payloadType\":\"date\",\"x\":290,\"y\":1280,\"wires\":[[\"bfe4274963a84e2e\"]]},{\"id\":\"249c223139c5779e\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Read MyDevice\",\"info\":\"\",\"x\":480,\"y\":1240,\"wires\":",[462,8418],{},"},{\"id\":\"efb293f13af17dc1\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Get MyLevel Value\",\"rules\":",[462,8421,7678,8422,7681],{},[462,8423,366],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1030,\"y\":1260,\"wires\":[[\"cd4941a8db3edcb6\"]]},{\"id\":\"507d2c11c7586957\",\"type\":\"switch\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"empty check\",\"property\":\"payload\",\"propertyType\":\"msg\",\"rules\":",[462,8426,7685],{},",\"checkall\":\"true\",\"repair\":false,\"outputs\":1,\"x\":810,\"y\":1280,\"wires\":[[\"efb293f13af17dc1\",\"3b7695a52a1bf6e0\"]]},{\"id\":\"3b7695a52a1bf6e0\",\"type\":\"change\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Get MySwitch Value\",\"rules\":",[462,8429,7678,8430,7681],{},[462,8431,7301],{},",\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1040,\"y\":1320,\"wires\":[[\"ad91d2ca81697fc2\"]]},{\"id\":\"594ec38acadc9673\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Display on Dashboard\",\"info\":\"\",\"x\":1260,\"y\":1220,\"wires\":",[462,8434],{},"},{\"id\":\"d4e2915ba92db8a6\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Parse MyDevice Values\",\"info\":\"\",\"x\":1040,\"y\":1220,\"wires\":",[462,8437],{},"},{\"id\":\"85619f0eab615ac7\",\"type\":\"comment\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Discard Empty Datasets\",\"info\":\"\",\"x\":800,\"y\":1240,\"wires\":",[462,8440],{},"},{\"id\":\"cd4941a8db3edcb6\",\"type\":\"ui-gauge\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"Level\",\"group\":\"ec0ecb26fde8db3e\",\"order\":0,\"width\":3,\"height\":3,\"gtype\":\"gauge-half\",\"gstyle\":\"needle\",\"title\":\"Level\",\"units\":\"%\",\"icon\":\"\",\"prefix\":\"\",\"suffix\":\"\",\"segments\":",[462,8443,8444],{},"{\"from\":\"0\",\"color\":\"#0094ce\"},{\"from\":\"25\",\"color\":\"#0094ce\"},{\"from\":\"50\",\"color\":\"#0094ce\"},{\"from\":\"100\",\"color\":\"#0094ce\"}",",\"min\":0,\"max\":\"100\",\"sizeThickness\":16,\"sizeGap\":4,\"sizeKeyThickness\":8,\"styleRounded\":true,\"styleGlow\":false,\"className\":\"\",\"x\":1250,\"y\":1260,\"wires\":",[462,8447],{},"},{\"id\":\"ad91d2ca81697fc2\",\"type\":\"ui-led\",\"z\":\"5b972161c4e0464e\",\"g\":\"25f95391088d4a08\",\"name\":\"\",\"group\":\"ec0ecb26fde8db3e\",\"order\":-1,\"width\":0,\"height\":0,\"label\":\"Switch\",\"labelPlacement\":\"left\",\"labelAlignment\":\"flex-start\",\"states\":",[462,8450,8451],{},"{\"value\":\"false\",\"valueType\":\"bool\",\"color\":\"#ff0000\"},{\"value\":\"true\",\"valueType\":\"bool\",\"color\":\"#00ff00\"}",",\"allowColorForValueInMessage\":false,\"shape\":\"circle\",\"showBorder\":true,\"showGlow\":true,\"x\":1250,\"y\":1320,\"wires\":",[462,8454],{},"},{\"id\":\"ec0ecb26fde8db3e\",\"type\":\"ui-group\",\"name\":\"MyDevice Status & Control\",\"page\":\"44d3feb2a1143d7b\",\"width\":\"3\",\"height\":\"1\",\"order\":4,\"showTitle\":true,\"className\":\"\",\"visible\":\"true\",\"disabled\":\"false\"},{\"id\":\"3de6c861611c3afa\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Write Mydevices values to OPC UA Server\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,8457,7941],{},[462,8459],{},[462,8461],{},[462,8463],{},[462,8465],{},[462,8467],{},"},{\"id\":\"fa08f0ed04296363\",\"type\":\"ui-switch\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"name\":\"\",\"label\":\"Toggle MySwitch\",\"group\":\"ec0ecb26fde8db3e\",\"order\":0,\"width\":0,\"height\":0,\"passthru\":false,\"topic\":\"topic\",\"topicType\":\"msg\",\"style\":\"\",\"className\":\"\",\"onvalue\":\"true\",\"onvalueType\":\"bool\",\"onicon\":\"\",\"oncolor\":\"\",\"offvalue\":\"false\",\"offvalueType\":\"bool\",\"officon\":\"\",\"offcolor\":\"\",\"x\":210,\"y\":1520,\"wires\":[[\"a66583d91b581cd8\"]]},{\"id\":\"9f591797b56c565d\",\"type\":\"ui-slider\",\"z\":\"5b972161c4e0464e\",\"g\":\"3de6c861611c3afa\",\"group\":\"ec0ecb26fde8db3e\",\"name\":\"\",\"label\":\"Modify MyLevel\",\"tooltip\":\"\",\"order\":0,\"width\":0,\"height\":0,\"passthru\":false,\"outs\":\"all\",\"topic\":\"topic\",\"topicType\":\"msg\",\"thumbLabel\":true,\"min\":\"0\",\"max\":\"100\",\"step\":1,\"className\":\"\",\"x\":200,\"y\":1580,\"wires\":[[\"fb7f57b4da5883ae\"]]},{\"id\":\"a6e9abacd0bdf3b6\",\"type\":\"group\",\"z\":\"5b972161c4e0464e\",\"name\":\"Read Alarms & Events From OPC UA Server\",\"style\":{\"label\":true,\"color\":\"#000000\"},\"nodes\":",[462,8470,8062],{},[462,8472],{},[462,8474,3287],{},[462,8476],{},[462,8478,8075],{},[462,8480,8079],{},[462,8482,8083],{},[462,8484],{},[462,8486],{},[462,8488],{},[7369,8490],{"value":324},[462,8492],{},[7369,8494],{"value":324},[462,8496],{},[7369,8498],{"value":324},[462,8500],{},{"title":458,"searchDepth":523,"depth":523,"links":8502},[8503,8504,8505,8506,8507,8508,8509,8510,8511],{"id":7134,"depth":491,"text":7135},{"id":7176,"depth":491,"text":7177},{"id":7229,"depth":491,"text":7230},{"id":7253,"depth":491,"text":7254},{"id":7557,"depth":491,"text":7558},{"id":7922,"depth":491,"text":7923},{"id":8044,"depth":491,"text":8045},{"id":8195,"depth":491,"text":8196},{"id":7058,"depth":491,"text":7059},{"type":6662,"title":8513,"description":8514},"Deploy Your OPC UA Dashboard with FlowFuse","Sign up for FlowFuse to securely deploy, share, and scale your Node-RED OPC UA client dashboard applications with team collaboration and DevOps pipelines.","2023-07-27","Building a Dashboard-Driven OPC UA Client to Browse, Read, Write, and Get Events from a 3rd party OPC UA Server","blog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-3\u002Fopc-ua-3-title-image.png",{"keywords":8519,"excerpt":8520},"opc ua client node-red, opc ua dashboard, node-red opcua client, opc ua browser node-red, read write opc ua node-red, opc ua alarms events, prosys simulation server",{"type":12,"value":8521},[8522],[15,8523,7112,8524,7116,8526,7120],{},[29,8525,7115],{"href":6639},[29,8527,7119],{"href":6632},"\u002Fblog\u002F2023\u002F07\u002Fhow-to-build-a-opc-client-dashboard-in-node-red",{"title":7105,"description":8516},{"loc":8528},"blog\u002F2023\u002F07\u002Fhow-to-build-a-opc-client-dashboard-in-node-red","Interactive OPC UA Client dashboard that communicates with a 3rd party OPC UA Server",[1696,826,6680,827,6169],"This part of the OPC UA series shows how to build an interactive Node-RED dashboard that connects to a third-party OPC UA server to browse the address space, read and write values, and display alarms and events. Complete flow source code is provided, making it a practical starting point for production OPC UA client applications.","iTvLAoss4hTIIwo4x9-95lGhpygpJvE5KrP3OBAPuPY",{"id":8537,"title":8538,"authors":8539,"body":8540,"cta":10378,"date":10381,"description":10382,"extension":802,"image":10383,"lastUpdated":6154,"meta":10384,"navigation":494,"path":10390,"seo":10391,"sitemap":10392,"stem":10393,"subtitle":10394,"tags":10395,"tldr":10396,"video":3,"__hash__":10397},"blog\u002Fblog\u002F2023\u002F07\u002Fhow-to-deploy-a-basic-opc-ua-server-in-node-red.md","How to Deploy a Basic OPC-UA Server in Node-RED - Part 1 (2026)",[7107],{"type":12,"value":8541,"toc":10371},[8542,8545,8549,8552,8555,8570,8574,8589,8598,8601,8608,8616,8624,8629,8632,8639,8653,8656,8660,8673,8682,8685,8691,8708,8963,8978,9227,9230,9237,9244,9251,9276,9282,9288,9298,9305,9311,9321,9324,9353,9356,9382,9393,9561,9564,9712,9715,10040,10043,10251,10258,10278,10285,10291,10295,10304,10307,10318,10321,10335,10341,10352,10358,10362,10365,10368],[15,8543,8544],{},"This article is the first part of a series of OPC-UA content.  Here, we will explain some basic concepts of OPC-UA as they apply to building a server in Node-RED, then walk through and deploy an example OPC-UA Server.",[48,8546,8548],{"id":8547},"what-is-opc-ua","What is OPC-UA?",[15,8550,8551],{},"Open Platform Communications Unified Architecture (OPC UA) is an open, platform independent communication framework frequently utilized in industrial automation, and is considered one of the key protocol standards for Industry 4.0 and Industrial IoT (IIoT).  The standard is developed and maintained by a consortium called the OPC Foundation, with recognizable industry names such as Siemens, Honeywell, Microsoft, Beckhoff, SAP, Yokogawa, ABB, Rockwell, and Schneider Electric.",[15,8553,8554],{},"Because of OPC-UA’s wide industry acceptance, it is increasingly becoming natively supported on devices and systems spanning the entirety of the automation pyramid.",[15,8556,8557,8562],{},[39,8558],{"alt":8559,"src":8560,"title":8561},"\"Automation Pyramid\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fautomation-pyramid.jpg","Automation Pyramid",[44,8563,8564,8565],{},"Image reference - ",[29,8566,8569],{"href":8567,"rel":8568},"https:\u002F\u002Fwww.motioncontroltips.com\u002Fwhat-is-opc-ua-and-how-does-it-compare-with-industrial-ethernet\u002F",[33],"imagecontroltips.com",[48,8571,8573],{"id":8572},"fieldbus-model-vs-opc-ua-information-model","Fieldbus Model vs OPC-UA Information Model",[15,8575,8576,8577,8582],{},"As of today, industrial ethernet fieldbuses dominate the field\u002Fdevice-level (level 0) and controller\u002FPLC-level (level 1) of the automation pyramid.\n",[39,8578],{"alt":8579,"src":8580,"title":8581},"\"OPC-UA Pyramid\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002FOPC-UA-pyramid-2.webp","OPC-UA Pyramid",[44,8583,8564,8584],{},[29,8585,8588],{"href":8586,"rel":8587},"https:\u002F\u002Fwww.mdpi.com\u002F1424-8220\u002F21\u002F14\u002F4656",[33],"mdpi.com",[15,8590,8591,8592,8597],{},"Fieldbuses such as Profinet, Ethernet\u002FIP, and EtherCAT, employ deterministic, real-time communication, which is essential for mission-critical and safety-oriented automation tasks.  OPC-UA is most commonly encountered at the SCADA level and above (level 2-4).  However, with the inclusion of ",[29,8593,8596],{"href":8594,"rel":8595},"https:\u002F\u002Fwww.tttech-industrial.com\u002Fresource-library\u002Fblog-posts\u002Fopc-ua-fx",[33],"Time Sensitive Networking (TSN) into the OPC-UA technology stack",", OPC-UA can be feasibly used for real-time communication all the way down to the device level.",[15,8599,8600],{},"Traditionally, fieldbus protocols transmit only raw data from field devices (ie, a float to represent a pressure, or a boolean to represent the position of a switch).  The fieldbus data gets pushed up the automation stack layer by layer, where eventually it will be converted to a format suitable for IT systems to consume (such as OPC-UA).",[15,8602,8603],{},[39,8604],{"alt":8605,"src":8606,"title":8607},"\"Fieldbus Model\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Ffieldbus-model.png","Fieldbus Model",[15,8609,8610,8611,8615],{},"In contrast to fieldbus protocols, OPC-UA represents automation data in the form of nodes. The framework for constructing nodes is referred to as the ",[29,8612,8614],{"href":8613},"\u002Fblog\u002F2023\u002F07\u002Flhttps:\u002Freference.opcfoundation.org\u002FCore\u002FPart5\u002Fv104\u002Fdocs","OPC Information model",", and consists of pre-defined classes and methods that are programmed in the OPC Server address space.",[15,8617,8618,8623],{},[39,8619],{"alt":8620,"src":8621,"title":8622},"\"OPC Information Model\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-information-model.png","OPC Information Model","\nDevices can be described as objects that give a holistic view of the device, beyond simply the raw value.  To construct a device object, we can take different individual attributes associated with a device, such as the transmitter raw value, transmitter fault flag, alarm setpoint, and combine them, similar to how user-defined datatypes (UDTs) are objects used to represent devices in PLCs.  The information model also defines a folder structure, to allow devices information to reside in a structured hierarchy.  Using the example temperature transmitter above, an example folder structure can be constructed as follows:",[15,8625,8626],{},[89,8627,8628],{},"\u002FRoot\u002FObjects\u002FCalcinator 1 PLC\u002FTemperature Transmitters\u002FTank 1 Temperature\u002FTransmitter Value",[15,8630,8631],{},"This folder structure will be exposed via the OPC Client browser, allowing end-users to easily “drill down” to individual node information in a logical manner.",[15,8633,8634,8638],{},[39,8635],{"alt":8636,"src":8637,"title":8622},"\"OPC Client Browser\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-client-browser.png","\nIn summary, OPC-UA represents a trade-off between complex information modeling, with the versatility for that data to be consumed by devices and systems all the way up the automation pyramid layers.  The data does not have to pass through subsequent automation layers on the way up, nor does the data need to undergo any conversion along the way.",[15,8640,8641,8646],{},[39,8642],{"alt":8643,"src":8644,"title":8645},"\"OPC-UA Distributed Model\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002FOPC-UA-distributed-model.jpg","OPC-UA Distributed Model",[44,8647,8564,8648],{},[29,8649,8652],{"href":8650,"rel":8651},"https:\u002F\u002Fifr.org\u002Fpost\u002Ffaster-robot-communication-through-the-opc-robotics-companion-specification",[33],"ifr.org",[15,8654,8655],{},"The OPC client simply needs to subscribe to the OPC Server endpoint url (ex. opc.tcp:\u002F\u002Fserver.address), and the client will be able to browse the structured OPC data as it’s modeled in the server.  Any client will receive the information in the same manner, regardless if it’s a PLC, SCADA, MES, or ERP system.  This opens the possibility for horizontal and vertical system integration in a standardized manner. Additionally, the more information that is exposed about a device, the easier it is to track, and use said data to autonomously reconfigure, or pre-emptively take maintenance actions.",[48,8657,8659],{"id":8658},"deploying-an-example-opc-ua-server-in-node-red","Deploying an Example OPC-UA Server in Node-RED",[15,8661,8662,8663,8668,8669,8672],{},"With some background on OPC-UA and how information is modeled in mind, we can take a look at the ",[29,8664,8667],{"href":8665,"rel":8666},"https:\u002F\u002Fflows.nodered.org\u002Fnode\u002Fnode-red-contrib-opcua-server",[33],"node-red-contrib-opcua-server"," node, which is merely a compact version of the ",[29,8670,2963],{"href":6240,"rel":8671},[33]," node that only focuses on the OPC-UA server and hence requires less dependencies.",[15,8674,8675,8676,8681],{},"An ",[29,8677,8680],{"href":8678,"rel":8679},"https:\u002F\u002Fgithub.com\u002FBiancoRoyal\u002Fnode-red-contrib-opcua-server\u002Fblob\u002Fmaster\u002Fexamples\u002Fserver-with-context.json",[33],"example flow"," is provided on github that can serve as a basis for understanding how a OPC-UA server is constructed.  Let’s get the example server up and running.",[15,8683,8684],{},"Deploying the example flow yields the following result -",[15,8686,8687],{},[39,8688],{"alt":8689,"src":8690,"title":8689},"Compact Server Flow","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fcompact-server-flow.png",[56,8692,8693],{},[59,8694,8695,8696,8699,8700,8703,8704,8707],{},"an inject node is trigging the function ",[89,8697,8698],{},"set flow context Inputs"," at a one second interval, which creates 7 randomly generated float values and stores them as flow context variables, ",[89,8701,8702],{},"isoInput2"," - ",[89,8705,8706],{},"isoInput8"," (isolated inputs).  The values will change to a new random number each time the node is injected.",[453,8709,8711],{"className":455,"code":8710,"language":457,"meta":458,"style":458},"flow.set('isoInput2', Math.random() + 12.0)\nflow.set('isoInput3', Math.random() + 13.0)\nflow.set('isoInput4', Math.random() + 14.0)\nflow.set('isoInput5', Math.random() + 15.0)\nflow.set('isoInput6', Math.random() + 16.0)\nflow.set('isoInput7', Math.random() + 17.0)\nflow.set('isoInput8', Math.random() + 18.0)\n\n...\n",[89,8712,8713,8751,8785,8819,8853,8887,8921,8954,8958],{"__ignoreMap":458},[462,8714,8715,8718,8720,8723,8725,8727,8729,8731,8733,8736,8738,8741,8743,8745,8748],{"class":464,"line":465},[462,8716,8717],{"class":472},"flow",[462,8719,215],{"class":476},[462,8721,8722],{"class":3607},"set",[462,8724,4069],{"class":472},[462,8726,5591],{"class":476},[462,8728,8702],{"class":514},[462,8730,5591],{"class":476},[462,8732,3055],{"class":476},[462,8734,8735],{"class":472}," Math",[462,8737,215],{"class":476},[462,8739,8740],{"class":3607},"random",[462,8742,3619],{"class":472},[462,8744,4405],{"class":476},[462,8746,8747],{"class":3625}," 12.0",[462,8749,8750],{"class":472},")\n",[462,8752,8753,8755,8757,8759,8761,8763,8766,8768,8770,8772,8774,8776,8778,8780,8783],{"class":464,"line":491},[462,8754,8717],{"class":472},[462,8756,215],{"class":476},[462,8758,8722],{"class":3607},[462,8760,4069],{"class":472},[462,8762,5591],{"class":476},[462,8764,8765],{"class":514},"isoInput3",[462,8767,5591],{"class":476},[462,8769,3055],{"class":476},[462,8771,8735],{"class":472},[462,8773,215],{"class":476},[462,8775,8740],{"class":3607},[462,8777,3619],{"class":472},[462,8779,4405],{"class":476},[462,8781,8782],{"class":3625}," 13.0",[462,8784,8750],{"class":472},[462,8786,8787,8789,8791,8793,8795,8797,8800,8802,8804,8806,8808,8810,8812,8814,8817],{"class":464,"line":498},[462,8788,8717],{"class":472},[462,8790,215],{"class":476},[462,8792,8722],{"class":3607},[462,8794,4069],{"class":472},[462,8796,5591],{"class":476},[462,8798,8799],{"class":514},"isoInput4",[462,8801,5591],{"class":476},[462,8803,3055],{"class":476},[462,8805,8735],{"class":472},[462,8807,215],{"class":476},[462,8809,8740],{"class":3607},[462,8811,3619],{"class":472},[462,8813,4405],{"class":476},[462,8815,8816],{"class":3625}," 14.0",[462,8818,8750],{"class":472},[462,8820,8821,8823,8825,8827,8829,8831,8834,8836,8838,8840,8842,8844,8846,8848,8851],{"class":464,"line":523},[462,8822,8717],{"class":472},[462,8824,215],{"class":476},[462,8826,8722],{"class":3607},[462,8828,4069],{"class":472},[462,8830,5591],{"class":476},[462,8832,8833],{"class":514},"isoInput5",[462,8835,5591],{"class":476},[462,8837,3055],{"class":476},[462,8839,8735],{"class":472},[462,8841,215],{"class":476},[462,8843,8740],{"class":3607},[462,8845,3619],{"class":472},[462,8847,4405],{"class":476},[462,8849,8850],{"class":3625}," 15.0",[462,8852,8750],{"class":472},[462,8854,8855,8857,8859,8861,8863,8865,8868,8870,8872,8874,8876,8878,8880,8882,8885],{"class":464,"line":544},[462,8856,8717],{"class":472},[462,8858,215],{"class":476},[462,8860,8722],{"class":3607},[462,8862,4069],{"class":472},[462,8864,5591],{"class":476},[462,8866,8867],{"class":514},"isoInput6",[462,8869,5591],{"class":476},[462,8871,3055],{"class":476},[462,8873,8735],{"class":472},[462,8875,215],{"class":476},[462,8877,8740],{"class":3607},[462,8879,3619],{"class":472},[462,8881,4405],{"class":476},[462,8883,8884],{"class":3625}," 16.0",[462,8886,8750],{"class":472},[462,8888,8889,8891,8893,8895,8897,8899,8902,8904,8906,8908,8910,8912,8914,8916,8919],{"class":464,"line":549},[462,8890,8717],{"class":472},[462,8892,215],{"class":476},[462,8894,8722],{"class":3607},[462,8896,4069],{"class":472},[462,8898,5591],{"class":476},[462,8900,8901],{"class":514},"isoInput7",[462,8903,5591],{"class":476},[462,8905,3055],{"class":476},[462,8907,8735],{"class":472},[462,8909,215],{"class":476},[462,8911,8740],{"class":3607},[462,8913,3619],{"class":472},[462,8915,4405],{"class":476},[462,8917,8918],{"class":3625}," 17.0",[462,8920,8750],{"class":472},[462,8922,8923,8925,8927,8929,8931,8933,8935,8937,8939,8941,8943,8945,8947,8949,8952],{"class":464,"line":564},[462,8924,8717],{"class":472},[462,8926,215],{"class":476},[462,8928,8722],{"class":3607},[462,8930,4069],{"class":472},[462,8932,5591],{"class":476},[462,8934,8706],{"class":514},[462,8936,5591],{"class":476},[462,8938,3055],{"class":476},[462,8940,8735],{"class":472},[462,8942,215],{"class":476},[462,8944,8740],{"class":3607},[462,8946,3619],{"class":472},[462,8948,4405],{"class":476},[462,8950,8951],{"class":3625}," 18.0",[462,8953,8750],{"class":472},[462,8955,8956],{"class":464,"line":570},[462,8957,495],{"emptyLinePlaceholder":494},[462,8959,8960],{"class":464,"line":583},[462,8961,8962],{"class":476},"...\n",[56,8964,8965],{},[59,8966,8967,8968,8971,8972,8703,8975,8707],{},"another inject node is triggering the function ",[89,8969,8970],{},"set flow context Outputs",", also at a one second interval, which creates another set of 7 randomly generated float values and stores them as flow context variables, ",[89,8973,8974],{},"isoOutput2",[89,8976,8977],{},"isoOutput8",[453,8979,8981],{"className":455,"code":8980,"language":457,"meta":458,"style":458},"flow.set('isoOutput2', Math.random() + 2.0)\nflow.set('isoOutput3', Math.random() + 3.0)\nflow.set('isoOutput4', Math.random() + 4.0)\nflow.set('isoOutput5', Math.random() + 5.0)\nflow.set('isoOutput6', Math.random() + 6.0)\nflow.set('isoOutput7', Math.random() + 7.0)\nflow.set('isoOutput8', Math.random() + 8.0)\n\n...\n",[89,8982,8983,9016,9050,9084,9118,9152,9186,9219,9223],{"__ignoreMap":458},[462,8984,8985,8987,8989,8991,8993,8995,8997,8999,9001,9003,9005,9007,9009,9011,9014],{"class":464,"line":465},[462,8986,8717],{"class":472},[462,8988,215],{"class":476},[462,8990,8722],{"class":3607},[462,8992,4069],{"class":472},[462,8994,5591],{"class":476},[462,8996,8974],{"class":514},[462,8998,5591],{"class":476},[462,9000,3055],{"class":476},[462,9002,8735],{"class":472},[462,9004,215],{"class":476},[462,9006,8740],{"class":3607},[462,9008,3619],{"class":472},[462,9010,4405],{"class":476},[462,9012,9013],{"class":3625}," 2.0",[462,9015,8750],{"class":472},[462,9017,9018,9020,9022,9024,9026,9028,9031,9033,9035,9037,9039,9041,9043,9045,9048],{"class":464,"line":491},[462,9019,8717],{"class":472},[462,9021,215],{"class":476},[462,9023,8722],{"class":3607},[462,9025,4069],{"class":472},[462,9027,5591],{"class":476},[462,9029,9030],{"class":514},"isoOutput3",[462,9032,5591],{"class":476},[462,9034,3055],{"class":476},[462,9036,8735],{"class":472},[462,9038,215],{"class":476},[462,9040,8740],{"class":3607},[462,9042,3619],{"class":472},[462,9044,4405],{"class":476},[462,9046,9047],{"class":3625}," 3.0",[462,9049,8750],{"class":472},[462,9051,9052,9054,9056,9058,9060,9062,9065,9067,9069,9071,9073,9075,9077,9079,9082],{"class":464,"line":498},[462,9053,8717],{"class":472},[462,9055,215],{"class":476},[462,9057,8722],{"class":3607},[462,9059,4069],{"class":472},[462,9061,5591],{"class":476},[462,9063,9064],{"class":514},"isoOutput4",[462,9066,5591],{"class":476},[462,9068,3055],{"class":476},[462,9070,8735],{"class":472},[462,9072,215],{"class":476},[462,9074,8740],{"class":3607},[462,9076,3619],{"class":472},[462,9078,4405],{"class":476},[462,9080,9081],{"class":3625}," 4.0",[462,9083,8750],{"class":472},[462,9085,9086,9088,9090,9092,9094,9096,9099,9101,9103,9105,9107,9109,9111,9113,9116],{"class":464,"line":523},[462,9087,8717],{"class":472},[462,9089,215],{"class":476},[462,9091,8722],{"class":3607},[462,9093,4069],{"class":472},[462,9095,5591],{"class":476},[462,9097,9098],{"class":514},"isoOutput5",[462,9100,5591],{"class":476},[462,9102,3055],{"class":476},[462,9104,8735],{"class":472},[462,9106,215],{"class":476},[462,9108,8740],{"class":3607},[462,9110,3619],{"class":472},[462,9112,4405],{"class":476},[462,9114,9115],{"class":3625}," 5.0",[462,9117,8750],{"class":472},[462,9119,9120,9122,9124,9126,9128,9130,9133,9135,9137,9139,9141,9143,9145,9147,9150],{"class":464,"line":544},[462,9121,8717],{"class":472},[462,9123,215],{"class":476},[462,9125,8722],{"class":3607},[462,9127,4069],{"class":472},[462,9129,5591],{"class":476},[462,9131,9132],{"class":514},"isoOutput6",[462,9134,5591],{"class":476},[462,9136,3055],{"class":476},[462,9138,8735],{"class":472},[462,9140,215],{"class":476},[462,9142,8740],{"class":3607},[462,9144,3619],{"class":472},[462,9146,4405],{"class":476},[462,9148,9149],{"class":3625}," 6.0",[462,9151,8750],{"class":472},[462,9153,9154,9156,9158,9160,9162,9164,9167,9169,9171,9173,9175,9177,9179,9181,9184],{"class":464,"line":549},[462,9155,8717],{"class":472},[462,9157,215],{"class":476},[462,9159,8722],{"class":3607},[462,9161,4069],{"class":472},[462,9163,5591],{"class":476},[462,9165,9166],{"class":514},"isoOutput7",[462,9168,5591],{"class":476},[462,9170,3055],{"class":476},[462,9172,8735],{"class":472},[462,9174,215],{"class":476},[462,9176,8740],{"class":3607},[462,9178,3619],{"class":472},[462,9180,4405],{"class":476},[462,9182,9183],{"class":3625}," 7.0",[462,9185,8750],{"class":472},[462,9187,9188,9190,9192,9194,9196,9198,9200,9202,9204,9206,9208,9210,9212,9214,9217],{"class":464,"line":564},[462,9189,8717],{"class":472},[462,9191,215],{"class":476},[462,9193,8722],{"class":3607},[462,9195,4069],{"class":472},[462,9197,5591],{"class":476},[462,9199,8977],{"class":514},[462,9201,5591],{"class":476},[462,9203,3055],{"class":476},[462,9205,8735],{"class":472},[462,9207,215],{"class":476},[462,9209,8740],{"class":3607},[462,9211,3619],{"class":472},[462,9213,4405],{"class":476},[462,9215,9216],{"class":3625}," 8.0",[462,9218,8750],{"class":472},[462,9220,9221],{"class":464,"line":570},[462,9222,495],{"emptyLinePlaceholder":494},[462,9224,9225],{"class":464,"line":583},[462,9226,8962],{"class":476},[15,9228,9229],{},"We can confirm the values are being stored in memory by checking the flow context data and pressing the refresh button.",[15,9231,9232],{},[39,9233],{"alt":9234,"src":9235,"title":9236},"\"Screenshot showing the Context Data option\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fcontext-data-1.png","Screenshot showing the Context Data option",[15,9238,9239,9243],{},[39,9240],{"alt":9241,"src":9242,"title":9241},"Screenshot showing the flow variables in the context data tab","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fcontext-data-2.png","\nEach time we hit refresh, the values change, confirming that the values are randomly changing every second.",[15,9245,9246,9247,9250],{},"The last, and most important part of the flow, is the ",[89,9248,9249],{},"Compact-Server"," node, which actually stands alone without any incoming or outgoing connections.",[15,9252,9253,8151,9258,9260,9261,9264,9265,222,9268,9271,9272,9275],{},[39,9254],{"alt":9255,"src":9256,"title":9257},"\"Compact Server Node\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fcompact-server-node.png","Compact Server Node",[89,9259,9249],{}," node properties, the first tab is ",[89,9262,9263],{},"Settings",", and the two important properties here are ",[89,9266,9267],{},"Port",[89,9269,9270],{},"Show Errors",".  As can be seen in the node screenshot above, the node is reporting ",[89,9273,9274],{},"active",", which means the server is configured correctly.",[15,9277,9278],{},[39,9279],{"alt":9280,"src":9281,"title":9280},"Screenshot showing the Settings Tab of compact server node","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fsettings-tab.png",[15,9283,1758,9284,9287],{},[89,9285,9286],{},"Limits"," tab specifies some default limits that we can configure if we like, but are not necessary to be modified for test purposes.",[15,9289,1758,9290,9293,9294,9297],{},[89,9291,9292],{},"Security"," tab has one important option, ",[89,9295,9296],{},"Allow Anonymous",".  By default, anonymous access is enabled.",[15,9299,9300,9304],{},[39,9301],{"alt":9302,"src":9303,"title":9302},"Screenshot showing the Security Tab of compact server node","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fsecurity-tab.png","\nFor a production system, we will want to enable security, but for test purposes, we will leave anonymous access enabled.",[15,9306,9307,9310],{},[89,9308,9309],{},"Users & Sets"," tab is related to security and permissions.  We can leave this empty for testing.",[15,9312,1758,9313,9315,9316,215],{},[89,9314,7417],{}," tab is where our server OPC Information Model is constructed, using classes and methods from the ",[29,9317,9320],{"href":9318,"rel":9319},"https:\u002F\u002Fnode-opcua.github.io\u002F",[33],"node-opcua sdk",[15,9322,9323],{},"Breaking down the provided example code for further context, it starts with a function that is responsible for invoking the OPC-UA server,",[453,9325,9327],{"className":455,"code":9326,"language":457,"meta":458,"style":458},"  const opcua = coreServer.choreCompact.opcua;\n",[89,9328,9329],{"__ignoreMap":458},[462,9330,9331,9334,9337,9339,9342,9344,9347,9349,9351],{"class":464,"line":465},[462,9332,9333],{"class":468},"  const",[462,9335,9336],{"class":472}," opcua ",[462,9338,477],{"class":476},[462,9340,9341],{"class":472}," coreServer",[462,9343,215],{"class":476},[462,9345,9346],{"class":472},"choreCompact",[462,9348,215],{"class":476},[462,9350,827],{"class":472},[462,9352,488],{"class":476},[15,9354,9355],{},"and then the namespace is created.",[453,9357,9359],{"className":455,"code":9358,"language":457,"meta":458,"style":458},"const namespace = addressSpace.getOwnNamespace();\n",[89,9360,9361],{"__ignoreMap":458},[462,9362,9363,9365,9368,9370,9373,9375,9378,9380],{"class":464,"line":465},[462,9364,469],{"class":468},[462,9366,9367],{"class":472}," namespace ",[462,9369,477],{"class":476},[462,9371,9372],{"class":472}," addressSpace",[462,9374,215],{"class":476},[462,9376,9377],{"class":3607},"getOwnNamespace",[462,9379,3662],{"class":472},[462,9381,488],{"class":476},[15,9383,9384,9385,9388,9389,9392],{},"Further down, the variables that will be published by the server (which are our ",[89,9386,9387],{},"isoInput"," & ",[89,9390,9391],{},"isoOutput"," flow context variables) are initialized,",[453,9394,9396],{"className":455,"code":9395,"language":457,"meta":458,"style":458},"  this.sandboxFlowContext.set(\"isoInput1\", 0);\n  this.setInterval(() => {\n    flexServerInternals.sandboxFlowContext.set(\n      \"isoInput1\",\n      Math.random() + 50.0\n    );\n  }, 500);\n  this.sandboxFlowContext.set(\"isoInput2\", 0);\n  this.sandboxFlowContext.set(\"isoInput3\", 0);\n...\n",[89,9397,9398,9428,9443,9459,9470,9486,9493,9505,9531,9557],{"__ignoreMap":458},[462,9399,9400,9403,9406,9408,9410,9412,9414,9417,9419,9421,9424,9426],{"class":464,"line":465},[462,9401,9402],{"class":476},"  this.",[462,9404,9405],{"class":472},"sandboxFlowContext",[462,9407,215],{"class":476},[462,9409,8722],{"class":3607},[462,9411,4069],{"class":472},[462,9413,518],{"class":476},[462,9415,9416],{"class":514},"isoInput1",[462,9418,518],{"class":476},[462,9420,3055],{"class":476},[462,9422,9423],{"class":3625}," 0",[462,9425,3639],{"class":472},[462,9427,488],{"class":476},[462,9429,9430,9432,9435,9437,9439,9441],{"class":464,"line":491},[462,9431,9402],{"class":476},[462,9433,9434],{"class":3607},"setInterval",[462,9436,4069],{"class":472},[462,9438,3662],{"class":476},[462,9440,5633],{"class":468},[462,9442,5636],{"class":476},[462,9444,9445,9448,9450,9452,9454,9456],{"class":464,"line":498},[462,9446,9447],{"class":472},"    flexServerInternals",[462,9449,215],{"class":476},[462,9451,9405],{"class":472},[462,9453,215],{"class":476},[462,9455,8722],{"class":3607},[462,9457,9458],{"class":573},"(\n",[462,9460,9461,9464,9466,9468],{"class":464,"line":523},[462,9462,9463],{"class":476},"      \"",[462,9465,9416],{"class":514},[462,9467,518],{"class":476},[462,9469,609],{"class":476},[462,9471,9472,9475,9477,9479,9481,9483],{"class":464,"line":544},[462,9473,9474],{"class":472},"      Math",[462,9476,215],{"class":476},[462,9478,8740],{"class":3607},[462,9480,3619],{"class":573},[462,9482,4405],{"class":476},[462,9484,9485],{"class":3625}," 50.0\n",[462,9487,9488,9491],{"class":464,"line":549},[462,9489,9490],{"class":573},"    )",[462,9492,488],{"class":476},[462,9494,9495,9498,9501,9503],{"class":464,"line":564},[462,9496,9497],{"class":476},"  },",[462,9499,9500],{"class":3625}," 500",[462,9502,3639],{"class":472},[462,9504,488],{"class":476},[462,9506,9507,9509,9511,9513,9515,9517,9519,9521,9523,9525,9527,9529],{"class":464,"line":570},[462,9508,9402],{"class":476},[462,9510,9405],{"class":472},[462,9512,215],{"class":476},[462,9514,8722],{"class":3607},[462,9516,4069],{"class":472},[462,9518,518],{"class":476},[462,9520,8702],{"class":514},[462,9522,518],{"class":476},[462,9524,3055],{"class":476},[462,9526,9423],{"class":3625},[462,9528,3639],{"class":472},[462,9530,488],{"class":476},[462,9532,9533,9535,9537,9539,9541,9543,9545,9547,9549,9551,9553,9555],{"class":464,"line":583},[462,9534,9402],{"class":476},[462,9536,9405],{"class":472},[462,9538,215],{"class":476},[462,9540,8722],{"class":3607},[462,9542,4069],{"class":472},[462,9544,518],{"class":476},[462,9546,8765],{"class":514},[462,9548,518],{"class":476},[462,9550,3055],{"class":476},[462,9552,9423],{"class":3625},[462,9554,3639],{"class":472},[462,9556,488],{"class":476},[462,9558,9559],{"class":464,"line":589},[462,9560,8962],{"class":476},[15,9562,9563],{},"and an OPC folder structure is defined.",[453,9565,9567],{"className":455,"code":9566,"language":457,"meta":458,"style":458},"  coreServer.debugLog(\"init dynamic address space\");\n  const rootFolder = addressSpace.findNode(\"RootFolder\");\n\n  node.warn(\"construct new address space for OPC UA\");\n\n  const myDevice = namespace.addFolder(rootFolder.objects, {\n    \"browseName\": \"RaspberryPI-Zero-WLAN\"\n  });\n...\n",[89,9568,9569,9592,9621,9625,9648,9652,9681,9699,9708],{"__ignoreMap":458},[462,9570,9571,9574,9576,9579,9581,9583,9586,9588,9590],{"class":464,"line":465},[462,9572,9573],{"class":472},"  coreServer",[462,9575,215],{"class":476},[462,9577,9578],{"class":3607},"debugLog",[462,9580,4069],{"class":472},[462,9582,518],{"class":476},[462,9584,9585],{"class":514},"init dynamic address space",[462,9587,518],{"class":476},[462,9589,3639],{"class":472},[462,9591,488],{"class":476},[462,9593,9594,9596,9599,9601,9603,9605,9608,9610,9612,9615,9617,9619],{"class":464,"line":491},[462,9595,9333],{"class":468},[462,9597,9598],{"class":472}," rootFolder ",[462,9600,477],{"class":476},[462,9602,9372],{"class":472},[462,9604,215],{"class":476},[462,9606,9607],{"class":3607},"findNode",[462,9609,4069],{"class":472},[462,9611,518],{"class":476},[462,9613,9614],{"class":514},"RootFolder",[462,9616,518],{"class":476},[462,9618,3639],{"class":472},[462,9620,488],{"class":476},[462,9622,9623],{"class":464,"line":498},[462,9624,495],{"emptyLinePlaceholder":494},[462,9626,9627,9630,9632,9635,9637,9639,9642,9644,9646],{"class":464,"line":523},[462,9628,9629],{"class":472},"  node",[462,9631,215],{"class":476},[462,9633,9634],{"class":3607},"warn",[462,9636,4069],{"class":472},[462,9638,518],{"class":476},[462,9640,9641],{"class":514},"construct new address space for OPC UA",[462,9643,518],{"class":476},[462,9645,3639],{"class":472},[462,9647,488],{"class":476},[462,9649,9650],{"class":464,"line":544},[462,9651,495],{"emptyLinePlaceholder":494},[462,9653,9654,9656,9659,9661,9664,9666,9669,9672,9674,9677,9679],{"class":464,"line":549},[462,9655,9333],{"class":468},[462,9657,9658],{"class":472}," myDevice ",[462,9660,477],{"class":476},[462,9662,9663],{"class":472}," namespace",[462,9665,215],{"class":476},[462,9667,9668],{"class":3607},"addFolder",[462,9670,9671],{"class":472},"(rootFolder",[462,9673,215],{"class":476},[462,9675,9676],{"class":472},"objects",[462,9678,3055],{"class":476},[462,9680,5636],{"class":476},[462,9682,9683,9686,9688,9690,9692,9694,9697],{"class":464,"line":564},[462,9684,9685],{"class":476},"    \"",[462,9687,7513],{"class":573},[462,9689,518],{"class":476},[462,9691,577],{"class":476},[462,9693,511],{"class":476},[462,9695,9696],{"class":514},"RaspberryPI-Zero-WLAN",[462,9698,625],{"class":476},[462,9700,9701,9704,9706],{"class":464,"line":570},[462,9702,9703],{"class":476},"  }",[462,9705,3639],{"class":472},[462,9707,488],{"class":476},[462,9709,9710],{"class":464,"line":583},[462,9711,8962],{"class":476},[15,9713,9714],{},"Then, with our variables and folder structure defined, nodes are added to the namespace for each context variable.",[453,9716,9718],{"className":455,"code":9717,"language":457,"meta":458,"style":458},"  const gpioDI1 = namespace.addVariable({\n    \"organizedBy\": isoInputs,\n    \"browseName\": \"I1\",\n    \"nodeId\": \"ns=1;s=Isolated_Input1\",\n    \"dataType\": \"Double\",\n    \"value\": {\n      \"get\": function() {\n        return new Variant({\n          \"dataType\": DataType.Double,\n          \"value\": flexServerInternals.sandboxFlowContext.get(\"isoInput1\")\n        });\n      },\n      \"set\": function(variant) {\n        flexServerInternals.sandboxFlowContext.set(\n          \"isoInput1\",\n          parseFloat(variant.value)\n        );\n        return opcua.StatusCodes.Good;\n      }\n    }\n  });\n\n...\n",[89,9719,9720,9740,9756,9775,9794,9813,9825,9843,9857,9877,9908,9917,9922,9943,9958,9968,9983,9991,10010,10016,10021,10030,10035],{"__ignoreMap":458},[462,9721,9722,9724,9727,9729,9731,9733,9736,9738],{"class":464,"line":465},[462,9723,9333],{"class":468},[462,9725,9726],{"class":472}," gpioDI1 ",[462,9728,477],{"class":476},[462,9730,9663],{"class":472},[462,9732,215],{"class":476},[462,9734,9735],{"class":3607},"addVariable",[462,9737,4069],{"class":472},[462,9739,5757],{"class":476},[462,9741,9742,9744,9747,9749,9751,9754],{"class":464,"line":491},[462,9743,9685],{"class":476},[462,9745,9746],{"class":573},"organizedBy",[462,9748,518],{"class":476},[462,9750,577],{"class":476},[462,9752,9753],{"class":472}," isoInputs",[462,9755,609],{"class":476},[462,9757,9758,9760,9762,9764,9766,9768,9771,9773],{"class":464,"line":498},[462,9759,9685],{"class":476},[462,9761,7513],{"class":573},[462,9763,518],{"class":476},[462,9765,577],{"class":476},[462,9767,511],{"class":476},[462,9769,9770],{"class":514},"I1",[462,9772,518],{"class":476},[462,9774,609],{"class":476},[462,9776,9777,9779,9781,9783,9785,9787,9790,9792],{"class":464,"line":523},[462,9778,9685],{"class":476},[462,9780,7524],{"class":573},[462,9782,518],{"class":476},[462,9784,577],{"class":476},[462,9786,511],{"class":476},[462,9788,9789],{"class":514},"ns=1;s=Isolated_Input1",[462,9791,518],{"class":476},[462,9793,609],{"class":476},[462,9795,9796,9798,9801,9803,9805,9807,9809,9811],{"class":464,"line":544},[462,9797,9685],{"class":476},[462,9799,9800],{"class":573},"dataType",[462,9802,518],{"class":476},[462,9804,577],{"class":476},[462,9806,511],{"class":476},[462,9808,332],{"class":514},[462,9810,518],{"class":476},[462,9812,609],{"class":476},[462,9814,9815,9817,9819,9821,9823],{"class":464,"line":549},[462,9816,9685],{"class":476},[462,9818,5703],{"class":573},[462,9820,518],{"class":476},[462,9822,577],{"class":476},[462,9824,5636],{"class":476},[462,9826,9827,9829,9832,9834,9836,9839,9841],{"class":464,"line":564},[462,9828,9463],{"class":476},[462,9830,9831],{"class":573},"get",[462,9833,518],{"class":476},[462,9835,577],{"class":476},[462,9837,9838],{"class":468}," function",[462,9840,3662],{"class":476},[462,9842,5636],{"class":476},[462,9844,9845,9848,9850,9853,9855],{"class":464,"line":570},[462,9846,9847],{"class":650},"        return",[462,9849,3604],{"class":476},[462,9851,9852],{"class":3607}," Variant",[462,9854,4069],{"class":573},[462,9856,5757],{"class":476},[462,9858,9859,9862,9864,9866,9868,9871,9873,9875],{"class":464,"line":583},[462,9860,9861],{"class":476},"          \"",[462,9863,9800],{"class":573},[462,9865,518],{"class":476},[462,9867,577],{"class":476},[462,9869,9870],{"class":472}," DataType",[462,9872,215],{"class":476},[462,9874,332],{"class":472},[462,9876,609],{"class":476},[462,9878,9879,9881,9883,9885,9887,9890,9892,9894,9896,9898,9900,9902,9904,9906],{"class":464,"line":589},[462,9880,9861],{"class":476},[462,9882,5703],{"class":573},[462,9884,518],{"class":476},[462,9886,577],{"class":476},[462,9888,9889],{"class":472}," flexServerInternals",[462,9891,215],{"class":476},[462,9893,9405],{"class":472},[462,9895,215],{"class":476},[462,9897,9831],{"class":3607},[462,9899,4069],{"class":573},[462,9901,518],{"class":476},[462,9903,9416],{"class":514},[462,9905,518],{"class":476},[462,9907,8750],{"class":573},[462,9909,9910,9913,9915],{"class":464,"line":594},[462,9911,9912],{"class":476},"        }",[462,9914,3639],{"class":573},[462,9916,488],{"class":476},[462,9918,9919],{"class":464,"line":612},[462,9920,9921],{"class":476},"      },\n",[462,9923,9924,9926,9928,9930,9932,9934,9936,9939,9941],{"class":464,"line":628},[462,9925,9463],{"class":476},[462,9927,8722],{"class":573},[462,9929,518],{"class":476},[462,9931,577],{"class":476},[462,9933,9838],{"class":468},[462,9935,4069],{"class":476},[462,9937,9938],{"class":5629},"variant",[462,9940,3639],{"class":476},[462,9942,5636],{"class":476},[462,9944,9945,9948,9950,9952,9954,9956],{"class":464,"line":634},[462,9946,9947],{"class":472},"        flexServerInternals",[462,9949,215],{"class":476},[462,9951,9405],{"class":472},[462,9953,215],{"class":476},[462,9955,8722],{"class":3607},[462,9957,9458],{"class":573},[462,9959,9960,9962,9964,9966],{"class":464,"line":642},[462,9961,9861],{"class":476},[462,9963,9416],{"class":514},[462,9965,518],{"class":476},[462,9967,609],{"class":476},[462,9969,9970,9973,9975,9977,9979,9981],{"class":464,"line":647},[462,9971,9972],{"class":3607},"          parseFloat",[462,9974,4069],{"class":573},[462,9976,9938],{"class":472},[462,9978,215],{"class":476},[462,9980,5703],{"class":472},[462,9982,8750],{"class":573},[462,9984,9986,9989],{"class":464,"line":9985},17,[462,9987,9988],{"class":573},"        )",[462,9990,488],{"class":476},[462,9992,9994,9996,9999,10001,10004,10006,10008],{"class":464,"line":9993},18,[462,9995,9847],{"class":650},[462,9997,9998],{"class":472}," opcua",[462,10000,215],{"class":476},[462,10002,10003],{"class":472},"StatusCodes",[462,10005,215],{"class":476},[462,10007,344],{"class":472},[462,10009,488],{"class":476},[462,10011,10013],{"class":464,"line":10012},19,[462,10014,10015],{"class":476},"      }\n",[462,10017,10019],{"class":464,"line":10018},20,[462,10020,631],{"class":476},[462,10022,10024,10026,10028],{"class":464,"line":10023},21,[462,10025,9703],{"class":476},[462,10027,3639],{"class":472},[462,10029,488],{"class":476},[462,10031,10033],{"class":464,"line":10032},22,[462,10034,495],{"emptyLinePlaceholder":494},[462,10036,10038],{"class":464,"line":10037},23,[462,10039,8962],{"class":476},[15,10041,10042],{},"Last, OPC views are defined.  Views create custom hierarchies our OPC Client can browse as an alternative to the default folder structure.",[453,10044,10046],{"className":455,"code":10045,"language":457,"meta":458,"style":458},"  const viewDI = namespace.addView({\n    \"organizedBy\": rootFolder.views,\n    \"browseName\": \"RPIW0-Digital-Ins\"\n  });\n\n  const viewDO = namespace.addView({\n    \"organizedBy\": rootFolder.views,\n    \"browseName\": \"RPIW0-Digital-Outs\"\n  });\n\n  viewDI.addReference({\n    \"referenceType\": \"Organizes\",\n    \"nodeId\": gpioDI1.nodeId\n  });\n\n...\n\n",[89,10047,10048,10068,10088,10105,10113,10117,10136,10154,10171,10179,10183,10197,10217,10235,10243,10247],{"__ignoreMap":458},[462,10049,10050,10052,10055,10057,10059,10061,10064,10066],{"class":464,"line":465},[462,10051,9333],{"class":468},[462,10053,10054],{"class":472}," viewDI ",[462,10056,477],{"class":476},[462,10058,9663],{"class":472},[462,10060,215],{"class":476},[462,10062,10063],{"class":3607},"addView",[462,10065,4069],{"class":472},[462,10067,5757],{"class":476},[462,10069,10070,10072,10074,10076,10078,10081,10083,10086],{"class":464,"line":491},[462,10071,9685],{"class":476},[462,10073,9746],{"class":573},[462,10075,518],{"class":476},[462,10077,577],{"class":476},[462,10079,10080],{"class":472}," rootFolder",[462,10082,215],{"class":476},[462,10084,10085],{"class":472},"views",[462,10087,609],{"class":476},[462,10089,10090,10092,10094,10096,10098,10100,10103],{"class":464,"line":498},[462,10091,9685],{"class":476},[462,10093,7513],{"class":573},[462,10095,518],{"class":476},[462,10097,577],{"class":476},[462,10099,511],{"class":476},[462,10101,10102],{"class":514},"RPIW0-Digital-Ins",[462,10104,625],{"class":476},[462,10106,10107,10109,10111],{"class":464,"line":523},[462,10108,9703],{"class":476},[462,10110,3639],{"class":472},[462,10112,488],{"class":476},[462,10114,10115],{"class":464,"line":544},[462,10116,495],{"emptyLinePlaceholder":494},[462,10118,10119,10121,10124,10126,10128,10130,10132,10134],{"class":464,"line":549},[462,10120,9333],{"class":468},[462,10122,10123],{"class":472}," viewDO ",[462,10125,477],{"class":476},[462,10127,9663],{"class":472},[462,10129,215],{"class":476},[462,10131,10063],{"class":3607},[462,10133,4069],{"class":472},[462,10135,5757],{"class":476},[462,10137,10138,10140,10142,10144,10146,10148,10150,10152],{"class":464,"line":564},[462,10139,9685],{"class":476},[462,10141,9746],{"class":573},[462,10143,518],{"class":476},[462,10145,577],{"class":476},[462,10147,10080],{"class":472},[462,10149,215],{"class":476},[462,10151,10085],{"class":472},[462,10153,609],{"class":476},[462,10155,10156,10158,10160,10162,10164,10166,10169],{"class":464,"line":570},[462,10157,9685],{"class":476},[462,10159,7513],{"class":573},[462,10161,518],{"class":476},[462,10163,577],{"class":476},[462,10165,511],{"class":476},[462,10167,10168],{"class":514},"RPIW0-Digital-Outs",[462,10170,625],{"class":476},[462,10172,10173,10175,10177],{"class":464,"line":583},[462,10174,9703],{"class":476},[462,10176,3639],{"class":472},[462,10178,488],{"class":476},[462,10180,10181],{"class":464,"line":589},[462,10182,495],{"emptyLinePlaceholder":494},[462,10184,10185,10188,10190,10193,10195],{"class":464,"line":594},[462,10186,10187],{"class":472},"  viewDI",[462,10189,215],{"class":476},[462,10191,10192],{"class":3607},"addReference",[462,10194,4069],{"class":472},[462,10196,5757],{"class":476},[462,10198,10199,10201,10204,10206,10208,10210,10213,10215],{"class":464,"line":612},[462,10200,9685],{"class":476},[462,10202,10203],{"class":573},"referenceType",[462,10205,518],{"class":476},[462,10207,577],{"class":476},[462,10209,511],{"class":476},[462,10211,10212],{"class":514},"Organizes",[462,10214,518],{"class":476},[462,10216,609],{"class":476},[462,10218,10219,10221,10223,10225,10227,10230,10232],{"class":464,"line":628},[462,10220,9685],{"class":476},[462,10222,7524],{"class":573},[462,10224,518],{"class":476},[462,10226,577],{"class":476},[462,10228,10229],{"class":472}," gpioDI1",[462,10231,215],{"class":476},[462,10233,10234],{"class":472},"nodeId\n",[462,10236,10237,10239,10241],{"class":464,"line":634},[462,10238,9703],{"class":476},[462,10240,3639],{"class":472},[462,10242,488],{"class":476},[462,10244,10245],{"class":464,"line":642},[462,10246,495],{"emptyLinePlaceholder":494},[462,10248,10249],{"class":464,"line":647},[462,10250,8962],{"class":476},[15,10252,10253,10254,10257],{},"Finally, on the ",[89,10255,10256],{},"Discovery"," tab, we must define an endpoint for an OPC Client to subscribe to.",[15,10259,1758,10260,10263,10264,10267,10268,10270,10271,10274,10275],{},[89,10261,10262],{},"Endpoint Url"," follows the format ",[89,10265,10266],{},"opc.tcp:\u002F\u002F\u003Caddress>:port",".  Our port was defined on the ",[89,10269,9263],{}," tab, which by default, is port ",[89,10272,10273],{},"54845",". The address will be either the url or ip address of your Node-RED instance.  In my case, it’s 192.168.0.114.  So my Endpoint Url = ",[89,10276,10277],{},"opc.tcp:\u002F\u002F192.168.0.114:54845",[15,10279,10280,10284],{},[39,10281],{"alt":10282,"src":10283,"title":10282},"Screenshot showing the Discovery Tab of compact server node","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fdiscovery-tab.png","\nOnce the endpoint url is added, deploy the flow, and confirm the server is reporting “active”.",[15,10286,10287],{},[39,10288],{"alt":10289,"src":10290,"title":10289},"Screenshot showing the Active Tab of compact server node","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fcompact-server-active.png",[48,10292,10294],{"id":10293},"connect-to-example-opc-server-using-opc-ua-browser","Connect to Example OPC-Server Using OPC-UA Browser",[15,10296,10297,10298,10303],{},"To connect to our OPC endpoint, we need an OPC Client.  Prosys provides a ",[29,10299,10302],{"href":10300,"rel":10301},"https:\u002F\u002Fwww.prosysopc.com\u002Fproducts\u002Fopc-ua-browser\u002F",[33],"free OPC-UA Browser ","that supports Windows, Linux, and Mac OS.  To test our Server, the Windows version of Prosys OPC-UA Browser will be utilized.",[15,10305,10306],{},"To connect to our Node-RED OPC server, enter the endpoint url and press “connect to server”.",[15,10308,10309,10314,10315,10317],{},[39,10310],{"alt":10311,"src":10312,"title":10313},"\"Screenshot showing the OPC Client\"","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-client-connect.png","Screenshot showing the OPC Client","\nIt will ask for security.  Remember that we allowed anonymous access, so the default security mode of ",[89,10316,229],{}," is the correct option.",[15,10319,10320],{},"Once connected, we can browse our OPC Server.",[15,10322,10323,10327,10328,10331,10332,10334],{},[39,10324],{"alt":10325,"src":10326},"OPC Client UI","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-client-ui.png","\nIf we navigate to ",[89,10329,10330],{},"Objects → RaspberryPI-Zero-WLAN → GPIO → Inputs",", we can see a list of inputs that correspond to the ",[89,10333,9387],{}," context variables defined in the example flow, which are randomly generated numbers.",[15,10336,10337,10338,10340],{},"Clicking ",[89,10339,9770],{}," we can see the value in real-time, along with some additional properties.",[15,10342,10343,10347,10348,10351],{},[39,10344],{"alt":10345,"src":10346,"title":10345},"OPC Client Node","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-client-node.png","\nIf we go to ",[89,10349,10350],{},"Views",", we can see the custom hierarchy defined in the example server, which divides the data by Digital-Ins and Digital-Outs.",[15,10353,10354],{},[39,10355],{"alt":10356,"src":10357},"OPC Client View","\u002Fblog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-client-view.png",[48,10359,10361],{"id":10360},"summary","Summary",[15,10363,10364],{},"In this article, we compare OPC-UA to traditional fieldbus protocols, explain the importance of the OPC UA Information Model to understand how data is modeled in the address space of an OPC Server, and then walk through and deploy an example compact OPC-UA Server flow.",[15,10366,10367],{},"In our next article, we will build a custom OPC-UA Server in Node-RED with data pulled from an Allen Bradley PLC over Ethernet\u002FIP, using the PLC data to develop a custom OPC UA Information Model programmed in the OPC server address space.",[782,10369,10370],{},"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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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":458,"searchDepth":523,"depth":523,"links":10372},[10373,10374,10375,10376,10377],{"id":8547,"depth":491,"text":8548},{"id":8572,"depth":491,"text":8573},{"id":8658,"depth":491,"text":8659},{"id":10293,"depth":491,"text":10294},{"id":10360,"depth":491,"text":10361},{"type":6662,"title":10379,"description":10380},"Run Your OPC UA Node-RED Server in the Cloud","Sign up for FlowFuse to deploy, manage, and scale your Node-RED OPC UA server flows securely in the cloud with built-in DevOps pipelines.","2023-07-13","Introduction to OPC-UA and how to deploy a Node-RED server flow.","blog\u002F2023\u002F07\u002Fimages\u002Fopc-ua-1\u002Fopc-ua-1-title-image.png",{"keywords":10385,"excerpt":10386},"opc ua server, opc ua server free, opc ua gateway, opc ua example, node-red-contrib-opcua, nodered opcua, node red opcua, node-red opcua, opcua node red, opcua nodered",{"type":12,"value":10387},[10388],[15,10389,8544],{},"\u002Fblog\u002F2023\u002F07\u002Fhow-to-deploy-a-basic-opc-ua-server-in-node-red",{"title":8538,"description":10382},{"loc":10390},"blog\u002F2023\u002F07\u002Fhow-to-deploy-a-basic-opc-ua-server-in-node-red","OPC-UA Server Information Modeling in Node-RED",[1696,6680,827,6169],"This first installment in an OPC UA series explains the OPC UA information model how devices are represented as structured node objects rather than raw register values and walks through deploying a working OPC UA server flow in Node-RED using the node-red-contrib-opcua package. Understanding the information model and address-space hierarchy is the key prerequisite before building OPC UA clients or integrations.","aqJxabkyaGvGNG0wnFPvtB40UOJhS_j2ZBJQHM1dw2U",1785528680364]