RESTClient, connects to a REST web service

  1. Home
  2. Knowledge Base
  3. Manualistica
  4. Programmazione IEC 61131-3
  5. Gestione networking
  6. RESTClient, connects to a REST web service

Questo blocco funzione gestisce la connessione verso un server REST con protocollo HTTP. Viene inviato il messaggio con i dati in POST (Lunghezza massima 12 Kbytes) e ritornati i dati ricevuti dal server (Lunghezza definita in BLength).

Per garantire il buffering dei dati su eventi molto rapidi, il servizio utilizza il FB di gestione FIFO per gestire uno stack FIFO su di un file, l'indirizzo di allocazione và passato in FIFOFile. In FIFOFilename occorre definire quale file utilizzare per appoggiare lo stack FIFO ed in FIFOSize che dimensione dare al file.  Se si desidera che la situazione dei dati nel FIFO sia mantenuta allo spegnimento del sistema in FIFOIDx occorre fornire l'indirizzo di un array di 2 UDINT che devono essere allocati in una memoria tampone.

In HTTPClient occorre indicare l'indirizzo di allocazione di un FB di gestione client HTTP per gestire la connessione al server REST. In HostAddress definire l'indirizzo IP o l'URL del server REST, è possibile definire anche l'HostName che sarà utilizzato nella richiesta (Di solito è uguale a HostAddress). In HostPort definire la porta del servizio REST (Di solito è la standard HTTP 80). In Page definire lo script di gestione del servizio REST sul server.

Attivando Enable ogni tempo definito in HBitTime viene inviato un messaggio di heartbeat al server REST, questo permette di controllare il corretto funzionamento del servizio anche in assenza di messaggi da inviare al server. L'uscita RSvcOn se attiva indica che la comunicazione con il server è attiva.

La comunicazione con il server è in formato JSON e quindi i dati che si desidera scambiare devono essere codiificati in JSON. Per inviare messaggi al server REST occorre eseguire il FB FIFOFile che trasferirà il messaggio nel buffer FIFO e successivamente al server. L'utilizzo di un buffer FIFO garantisce che tutti i messaggi siano inviati al server bufferizzandoli nel caso di mancata connessione.

La risposta ricevuta dal server è memorizzata in un buffer interno al FB (Di dimensione BLength il cui indirizzo è fornito in PBuffer), alla ricezione si attiva SvcOk ed il programma utente potrà utilizzare i dati presenti nel buffer. In caso di errore ricezione dal server si attiva SvcError ed in PBuffer vi è la pagina ricevuta dal server, sarà possibile trasferirla in un file per visualizzarla da browser per indagare sull'errore.

Function block
CODESYS: Non disponibile
LogicLab: eLLabNetworkLib

Enable (BOOL) Comando attivazione connessione al server REST.

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

FIFOFile (@FIFOFile_v1) Indirizzo allocazione FB FIFOFile_v1 di supporto.

FIFOFilename (@STRING) Percorso e nome file appoggio stack FIFO. Se NULL dati sono appoggiati in un buffer in memoria.

FIFOSize (UDINT)) Dimensione in bytes dello stack FIFO.

FIFOIDx (@UDINT) Pointer alla variabile indice gestione FIFO (Deve essere un array di 2 UDINT). Definire NULL se non occorre memorizzare i dati nelo stack FIFO allo spegnimento.

HTTPClient (@HTTPClient_v1) Indirizzo allocazione FB HTTPClient_v1 di supporto.

HostAddress (@STRING) Indirizzo IP o URL del server REST a cui connettersi.

HostName (@STRING) Nome del server utilizzato nella richiesta (Di solito è uguale a HostAddress).

HostPort (UINT)) Numero porta TCP a cui connettersi (Default 80).

Page (@STRING) Stringa di definizione script gestione servizio REST sul server.

HBitTime (UINT) Tempo invio heartbeat al server (S). Ogni tempo definito viene inviato un messaggio di heartbeat al server.

BLength (UDINT) Dimensione allocazione buffer pagina ricevuta da server REST (SysRMalloc).

Enabled (BOOL) Blocco funzione abilitato.

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

RSvcOn (BOOL) Servizio REST attivo. Si attiva su comunicazione con il server REST attiva, viene disattivato se si interrompe la comunicazione, errore su invio di messaggi o heartbeat.

SvcOk (BOOL) Ok ricezione da server REST, si attiva per un loop su ricezione risposta.

SvcError (BOOL) Errore ricezione da server REST, si attiva per un loop su ricezione risposta. Il messaggio viene automaticamente reinviato al server.

PBuffer (@STRING) Pointer buffer pagina ricevuta da server REST. Il buffer è allocato nel FB tramite funzione SysRMAlloc, è valido per un solo loop su attivazione di SvcOk o SvcError.

FIFOSpace (UDINT) Spazio disponibile nel file FIFO.

RSvcTime (REAL) Tempo esecuzione servizio REST (S).

PktsOk (UDINT) Counter pacchetti REST correttamente scambiati con il server. Raggiunto il valore massimo il conteggio riprende da 0.

Resyncs (UDINT) Counter resincronizzazioni con il server REST. Raggiunto il valore massimo il conteggio riprende da 0. I messaggi scambiati tra FB e server hanno un identificativo che ne permette il controllo. In caso di disallineamento (Perdita di un messaggio) viene eseguita una resincronizzazione.

Errors (UDINT) Counter errori comunicazione con il server REST. Raggiunto il valore massimo il conteggio riprende da 0.

Trigger di spy

Se SpyOn attivo viene eseguita la funzione SysSpyData che permette di 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.

Viene fornito il dimostrativo "RESTSvcDemo" che include il programma da installare su di un sistema SlimLine e lo script PHP da eseguire su di un qualsiasi server web. Per facilitare il test del programma abbiamo installato lo script PHP su di un server hostato presso Altervista, per testare il programma basterà eseguirlo su di un sistema SlimLine connesso ad Internet.

LogicLab (Ptp135)
PROGRAM ST_RESTClient_v1
VAR
    i : UDINT; (* Auxiliary variable *)
    TimeBf : UDINT; (* Time buffer (uS) *)
    LError : UDINT; (* Last error *)
    FIFO : FIFOFile_v1; (* FIFO on file *)
    REST : RESTClient_v2; (* REST service client *)
    HTTP : HTTPClient_v1; (* HTTP client *)
    JDecode : JSONDecode_v2; (* JSON decode *)
    JEncode : JSONEncode_v1; (* JSON encode *)
    RESTAnswer : STRING[ 128 ]; (* REST answer *)
    RESTRequest : STRING[ 128 ]; (* REST request *)
    RESTData : ARRAY[0..2] OF REAL; (* Data exchanged with REST server *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_RESTClient_v1"
// *****************************************************************************
// The program sends data to a REST server and manage the answer.
// -----------------------------------------------------------------------------

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

    IF (SysFirstLoop) THEN
        TimeBf:=SysGetSysTime(TRUE); //Time buffer (uS)
        REST.SpyOn:=TRUE; //Spy On

        // FIFO saved on RAM memory.

        REST.FIFOFile:=ADR(FIFO); //FIFO on file
        REST.FIFOFilename:=NULL; //Path and name of FIFO file
        REST.FIFOSize:=2048; //FIFO file size
        REST.FIFOIDx:=NULL; //FIFO indexes

        // REST server address.

        REST.HostAddress:=ADR('www.slimline.altervista.org'); //Host address server REST
        REST.HostName:=REST.HostAddress; //Host name server REST
        REST.Page:=ADR('Utilities/RESTSvcDemo/RESTSvc.php'); //REST server script
        REST.HostPort:=80; //REST server port

        REST.HTTPClient:=ADR(HTTP); //HTTP Client
        REST.HBitTime:=5; //Heartbeat time (S)
        REST.BLength:=512; //REST Request/Answer buffers length
    END_IF;

    // -------------------------------------------------------------------------
    // REST CLIENT MANAGEMENT                                                
    // -------------------------------------------------------------------------
    // Here the REST client is managed, it's always enabled.

    REST(Enable:=TRUE); //REST client management
    IF (REST.Fault) THEN LError:=SysGetLastError(TRUE); END_IF;

    // -------------------------------------------------------------------------
    // SEND DATA TO SERVER                                                   
    // -------------------------------------------------------------------------
    // Request string, preparation and sending, it will be of the type:
    // {"Dividend":502.987671,"Divisor":584.047363}

    IF ((SysGetSysTime(TRUE)-TimeBf) > 10000000) THEN
        TimeBf:=SysGetSysTime(TRUE); //Time buffer (uS)
        RESTData[0]:=SysGetRandom(TRUE)*1000.0; //Data exchanged with REST server
        RESTData[1]:=SysGetRandom(TRUE)*1000.0; //Data exchanged with REST server

        i:=Sysmemset(ADR(RESTRequest), 0, SIZEOF(RESTRequest)); //REST request
        JEncode(Object:=ADR(RESTRequest), OSize:=SIZEOF(RESTRequest), Name:=ADR('Dividend'), VType:=REAL_TYPE, VAddress:=ADR(RESTData[0]), Count:=1);
        JEncode(Object:=ADR(RESTRequest), OSize:=SIZEOF(RESTRequest), Name:=ADR('Divisor'), VType:=REAL_TYPE, VAddress:=ADR(RESTData[1]), Count:=1);
        FIFO(In:=TRUE, Dp:=ADR(RESTRequest), Dls:=LEN(RESTRequest)); //Write record on FIFO
    END_IF;

    // -------------------------------------------------------------------------
    // RECEIVED VARIABLES ACQUISITION                                        
    // -------------------------------------------------------------------------
    // When answer is received decodes it's value and store it on variable.
    // The REST server answer will be {"Result":"xxxx"}

    IF (REST.SvcOk AND (REST.PBuffer <> NULL)) THEN

        // Copy the received data to buffer.

        i:=Sysmemset(ADR(RESTAnswer), 0, SIZEOF(RESTAnswer));
        i:=Sysstrlen(REST.PBuffer); //Received string length
        IF (i > SIZEOF(RESTAnswer)) THEN i:=SIZEOF(RESTAnswer); END_IF;
        i:=Sysmemmove(ADR(RESTAnswer), REST.PBuffer, i); 

        // Decodes the value of "Result" and stores it to RESTData[2].

        JDecode(Object:=REST.PBuffer, Name:=ADR('Result'), VType:=REAL_TYPE, VAddress:=ADR(RESTData[2]), Count:=1);
    END_IF;

// [End of file]
PHP (Ptp135)

Ti è stato utile questo articolo ?

Ultimo aggiornamento: 3 Dicembre 2019