Salta ai contenuti

Connettore OPC UA PubSub

Il connettore OPC UA PubSub implementa il pattern publish/subscribe definito dalla specifica OPC UA PubSub (Parte 14). Abilita comunicazione disaccoppiata ad alto throughput tra produttori e consumatori OPC UA utilizzando una delle due mappature di trasporto:

  • MQTT - Messaggi codificati JSON su MQTT/UDP per fan-out basato su broker
  • UADP - UADP binario (UA Datagram Protocol) su UDP multicast per distribuzione LAN a bassa latenza

Tipi Connettore:

  • OpcuaPubSubReader - Ascolta messaggi PubSub in ingresso e li emette come payload Meddle
  • OpcuaPubSubWriter - Pubblica payload Meddle come messaggi PubSub
  • ✅ Due trasporti: MQTT (JSON) e UADP (multicast binario)
  • ✅ Decodifica automatica sia del formato JSON che UADP
  • ✅ Gestione di gruppi multicast UDP con selezione dell’interfaccia
  • ✅ Filtraggio opzionale per publisher ID e nome dataset
  • ✅ Produttore/consumatore disaccoppiati (nessuna sessione punto-a-punto necessaria)
  • ✅ Progettato per la distribuzione di telemetria ad alta frequenza
{
"type": "OpcuaPubSubReader",
"config": {
"transport": "uadp",
"multicastAddr": "opc.udp://224.0.5.1:4840/eth0",
"publisherId": "Publisher_1",
"dataSetName": "TankFarmDataSet"
}
}
{
"type": "OpcuaPubSubWriter",
"config": {
"transport": "uadp",
"multicastAddr": "opc.udp://224.0.5.1:4840/eth0",
"publisherId": "Publisher_1",
"dataSetName": "TankFarmDataSet"
}
}

Il trasporto utilizzato per i messaggi PubSub. Deve essere uno tra:

  • mqtt - Messaggi JSON su UDP (bridge tramite broker in produzione)
  • uadp - Frame UADP binari su UDP multicast
{
"transport": "uadp"
}

Richiesto quando transport: mqtt. L’indirizzo a cui Meddle si lega (reader) o invia (writer).

{
"brokerUrl": "192.168.1.20:1883"
}

Formato: host:port.

Note:

  • Il reader si lega a un listener UDP su questo indirizzo
  • Per il writer, è l’indirizzo di destinazione a cui vengono inviati i messaggi PubSub

Identificatore di topic logico opzionale. Metadato informativo incluso insieme al filtro per dataset.

{
"topic": "factory/line1"
}

Richiesto quando transport: uadp. Il gruppo multicast IPv4 più l’interfaccia opzionale.

{
"multicastAddr": "opc.udp://224.0.5.1:4840/eth0"
}

Formato: opc.udp://<host>:<port>/<interfaccia>.

  • host:port - Il gruppo multicast e la porta (tipicamente 224.0.5.1:4840 come default OPC UA PubSub)
  • interfaccia - Nome dell’interfaccia di rete richiesto (eth0, en0, lo0)

Perché è richiesta l’interfaccia? Le join multicast UDP sono limitate per interfaccia. Senza un’interfaccia specificata, l’OS non può legare in modo affidabile il gruppo multicast, specialmente su macOS (lo0) e VM cloud con NIC multiple.

host:port semplice (senza schema) è accettato per retrocompatibilità ma la selezione dell’interfaccia è fortemente raccomandata.

Identifica l’origine dei messaggi PubSub.

{
"publisherId": "Publisher_1"
}

Note:

  • Richiesto sul writer (ogni messaggio pubblicato è marcato con esso)
  • Opzionale sul reader (quando impostato, vengono conservati solo i messaggi di questo publisher; quando vuoto, vengono accettati tutti i publisher)

Identifica il dataset logico all’interno di un publisher.

{
"dataSetName": "TankFarmDataSet"
}

Note:

  • Opzionale sia su reader che writer
  • Sul reader, agisce come filtro quando impostato

Il trasporto MQTT emette messaggi in un envelope JSON standard:

{
"PublisherId": "Publisher_1",
"Messages": [
{
"DataSetName": "TankFarmDataSet",
"Payload": {
"tank_1_level": 78.4,
"tank_2_level": 62.1,
"pump_running": true
}
}
]
}

Il trasporto UADP emette frame binari secondo il framing OPC UA Parte 14. Il reader rileva automaticamente il contenuto UADP vs JSON e decodifica entrambi. Ogni DataSet UADP decodificato emette un payload Meddle.

Multicast / UDP → OpcuaPubSubReader → (decodifica JSON o UADP) → Payload Meddle

Più dataset in un singolo messaggio di rete producono più payload Meddle (uno per dataset).

Payload Meddle → OpcuaPubSubWriter → (codifica envelope JSON) → invio UDP → Sottoscrittori

Il writer emette sempre JSON per entrambi i trasporti. Ogni invocazione di Write produce esattamente un messaggio di rete.

1. Distribuzione Telemetria Disaccoppiata in Pianta

Sezione intitolata “1. Distribuzione Telemetria Disaccoppiata in Pianta”

Un PLC centrale pubblica variabili di processo su un gruppo multicast UADP; più sottoscrittori Meddle le consumano indipendentemente.

{
"type": "OpcuaPubSubReader",
"config": {
"transport": "uadp",
"multicastAddr": "opc.udp://224.0.5.1:4840/eth0",
"publisherId": "PLC_Master"
}
}

Effettua il bridge da OPC UA PubSub a un topic MQTT JSON-friendly per l’ingestione in piattaforme cloud:

{
"type": "OpcuaPubSubReader",
"config": {
"transport": "mqtt",
"brokerUrl": "0.0.0.0:1883",
"topic": "factory/sensors",
"dataSetName": "EnergyMeters"
}
}

Dopo l’elaborazione, pubblica i KPI aggregati come singolo messaggio PubSub:

{
"type": "OpcuaPubSubWriter",
"config": {
"transport": "uadp",
"multicastAddr": "opc.udp://224.0.5.1:4840/eth0",
"publisherId": "Edge_Gateway_1",
"dataSetName": "PlantKPIs"
}
}

Problema: Il reader gira silenziosamente ma non emette mai payload

Soluzioni:

  1. Conferma che il gruppo multicast corrisponda esattamente al publisher (224.0.5.1:4840)
  2. Specifica l’interfaccia in multicastAddr (es. /eth0) — l’auto-discovery non è affidabile
  3. Usa uno sniffer di rete come tcpdump -i eth0 host 224.0.5.1 and port 4840 per confermare che i pacchetti stiano arrivando
  4. Verifica che il routing multicast sia abilitato su switch/router tra publisher e sottoscrittore

Problema: La configurazione UADP viene rifiutata all’avvio

Soluzioni:

  1. Aggiorna multicastAddr per includere l’interfaccia: opc.udp://224.0.5.1:4840/eth0
  2. Su macOS l’interfaccia loopback è lo0; su Linux è lo. Controlla con ifconfig o ip addr

Problema: Il reader vede messaggi sulla rete ma non ne emette nessuno

Soluzioni:

  1. Controlla il filtro publisherId sul reader — quando impostato, passano solo i messaggi da quel publisher. Cancellalo per accettare tutti
  2. Lo stesso vale per dataSetName — quando impostato, passano solo i dataset corrispondenti

Problema: bind: address already in use

Soluzioni:

  1. Più reader sullo stesso host devono usare porte distinte
  2. Per multicast UADP, più processi sullo stesso host possono unirsi allo stesso gruppo solo se SO_REUSEPORT è onorato (Linux); su macOS è consentito un solo binding per gruppo+porta per processo

Problema: Viene sollevato ErrOpcuaPubSubDecode su ogni messaggio

Soluzioni:

  1. Controlla se il publisher usa JSON o UADP — il reader rileva automaticamente ma dati malformati falliscono in entrambi i percorsi
  2. Ispeziona la configurazione PubSub del publisher: il content type del dataset deve essere uno scalare o struttura supportata
  3. Verifica che publisher e sottoscrittore siano d’accordo sulla codifica (la configurazione PubSub del server OPC UA la definisce)

UADP è più veloce e ha overhead inferiore rispetto a JSON-su-MQTT. Usalo ogni volta che controlli la rete.

JSON è portabile e facile da debuggare. Quando i messaggi devono attraversare l’internet pubblico o essere consumati da strumenti non OPC UA, MQTT-JSON è più pragmatico.

Non affidarti mai all’OS per “indovinare” la NIC giusta. Host multi-homed e container falliscono silenziosamente altrimenti.

Il filtro publisherId e dataSetName è economico lato server e riduce drasticamente il carico di elaborazione a valle.

  • Usa il range riservato dalla OPC UA Foundation (224.0.5.0/24)
  • Coordina con il tuo team di rete — il multicast non controllato può inondare la LAN
  • Testa con tcpdump/Wireshark prima di andare in produzione
PLC (Publisher) → multicast UADP 224.0.5.1:4840
┌────────┼────────┬──────────────┐
↓ ↓ ↓ ↓
OpcuaPubSubReader OpcuaPubSubReader OpcuaPubSubReader
(Storage) (Dashboard) (Alerting)
│ │ │
↓ ↓ ↓
InfluxDb2Writer Chart Isa182 → Alert
ModbusReader → Reshape → OpcuaPubSubWriter (MQTT) → Broker Esterno → Sottoscrittori Cloud

Effettua il bridge di dispositivi Modbus legacy nel moderno ecosistema OPC UA PubSub.

  • OPC UA - Protocollo OPC UA classico client/server (punto-a-punto)
  • MQTT v5 - PubSub MQTT generico (non OPC UA)
  • Modbus - Bridge di dispositivi legacy nel tessuto PubSub
  • Reshape - Normalizza i nomi dei campi prima della pubblicazione
  • InfluxDB v2 - Persiste la telemetria sottoscritta