Olivia_v2017/Olivia/olv_sens_ws.cpp

244 lines
5.8 KiB
C++

#include "stdafx.h"
#ifdef OLIVIA_COMPILA
#include "olv_sens_ws.h"
#ifndef OLIVIA_NSENS
#include <curl.h>
#include <json.h>
#include <time.h>
#endif
/**
* @file olv_sens_ws.cpp
* Archivo de implementaciones de la utilidad para conexión al Web Service para lectura de los sensores de la herramienta Olivia.
*/
/**
* Clase para conexión al Web Service para lectura de los sensores de la herramienta Olivia.
*/
Colv_sens_ws::Colv_sens_ws(void)
{
info=NULL;
cuerpo[0]=0;
}
Colv_sens_ws::~Colv_sens_ws(void)
{
}
//*************************************************************************************
void Colv_sens_ws::inicia(Info_sens *info_)
{
info=info_;
strcpy_s(url,OLV_MAX_URL,info->url );
sprintf_s(cuerpo,OLV_MAX_CUERPO,"?%s=%s&id=%s&%s=%s&%s=%s&%s=%s&%s=%s",
info->camps.fn,info->fn_cont_status,
"%s",//deja abierto para meter el id del sensor que toque
info->camps.startdate,info->fecha_ini,
info->camps.enddate,info->fecha_fin,
info->camps.usr,info->usr,
info->camps.pwd,info->pwd);
}
//*************************************************************************************
/*
Pide el porcentaje de llenado en tanto por cien del contenedor id
*/
double Colv_sens_ws::dame_porc_cont_i(char *id)
{
int ndata;
int ini;
int *data_vol;
double perc;
//manda pregunta
if(!get_status_cont_i(id))
return FALSE;
//recibe respuesta
ndata=0;
data_vol=NULL;
if(!answer_json(id,&ndata,&data_vol))
return FALSE;
perc=0;
if(ndata>0)
{
if(info->modo_pet==OLV_SENS_PET_UNICO)
ini=ndata-1;//solo se queda con el valor único último
else if(info->modo_pet==OLV_SENS_PET_MEDIA)
ini=0;
for (int i=ini;i<ndata;i++)
{
perc+=data_vol[i]*1./(ndata-ini);
}
}
if(data_vol)
free(data_vol);
return perc;
}
//*************************************************************************************
BOOL Colv_sens_ws::get_status_cont_i(char *id)
{
////////////
//Monta el cuerpo POST
char cuerpo_aux[OLV_MAX_CUERPO+OLV_MAX_URL];
strcpy_s(cuerpo_aux,OLV_MAX_URL,url);
sprintf_s(&cuerpo_aux[strlen(cuerpo_aux)],OLV_MAX_CUERPO,cuerpo,id);
//envía el Post
if(!post_curl(cuerpo_aux))
return FALSE;
return TRUE;
}
//*************************************************************************************
BOOL Colv_sens_ws::post_curl(char *body)
{
#ifndef OLIVIA_NSENS
//envía el Post
CURL *curl;
CURLcode res;
BOOL mal=FALSE;
/* In windows, this will init the winsock stuff */
res=curl_global_init(CURL_GLOBAL_ALL);
if(res != CURLE_OK)
{
sprintf_s(err_str, "Error al iniciar conexión con servicio web: %s\n",
curl_easy_strerror(res));
return FALSE;
}
/* get a curl handle */
curl = curl_easy_init();
if(!curl)
{
sprintf_s(err_str, "Error al iniciar conexión con servicio web: %s\n",
curl_easy_strerror(res));
return FALSE;
}
/* First set the URL that is about to receive our POST. This URL can
just as well be a https:// URL if that is what should receive the
data. */
curl_easy_setopt(curl, CURLOPT_URL, body);
cURL_JSON_data.clear();
/* Specify which function will parse the answer */
res=curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Colv_sens_ws::writeJSONURLCallback);
/* Specify variable to parse data */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)this);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
{
sprintf_s(err_str, "Error al enviar POST en el servicio web: %s\n",
curl_easy_strerror(res));
mal=TRUE;
}
/* always cleanup */
curl_easy_cleanup(curl);
curl_global_cleanup();
return !mal;
#else
return FALSE;
#endif
}
//*************************************************************************************
size_t Colv_sens_ws::writeJSONURLCallback(char* buf, size_t siz, size_t nmemb, void* up)//Callback function to store the URL's data
{
#ifndef OLIVIA_NSENS
if(!up)
return siz*nmemb;
Colv_sens_ws *cl=(Colv_sens_ws*)up;
for (int c = 0; c<(int)(siz*nmemb); c++)
{
cl->cURL_JSON_data.push_back(buf[c]);
}
return siz*nmemb;
#endif
return 0;
}
//*************************************************************************************
BOOL Colv_sens_ws::answer_json(char *id_, int *ndata_, int **data_vol_)
{
#ifndef OLIVIA_NSENS
int ndata,i;
int *data_vol;
std::string id;
std::string err_code;
Json::Reader jsonReader;
Json::Value jsonData;
Json::Value histoData;
ndata=0;
data_vol=0;
if (jsonReader.parse(cURL_JSON_data, jsonData))
{
//comprueba que sea el id elegido
id = jsonData[info->camps_json.id].asString();
if(id.length()==0)
{
//mira a ver si ha habido error
err_code=jsonData[info->camps_json.resp_code].asString();
if(err_code.length()>0 && err_code.compare(info->camps_json.resp_code_err))
{
sprintf_s(err_str, "Error en la petición %s\n",jsonData[info->camps_json.resp_data].asString());
jsonData.clear();
return FALSE;
}
}
if(strcmp(id.data(),id_))
{
sprintf_s(err_str, "Error, no se ha recibido el id del contenedor solicitado %s %s\n",id,id_);
jsonData.clear();
return FALSE;
}
//coge la info histórica de carga
histoData = jsonData[info->camps_json.histo];
ndata = (int) histoData.size();
//crea el array para almacenar los valores de carga
data_vol=(int*)malloc(ndata*sizeof(int));
if(!data_vol)
{
sprintf_s(err_str, "Error, sin memoria al leer info JSON\n");
jsonData.clear();
return FALSE;
}
i=0;
for (Json::ValueConstIterator it = histoData.begin(); it != histoData.end(); ++it)
{
const Json::Value data = *it;
data_vol[i]=data[info->camps_json.porc].asInt();
i++;
}
if(i!=ndata)
return FALSE;
}
else
{
sprintf_s(err_str, "Error al leer info JSON: %s\n",
jsonReader.getFormattedErrorMessages());
return FALSE;
}
jsonData.clear();
*data_vol_=data_vol;
*ndata_=ndata;
#endif
return TRUE;
}
#endif