In Neste artigo vimos como é possível de forma extremamente simples implementar aplicativos em nuvem com nossos sistemas SlimLine e Netsyst usando a arquitetura REST. Agora vamos ver como é simples criar um site que permita histórico de dados em um banco de dados MySQL e exibi-los em forma de tabela ou gráfico. Incluímos um sistema em nosso armário de data center Netsyst que monitora o consumo por meio de um analisador de rede SDM120. Os dados adquiridos são exibidos na tela do produto e enviados via REST para um servidor na nuvem.
O programa usando os FBs para gerenciar o contador Eastron SDM120 realiza a aquisição de dados de consumo em um programa FBD simples, que, suportado por variáveis globais, são mostrados na tela e enviados via REST para o servidor em nuvem.
O script PHP no servidor da nuvem recebe os dados no POST e o armazena em um banco de dados, uma página htm de consulta permite que você veja os dados recebidos em um painel. A biblioteca de código aberto é usada para exibir o gráfico Chart.js que permite criar gráficos em HTML5, aqui está como é apresentado painel de instrumentos.
Exemplo de programa
Como usar os exemplos.
O projeto é fornecido RESTLogger (Baixe o projeto inteiro) com o programa de demonstração que gerencia o painel visível no exemplo. O projeto é composto por diferentes programas, a lista dos mais significativos que ilustram seu funcionamento está listada a seguir.
RESTLogger: Cliente rodando em um sistema SlimLine que adquire dados de um medidor de energia Eastron e os envia em REST para o programa do servidor.
RESTSvc: Script do lado do servidor executado em um sistema LAMP que insere os dados recebidos do programa cliente no banco de dados MySQL.
AjaxSvc: O script do lado do servidor executado no mesmo sistema LAMP onde RESTSvc é executado, retorna os dados do banco de dados MySQL para exibir o painel com os dados atualizados em tempo real.
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]