566 lines
17 KiB
C
566 lines
17 KiB
C
/****************************************************************************
|
|
* This file is part of the project AqHome.
|
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
|
*
|
|
* The license for this file can be found in the file COPYING which you
|
|
* should have received along with this file.
|
|
****************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
|
|
#include "./mdevices.h"
|
|
|
|
#include "aqhome-cgi/modules/devices/mdevices_index.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_valuestable.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_valuesgraph.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_value.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_setdata.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_vgraph.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_device.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_setdevice.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_page.h"
|
|
#include "aqhome-cgi/service/module.h"
|
|
#include "aqhome-cgi/modules/mdataclient.h"
|
|
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/timestamp.h>
|
|
#include <gwenhywfar/text.h>
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* defs and enums
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#define GBAS GWEN_Buffer_AppendString
|
|
#define GBAA GWEN_Buffer_AppendArgs
|
|
|
|
#define P_DEVICEREAD AQH_MODDEVICES_PERMS_DEVICEREAD
|
|
#define P_DEVICEWRITE AQH_MODDEVICES_PERMS_DEVICEWRITE
|
|
#define P_VALUEREAD AQH_MODDEVICES_PERMS_VALUEREAD
|
|
#define P_VALUEWRITE AQH_MODDEVICES_PERMS_VALUEWRITE
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName);
|
|
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem);
|
|
|
|
static void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqValuesTableGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqValuesGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqDeviceGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqPagePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqPageGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
|
|
static AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues);
|
|
|
|
static void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
static void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* vars
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
|
|
{"index.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD, _handleRqIndexGet},
|
|
{"device.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqDeviceGet},
|
|
{"device.html", AQCGI_REQUEST_METHOD_POST, P_DEVICEWRITE, _handleRqDevicePost},
|
|
{"vtable.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValuesTableGet},
|
|
{"vgraph.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValuesGraphGet},
|
|
{"value.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValueGet},
|
|
{"setdata.html", AQCGI_REQUEST_METHOD_POST, P_VALUEWRITE, _handleRqSetDataPost},
|
|
{"graph.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqGraphGet},
|
|
{"page.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqPageGet},
|
|
{"page.html", AQCGI_REQUEST_METHOD_POST, P_VALUEWRITE, _handleRqPagePost},
|
|
{"pgraph.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqPageGraphGet},
|
|
{NULL, 0, 0, NULL}
|
|
};
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* code
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder)
|
|
{
|
|
AQH_ModService_Extend(m, sv, baseFolder);
|
|
AQH_ModService_SetHandleRequestFn(m, _handleRequest);
|
|
AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule);
|
|
}
|
|
|
|
|
|
|
|
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem)
|
|
{
|
|
AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable);
|
|
return AQCGI_SendResponse(rq);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunIndex, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqValuesTableGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsTable, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqValuesGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsGraph, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValue, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetData, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunGraphValue, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqDeviceGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunDevice, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetDevice, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqPageGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPageGet, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqPagePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPagePost, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqPageGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunPageGraph, dbuf);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t AQH_ModDevices_ColorFromHexString(const char *s)
|
|
{
|
|
uint32_t colorIn=0;
|
|
|
|
while(*s && *s<33)
|
|
s++;
|
|
if (*s=='#')
|
|
s++;
|
|
while(*s) {
|
|
uint c;
|
|
|
|
c=(*s)-'0';
|
|
if (c>9)
|
|
c-=7;
|
|
colorIn<<=4;
|
|
colorIn|=c & 0xf;
|
|
s++;
|
|
}
|
|
|
|
/* hex 00RRGGBB -> GGRRWWBB */
|
|
//return _htmlColorToValueRGBW(colorIn);
|
|
return colorIn;
|
|
}
|
|
|
|
|
|
|
|
uint32_t AQH_ModDevices_HtmlColorToValueRGBW(uint32_t colorIn)
|
|
{
|
|
uint32_t colorOut;
|
|
/* hex 00RRGGBB -> GGRRWWBB */
|
|
/* RGBW GGRRWWBB GGRRWWBB GGRRWWBB */
|
|
/* html 00RRGGBB 00RRGGBB 00RRGGBB*/
|
|
colorOut=(colorIn & 0x00ff0000) | ((colorIn<<16) & 0xff000000) | (colorIn & 0x000000ff);
|
|
return colorOut;
|
|
}
|
|
|
|
|
|
|
|
uint32_t AQH_ModDevices_RgbwToHtmlColor(uint32_t colorIn)
|
|
{
|
|
uint32_t colorOut;
|
|
/* RGBW GGRRWWBB GGRRWWBB GGRRWWBB */
|
|
/* hex 00RRGGBB 00RRGGBB 00RRGGBB*/
|
|
colorOut=(colorIn & 0x00ff0000) | ( (colorIn>>16) & 0x0000ff00) | (colorIn & 0x000000ff);
|
|
return colorOut;
|
|
}
|
|
|
|
|
|
|
|
uint32_t AQH_ModDevices_RgbwFromComponents(int r, int g, int b, int w)
|
|
{
|
|
uint32_t colorOut;
|
|
|
|
colorOut=((r & 0xff)<<16) | ((g & 0xff)<<24) | (b & 0xff) | ((w & 0xff)<<8);
|
|
return colorOut;
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModDevices_RgbwGetR(uint32_t color)
|
|
{ /* GGRRWWBB */
|
|
return (color & 0x00ff0000)>>16;
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModDevices_RgbwGetG(uint32_t color)
|
|
{ /* GGRRWWBB */
|
|
return (color & 0xff000000)>>24;
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModDevices_RgbwGetB(uint32_t color)
|
|
{ /* GGRRWWBB */
|
|
return (color & 0x000000ff);
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModDevices_RgbwGetW(uint32_t color)
|
|
{ /* GGRRWWBB */
|
|
return (color & 0x0000ff00)>>8;
|
|
}
|
|
|
|
|
|
|
|
void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sValueName;
|
|
|
|
sValueName=AQH_Value_GetName(value);
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW:
|
|
GBAA(dbuf, "<input type=\"color\" name=\"%s\" value=\"refresh\"/>", sValueName);
|
|
break;
|
|
case AQH_ValueModality_OnOff:
|
|
GBAA(dbuf,
|
|
"<select name=\"%s\">"
|
|
"<option value=\"unchanged\">unchanged</option>"
|
|
"<option value=\"off\">off</option>"
|
|
"<option value=\"on\">on</option>"
|
|
"</select>",
|
|
sValueName);
|
|
break;
|
|
case AQH_ValueModality_OnOffAuto:
|
|
GBAA(dbuf,
|
|
"<select name=\"%s\">"
|
|
"<option value=\"unchanged\">unchanged</option>"
|
|
"<option value=\"off\">off</option>"
|
|
"<option value=\"on\">on</option>"
|
|
"<option value=\"auto\">auto</option>"
|
|
"</select>",
|
|
sValueName);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sValueSystemName;
|
|
const char *sValueName;
|
|
uint64_t dataPoints[2];
|
|
uint64_t recvdNum;
|
|
// uint64_t timestamp;
|
|
union {double f; uint64_t i;} u;
|
|
int intVal;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
sValueName=AQH_Value_GetName(value);
|
|
recvdNum=AQH_DataClient_GetLastData(dc, sValueSystemName, &dataPoints[0], 1);
|
|
if (recvdNum>0) {
|
|
// timestamp=dataPoints[0];
|
|
u.i=dataPoints[1];
|
|
intVal=(int) u.f;
|
|
}
|
|
else {
|
|
u.i=0;
|
|
intVal=-1;
|
|
}
|
|
|
|
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
|
DBG_ERROR(NULL, "Adding actor");
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW:
|
|
DBG_ERROR(NULL, "Color: %.f RGBW=%08x HTML=%08x, RGBW2=%08x",
|
|
u.f,
|
|
(uint32_t) (u.f),
|
|
AQH_ModDevices_RgbwToHtmlColor(u.f),
|
|
AQH_ModDevices_HtmlColorToValueRGBW(AQH_ModDevices_RgbwToHtmlColor(u.f)));
|
|
#if 1
|
|
GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"#%08x\"/>", sValueName, (uint32_t) (u.f));
|
|
#else
|
|
GBAA(dbuf, "<input type=\"color\" name=\"%s\" value=\"#%08x\"/>#%08x (#%08x)",
|
|
sValueName,
|
|
_rgbwToHtmlColor((unsigned int) (u.f)),
|
|
_rgbwToHtmlColor((unsigned int) (u.f)),
|
|
(uint32_t) (u.f));
|
|
#endif
|
|
break;
|
|
case AQH_ValueModality_OnOff:
|
|
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
|
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
|
GBAS(dbuf, "</select>");
|
|
break;
|
|
case AQH_ValueModality_OnOffAuto:
|
|
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
|
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"auto\" %s>auto</option>", (intVal==2)?"selected":"");
|
|
GBAS(dbuf, "</select>");
|
|
break;
|
|
default:
|
|
// GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"%.2f\"/>", sValueName, u.f);
|
|
GBAA(dbuf, "%.2f", u.f);
|
|
break;
|
|
} /* switch */
|
|
} /* if actor */
|
|
else {
|
|
DBG_ERROR(NULL, "Adding sensor (%s=%.2f)", sValueName, u.f);
|
|
GBAA(dbuf, "%.2f", u.f);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
AQH_VALUE *AQH_ModDevices_GetValueForDevice(AQH_DATACLIENT *dc, const char *sDeviceName, const char *sValueName)
|
|
{
|
|
AQH_VALUE_LIST *valueList;
|
|
|
|
valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
|
|
if (valueList) {
|
|
AQH_VALUE *value;
|
|
|
|
value=AQH_Value_List_First(valueList);
|
|
while(value) {
|
|
const char *s;
|
|
|
|
s=AQH_Value_GetName(value);
|
|
if (s && *s && strcasecmp(s, sValueName)==0) {
|
|
break;
|
|
}
|
|
value=AQH_Value_List_Next(value);
|
|
}
|
|
|
|
if (value) {
|
|
AQH_Value_List_Del(value);
|
|
AQH_Value_List_free(valueList);
|
|
return value;
|
|
}
|
|
|
|
AQH_Value_List_free(valueList);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
AQH_DEVICE *AQH_ModDevices_GetDevice(AQH_DATACLIENT *dc, const char *sDeviceName)
|
|
{
|
|
AQH_DEVICE_LIST *deviceList;
|
|
|
|
deviceList=AQH_DataClient_GetDevices(dc, sDeviceName);
|
|
if (deviceList) {
|
|
AQH_DEVICE *device;
|
|
|
|
device=AQH_Device_List_First(deviceList);
|
|
while(device) {
|
|
const char *s;
|
|
|
|
s=AQH_Device_GetNameForSystem(device);
|
|
if (s && *s && 0==strcasecmp(s, sDeviceName)) {
|
|
AQH_Device_List_Del(device);
|
|
AQH_Device_List_free(deviceList);
|
|
return device;
|
|
}
|
|
device=AQH_Device_List_Next(device);
|
|
}
|
|
AQH_Device_List_free(deviceList);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModDevices_ValueGetLastDataAsInt(AQH_DATACLIENT *dc, const AQH_VALUE *value, int defaultValue)
|
|
{
|
|
const char *sValueSystemName;
|
|
uint64_t dataPoints[2];
|
|
uint64_t recvdNum;
|
|
// uint64_t timestamp;
|
|
union {double f; uint64_t i;} u;
|
|
int intVal;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
recvdNum=AQH_DataClient_GetLastData(dc, sValueSystemName, &dataPoints[0], 1);
|
|
if (recvdNum>0) {
|
|
// timestamp=dataPoints[0];
|
|
u.i=dataPoints[1];
|
|
intVal=(int) u.f;
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "No last value for \"%s\"", sValueSystemName);
|
|
intVal=defaultValue;
|
|
}
|
|
|
|
return intVal;
|
|
}
|
|
|
|
|
|
|
|
uint32_t AQH_ModDevices_ValueGetLastDataAsUint32(AQH_DATACLIENT *dc, const AQH_VALUE *value, uint32_t defaultValue)
|
|
{
|
|
const char *sValueSystemName;
|
|
uint64_t dataPoints[2];
|
|
uint64_t recvdNum;
|
|
// uint64_t timestamp;
|
|
union {double f; uint64_t i;} u;
|
|
uint32_t uintVal;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
recvdNum=AQH_DataClient_GetLastData(dc, sValueSystemName, &dataPoints[0], 1);
|
|
if (recvdNum>0) {
|
|
// timestamp=dataPoints[0];
|
|
u.i=dataPoints[1];
|
|
uintVal=(uint32_t) u.f;
|
|
DBG_ERROR(NULL, "Transformed value %.2f -> %08x", u.f, uintVal);
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "No last value for \"%s\"", sValueSystemName);
|
|
uintVal=defaultValue;
|
|
}
|
|
|
|
return uintVal;
|
|
}
|
|
|
|
|
|
|
|
|
|
AQDG_GRAPH_DATAPAIR_LIST *AQH_ModDevices_RequestDataPairList(AQH_DATACLIENT *dc, const char *systemValueName,
|
|
uint64_t tsBegin, uint64_t tsEnd, uint64_t num)
|
|
{
|
|
uint64_t *dataPoints;
|
|
uint64_t recvdNum;
|
|
|
|
dataPoints=malloc(num*sizeof(uint64_t)*2);
|
|
|
|
recvdNum=AQH_DataClient_GetPeriodData(dc, systemValueName, dataPoints, num, tsBegin, tsEnd);
|
|
if (recvdNum>0) {
|
|
AQDG_GRAPH_DATAPAIR_LIST *dpList;
|
|
|
|
dpList=_createDataPairListFromDataPoints(dataPoints, recvdNum);
|
|
free(dataPoints);
|
|
return dpList;
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "No data received for %s", systemValueName);
|
|
free(dataPoints);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues)
|
|
{
|
|
AQDG_GRAPH_DATAPAIR_LIST *dpList;
|
|
uint64_t i;
|
|
|
|
DBG_DEBUG(NULL, "Got %d datapoints", (int) numValues);
|
|
dpList=AQDG_Graph_DataPair_List_new();
|
|
for(i=0; i<numValues; i++) {
|
|
AQDG_GRAPH_DATAPAIR *dp;
|
|
double timestamp;
|
|
union {double f; uint64_t i;} u;
|
|
|
|
timestamp=(double)(*(dataPoints++));
|
|
u.i=*(dataPoints++);
|
|
dp=AQDG_Graph_DataPair_new();
|
|
AQDG_Graph_DataPair_SetValueX(dp, timestamp);
|
|
AQDG_Graph_DataPair_SetValueY(dp, u.f);
|
|
AQDG_Graph_DataPair_List_Add(dp, dpList);
|
|
}
|
|
AQDG_Graph_DataPair_List_SortByValueX(dpList, 1);
|
|
return dpList;
|
|
}
|
|
|
|
|
|
|