MQTTClient, client for a MQTT server

  1. Home
  2. Knowledge Base
  3. Manualistica
  4. Programmazione IEC 61131-3
  5. Gestione networking
  6. MQTTClient, client for a MQTT server

Questo blocco funzione permette di gestire la connessione ad un server utilizzando il protocollo MQTT (Message Queuing Telemetry Transport) di IBM che l'Organization for the Advancement of Structured Information Standards (OASIS) ha dichiarato come lo standard di riferimento per la comunicazione per l'Internet delle Cose. Il protocollo adotta un meccanismo di pubblicazione e sottoscrizione per scambiare messaggi tramite un appostivo "message broker” che fa da server. Il FB permette sia di pubblicare che di sottoscrivere topics sul broker.

Questo è un blocco funzione protetto per utilizzarlo occorre richiedere il codice di protezione, vedi protezione funzioni e blocchi funzione. E' comunque possibile utilizzarlo liberamente su tutti i broker che non richiedono autenticazione (Username e Password non definiti). Sui broker autenticati il FB funziona in modo test per 30 Min.

Con il comando Enable si forza la connessione al Server (Message broker) sulla porta Port, utilizzando Username e Password definite. Se la connessione và a buon fine si attiva l'uscita Connected. A connessione avvenuta ogni 1/3 del tempo definito in KeepAlive viene inviato un comando di ping per mantenere la connessione. Se il broker non riceve il ping nel tempo definito in KeepAlive ritiene la connessione terminata.

Il comando di Publish permette di pubblicare sul broker il Topic indicato con relative Value, Flags e QoS. Se la pubblicazione và a buon fine si attiva per un loop l'uscita Published.

Il comando di Subscribe permette di sottoscrivere sul broker il Topic indicato con relative Flags e QoS. Se la sottoscrizione và a buon fine si attiva per un loop l'uscita Subscribed. Ad ogni sottoscrizione del valore di un topic sul broker, il broker ne invia il valore a tutti i client che lo hanno sottoscritto. Il FB riceve sia il nome del topic ritornato in TBufferRxD che il valore ritornato in VbufferRxD ed attiva per un loop TopicRxD. In VLengthRxD è ritornata la lunghezza del valore di topic ricevuto.

In CTime è ritornato il tempo di comunicazione con broker, rilevato alla connessione ed a ogni esecuzione di ping. O sulla pubblicazione di topic solo se QoS è 1. In caso di errore viene eseguita una disconnessione e riconnessione al broker e si attiva per un loop l'uscita Fault.

Function block
CODESYS: Non disponibile
LogicLab: eLLabNetworkLib

Enable (BOOL) Comando abilitazione connessione al server MQTT message broker.

SpyOn (BOOL) Se attivo permette di spiare il funzionamento della FB.

Publish (BOOL) Comando pubblicazione di un topic sul server.

Subscribe (BOOL) Comando sottoscrizione di un topic sul server.

Server (@STRING) Puntatore stringa definizione server MQTT.

Port (UINT) Numero porta TCP a cui connettersi.

Username (@STRING) Puntatore stringa definizione nome utente (1).

Password (@STRING) Puntatore stringa definizione password accesso (1).

User (@STRING) Puntatore stringa definizione nome utente.

Password (@STRING) Puntatore stringa definizione password.

ClientID (@STRING) Puntatore stringa definizione identificativo client (Massimo 23 caratteri) (1).

KeepAlive (REAL) Tempo di vita connessione da parte del broker (S).

Flags (DWORD) Flags connessione, pubblicazione, sottoscrizione.

QoS (USINT) Quality of Service.

Topic (@STRING) Puntatore stringa definizione nome topic (Pubblicazione/Sottoscrizione).

Value (@STRING) Puntatore valore topic (Pubblicazione).

VLength (UDINT) Lunghezza valore topic (Pubblicazione).

TBufferRxD (@STRING) Puntatore buffer nome topic ricevuto da broker.

TBLengthRxD (UDINT) Dimensione buffer nome topic ricevuto da broker.

VBufferRxD (@STRING) Puntatore buffer valore topic ricevuto da broker.

VBLengthRxD (UDINT) Dimensione buffer valore topic ricevuto da broker.

Connected (BOOL) Si attiva se connessione al server MQTT avvenuta.

Fault (BOOL) Attivo per un loop se errore esecuzione.

Published (BOOL) Attivo per un loop su pubblicazione di un topic sul server.

Subscribed (BOOL) Attivo per un loop su sottoscrizione di un topic sul server.

TopicRxD (BOOL) Attivo per un loop su ricezione di un topic dal server.

VLengthRxD (UINT) Lunghezza valore topic ricevuto dal broker.

CTime (Real) Tempo di comunicazione con il broker (S).

Nota (1): Se nella stringa è presente il carattere $, và indicato come $$ (Esempio Us$er diventa Us$$er).

Trigger di spy

Se SpyOn attivo è possibile utilizzare utilizzare la console di spionaggio per verificare il funzionamento della FB. Sono previsti vari livelli di triggers.

Errori

In caso di errore eseguendo immediatamente dopo la funzione SysGetLastError è possibile rilevare il codice di errore. Fare riferimento alla tabella seguente per la descrizione.

Esempi

Come utilizzare gli esempi.

Abilitando da debug Enable il FB si connette al broker broker.mqttdashboard.com, un broker gratuito e senza autenticazione (Quindi il FB può essere usato gratuitamente), se la connessione và a buon file si attiva l'uscita Connected, ed esegue la pubblicazione dello stato dalla variabile Command sul topic IOCommand. Il programma si sottoscrive allo stesso topic così ne riceve dal broker lo stato ad ogni variazione, e lo stato ricevuto viene trasferito sulla variabile Status.

Agendo da debug sulla variabile Command ci ritroveremo lo stesso stato sulla variabile Status, passando attraverso la pubblicazione sul broker ed alla relativa ricezione della notifica in sottoscrizione. In questo articolo informazioni su come interagire con l'esempio da Smartphone.

Nota: non essendoci autenticazione chiunque pubblichi qualcosa sul topic IOCommand và in conflitto con quanto pubblicato dal programma, quindi per evitare conflitti conviene modificare il nome del topic e l'identificativo utente. Ci può solo essere un utente con lo stesso identificativo sullo stesso broker.

LogicLab (Ptp119)
PROGRAM ST_MQTTClient
VAR
    Enable : BOOL; (* Enable command *)
    Command : BOOL; (* Command status *)
    Status : BOOL; (* Received topic status *)
    CPulse : BOOL; (* Command pulse *)
    CaseNr : USINT; (* Program case *)
    TimeBf : UDINT; (* Time buffer (uS) *)
    Topic : STRING[ 32 ] := 'IOCommand'; (* Topic name *)
    TopicRxD : STRING[ 64 ]; (* Topic received buffer *)
    ValueRxD : STRING[ 300 ]; (* Value received buffer *)
    MQTT : MQTTClient; (* MQTT client FB *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_MQTTClient"
// *****************************************************************************
// This program connects to a free broker, it publishes the state of the BOOL
// variable "Command" on the "IOCommand" topic. It subscribes to the same topic
// so receives the topic status from the broker and transfer it to the BOOL
// variable "Status".
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATION
    // -------------------------------------------------------------------------
    // Program initializations.

    IF (SysFirstLoop) THEN
        MQTT.SpyOn:=TRUE; //Spy active
        MQTT.Server:=ADR('broker.mqttdashboard.com'); //Broker URL
        MQTT.Port:=1883; //Broker TCP port
        MQTT.Username:=NULL; //Broker username
        MQTT.Password:=NULL; //Broker password
        MQTT.ClientID:=ADR('Elsist'); //Client identifier
        MQTT.KeepAlive:=180; //Keep alive time (S)
        MQTT.Flags:=16#00000000; //Connection/Publish/Subscribe flags
        MQTT.QoS:=1; //Quality of Service
        MQTT.TBufferRxD:=ADR(TopicRxD); //Topic buffer (Received)
        MQTT.TBLengthRxD:=SIZEOF(TopicRxD); //Topic buffer length (Received)
        MQTT.VBufferRxD:=ADR(ValueRxD); //Value buffer (Received)
        MQTT.VBLengthRxD:=SIZEOF(ValueRxD); //Value buffer length (Received)
    END_IF;

    // -------------------------------------------------------------------------
    // MQTT CLIENT MANAGEMENT
    // -------------------------------------------------------------------------
        // MQTTClient management.

    MQTT(); //MQTTClient management
    IF (MQTT.Fault) THEN MQTT.Enable:=FALSE; CaseNr:=0; RETURN; END_IF;
    IF NOT(MQTT.Connected) THEN CaseNr:=0; END_IF;

    // -------------------------------------------------------------------------
    // TOPIC VALUE RECEPTION
    // -------------------------------------------------------------------------
    // Check if a topic value has been received.

    IF (MQTT.TopicRxD) THEN

        // Check if the received topic is the expected.

        IF (SysStrFind(ADR(TopicRxD),ADR(Topic), FIND_DEFAULT) <> NULL) THEN

            // The received topic is the expected, so check its value.

            IF (SysStrFind(ADR(ValueRxD), ADR('Off'), FIND_DEFAULT) <> NULL) THEN Status:=FALSE; END_IF;
            IF (SysStrFind(ADR(ValueRxD), ADR('On'), FIND_DEFAULT) <> NULL) THEN Status:=TRUE; END_IF;
        END_IF;
    END_IF;

    // -------------------------------------------------------------------------
    // PROGRAM CASES
    // -------------------------------------------------------------------------
    // Program cases.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // CONNECTION TO BROKER
        // ---------------------------------------------------------------------
        // Check if connected to broker.

        0:
        MQTT.Enable:=Enable; //Connection enable
        IF NOT(MQTT.Connected) THEN RETURN; END_IF;

        // Client connected to broker, manage the subscription

        MQTT.Topic:=ADR(Topic); //Topic name
        MQTT.Subscribe:=TRUE; //Topic subscribe
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Waits for subscription.

        1:
        MQTT.Subscribe:=FALSE; //Topic subscribe
        IF NOT(MQTT.Subscribed) THEN RETURN; END_IF;
        CaseNr:=10; //Program case

        // ---------------------------------------------------------------------
        // TOPIC PUBLISH
        // ---------------------------------------------------------------------
        // Checks if the command status change and publish it.

        10:
        IF (Command = CPulse) THEN RETURN; END_IF;
        CPulse:=Command; //Command pulse

        // Defines the topic to publish.        

        MQTT.Topic:=ADR(Topic); //Topic name

        // Defines the value to publish.

        IF NOT(Command) THEN MQTT.Value:=ADR('Off'); END_IF;
        IF (Command) THEN MQTT.Value:=ADR('On'); END_IF;

        // Defines length of the value.

        MQTT.VLength:=Sysstrlen(MQTT.Value); //Value length            
        MQTT.Publish:=TRUE; //Topic publish
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Waits for the publishing.

        11:
        MQTT.Publish:=FALSE; //Topic publish
        IF NOT(MQTT.Published) THEN RETURN; END_IF;
        CaseNr:=10; //Program case
    END_CASE;

// [End of file]

Ti è stato utile questo articolo ?

Ultimo aggiornamento: 5 Ottobre 2020