304 lines
9.5 KiB
C
304 lines
9.5 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_values.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/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_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 _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 _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
|
|
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},
|
|
{"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},
|
|
{"graph.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqGraphGet},
|
|
{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 _handleRqValuesGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValues, 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);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|