aqhome-cgi: more code sharing, adding page handling

allows to define your own pages with graphs, sensors and actors.
This commit is contained in:
Martin Preuss
2025-10-27 23:15:28 +01:00
parent 1b0145c97d
commit 7c5abc0f3b
9 changed files with 1205 additions and 111 deletions

View File

@@ -21,6 +21,7 @@
#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"
@@ -61,6 +62,11 @@ static void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *
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);
@@ -81,6 +87,9 @@ static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
{"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}
};
@@ -171,6 +180,26 @@ void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session,
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);
}
@@ -227,6 +256,44 @@ uint32_t AQH_ModDevices_RgbwToHtmlColor(uint32_t colorIn)
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)
{
return (color & 0xff0000)>>16;
}
int AQH_ModDevices_RgbwGetG(uint32_t color)
{
return (color & 0xff000000)>>24;
}
int AQH_ModDevices_RgbwGetB(uint32_t color)
{
return (color & 0xff);
}
int AQH_ModDevices_RgbwGetW(uint32_t color)
{
return (color & 0xff00)>>8;
}
void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf)
{
const char *sValueName;
@@ -392,4 +459,80 @@ AQH_DEVICE *AQH_ModDevices_GetDevice(AQH_DATACLIENT *dc, const char *sDeviceName
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;
}
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;
}