In this article we have seen how it is possible in an extremely simple way to implement cloud applications with our systems SlimLine e Netsyst using the REST architecture. Now let's see how simple it is to create a website that allows you to historicize data in a MySQL database and display them in table or graphic form. We have included a system in our data center closet Netsyst which monitors consumption by means of a SDM120 network analyzer. The acquired data is displayed on the product display and sent via REST to a server in the cloud.
The program using the FBs for managing the counter Eastron SDM120 performs the acquisition of consumption data in a simple FBD program, which, supported by global variables, are shown on the display and sent via REST to the cloud server.
The PHP script on the cloud server receives the data in POST and stores it in a database, a htm page of consultation allows you to view the data received on a dashboard. The open source library is used to display the graph Chart.js which allows you to create graphics in HTML5, here is how it is presented dashboards.
Example program
How to use the examples.
The project is provided RESTLogger (Download entire project) with the demonstration program that manages the dashboard visible in the example. The project is made up of different programs, the list of the most significant that illustrate how it works is listed below.
RESTLogger: Client running on a system SlimLine which acquires data from an Eastron energy meter and sends them in REST to the server program.
RESTSvc: Server-side script executed on a LAMP system that inserts the data received from the client program into the MySQL database.
AjaxSvc: Server side script executed on the same LAMP system where RESTSvc is executed, returns the data from the MySQL database to display the dashboard with data updated in real time.
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]