While the Publisher → Telegraf → InfluxDB path handles read-only telemetry, UA Cloud Commander adds a command & control path so a cloud (or local) application can remotely read, write, call methods on, and historically read OPC UA nodes on the edge — all over the same Mosquitto broker.
Cloud Commander implements the OPC UA PubSub Actions request/response pattern
(IEC 62541-14). It acts as the Responder: it subscribes to the commands/#
topic, executes the requested OPC UA operation against an on-premises OPC UA
server (e.g. the Edge Translator at opc.tcp://<device-ip>:4840), and publishes
the result to the responses topic.
ua-cloudcommander is deployed by cloud.yaml and connects to Mosquitto via
these environment variables (no web UI — it is configured entirely through env):
| Variable | Value | Purpose |
|---|---|---|
BROKERNAME |
mosquitto.cloud.svc.cluster.local |
In-cluster Mosquitto Service. |
BROKERPORT |
8883 |
TLS MQTT port. |
USE_TLS |
true |
Mosquitto requires TLS. |
CLIENTNAME |
UACloudCommander |
MQTT client id / Responder PublisherId. |
TOPIC |
commands/# |
Topic it subscribes to for ua-action-request messages. |
RESPONSE_TOPIC |
responses |
Default topic for ua-action-response messages (used when a request omits ResponseAddress). |
USERNAME / PASSWORD |
${IOT_USERNAME} / ${IOT_PASSWORD} |
Broker credentials (same as the rest of the stack). |
UA_USERNAME / UA_PASSWORD |
${IOT_USERNAME} / ${IOT_PASSWORD} |
Credentials used to sign in to the target OPC UA servers. |
The OPC UA client certificate and logs are persisted on the Pi under
/commander/pki and /commander/logs.
Self-signed TLS: Mosquitto uses a self-signed certificate generated at pod startup. If Cloud Commander rejects the TLS handshake, mount/trust the broker's CA certificate in the Commander container (or use a trusted-CA certificate for Mosquitto) as recommended in the security note above.
Publish a ua-action-request NetworkMessage to the commands topic and listen
on responses for the reply. For example, to read a node (from a machine that
can reach the broker, using the stack credentials over TLS):
# Subscribe for responses in one terminal
mosquitto_sub -h <device-ip> -p 8883 --cafile ca.crt \
-u "$IOT_USERNAME" -P "$IOT_PASSWORD" -t responses
# Publish a Read request in another terminal
mosquitto_pub -h <device-ip> -p 8883 --cafile ca.crt \
-u "$IOT_USERNAME" -P "$IOT_PASSWORD" -t commands -m '{
"MessageId": "32235f26-4a3a-4a56-9f1f-2b6f8a2f0a11",
"MessageType": "ua-action-request",
"PublisherId": "MyCloudApp",
"Timestamp": "2022-11-28T12:01:00.0923534Z",
"RequestorId": "MyCloudApp",
"TimeoutHint": 15000,
"Messages": [
{
"DataSetWriterId": 1,
"ActionTargetId": 1,
"RequestId": 1,
"ActionState": 1,
"Payload": {
"Endpoint": "opc.tcp://<device-ip>:4840",
"NodeId": "http://opcfoundation.org/UA/Station/;i=123"
}
}
]
}'The ActionTargetId selects the operation: 1 = Read, 2 = HistoricalRead,
3 = Write, 4 = MethodCall. Cloud Commander replies on responses with a
ua-action-response message echoing RequestorId / RequestId and containing
the Result (or an Error). See the
UA Cloud Commander documentation
for the full payload schema of each operation.
UA Cloud Action is the automated Requestor counterpart to Cloud Commander.
Instead of a human publishing a command, it polls telemetry and reacts: on a
15-second loop it queries a configured value and, when it crosses a threshold,
publishes a ua-action-request (a MethodCall) to the commands topic — which
Cloud Commander executes on the target OPC UA server. This closes an edge-local
digital feedback loop entirely on the Pi.
In this reference stack it is deployed (cloud.yaml) to read from InfluxDB
and drive UA Cloud Commander over Mosquitto:
| Variable | Value | Purpose |
|---|---|---|
DATA_SOURCE |
InfluxDB |
Use InfluxDB as the trigger source (instead of Azure Data Explorer). |
INFLUX_URL |
http://influxdb.cloud.svc.cluster.local:8086 |
InfluxDB endpoint. |
INFLUX_ORG / INFLUX_BUCKET |
iot / mqtt |
Org and bucket to query. |
INFLUX_MEASUREMENT |
opcua_pubsub |
Measurement to query. |
INFLUX_FIELD |
Payload_Pressure_Value |
Numeric field to evaluate — change to match your assets. |
INFLUX_THRESHOLD |
4000 |
Trigger when the latest value exceeds this. |
INFLUX_RANGE |
-1m |
Look-back window for the latest value. |
INFLUX_TOKEN |
(from influxdb-auth) |
Query token. |
MESSAGING_PLATFORM |
MQTT |
Reach Commander over MQTT (not Kafka). |
MQTT_TARGET |
UACloudCommander |
Send the full OPC UA PubSub ActionRequest envelope. |
BROKER_NAME / MQTT_PORT |
mosquitto… / 8883 |
Mosquitto broker (TLS). |
MQTT_USE_TLS / MQTT_TLS_INSECURE |
true / true |
TLS with the self-signed broker cert (verification skipped, like Telegraf). |
BROKER_USERNAME / BROKER_PASSWORD |
${IOT_USERNAME} / ${IOT_PASSWORD} |
Broker credentials. |
TOPIC / RESPONSE_TOPIC |
commands / responses |
The topics Cloud Commander subscribes/replies on. |
UA_SERVER_ENDPOINT, UA_SERVER_METHOD_ID, UA_SERVER_OBJECT_ID, … |
(placeholders) | The OPC UA method Cloud Commander invokes on trigger — set these to a real method on your target server (e.g. the Edge Translator). |
InfluxDB data source: support for querying InfluxDB was added to UA Cloud Action for this stack (the upstream app queries Azure Data Explorer). The
DATA_SOURCE=InfluxDBbranch runs a Flux query for the latestINFLUX_FIELDvalue and compares it toINFLUX_THRESHOLD. SetINFLUX_FIELDto a numeric field your assets actually publish (discover exact names in the InfluxDB Data Explorer or Grafana), otherwise no trigger will fire.
A small status UI is available at http://<device-ip>:8082 (log in with your
IOT_USERNAME / IOT_PASSWORD), showing connectivity to the data source, the
broker, and Cloud Commander.