Vai al contenuto

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 il protocollo MQTT tramite il FB MQTTCBeebotte. 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 attraverso una semplice API in REST a cui è possibile inviare dati tramite il FB RESTClient. 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.

ServerMonitor, datacenter con Netlog

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.

Esempio in FBD di FB EastronSDM120

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.

ServerMonitor, dashboard valori

Programma di esempio

Come utilizzare gli esempi.
Con LogicLab viene fornito il progetto Ptp145 RESTLogger con il programma che gestisce la dashboard visibile nell’esempio. Il progetto è suddiviso in due cartelle la cartella LogicLab contiene il programma del PLC, la cartella RESTLogger contiene i programmi PHP e la pagina HTML di visualizzazione.

LogicLab (Ptp145, ST_RESTDataSend)
PROGRAM ST_RESTDataSend
VAR
    DSCmd : BOOL; (* Debug send command *)
    UTCDateTime : UDINT; (* UTC Date/Time *)
    RESTRequest : STRING[ 128 ];  (* REST request *)
    FIFO : FIFOFile_v1; (* FIFO on file *)
    TCPClient : SysTCPClient; (* TCP client management *)
    HTTPRq : HTTPClient_v5; (* HTTP client *)
    REST : RESTClient_v7; (* REST service client *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_RESTDataSend"
// *****************************************************************************
// It sends data to the REST server,
// https://support.elsist.biz/articoli/una-applicazione-rest-in-pratica/
// -----------------------------------------------------------------------------
// To test the program you have to install the RESTLogger PHP program on a LAMP
// or XAMP environment. To test if the RESTServer works properly you can open
// in your browser the bottom link.
// http://localhost/RESTLogger/RESTSvc.php?Post={"MID":1234, "ST":0, "UID":10879070, "MV":"1.0"}
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // PROGRAM INIT
    // -------------------------------------------------------------------------
    // Executed at first program execution, all variables are initialized.

    IF (SysFirstLoop) THEN

        // Set FIFO parameters

        FIFO.FIFOFilename:=eNULL; //Path and name of FIFO file
        FIFO.FIFOSize:=2048; //FIFO file size
        FIFO.FIFOIDx:=eNULL; //FIFO indexes

        // Set TCPClient parameters.

        TCPClient.PeerAdd:=ADR('192.168.1.122'); //Peer address
        TCPClient.PeerPort:=80; //Peer port
        TCPClient.LocalAdd:=ADR('0.0.0.0'); //Local address
        TCPClient.LocalPort:=0; //Local port
        TCPClient.FlushTm:=50; //Flush time (mS)
        TCPClient.LifeTm:=20; //Life time (S)
        TCPClient.RxSize:=512; //Rx buffer size
        TCPClient.TxSize:=512; //Tx buffer size

        // Set HTTPClient parameters.

        HTTPRq.SpyOn:=TRUE; //Activate the spy
        HTTPRq.KeepAlive:=FALSE; //HTTP keep-alive
        HTTPRq.RMethod:=HTTP_REQUEST#HTTP_POST; //Request method
        HTTPRq.HostName:=TCPClient.PeerAdd; // Hostname
        HTTPRq.Page:=ADR('/RESTLogger/RESTSvc.php'); //Web page
        HTTPRq.Header:=ADR('Content-Type:application/json$r$n'); //HTTP header
        HTTPRq.DBSize:=512; //Data buffer size
        HTTPRq.Timeout:=T#10s; //Execution timeout

        // REST definitions.

        REST.SpyOn:=TRUE; //Spy On
        REST.BLength:=512; //REST Request/Answer buffers length
        REST.Delay:=T#2s; //Delay time
        REST.HBitTime:=T#5s; //Heartbeat time

        // REST auxiliary object references.

        REST.FIFOFile:=ADR(FIFO); //FIFO on file
        REST.HTTPClient:=ADR(HTTPRq); //HTTP Client
    END_IF;

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

    TCPClient(Connect:=HTTPRq.Connect); //TCPClient management
    HTTPRq(File:=TCPClient.File); //HTTP client
    REST(Enable:=TRUE); //REST client management
    REST.DDelete:=FALSE; //Delete data from FIFO

    // -------------------------------------------------------------------------
    // ERROR MANAGEMENT                                       
    // -------------------------------------------------------------------------
    // On error it's possible to count the retries and then decide what to do.

    IF (REST.SvcError) THEN

        // After 3 retries the message to be sent to the REST server is removed
        // from the FIFO register. Before to remove the message it's returned
        // to the spy console.

        IF (REST.Retries > 3) THEN
            FIFO(Out:=TRUE, Dp:=eNULL, Dls:=0); //Read record length
            IF NOT(SysRMAlloc(FIFO.Dl+1, ADR(FIFO.Dp))) THEN RETURN; END_IF;
            FIFO(Out:=TRUE, Dls:=FIFO.Dl); //Read record data
            eTO_JUNK(SysWrSpyData(SPY_ASCII, 0, 16#00000001, ADR('-Delete-'), FIFO.Dp));
            eTO_JUNK(SysRMFree(ADR(FIFO.Dp))); //Free malloc memory
            REST.DDelete:=TRUE; //Delete data from FIFO
         END_IF;
    END_IF;

    // -------------------------------------------------------------------------
    // SEND DATA TO SERVER
    // -------------------------------------------------------------------------
    // Every minute data are send to the server.
    
    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.

            eTO_JUNK(Sysmemset(ADR(RESTRequest), 0, SIZEOF(RESTRequest))); //REST request
            eTO_JUNK(JSONEncoder(ADR(RESTRequest), SIZEOF(RESTRequest), ADR('Frequency'), REAL_TYPE, ADR(Frequency), 1));
            eTO_JUNK(JSONEncoder(ADR(RESTRequest), SIZEOF(RESTRequest), ADR('Voltage'), REAL_TYPE, ADR(Voltage), 1));
            eTO_JUNK(JSONEncoder(ADR(RESTRequest), SIZEOF(RESTRequest), ADR('AcPower'), REAL_TYPE, ADR(AcPower), 1));
            eTO_JUNK(JSONEncoder(ADR(RESTRequest), SIZEOF(RESTRequest), ADR('PwFactor'), REAL_TYPE, ADR(PwFactor), 1));
            FIFO(In:=TRUE, Dp:=ADR(RESTRequest), Dls:=LEN(RESTRequest)); //Write record on FIFO
        END_IF;
    END_IF;

// [End of file]]
Was this article helpful?