From 01aca2d3b739e17b577d478c519773b0773c2d55 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Fri, 10 Oct 2025 00:29:52 +0200 Subject: [PATCH] aqcgi: use single value pages. --- apps/aqhome-cgi/modules/mdevices.c | 245 +++++++++++++++++++++++++---- 1 file changed, 211 insertions(+), 34 deletions(-) diff --git a/apps/aqhome-cgi/modules/mdevices.c b/apps/aqhome-cgi/modules/mdevices.c index f5489f8..1b7b430 100644 --- a/apps/aqhome-cgi/modules/mdevices.c +++ b/apps/aqhome-cgi/modules/mdevices.c @@ -49,14 +49,23 @@ static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session static void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf); static void _handleRqValuesGet(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 _runIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); static void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); +static void _runValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); +static void _runValueWithArgs(AQH_MODULE *m, + AQCGI_REQUEST *rq, + AQH_SESSION *session, + AQH_DATACLIENT *dc, + const char *sDeviceName, + const char *sValueName, + GWEN_BUFFER *dbuf); static void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); -static void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf); -static void _writeValueToTable(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf); +static void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, uint32_t perms, GWEN_BUFFER *dbuf); +static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, uint32_t perms, GWEN_BUFFER *dbuf); static void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf); static uint32_t _colorFromHexString(const char *s); static uint32_t _htmlColorToValueRGBW(uint32_t colorIn); @@ -66,6 +75,8 @@ static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); static void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf); +static void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf); + /* ------------------------------------------------------------------------------------------------ @@ -76,6 +87,7 @@ static void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={ {"index.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD, _handleRqIndexGet}, {"values.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValuesGet}, + {"value.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValueGet}, {"setdata.html", AQCGI_REQUEST_METHOD_POST, P_VALUEWRITE, _handleRqSetDataPost}, {NULL, 0, 0, NULL} }; @@ -201,6 +213,13 @@ void _handleRqValuesGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, +void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) +{ + AQH_ModDataClient_HandleRequest(m, rq, session, _runValue, dbuf); +} + + + void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf) { AQH_ModDataClient_HandleRequest(m, rq, session, _runSetData, dbuf); @@ -300,6 +319,9 @@ void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATA { GWEN_DB_NODE *dbQuery; const char *sDeviceName; + uint32_t perms; + + perms=AQH_ModService_GetUserPerms(m); dbQuery=AQCGI_Request_GetDbQuery(rq); sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL); @@ -312,13 +334,8 @@ void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATA if (valueList && AQH_Value_List_GetCount(valueList)) { GBAA(dbuf,"

Values for Device %s

\n", sDeviceName); - - GBAS(dbuf,"
\n"); - GBAA(dbuf, "\n", sDeviceName); - _writeValueListToTable(dc, valueList, dbuf); - - GBAS(dbuf,""); - GBAS(dbuf, "
\n\n"); + _writeValueListToTable(sDeviceName, valueList, perms, dbuf); + GBAS(dbuf, "\n"); } else { GBAS(dbuf,"

No values.

\n"); @@ -329,17 +346,102 @@ void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATA +void _runValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) +{ + GWEN_DB_NODE *dbQuery; + const char *sDeviceName; + const char *sValueName; + + dbQuery=AQCGI_Request_GetDbQuery(rq); + sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL); + sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL); + if (sDeviceName && *sDeviceName && sValueName && *sValueName) { + GWEN_BUFFER *bufDeviceName; + GWEN_BUFFER *bufValueName; + + bufDeviceName=GWEN_Buffer_new(0, 64, 0, 1); + GWEN_Text_UnescapeToBufferTolerant(sDeviceName, bufDeviceName); + bufValueName=GWEN_Buffer_new(0, 64, 0, 1); + GWEN_Text_UnescapeToBufferTolerant(sValueName, bufValueName); + _runValueWithArgs(m, rq, session, dc, + GWEN_Buffer_GetStart(bufDeviceName), + GWEN_Buffer_GetStart(bufValueName), + dbuf); + GWEN_Buffer_free(bufValueName); + GWEN_Buffer_free(bufDeviceName); + } + +#if 0 + if (sDeviceName && *sDeviceName && sValueName && *sValueName) { + GWEN_BUFFER *pbuf; + + pbuf=GWEN_Buffer_new(0, 256, 0, 1); + GBAS(pbuf, "Location: /aqbt/devices/value.html?device="); + GWEN_Text_EscapeToBufferTolerant(sDeviceName, pbuf); + GBAS(pbuf, "&value="); + GWEN_Text_EscapeToBufferTolerant(sValueName, pbuf); + AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(pbuf)); + GWEN_Buffer_free(pbuf); + } + AQCGI_Request_SetResponseCode(rq, 303); + AQCGI_Request_SetResponseText(rq, "See other"); +#endif +} + + + +void _runValueWithArgs(AQH_MODULE *m, + AQCGI_REQUEST *rq, + AQH_SESSION *session, + AQH_DATACLIENT *dc, + const char *sDeviceName, + const char *sValueName, + GWEN_BUFFER *dbuf) +{ + GWEN_DB_NODE *dbQuery; + AQH_VALUE_LIST *valueList; + + dbQuery=AQCGI_Request_GetDbQuery(rq); + DBG_ERROR(NULL, "Device=%s, value=%s", sDeviceName?sDeviceName:"", sValueName?sValueName:""); + + valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0); + if (valueList) { + const 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_GetValueType(value)==AQH_ValueType_Actor) { + _mkValueForm(dc, sDeviceName, value, dbuf); + } + else { + } + AQH_Value_List_free(valueList); + } +} + + + void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf) { AQH_SERVICE *sv; GWEN_DB_NODE *dbPost; const char *sDeviceName; + const char *sValueName; AQH_VALUE_LIST *valueList; /* sample data */ sv=AQH_ModService_GetService(m); dbPost=AQCGI_Request_GetDbPostBody(rq); sDeviceName=dbPost?GWEN_DB_GetCharValue(dbPost, "device", 0, NULL):NULL; + sValueName=dbPost?GWEN_DB_GetCharValue(dbPost, "value", 0, NULL):NULL; + DBG_ERROR(NULL, "Device=[%s], value=[%s]", sDeviceName?sDeviceName:"", sValueName?sValueName:""); valueList=sDeviceName?AQH_DataClient_GetValues(dc, sDeviceName, 0):NULL; if (valueList && AQH_Value_List_GetCount(valueList)) { const AQH_VALUE *value; @@ -372,8 +474,16 @@ void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DAT GWEN_BUFFER *pbuf; pbuf=GWEN_Buffer_new(0, 256, 0, 1); - GBAS(pbuf, "Location: /aqbt/devices/values.html?device="); - GWEN_Text_EscapeToBufferTolerant(sDeviceName, pbuf); + if (sValueName && *sValueName) { + GBAS(pbuf, "Location: /aqbt/devices/value.html?device="); + GWEN_Text_EscapeToBuffer(sDeviceName, pbuf); + GBAS(pbuf, "&value="); + GWEN_Text_EscapeToBuffer(sValueName, pbuf); + } + else { + GBAS(pbuf, "Location: /aqbt/devices/values.html?device="); + GWEN_Text_EscapeToBuffer(sDeviceName, pbuf); + } AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(pbuf)); GWEN_Buffer_free(pbuf); } @@ -382,8 +492,7 @@ void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DAT } - -void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf) +void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, uint32_t perms, GWEN_BUFFER *dbuf) { const AQH_VALUE *value; @@ -399,7 +508,6 @@ void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, "Device" "Name for System" #endif - "Action" "" "\n" "\n"); @@ -407,7 +515,7 @@ void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, value=AQH_Value_List_First(valueList); while(value) { if (AQH_Value_GetModality(value)!=AQH_ValueModality_Stats) - _writeValueToTable(dc, value, dbuf); + _writeValueToTable(sDeviceName, value, perms, dbuf); value=AQH_Value_List_Next(value); } GBAS(dbuf, @@ -417,36 +525,33 @@ void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, -void _writeValueToTable(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf) +void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, uint32_t perms, GWEN_BUFFER *dbuf) { const char *s; GBAS(dbuf, ""); - + + /* name for system */ s=AQH_Value_GetName(value); - GBAA(dbuf, "%s", s?s:""); - + if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) { + uint32_t pos; + + pos=GWEN_Buffer_GetPos(dbuf); + GBAS(dbuf,"%s", s); + } + else + GBAA(dbuf,"%s", s?s:""); + s=AQH_ValueType_toString(AQH_Value_GetValueType(value)); GBAA(dbuf, "%s", s?s:""); s=AQH_ValueModality_toString(AQH_Value_GetModality(value)); GBAA(dbuf, "%s", s?s:""); -#if 0 - s=AQH_Value_GetDriver(value); - GBAA(dbuf, "%s", s?s:""); - - s=AQH_Value_GetDeviceNameForSystem(value); - GBAA(dbuf, "%s", s?s:""); - - s=AQH_Value_GetNameForSystem(value); - GBAA(dbuf, "%s", s?s:""); -#endif - - GBAS(dbuf, ""); - _addLastValueToForm(dc, value, dbuf); - GBAS(dbuf, ""); - GBAA(dbuf, "\n"); } @@ -694,3 +799,75 @@ void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER +void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, 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; + } + + GBAA(dbuf,"

Value %s/%s

\n", sDeviceName, sValueName); + + GBAS(dbuf,"
\n"); + GBAA(dbuf, "\n", sDeviceName); + GBAA(dbuf, "\n", sValueName); + + 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), + _rgbwToHtmlColor(u.f), + _htmlColorToValueRGBW(_rgbwToHtmlColor(u.f))); +#if 1 + GBAA(dbuf, "", sValueName, (uint32_t) (u.f)); +#else + GBAA(dbuf, "#%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, ""); + break; + case AQH_ValueModality_OnOffAuto: + GBAA(dbuf, ""); + break; + default: + // GBAA(dbuf, "", sValueName, u.f); + GBAA(dbuf, "%.2f", u.f); + break; + } /* switch */ + + GBAS(dbuf,""); + GBAS(dbuf, "
\n\n"); +} + + +