Una applicazione REST in pratica

In questo articolo abbiamo visto come sia possibile in modo estremamente semplice implementare applicazioni cloud con i nostri sistemi SlimLine e Netsyst utilizzando l'architettura REST. Ora vediamo come sia altrettanto semplice realizzare un sito web che permette di storicizzare i dati in un database MySQL e di visualizzarli in forma tabellare o grafica. Abbiamo inserito nell'armadio del nostro datacenter un sistema Netsyst che ne monitorizza tramite un analizzatore di rete SDM120 i consumi. I dati acquisiti sono visualizzati sul display del prodotto ed inviati via REST ad un server nel cloud.

Il programma utilizzando i FB per la gestione dei contatore Eastron SDM120 esegue in un semplice programma FBD l'acquisizione dei dati di consumo, che, appoggiati a variabili globali sono visualizzati sul display ed inviati via REST al server cloud.

Lo script in linguaggio PHP sul server cloud riceve i dati in POST e li memorizza in un database, una pagina htm di consultazione permette di visualizzare i dati ricevuti su di una dashboard. Per la visualizzazione del grafico viene utilizzata la libreria open source Chart.js che permette di realizzare grafici in HTML5, ecco come si presenta la dashboard.

Programma di esempio

Come utilizzare gli esempi.
Viene fornito il progetto RESTLogger (Download intero progetto) con il programma dimostrativo che gestisce la dashboard visibile nell'esempio. Il progetto si compone di diversi programmi, di seguito riporto il listato dei più significativi che ne illustrano il funzionamento.

RESTLogger: Client eseguito su di un sistema SlimLine che acquisisce i dati da un misuratore di energia Eastron e li invia in REST al programma server.

RESTSvc: Script lato server eseguito su di un sistema LAMP che inserisce i dati ricevuti dal programma client nel database MySQL.

AjaxSvc: Script lato server eseguito sullo stesso sistema LAMP dove è eseguito RESTSvc, ritorna i dati dal database MySQL per visualizzare la dashboard con i dati aggiornati in tempo reale.

RESTLogger (Ptp145)
PROGRAM RESTLogger
VAR
    DSCmd : BOOL; (* Debug send command *)
    i : UDINT; (* Auxiliary variable *)
    Fp : eFILEP; (* File pointer *)
    REST : RESTClient_v3; (* REST service client *)
    HTTP : HTTPClient_v2; (* HTTP client *)
    JDecode : JSONDecode_v2; (* JSON decode *)
    JEncode : JSONEncode_v1; (* JSON encode *)
    PageFile : STRING[ 32 ] := 'D:/Page.html'; (* Page file *)
    RESTRequest : STRING[ 128 ]; (* REST request *)
    FIFO : FIFOFile_v1; (* FIFO on file *)
    FIFOIDx : ARRAY[0..1] OF UDINT; (* FIFO indexes *)
    FIFOFile : STRING[ 32 ] := 'D:/REST.bin'; (* FIFO file *)
    UTCDateTime : UDINT; (* UTC Date/Time *)
END_VAR

// *****************************************************************************
// PROGRAM "RESTLogger"
// *****************************************************************************
// Eseguo gestione servizio REST sul web.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // ESEGUO INIZIALIZZAZIONI
    // -------------------------------------------------------------------------
    // Eseguo inizializzazione variabili.

    IF (SysFirstLoop) THEN

        // Wear leveling, se i due indici sono uguali eseguo cancellazione
        // file così viene ricreato in una nuova posizione sul disco.

        IF (SysGetFileLen(ADR(FIFOFile)) <> -1) THEN
            IF (FIFOIDx[0] = FIFOIDx[1]) THEN i:=SysFileRemove(ADR(FIFOFile)); FIFOIDx[0]:=0; FIFOIDx[1]:=0; END_IF;
        END_IF;

        // Configurazione REST client.

        REST.SpyOn:=TRUE; //Spy On

        REST.FIFOFile:=ADR(FIFO); //FIFO on file
        REST.FIFOFilename:=ADR(FIFOFile); //Path and name of FIFO file
        REST.FIFOSize:=1000; //FIFO file size
        REST.FIFOIDx:=ADR(FIFOIDx); //FIFO indexes
        
        REST.HostAddress:=ADR('192.168.1.15'); //Host address server REST
        REST.HostName:=REST.HostAddress; //Host name server REST
        REST.Page:=ADR('/RESTLogger/RESTSvc.php'); //Pagina server REST
        REST.HostPort:=80; //Porta server REST
        
        REST.HTTPClient:=ADR(HTTP); //HTTP Client
        REST.HBitTime:=15; //Heartbeat time (S)
        REST.BLength:=512; //REST Request/Answer buffers length
    END_IF;

    // -------------------------------------------------------------------------
    // GESTIONE SERVIZIO REST
    // -------------------------------------------------------------------------
    // Eseguo gestione servizio REST.

    REST(Enable:=TRUE); //Eseguo gestione servizio REST

    // Se errore copio risposta su file per visualizzarla da browser.

    IF (REST.SvcError AND (REST.PBuffer <> NULL)) THEN
         i:=SysFileRemove(ADR(PageFile)); // Cancello file pagina
        Fp:=SysFfopen(ADR(PageFile), ADR('a')); // File pointer
        IF (Fp <> NULL) THEN
            i:=Sysfwrite(REST.PBuffer, TO_INT(Sysstrlen(REST.PBuffer)), 1, Fp);
            i:=Sysfclose(Fp); // Eseguo chiusura file
        END_IF;
    END_IF;

    // -------------------------------------------------------------------------
    // ACQUISIZIONE VALORE VARIABILI IN READ
    // -------------------------------------------------------------------------

//    IF (REST.SvcOk) THEN
//        JDecode(Object:=REST.PBuffer, Name:=ADR('RVariable'), VType:=UDINT_TYPE, VAddress:=ADR(RVariable), VSize:=SIZEOF(RVariable));
//    END_IF;

    // -------------------------------------------------------------------------
    // INVIO VALORI AL SERVER CLOUD
    // -------------------------------------------------------------------------
    // Eseguo temporizzazione invio.
    
    IF (SysGetUTCDateTime(TRUE) <> UTCDateTime) THEN
        UTCDateTime:=SysGetUTCDateTime(TRUE); //UTC Date/Time
        IF ((MOD(UTCDateTime, 60) = 0) OR (DSCmd)) THEN
            DSCmd:=FALSE; //Debug send command

            // Eseguo compilazione dati da inviare al server in JSON.

            i:=Sysmemset(ADR(RESTRequest), 0, SIZEOF(RESTRequest)); //REST request
            JEncode(Object:=ADR(RESTRequest), OSize:=SIZEOF(RESTRequest), Name:=ADR('Frequency'), VType:=REAL_TYPE, VAddress:=ADR(Frequency));
            JEncode(Object:=ADR(RESTRequest), OSize:=SIZEOF(RESTRequest), Name:=ADR('Voltage'), VType:=REAL_TYPE, VAddress:=ADR(Voltage));
            JEncode(Object:=ADR(RESTRequest), OSize:=SIZEOF(RESTRequest), Name:=ADR('AcPower'), VType:=REAL_TYPE, VAddress:=ADR(AcPower));
            JEncode(Object:=ADR(RESTRequest), OSize:=SIZEOF(RESTRequest), Name:=ADR('PwFactor'), VType:=REAL_TYPE, VAddress:=ADR(PwFactor));
            FIFO(In:=TRUE, Dp:=ADR(RESTRequest), Dls:=LEN(RESTRequest)); //Write record on FIFO
        END_IF;
    END_IF;

// [End of file]
RESTSvc.php (Ptp145)
AjaxSvc.php (Ptp145)
Was this article helpful?