Bridging Desigo CC to Azure IoT Hub via Siemens IoT2040

David Krause11 min read
OPC / OPC UASiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview

Bridging a building management system that runs Siemens Desigo CC on PXC-100 series automation stations to Microsoft Azure requires an industrial edge gateway that can translate between two protocol worlds: OPC UA on the plant side and a cloud-friendly MQTT/AMQP transport on the Azure side. The Siemens SIMATIC IoT2040 (6ES7647-0AA00-0YA2) is an Intel Quark-based DIN-rail gateway shipped with a Yocto Linux image that already contains Node-RED, the Modbus TCP contrib nodes, and a working OPC UA stack. Combined with node-red-contrib-opcua on the field side and the official azure-iot-sdk-node device client on the cloud side, the IoT2040 becomes a self-contained Desigo CC → Azure IoT Hub forwarder that requires no Windows service, no custom C++ driver, and no permanent outbound firewall holes for SCADA workstations.

This article documents the full reference architecture, the bring-up of the IoT2040 firmware image, the Desigo CC OPC UA server configuration, the Node-RED flow that performs subscription-based polling, and the JSON telemetry payload that lands in Azure IoT Hub. It also explains why BACnet over the IoT2040 is not the recommended path (the node-bacnet package is known to fail on the IOT2000 class of devices due to UDP broadcast and timing issues on the Yocto userspace) and why OPC UA is the protocol of choice when Desigo CC exposes it.

Reference Architecture

The end-to-end data path has five discrete hops. Each hop is owned by a different component, and a failure at any hop is isolated by design so that a cloud outage does not stop on-site control.

  1. PXC-100 automation station – reads physical I/O (analog inputs, binary inputs) and exposes them as BACnet/OPC objects.
  2. Desigo CC server – the supervisory SCADA that aggregates PXC points, runs graphics, and hosts the OPC UA server endpoint on TCP port 4840 (or 4841 for encrypted).
  3. IoT2040 gateway – runs Node-RED with the node-red-contrib-opcua client package. Reads subscribed OPC UA nodes at a configurable scan rate and forwards them as JSON.
  4. Azure IoT Hub – the cloud ingress that accepts device-to-cloud telemetry over MQTT (port 8883), AMQP (port 5671), or HTTPS (port 443).
  5. Downstream Azure services – Stream Analytics, Time Series Insights, Event Grid, or Data Lake – consume device-to-cloud messages from the built-in endpoint messages/events.
Design rule: Never rely on a single SCADA workstation for the cloud uplink. The IoT2040 must be configured to talk to Desigo CC independently. If the Desigo CC workstation goes down, the gateway continues to cache the last-known values and pushes them once the SCADA returns.

Prerequisites

Component Specification / Version
Siemens IoT2040 6ES7647-0AA00-0YA2, Intel Quark x86, 1 GB RAM, 8 GB eMMC
Example image Siemens IOT2000 V2.6.0 (or later) – includes Node-RED 0.20.x, Node.js 8.x
Desigo CC V4.x or V5.x with the OPC UA Server option licensed and enabled
PXC-100 controllers Firmware ≥ 4.0 with the BACnet/IP profile exposed to Desigo CC
Azure subscription Active subscription with permission to create IoT Hub (S1 tier recommended for BMS telemetry)
Node-RED contrib node-red-contrib-opcua ≥ 0.2.1 and node-red-contrib-azure-iot-hub ≥ 1.5.0
Network TCP 4840 (or 4841) from IoT2040 to Desigo CC, outbound TCP 8883 from IoT2040 to Azure

Step 1 – Configure the Desigo CC OPC UA Server

Desigo CC ships with a built-in OPC UA server, but it is not enabled by default. Activate it once per management station.

  1. Open the Desigo CC Management Console and log in with engineering credentials.
  2. Navigate to System → Connectivity → OPC UA Server.
  3. Tick Enable OPC UA Server and choose the listen port (default 4840). If you need encryption, switch to 4841 and bind the Desigo CC project certificate.
  4. Add the security policies you want to expose. For an IoT2040 client on the same VLAN, None + Sign is acceptable. For multi-tenant or shared networks, select Basic256Sha256 and load the IoT2040 client certificate.
  5. Click Apply. The service DesigoCC OPC UA Server restarts and binds to 0.0.0.0:4840.
  6. Verify reachability from a Windows workstation using UaExpert – connect to opc.tcp://<desigo-cc-fqdn>:4840, accept the self-signed certificate, and browse the Objects → Desigo CC folder to confirm that the PXC-100 points are visible.
If the Desigo CC license does not include the OPC UA option, the equivalent path is to expose the points through Desigo CC's Automation API (REST) and consume them from Node-RED with the http request node. The rest of the article still applies – only step 3 changes.

Step 2 – Bring Up the IoT2040

  1. Download the latest Example Image V2.6.0 for the IoT2040 from Siemens Industry Online Support (article ID 109741799). The image is a 1.6 GB ZIP that contains a pre-baked SD card image.
  2. Write the image to a ≥ 8 GB industrial-grade microSD card using balenaEtcher or Win32DiskImager.
  3. Insert the card, power the IoT2040 with 24 V DC on the bottom terminal block, and wait ~90 s for the green PWR and RUN LEDs to go solid.
  4. Connect a serial console (115 200 8N1) to the CON port and log in as root with the default password from the image release notes.
  5. Assign a static IP on X1P1 (the plant-side NIC) and route X2P1 (the cloud-side NIC) through the corporate firewall:
ifconfig eth0 192.168.10.50 netmask 255.255.255.0 up
route add default gw 192.168.10.1
  1. Confirm internet egress:
ping -c 3 mqtt.azure-devices.net

If the ping is blocked, add an explicit NAT or proxy exception for *.azure-devices.net on TCP 8883 and TCP 443.

Step 3 – Install the Node-RED Contrib Packages

Open the Node-RED UI on http://192.168.10.50:1880, then from the menu select Manage palette → Install and add the following two packages:

node-red-contrib-opcua
node-red-contrib-azure-iot-hub

For headless installs, drop to the IoT2040 shell and run:

cd /usr/lib/node_modules/node-red
npm install node-red-contrib-opcua
npm install node-red-contrib-azure-iot-hub
systemctl restart node-red

The node-red-contrib-opcua package provides the OpcUa-Browser, OpcUa-Client, and OpcUa-Item nodes used to discover, subscribe to, and read Desigo CC points. The node-red-contrib-azure-iot-hub package wraps the azure-iot-sdk-node device client and exposes a configurable Azure IoT Hub node that takes a connection string and a topic filter.

Step 4 – Create the OPC UA Subscription Flow

The recommended pattern is to subscribe to a MonitoredItem on the Desigo CC server with a 1000 ms publishing interval. Subscription-based reads are dramatically more efficient than polled reads because the server pushes only deltas.

  1. Drag an OpcUa-Client node into the flow and configure it:
    • Endpoint: opc.tcp://192.168.10.20:4840
    • Security Mode: None (or Sign if you enabled signing)
    • Security Policy: None
    • Authentication: Anonymous for the default Desigo CC install, or User/Password for an OPC UA account.
  2. Add an OpcUa-Item node for each Desigo CC point you want to forward. Use the OpcUa-Browser to navigate to Objects → Desigo CC → <System> → ... and pick a node by double-click. Common candidates are room temperature, damper position, and AHU enable command.
  3. Wire the OpcUa-Item to an OpcUa-Subscription node with these settings:
    • Interval: 1000 ms
    • QueueSize: 10
    • DiscardOldest: true

The subscription node emits a msg.payload object with the structure:

{
  "topic": "ns=4;s=Plant1.AHU01.RoomTemp",
  "payload": 22.4,
  "dataType": "Float",
  "value": { "value": 22.4, "dataType": "Float" },
  "statusCode": { "value": 0 }
}

Step 5 – Connect to Azure IoT Hub

  1. In the Azure portal, create an IoT Hub (S1 tier is fine for BMS data rates below 50 messages/s). Note the hostname (e.g. bms-hub.azure-devices.net).
  2. Under Devices → Add Device, create a device with ID iot2040-gw-01 and copy the primary connection string – it has the form:
HostName=bms-hub.azure-devices.net;DeviceId=iot2040-gw-01;SharedAccessKey=xxxxxxxxxxxxxx=
  1. Drop an Azure IoT Hub node in the Node-RED flow and paste the connection string. Set the Method to device-to-cloud and the topic to devices/iot2040-gw-01/messages/events/.
  2. Add a function node between the OpcUa-Subscription and the Azure node to build a clean JSON envelope:
msg.payload = {
  deviceId: "iot2040-gw-01",
  ts: new Date().toISOString(),
  point: msg.topic,
  value: msg.payload.value,
  dataType: msg.payload.dataType,
  quality: (msg.statusCode && msg.statusCode.value === 0) ? "Good" : "Bad"
};
msg.payload = JSON.stringify(msg.payload);
return msg;
  1. Wire the function output to the Azure IoT Hub node and click Deploy. The bottom-right status bar should read Connected within five seconds.

Step 6 – Verify the End-to-End Path

  1. From any workstation with the Azure IoT Explorer tool installed, connect to the hub and select device iot2040-gw-01.
  2. Click Telemetry and observe live messages arriving. Each message corresponds to one subscribed OPC UA point.
  3. From the IoT2040 shell, run journalctl -u node-red -f and confirm that no BAD_COMMUNICATION_ERROR or SERVICE_BAD lines appear in the last hour.
  4. Force a value change in Desigo CC (e.g. override an analog output). The new value should land in IoT Explorer within one scan interval (≤ 1 s).
If messages are visible in the IoT Explorer but the JSON value field is always null, the OpcUa-Client is connected but the subscription is using Read instead of Subscribe. Open the subscription node, switch the action from read to subscribe, and redeploy.

Message Format and Schema

Every device-to-cloud message is a UTF-8 JSON document with the schema below. Schema-enforcement at the IoT Hub route simplifies downstream Stream Analytics queries.

Field Type Description
deviceId string Always iot2040-gw-01; redundant with the IoT Hub system property but convenient for routing.
ts string (ISO 8601) UTC timestamp the IoT2040 received the value.
point string OPC UA node id, e.g. ns=4;s=Plant1.AHU01.RoomTemp.
value number / boolean / string The actual data value.
dataType string OPC UA data type: Float, Double, Boolean, String, Int32.
quality string Good or Bad; derived from statusCode.

Performance and Sizing

The IoT2040 has a single-core 400 MHz Intel Quark CPU and 1 GB of RAM. The practical ceiling for an OPC UA subscription running through Node-RED is approximately 500 monitored items at a 1 s interval. Above that, the node-opcua client begins to drop KeepAlive packets and the Azure node queues up.

For a typical BMS of one Desigo CC server with 200 physical points, the load is well within the budget. If you need to forward 1 000+ points, the recommended path is to deploy a SIMATIC IOT2050 (6ES7647-0BA00-0YA2) with the dual-core ARM Cortex-A53 and 2 GB of RAM, and run the same flow.

Security Hardening

  1. Change the default root password on the IoT2040 image before commissioning. Siemens ships the example image with a publicly documented password.
  2. Enable OPC UA Sign-and-Encrypt on Desigo CC and load the IoT2040 client certificate. Generate the cert with openssl on the IoT2040:
openssl req -x509 -newkey rsa:2048 -keyout iot2040.key -out iot2040.pem \
  -days 3650 -nodes -subj "/CN=iot2040-gw-01"
  1. Switch the Azure node to MQTT over TLS (port 8883). The default contrib node does this automatically when the connection string contains the SAS key.
  2. Add an IoT Hub IP filter that whitelists only the IoT2040's public IP. This prevents rogue devices from injecting telemetry.
  3. Enable IoT Hub diagnostic logs to Azure Monitor and alert on Throttling or Unauthorized events.

Alternative: Azure IoT Hub Integration Patterns

The Node-RED + IoT2040 path is the lowest-cost, on-premises-only option. If your facility cannot host the IoT2040 or you want a managed connector, third-party services such as CloudRail provide a drop-in OPC UA → Azure IoT Hub bridge that can read Desigo CC points in minutes without any on-site Linux box. The trade-off is per-message licensing and a hard dependency on the vendor's cloud relay.

For a hybrid architecture where Desigo CC stays on-prem and only aggregated alarms are pushed to Azure, the recommended Azure-side services are Azure IoT Hub (ingress), Stream Analytics (windowing), and Time Series Insights (historical visualization). For an SAP DMC integration, see the reference pattern documented on Microsoft Learn for routing IoT Hub events to SAP Digital Manufacturing via Event Grid.

Troubleshooting Matrix

Symptom Likely Cause Remediation
Node-RED disconnected from Desigo CC Firewall on TCP 4840 or wrong endpoint URL Test with telnet desigo-cc 4840 from the IoT2040 shell; correct the Endpoint string.
Subscription publishes, Azure node stays idle Wrong connection string or expired SAS key Regenerate the device key in IoT Hub, redeploy with the new string.
Values are null in IoT Explorer Action is read instead of subscribe Change the subscription node action and redeploy.
Bad quality codes PXC-100 offline or BACnet link down Check the PXC status in Desigo CC; resolve the field link first.
Gateway runs out of memory Too many monitored items or a payload-format loop Lower the queue size; add a debug counter; switch to IOT2050.
TLS handshake fails on Azure Outdated CA bundle on the Yocto image Update ca-certificates package and restart Node-RED.

FAQ

Why is BACnet not used on the IoT2040?

The node-bacnet contrib package relies on UDP broadcast, which the IOT2000 series example image does not support reliably because of the custom Yocto network stack. Building a BACnet stack from source is possible but not production-stable. OPC UA over TCP is the recommended transport when the upstream SCADA exposes it.

Does the IoT2040 support encryption on the Azure side?

Yes. The node-red-contrib-azure-iot-hub package uses MQTT over TLS on TCP 8883 by default. The shared access key in the connection string authenticates the device to IoT Hub; no additional cert is required.

How many OPC UA points can a single IoT2040 forward?

Roughly 500 monitored items at a 1 s scan rate on a 400 MHz Quark with 1 GB RAM. For 1 000+ points, migrate to the IOT2050 (dual-core ARM, 2 GB RAM) running the same Node-RED flow.

Can I read Desigo CC points without enabling the OPC UA server?

Yes – use the Desigo CC Automation REST API and an http request node. The endpoint pattern is https://<desigo>/api/automation/v1/points/.... The Azure side of the flow is identical.

What happens if Azure IoT Hub is unreachable?

The azure-iot-sdk-node device client buffers messages locally and retries with exponential backoff. On the IoT2040 the default buffer is 50 messages – increase it in the Azure node configuration if you expect longer outages.

Back to blog