Rela AIRela AI Docs
Casi d'Uso

Flotta eterogenea — 3 marche di PLC diverse, un solo tunnel VPN (Modbus TCP)

Un panificio ha mescolatrice Schneider, camera Carel e forno WAGO. Tutti parlano Modbus TCP ma con quirks diversi. Come configurarli in un solo tenant Rela AI senza perdere ore a debuggare il byte order.

Flotta eterogenea — 3 marche di PLC, un tunnel VPN

Modbus TCP è la lingua franca dell'automazione industriale: praticamente ogni marca di PLC lo parla. Ma "parla Modbus" non significa "parla allo stesso modo" — ogni costruttore ha quirks su byte order, convenzione di indirizzi e limiti di connessioni concorrenti. Questo caso mostra come Rela AI gestisce una flotta mista senza che il cliente debba normalizzare nulla lato PLC.

Riassunto esecutivo

Il punto di svolta: un solo tenant Rela tratta PLC di marche diverse come se fossero dello stesso fabbricante. AHI, agente IA, regole di allarme e KPI operano su eventi unificati — l'eterogeneità resta intrappolata nella configurazione di ogni fonte e non si propaga alla pipeline predittiva.

PrimaDopo
Ogni marca esige un'integrazione SCADA diversa3 fonti Modbus in Rela, un click ciascuna
Gli operatori imparano 3 SCADA diversi (uno per marca)Un solo dashboard, stesso linguaggio per le 3 macchine
Regole duplicate per marca: una per forni Schneider, un'altra per forni WAGOUna sola regola "forno temperatura > 280" — tag_enrichment discrimina
Quando una sonda deriva su una marca, nessun apprendimento incrociatoIl rilevatore ML impara pattern per asset, indipendente dalla marca

A cosa serve

  • Sorvegliare macchine di marche diverse già in fabbrica senza sostituire nulla.
  • Centralizzare l'inbox allarmi: una sola schermata, un solo agente IA, escalation comune.
  • Applicare regole deterministiche e manutenzione predittiva sugli asset più importanti, non solo su quelli già in uno SCADA omogeneo.
  • Capire le differenze tra marche (byte order, addressing) una sola volta in fase di configurazione, e dimenticarsene dopo.

Prima di iniziare — perché sei tu a configurare il peer

Anche per una flotta multi-brand, il modello di accesso non cambia: il cliente crea il proprio peer WireGuard, Rela non riceve mai credenziali di VPN aziendali.

Tre ragioni critiche (le 9 complete sono in Perché un tunnel dedicato):

  1. Principio del minimo privilegio: la tua VPN aziendale apre l'intera rete (ERP, mail, SharePoint, OT). Rela ha bisogno solo della subnet dei 3 PLC. Una violazione lato Rela colpisce una subnet OT, non tutta l'azienda.
  2. Revoca in pochi secondi: elimini il peer dal tuo router quando vuoi, senza ticket né coordinamenti con noi. La chiave privata vive nel tuo apparato e non esce mai.
  3. Conformità (IEC 62443, NIST SP 800-82, SOC 2, ISO 27001): tutte richiedono la separazione IT/OT tramite tunnel dedicato. Condividere credenziali aziendali è un findable diretto in qualsiasi audit.

Il modello peer-dedicato funziona identico per 1, 3 o N PLC dietro la stessa LAN — è il sito che decide il numero di tunnel, non le macchine. Condividere credenziali esce dal modello self-service ed entra nel deployment enterprise custom.

Come funziona

flowchart LR
  M["Schneider M340<br/>Mescolatrice<br/>192.168.10.55"] --> R[("Router del cliente<br/>WireGuard + DNAT")]
  C["Carel pCO5 plus<br/>Camera lievitazione<br/>192.168.10.50"] --> R
  W["WAGO 750-881<br/>Forno rotativo<br/>192.168.10.65"] --> R
  R -- "1 solo tunnel" --> CONC[("Concentratore<br/>Rela VPN")]
  CONC --> WORKER[("Cloud Run worker<br/>3 modbus_listener tasks")]
  WORKER --> PIPE[("Pipeline unificata<br/>_machine_events")]
  PIPE --> AGENT[("Agente IA<br/>Sorvegliante Stabilimento")]
  PIPE --> MAST[Asset Mescolatrice]
  PIPE --> CAST[Asset Camera]
  PIPE --> WAST[Asset Forno]

Il trucco: i 3 task listener girano sullo stesso worker. Ognuno decodifica con la sua configurazione (byte order specifico per registro), ma tutti emettono allo stesso _machine_events. L'agente IA e le regole non sanno — né vogliono sapere — che provengono da marche diverse.

Parametri / Configurazione

Byte order per marca (la gotcha più comune)

modbus_byte_order si configura per registro, non per fonte — perché alcuni PLC mescolano convenzioni a seconda del firmware o del DB. Default realistici:

Marca / firmwareDefault float32Default 32-bit intNote
Schneider Modicon M340 / M580big_endian_swap (CDAB)big_endian (ABCD)Il word-swap è una stranezza storica Modicon. Verificare con mbpoll
Carel pCO5+ / pCOWebbig_endian (ABCD)big_endianStandard Carel
WAGO 750-881big_endian (ABCD)big_endianConfigurabile, default ABCD
Siemens S7 con modulo Modbusbig_endian (ABCD)big_endianBig-endian nativo S7
Allen-Bradley via gateway Modbuslittle_endian (DCBA)little_endianInverso a Schneider
Omron CJ/CPbig_endian (ABCD)big_endianStandard

Suggerimento operativo: in caso di dubbio, leggere un registro con un valore noto (es: setpoint = 25.0) con i 4 byte order e prendere quello che restituisce il numero corretto. Cinque minuti che evitano giorni di debug.

Convenzione degli indirizzi

Rela usa l'indirizzo Modbus 0-based della wire (quello che pymodbus invia). Conversione rapida dalla doc del costruttore:

La doc del vendor diceIn Rela metti
Modicon 40101 (5-digit)address 100, FC 3
Modicon 30015address 14, FC 4
Carel "register 1"address 0, FC 3
WAGO "%MW100"address 100, FC 3
Siemens DB1.DBW0 via Modbusdipende dal mapping in TIA

Limiti di connessioni concorrenti

PLCConnessioni concorrentiImplicazione
Schneider M3408Confortevole per Rela + SCADA + HMI
Schneider M58016Abbondante
Carel pCOWeb4Critico: SCADA + Rela + HMI + tablet già saturano
WAGO 750-8814-8 (dipende dal firmware)Verificare prima di aggiungere client
Siemens S7 con CM 12411-3Molto stretto — Rela può essere l'unico client

Mappatura Modbus della flotta (riassunto eseguibile)

Mescolatrice — Schneider Modicon M340 (10.200.7.55:502, unit_id 1)

RegistroAddressFCTipoByte orderUnità
motor_torque1003float32big_endian_swap%
motor_speed1023float32big_endian_swaprpm
motor_temperature1043float32big_endian_swap°C
mixing_time_seconds1063uint16big_endians
motor_running501bool0/1
alarm_overpressure601bool0/1

Camera lievitazione — Carel pCO5+ (10.200.7.50:502, unit_id 1)

RegistroAddressFCTipoByte orderUnità
measured_temperature23float32big_endian°C
measured_humidity43float32big_endian%
cycle_phase103uint16big_endian1-5
door_open12bool0/1
probe_t_alarm202bool0/1

Forno rotativo — WAGO 750-881 (10.200.7.65:502, unit_id 1)

RegistroAddressFCTipoByte orderUnità
chamber_temperature2003float32big_endian°C
deck_temperature2023float32big_endian°C
fan_speed2043uint16big_endian%
batch_count2063uint32big_endianpezzi
door_open102bool0/1
alarm_overheat112bool0/1

Come usarlo

Passo 1 — Creare il tunnel VPN (uno solo, come per le flotte omogenee)

Sidebar → SettingsConnectivity → etichetta Panificio - Produzione → scaricare .conf → importarlo nel router.

Passo 2 — DNAT delle 3 IP sul router

/ip firewall nat
add chain=dstnat dst-address=10.200.7.55 dst-port=502 \
    protocol=tcp action=dst-nat to-addresses=192.168.10.55 to-ports=502
add chain=dstnat dst-address=10.200.7.50 dst-port=502 \
    protocol=tcp action=dst-nat to-addresses=192.168.10.50 to-ports=502
add chain=dstnat dst-address=10.200.7.65 dst-port=502 \
    protocol=tcp action=dst-nat to-addresses=192.168.10.65 to-ports=502

/ip firewall filter
add action=accept chain=forward in-interface=rela-vpn src-address=10.200.0.0/16

Passo 3 — Creare i 3 asset

CampoMescolatriceCameraForno
NomeMescolatrice a SpiraleCamera Lievitazione 1Forno Rotativo 1
Asset codeMES-01LIE-01FOR-01
Asset typemixerfermentation_chamberrotary_oven
Criticitàmediumhighhigh
PlantPanificio CentralePanificio CentralePanificio Centrale
AreaProduzioneProduzioneProduzione

Passo 4 — Agente IA comune

Sidebar → AllarmiAgenti macchina+ Nuovo.

Nome:         Sorvegliante Stabilimento
Modello:      gemini-3.1-pro-preview
Auto-task:    sì  → Reparto "Manutenzione"
Auto-notify:  sì  → WhatsApp del capo turno
Escalation:   sì (5 min / 15 min / 30 min)

Un solo agente copre le 3 marche. Le regole filtrano per tag_enrichment.machine_type quando serve specializzazione.

Passo 5 — Creare le 3 fonti Modbus con la config specifica per marca

Sidebar → AllarmiSources+ Nuova fonte, ripetere 3 volte.

Fonte 1: Mescolatrice Schneider

Source ID:    mescolatrice-schneider
Agente:       Sorvegliante Stabilimento
Protocollo:   Modbus TCP
Modbus host:  10.200.7.55
Modbus port:  502
Unit ID:      1

Registri:
  - motor_torque         addr=100  fc=3  type=float32  byte_order=big_endian_swap  unit="%"
  - motor_speed          addr=102  fc=3  type=float32  byte_order=big_endian_swap  unit="rpm"
  - motor_temperature    addr=104  fc=3  type=float32  byte_order=big_endian_swap  unit="°C"
  - alarm_overpressure   addr=60   fc=1  type=bool     emit=bit_flip

Field mapping:
  tag_enrichment:
    machine_type: mixer
    brand: schneider
    model: modicon-m340

Fonte 2: Camera Carel

Source ID:    camera-carel
Agente:       Sorvegliante Stabilimento
Protocollo:   Modbus TCP
Modbus host:  10.200.7.50
Modbus port:  502
Unit ID:      1

Registri:
  - measured_temperature  addr=2   fc=3  type=float32  byte_order=big_endian  unit="°C"
  - measured_humidity     addr=4   fc=3  type=float32  byte_order=big_endian  unit="%"
  - door_open             addr=1   fc=2  type=bool     emit=bit_flip

Field mapping:
  tag_enrichment:
    machine_type: proofer
    brand: carel
    model: pco5plus

Fonte 3: Forno WAGO

Source ID:    forno-wago
Agente:       Sorvegliante Stabilimento
Protocollo:   Modbus TCP
Modbus host:  10.200.7.65
Modbus port:  502
Unit ID:      1

Registri:
  - chamber_temperature   addr=200  fc=3  type=float32  byte_order=big_endian  unit="°C"
  - deck_temperature      addr=202  fc=3  type=float32  byte_order=big_endian  unit="°C"
  - fan_speed             addr=204  fc=3  type=uint16   unit="%"
  - alarm_overheat        addr=11   fc=2  type=bool     emit=bit_flip

Field mapping:
  tag_enrichment:
    machine_type: oven
    brand: wago
    model: 750-881

Passo 6 — Collegare ogni fonte al suo asset

Sidebar → Asset → modificare ognuno → aggiungere il event_source_ids corrispondente.

Passo 7 — Una sola regola che copre più marche

Sidebar → AllarmiRegole+ Nuova regola.

Nome:         Forno surriscaldamento
Source:       (vuoto — applica globalmente)
Conditions:
  - field: machine_type
    operator: eq
    value: oven
  - field: chamber_temperature
    operator: gt
    value: 280
Recurrence:
  count_threshold: 3
  window_minutes: 2
Actions:
  - change_severity: critical
  - create_task:
      title: "Surriscaldamento forno"
      priority: urgent
      department_id: <Manutenzione>
  - trigger_escalation

Perché è importante: questa regola si applica a TUTTI i forni del tenant (oggi WAGO 750-881; domani se aggiungi un Schneider o un Siemens). La discriminazione la fa tag_enrichment.machine_type, non il source_id. Riusabile e senza duplicazioni.

Casi d'uso reali

Stessa logica di allarme per 3 marche diverse

L'operatore lascia la porta del forno aperta e il door_open del WAGO flippa a 1. Stessa logica dell'evento door_open della camera Carel nel caso proofer-fleet-modbus — ma il forno ha il suo bit_flip e il suo asset. L'agente invia due WhatsApp (uno per macchina), non uno mescolato.

Manutenzione predittiva cross-brand

Il motore della mescolatrice (Schneider) mostra motor_temperature con deriva di +3°C costante per 7 giorni. L'AHI scende da A a C. Il rilevatore ML ha imparato il pattern normale di quella mescolatrice (non la media delle mescolatrici Schneider in generale — il modello è per asset). Genera un task di manutenzione preventiva "Verificare raffreddamento motore" 2 settimane prima del guasto previsto.

Lo stesso accadrebbe se la marca cambiasse a Siemens o ABB — il modello è per asset, non per marca. Zero training pregresso, zero migrazione.

Benchmark cross-brand

/dashboard/operational mostra i 3 asset uno accanto all'altro:

  • Mescolatrice MES-01: AHI 92 (A), ultimo guasto 180 giorni fa, RUL 90 giorni.
  • Camera LIE-01: AHI 78 (B), 2 allarmi critici negli ultimi 7 giorni, RUL 30 giorni.
  • Forno FOR-01: AHI 85 (B), uso 1.200 ore/mese, RUL 120 giorni.

Il manager vede questi dati e decide di prioritizzare la camera anche se è di marca diversa. Senza Rela starebbe confrontando 3 dashboard SCADA incompatibili.

Limitazioni e ipotesi

  • Ogni marca esige il suo manuale Modbus. Niente magia. Indirizzi, byte order e FC vengono dal manuale del costruttore o si scoprono con mbpoll dalla LAN prima della configurazione.
  • Se una marca espone il dato tramite un protocollo non-Modbus che il PLC parla nativamente (tipico: Siemens parla S7comm nativamente, Allen-Bradley parla EtherNet/IP CIP), conviene usare quel protocollo in Rela invece di forzare Modbus per compatibilità. I listener nativi estraggono più metadata (data type senza ambiguità, status codes, timestamp di sorgente).
  • Connessioni concorrenti sature: se il cliente ha già SCADA + HMI che leggono un PLC con max_connections=4 (tipico Carel), aggiungere Rela può far cadere la connessione più vecchia. Coordinare il rollout col team di automazione.
  • Mischiare marche moltiplica i vettori di fallimento in config. Il troubleshooting senza metodologia costa giorni. Per questo il documento include la matrice di byte_order — è la prima cosa da verificare con letture strane.

Troubleshooting

SintomoCausa probabileSoluzione
Mescolatrice mostra motor_speed = 1.4e-39 (numero assurdo)byte_order errato: hai provato big_endian e l'M340 voleva big_endian_swapCambiare byte_order del registro a big_endian_swap e verificare con mbpoll -t 4 -1 -r 102 -c 2 -F
Carel disconnesso ma Schneider e WAGO OKCarel pCOWeb saturo: 4 connessioni occupateChiudere 1 client (HMI duplicata, SCADA duplicato) o upgrade a pCOWeb Pro
Forno con eventi solo ogni 30 min invece di 10 smin_interval troppo alto, o firmware WAGO non aggiornatoAbbassare min_interval a 10 s; se persiste, aggiornare il firmware WAGO
3 fonti verdi ma machine_type non appare negli eventitag_enrichment non applicato (fonte senza field_mapping in config)Modificare la fonte e aggiungere il blocco field_mapping.tag_enrichment
Le regole con field: machine_type non si attivanotag_enrichment è nella fonte ma la regola valuta prima dell'iniezioneVerificare l'ordine della pipeline nei log: field_mapping gira prima di event_rules_engine

Vantaggi chiave

  • 1 tenant, 1 VPN, N marche: qualsiasi combinazione di PLC Modbus TCP entra nello stesso dashboard senza overhead organizzativo.
  • Regole che scalano con lo stabilimento: tag_enrichment permette di scrivere 1 regola per tipo di macchina invece di 1 per marca; aggiungere una nuova marca non richiede di duplicare regole.
  • Manutenzione predittiva agnostica del brand: il modello ML impara pattern per asset, non per marca. Sostituire un PLC su una macchina (upgrade tecnologico) non richiede ri-allenamento.
  • Onboarding pedagogico: la matrice byte_order e la convenzione di addressing sono documentate qui cosicché il team di implementazione non scopra le gotchas nel momento peggiore (cliente in produzione).
  • Benchmark cross-brand: vedere AHI e RUL di macchine eterogenee fianco a fianco nello stesso dashboard — impossibile con SCADA per marca.

Vedi anche

In questa pagina