moved code for device module into its own folder. Implement graphs.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
<includes type="c" >
|
||||
$(gwenhywfar_cflags)
|
||||
$(aqcgi_cflags)
|
||||
$(aqdiagram_cflags)
|
||||
-I$(topsrcdir)
|
||||
-I$(topbuilddir)
|
||||
-I$(topsrcdir)/apps
|
||||
@@ -58,6 +59,7 @@
|
||||
$(gwenhywfar_libs)
|
||||
-lm
|
||||
$(aqcgi_libs)
|
||||
$(aqdiagram_libs)
|
||||
</libraries>
|
||||
|
||||
<subdirs>
|
||||
@@ -127,6 +129,7 @@
|
||||
$(gwenhywfar_libs)
|
||||
-lm
|
||||
$(aqcgi_libs)
|
||||
$(aqdiagram_libs)
|
||||
</libraries>
|
||||
|
||||
<subdirs>
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
#include "aqhome-cgi/modules/common/madmin.h"
|
||||
#include "aqhome-cgi/modules/common/mmodules.h"
|
||||
#include "aqhome-cgi/modules/common/musers.h"
|
||||
#include "aqhome-cgi/modules/mdevices.h"
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
#include "aqhome/aqhome.h"
|
||||
|
||||
#include <aqcgi/cgi.h>
|
||||
#include <aqcgi/request.h>
|
||||
#include <aqdiagram/aqdiagram.h>
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/nogui.h>
|
||||
@@ -26,21 +27,34 @@
|
||||
|
||||
#define AQHOME_CGI_DEFAULT_STATIC_FILES AQHOME_CGI_WWWDIR"/static"
|
||||
#define AQHOME_CGI_DEFAULT_RUNTIME_FILES AQHOME_CGI_WWWDIR"/data"
|
||||
#define AQHOME_CGI_DEFAULT_CACHE_FILES AQHOME_CGI_WWWDIR"/cache"
|
||||
#define AQHOME_CGI_DEFAULT_BASE_URL "http://127.0.0.1/aqbt"
|
||||
|
||||
|
||||
|
||||
static void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles);
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles, const char *sBaseUrl);
|
||||
static int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles);
|
||||
static void logStart(void);
|
||||
static int _init(const char *sPathRuntimeFiles);
|
||||
static int _init(const char *sPathRuntimeFiles, const char *sBaseUrl);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GWEN_GUI *gui;
|
||||
const char *sPathStaticFiles;
|
||||
const char *sPathRuntimeFiles;
|
||||
const char *sBaseUrl;
|
||||
|
||||
sPathStaticFiles=getenv("AQHOME_STATIC_FILES");
|
||||
if (!(sPathStaticFiles && *sPathStaticFiles))
|
||||
@@ -50,6 +64,10 @@ int main(int argc, char **argv)
|
||||
if (!(sPathRuntimeFiles && *sPathRuntimeFiles))
|
||||
sPathRuntimeFiles=AQHOME_CGI_DEFAULT_RUNTIME_FILES;
|
||||
|
||||
sBaseUrl=getenv("AQHOME_BASE_URL");
|
||||
if (!(sBaseUrl && *sBaseUrl))
|
||||
sBaseUrl=AQHOME_CGI_DEFAULT_BASE_URL;
|
||||
|
||||
GWEN_Init();
|
||||
gui=GWEN_NoGui_new();
|
||||
GWEN_Gui_SetGui(gui);
|
||||
@@ -58,6 +76,7 @@ int main(int argc, char **argv)
|
||||
GWEN_Logger_Open(GWEN_LOGDOMAIN, "gwenhywfar", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon);
|
||||
GWEN_Logger_Open(AQH_LOGDOMAIN, "aqhome", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon);
|
||||
GWEN_Logger_Open(AQCGI_LOGDOMAIN, "aqcgi", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon);
|
||||
GWEN_Logger_Open(AQDG_LOGDOMAIN, "aqdiagram", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon);
|
||||
GWEN_Logger_Open(NULL, "aqhome-cgi", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon);
|
||||
|
||||
GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug);
|
||||
@@ -69,13 +88,14 @@ int main(int argc, char **argv)
|
||||
|
||||
GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug);
|
||||
GWEN_Logger_SetLevel(AQCGI_LOGDOMAIN, GWEN_LoggerLevel_Debug);
|
||||
GWEN_Logger_SetLevel(AQDG_LOGDOMAIN, GWEN_LoggerLevel_Debug);
|
||||
GWEN_Logger_SetLevel(NULL, GWEN_LoggerLevel_Debug);
|
||||
|
||||
if (argc>1 && argv[1]) {
|
||||
if (0==strcasecmp(argv[1], "init")) {
|
||||
int rv;
|
||||
|
||||
rv=_init(sPathRuntimeFiles);
|
||||
rv=_init(sPathRuntimeFiles, sBaseUrl);
|
||||
if (rv<0) {
|
||||
fprintf(stderr, "Error on init (%d)\n", rv);
|
||||
return 2;
|
||||
@@ -90,7 +110,7 @@ int main(int argc, char **argv)
|
||||
AQCGI_Init();
|
||||
rq=AQCGI_ReadRequest();
|
||||
if (rq) {
|
||||
_handleRequest(rq, sPathStaticFiles, sPathRuntimeFiles);
|
||||
_handleRequest(rq, sPathStaticFiles, sPathRuntimeFiles, sBaseUrl);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, "Content-type: text/plain\n\n");
|
||||
@@ -104,12 +124,12 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
|
||||
void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles)
|
||||
void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles, const char *sBaseUrl)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
int rv;
|
||||
|
||||
sv=AQH_ServiceFiles_new(sPathRuntimeFiles);
|
||||
sv=AQH_ServiceFiles_new(sPathRuntimeFiles, sBaseUrl);
|
||||
|
||||
rv=_handlePath(sv, rq, sPathStaticFiles);
|
||||
if (rv<0) {
|
||||
@@ -160,6 +180,7 @@ int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles
|
||||
int rv;
|
||||
|
||||
/* last, let module handle remaining part */
|
||||
DBG_ERROR(NULL, "Entry: %s (last)", s);
|
||||
rv=AQH_ModService_HandleRequest(mParent, rq, session, s);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
@@ -199,13 +220,13 @@ void logStart()
|
||||
|
||||
|
||||
|
||||
int _init(const char *sPathRuntimeFiles)
|
||||
int _init(const char *sPathRuntimeFiles, const char *sBaseUrl)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
int rv;
|
||||
|
||||
fprintf(stdout, "Creating aqhome-cgi environment in \"%s\"\n", sPathRuntimeFiles);
|
||||
sv=AQH_ServiceFiles_new(sPathRuntimeFiles);
|
||||
DBG_ERROR(NULL, "Creating aqhome-cgi environment in \"%s\"", sPathRuntimeFiles);
|
||||
sv=AQH_ServiceFiles_new(sPathRuntimeFiles, sBaseUrl);
|
||||
rv=AQH_ModAdmin_Create(sv);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error creating module \"admin\"");
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
|
||||
<headers dist="true" install="$(pkgincludedir)/service" >
|
||||
mdataclient.h
|
||||
mdevices.h
|
||||
mroot.h
|
||||
</headers>
|
||||
|
||||
@@ -64,7 +63,6 @@
|
||||
$(local/typefiles)
|
||||
|
||||
mdataclient.c
|
||||
mdevices.c
|
||||
mroot.c
|
||||
</sources>
|
||||
|
||||
@@ -75,10 +73,12 @@
|
||||
|
||||
<useTargets>
|
||||
aqhcgi_modcom
|
||||
aqhcgi_mdevices
|
||||
</useTargets>
|
||||
|
||||
<subdirs>
|
||||
common
|
||||
devices
|
||||
static
|
||||
</subdirs>
|
||||
|
||||
|
||||
@@ -518,9 +518,13 @@ void AQH_ModService_HandleRequestWithTable(AQH_MODULE *m,
|
||||
}
|
||||
}
|
||||
|
||||
AQH_ModService_AddFooter(m, "en", dbuf);
|
||||
if (!(AQCGI_Request_GetFlags(rq) & AQH_MODSERVICE_RQFLAGS_RAWFILE)) {
|
||||
DBG_ERROR(NULL, "Not adding footer");
|
||||
AQH_ModService_AddFooter(m, "en", dbuf);
|
||||
}
|
||||
AQCGI_Request_SetBufferResponseBody(rq, dbuf);
|
||||
AQCGI_Request_AddResponseHeaderData(rq, "Content-type: text/html");
|
||||
if (AQCGI_Request_GetFlags(rq) & AQCGI_FLAGS_HAS_CONTENT_HEADER)
|
||||
AQCGI_Request_AddResponseHeaderData(rq, "Content-type: text/html");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
#define AQH_MODSERVICE_RQFLAGS_RAWFILE 0x10000000
|
||||
|
||||
|
||||
|
||||
typedef int (*AQH_MODSERVICE_HANDLEREQUEST_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem);
|
||||
typedef AQH_MODULE* (*AQH_MODSERVICE_LOADSUBMODULE_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName);
|
||||
typedef void (*AQH_MODSERVICE_ADDHEADER_FN)(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf);
|
||||
|
||||
93
apps/aqhome-cgi/modules/devices/0BUILD
Normal file
93
apps/aqhome-cgi/modules/devices/0BUILD
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml?>
|
||||
|
||||
<gwbuild>
|
||||
|
||||
<target type="ConvenienceLibrary" name="aqhcgi_mdevices" >
|
||||
|
||||
<includes type="c" >
|
||||
$(gwenhywfar_cflags)
|
||||
$(aqcgi_cflags)
|
||||
$(aqdiagram_cflags)
|
||||
-I$(topsrcdir)
|
||||
-I$(topbuilddir)
|
||||
-I$(topsrcdir)/apps
|
||||
-I$(topbuilddir)/apps
|
||||
-I$(builddir)
|
||||
-I$(srcdir)
|
||||
</includes>
|
||||
|
||||
<includes type="tm2" >
|
||||
--include=$(builddir)
|
||||
--include=$(srcdir)
|
||||
</includes>
|
||||
|
||||
|
||||
<define name="not_BUILDING_AQHOME" />
|
||||
|
||||
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
||||
|
||||
|
||||
<setVar name="tm2flags-INACTIVE" >
|
||||
--api=AQHOME_API
|
||||
</setVar>
|
||||
|
||||
<setVar name="local/typefiles" >
|
||||
</setVar>
|
||||
|
||||
<setVar name="local/built_sources" >
|
||||
</setVar>
|
||||
|
||||
<setVar name="local/built_headers_pub">
|
||||
</setVar>
|
||||
|
||||
|
||||
<setVar name="local/built_headers_priv" >
|
||||
</setVar>
|
||||
|
||||
|
||||
<headers dist="false" install="$(pkgincludedir)/service" >
|
||||
$(local/built_headers_pub)
|
||||
</headers>
|
||||
|
||||
|
||||
<headers dist="true" install="$(pkgincludedir)/service" >
|
||||
mdevices.h
|
||||
mdevices_init.h
|
||||
mdevices_index.h
|
||||
mdevices_values.h
|
||||
mdevices_value.h
|
||||
mdevices_setdata.h
|
||||
mdevices_vgraph.h
|
||||
</headers>
|
||||
|
||||
|
||||
<headers dist="true" >
|
||||
</headers>
|
||||
|
||||
|
||||
<sources>
|
||||
$(local/typefiles)
|
||||
|
||||
mdevices.c
|
||||
mdevices_init.c
|
||||
mdevices_index.c
|
||||
mdevices_values.c
|
||||
mdevices_value.c
|
||||
mdevices_setdata.c
|
||||
mdevices_vgraph.c
|
||||
</sources>
|
||||
|
||||
|
||||
<extradist>
|
||||
</extradist>
|
||||
|
||||
|
||||
<useTargets>
|
||||
</useTargets>
|
||||
|
||||
<subdirs>
|
||||
</subdirs>
|
||||
|
||||
</target>
|
||||
|
||||
</gwbuild>
|
||||
303
apps/aqhome-cgi/modules/devices/mdevices.c
Normal file
303
apps/aqhome-cgi/modules/devices/mdevices.c
Normal file
@@ -0,0 +1,303 @@
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolde
|
||||
int AQH_ModDevices_Create(AQH_SERVICE *sv);
|
||||
|
||||
|
||||
uint32_t AQH_ModDevices_ColorFromHexString(const char *s);
|
||||
uint32_t AQH_ModDevices_HtmlColorToValueRGBW(uint32_t colorIn);
|
||||
uint32_t AQH_ModDevices_RgbwToHtmlColor(uint32_t colorIn);
|
||||
|
||||
|
||||
|
||||
|
||||
110
apps/aqhome-cgi/modules/devices/mdevices_index.c
Normal file
110
apps/aqhome-cgi/modules/devices/mdevices_index.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/****************************************************************************
|
||||
* 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_index.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
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void AQH_ModDevices_RunIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
AQH_DEVICE_LIST *deviceList;
|
||||
AQH_DEVICE *device;
|
||||
uint32_t perms;
|
||||
|
||||
perms=AQH_ModService_GetUserPerms(m);
|
||||
|
||||
deviceList=AQH_DataClient_GetDevices(dc, NULL);
|
||||
if (deviceList==NULL) {
|
||||
DBG_ERROR(NULL, "No device received");
|
||||
GBAS(dbuf, "<p>No devices.</p>");
|
||||
return;
|
||||
}
|
||||
|
||||
GBAS(dbuf, "<h1>Devices</h1>\n");
|
||||
GBAS(dbuf,
|
||||
"<table class=\"datatable\">\n"
|
||||
"<thead>\n"
|
||||
"<tr>"
|
||||
"<th>Name For System</th>"
|
||||
"<th>Room</th>"
|
||||
"<th>Location</th>"
|
||||
"<th>Description</th>"
|
||||
"</tr>\n"
|
||||
"</thead>\n"
|
||||
"<tbody>\n");
|
||||
|
||||
device=AQH_Device_List_First(deviceList);
|
||||
while(device) {
|
||||
const char *s;
|
||||
|
||||
GBAA(dbuf, "<tr>");
|
||||
/* name for system */
|
||||
s=AQH_Device_GetNameForSystem(device);
|
||||
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
||||
GBAS(dbuf,"<td><a href=\"values.html?device=");
|
||||
GWEN_Text_EscapeToBufferTolerant(s, dbuf);
|
||||
GBAA(dbuf,"\">%s</a></td>", s?s:"");
|
||||
}
|
||||
else
|
||||
GBAA(dbuf,"<td>%s</td>", s?s:"");
|
||||
/* room */
|
||||
s=AQH_Device_GetRoomName(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* location */
|
||||
s=AQH_Device_GetLocation(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* description */
|
||||
s=AQH_Device_GetDescription(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
|
||||
GBAA(dbuf, "</tr>");
|
||||
device=AQH_Device_List_Next(device);
|
||||
}
|
||||
|
||||
GBAS(dbuf,
|
||||
"</tbody>\n"
|
||||
"</table>\n");
|
||||
AQH_Device_List_free(deviceList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
27
apps/aqhome-cgi/modules/devices/mdevices_index.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_index.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_CGI_MDEVICES_INDEX_H
|
||||
#define AQHOME_CGI_MDEVICES_INDEX_H
|
||||
|
||||
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
|
||||
#include "aqhome/aqhome.h"
|
||||
#include "aqhome/dataclient/client.h"
|
||||
|
||||
#include <aqcgi/request.h>
|
||||
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
|
||||
void AQH_ModDevices_RunIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||
|
||||
|
||||
#endif
|
||||
129
apps/aqhome-cgi/modules/devices/mdevices_init.c
Normal file
129
apps/aqhome-cgi/modules/devices/mdevices_init.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
* 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_init.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 void _createPermDefList(AQH_MODULE *m);
|
||||
static void _createRoleList(AQH_MODULE *m);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int AQH_ModDevices_Create(AQH_SERVICE *sv)
|
||||
{
|
||||
AQH_MODULE *m;
|
||||
int rv;
|
||||
|
||||
m=AQH_Module_new();
|
||||
AQH_Module_SetName(m, "devices");
|
||||
AQH_Module_SetDescr(m, "device module");
|
||||
AQH_Module_SetGuestPerms(m, 0);
|
||||
|
||||
_createPermDefList(m);
|
||||
_createRoleList(m);
|
||||
|
||||
rv=AQH_Service_AddModule(sv, m);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
}
|
||||
AQH_Module_free(m);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _createPermDefList(AQH_MODULE *m)
|
||||
{
|
||||
AQH_PERMDEF_LIST *permDefList;
|
||||
|
||||
permDefList=AQH_PermDef_List_new();
|
||||
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceRead", 0x001, "Read and list devices");
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceWrite", 0x002, "Modify devices");
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceAdd", 0x004, "Add devices");
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceDel", 0x008, "Remove devices");
|
||||
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueRead", 0x010, "Read and list values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueWrite", 0x020, "Modify values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueAdd", 0x040, "Add values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueDel", 0x080, "Remove values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueSet", 0x100, "Set values");
|
||||
|
||||
AQH_Module_SetPermDefList(m, permDefList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _createRoleList(AQH_MODULE *m)
|
||||
{
|
||||
AQH_ROLE_LIST *roleList;
|
||||
int id=0;
|
||||
|
||||
roleList=AQH_Role_List_new();
|
||||
AQH_ModService_AddRole(roleList, id++, "Reader",
|
||||
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUEREAD,
|
||||
"Read devices and values");
|
||||
AQH_ModService_AddRole(roleList, id++, "Writer",
|
||||
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
||||
AQH_MODDEVICES_PERMS_DEVICEWRITE |
|
||||
AQH_MODDEVICES_PERMS_DEVICEADD |
|
||||
AQH_MODDEVICES_PERMS_DEVICEDEL |
|
||||
AQH_MODDEVICES_PERMS_VALUEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUEWRITE |
|
||||
AQH_MODDEVICES_PERMS_VALUEADD |
|
||||
AQH_MODDEVICES_PERMS_VALUEDEL |
|
||||
AQH_MODDEVICES_PERMS_VALUESET,
|
||||
"Read and write devices and values");
|
||||
AQH_ModService_AddRole(roleList, id++, "Setter",
|
||||
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUESET,
|
||||
"Set values");
|
||||
AQH_Module_SetRoleList(m, roleList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
27
apps/aqhome-cgi/modules/devices/mdevices_init.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_init.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_CGI_MDEVICES_INIT_H
|
||||
#define AQHOME_CGI_MDEVICES_INIT_H
|
||||
|
||||
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
|
||||
#include "aqhome/aqhome.h"
|
||||
#include "aqhome/dataclient/client.h"
|
||||
|
||||
#include <aqcgi/request.h>
|
||||
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
|
||||
int AQH_ModDevices_Create(AQH_SERVICE *sv);
|
||||
|
||||
|
||||
#endif
|
||||
202
apps/aqhome-cgi/modules/devices/mdevices_setdata.c
Normal file
202
apps/aqhome-cgi/modules/devices/mdevices_setdata.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
* 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_setdata.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
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
||||
static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
||||
static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void AQH_ModDevices_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;
|
||||
|
||||
value=AQH_Value_List_First(valueList);
|
||||
while(value) {
|
||||
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
||||
const char *sValueName;
|
||||
const char *sValue;
|
||||
|
||||
sValueName=AQH_Value_GetName(value);
|
||||
sValue=GWEN_DB_GetCharValue(dbPost, sValueName, 0, NULL);
|
||||
if (sValueName && *sValueName) {
|
||||
DBG_ERROR(NULL, "Setting value %s to %s", sValueName?sValueName:"no name", sValue?sValue:"no value");
|
||||
switch(AQH_Value_GetModality(value)) {
|
||||
case AQH_ValueModality_RGBW: _setRgbwData(dc, value, sValue); break;
|
||||
case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sValue); break;
|
||||
case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break;
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
} /* if (sValueName) */
|
||||
}
|
||||
value=AQH_Value_List_Next(value);
|
||||
} /* while */
|
||||
}
|
||||
AQH_Value_List_free(valueList);
|
||||
|
||||
if (sDeviceName && *sDeviceName) {
|
||||
GWEN_BUFFER *pbuf;
|
||||
|
||||
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
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);
|
||||
}
|
||||
AQCGI_Request_SetResponseCode(rq, 303);
|
||||
AQCGI_Request_SetResponseText(rq, "See other");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
||||
{
|
||||
if (sValue) {
|
||||
const char *sValueSystemName;
|
||||
uint32_t color;
|
||||
int rv;
|
||||
|
||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
||||
color=AQH_ModDevices_ColorFromHexString(sValue);
|
||||
DBG_ERROR(NULL, "Send value [#%08x] to %s", color, sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, (double) color);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
||||
{
|
||||
if (sValue) {
|
||||
const char *sValueSystemName;
|
||||
int rv;
|
||||
|
||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
||||
if (strcasecmp(sValue, "unchanged")==0) {
|
||||
DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
|
||||
}
|
||||
else if (strcasecmp(sValue, "on")==0) {
|
||||
DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sValue, "off")==0) {
|
||||
DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
||||
{
|
||||
if (sValue) {
|
||||
const char *sValueSystemName;
|
||||
int rv;
|
||||
|
||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
||||
if (strcasecmp(sValue, "unchanged")==0) {
|
||||
DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
|
||||
}
|
||||
else if (strcasecmp(sValue, "on")==0) {
|
||||
DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sValue, "off")==0) {
|
||||
DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sValue, "auto")==0) {
|
||||
DBG_ERROR(NULL, "Send value 2 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 2.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
27
apps/aqhome-cgi/modules/devices/mdevices_setdata.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_setdata.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_CGI_MDEVICES_SETVALUE_H
|
||||
#define AQHOME_CGI_MDEVICES_SETVALUE_H
|
||||
|
||||
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
|
||||
#include "aqhome/aqhome.h"
|
||||
#include "aqhome/dataclient/client.h"
|
||||
|
||||
#include <aqcgi/request.h>
|
||||
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
|
||||
void AQH_ModDevices_RunSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||
|
||||
|
||||
#endif
|
||||
245
apps/aqhome-cgi/modules/devices/mdevices_value.c
Normal file
245
apps/aqhome-cgi/modules/devices/mdevices_value.c
Normal file
@@ -0,0 +1,245 @@
|
||||
/****************************************************************************
|
||||
* 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_value.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
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
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 _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
||||
static void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf);
|
||||
static void _writeOnOffToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf);
|
||||
static void _writeOnOffAutoToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void AQH_ModDevices_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;
|
||||
|
||||
DBG_ERROR(NULL, "RunValue");
|
||||
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:"<empty>", sValueName?sValueName:"<empty>");
|
||||
|
||||
GBAA(dbuf,"<h1>Value %s/%s</h1>\n", sDeviceName, 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 {
|
||||
GBAS(dbuf, "<table>\n");
|
||||
GBAS(dbuf, "<tr><td>");
|
||||
GBAS(dbuf, "<img src=\"graph.html?device=");
|
||||
GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
|
||||
GBAS(dbuf, "&value=");
|
||||
GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
|
||||
GBAS(dbuf, "&period=4h\"/>");
|
||||
GBAS(dbuf, "</td></tr>");
|
||||
|
||||
GBAS(dbuf, "<tr><td>");
|
||||
GBAS(dbuf, "<img src=\"graph.html?device=");
|
||||
GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
|
||||
GBAS(dbuf, "&value=");
|
||||
GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
|
||||
GBAS(dbuf, "&period=1d\"/>");
|
||||
GBAS(dbuf, "</td></tr>");
|
||||
|
||||
GBAS(dbuf, "<tr><td>");
|
||||
GBAS(dbuf, "<img src=\"graph.html?device=");
|
||||
GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
|
||||
GBAS(dbuf, "&value=");
|
||||
GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
|
||||
GBAS(dbuf, "&period=1w\"/>");
|
||||
GBAS(dbuf, "</td></tr>");
|
||||
|
||||
GBAS(dbuf, "</table>");
|
||||
}
|
||||
AQH_Value_List_free(valueList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
GBAS(dbuf,"<form action=\"setdata.html\" method=\"post\">\n");
|
||||
GBAA(dbuf, "<input type=\"hidden\" name=\"device\" value=\"%s\">\n", sDeviceName);
|
||||
GBAA(dbuf, "<input type=\"hidden\" name=\"value\" value=\"%s\">\n", sValueName);
|
||||
|
||||
DBG_ERROR(NULL, "Adding actor");
|
||||
switch(AQH_Value_GetModality(value)) {
|
||||
case AQH_ValueModality_RGBW: _writeRgbwToForm(sValueName, u.f, dbuf); break;
|
||||
case AQH_ValueModality_OnOff: _writeOnOffToForm(sValueName, intVal, dbuf); break;
|
||||
case AQH_ValueModality_OnOffAuto: _writeOnOffAutoToForm(sValueName, intVal, dbuf); break;
|
||||
default: GBAA(dbuf, "%.2f", u.f); break;
|
||||
} /* switch */
|
||||
|
||||
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
||||
GBAS(dbuf, "</form>\n\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
#if 1
|
||||
GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"#%08x\"/>", sValueName, color);
|
||||
#else
|
||||
GBAA(dbuf, "<input type=\"color\" name=\"%s\" value=\"#%08x\"/>#%08x (#%08x)",
|
||||
sValueName,
|
||||
AQH_ModDevices_RgbwToHtmlColor(color),
|
||||
AQH_ModDevices_RgbwToHtmlColor(color),
|
||||
color);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeOnOffToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
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>");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeOnOffAutoToForm(const char *sValueName, int intVal, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
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>");
|
||||
}
|
||||
|
||||
|
||||
|
||||
27
apps/aqhome-cgi/modules/devices/mdevices_value.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_value.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_CGI_MDEVICES_VALUE_H
|
||||
#define AQHOME_CGI_MDEVICES_VALUE_H
|
||||
|
||||
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
|
||||
#include "aqhome/aqhome.h"
|
||||
#include "aqhome/dataclient/client.h"
|
||||
|
||||
#include <aqcgi/request.h>
|
||||
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
|
||||
void AQH_ModDevices_RunValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||
|
||||
|
||||
#endif
|
||||
145
apps/aqhome-cgi/modules/devices/mdevices_values.c
Normal file
145
apps/aqhome-cgi/modules/devices/mdevices_values.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/****************************************************************************
|
||||
* 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_values.h"
|
||||
#include "./mdevices_index.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
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void AQH_ModDevices_RunValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
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);
|
||||
if (!(sDeviceName && *sDeviceName))
|
||||
AQH_ModDevices_RunIndex(m, rq, session, dc, dbuf);
|
||||
else {
|
||||
AQH_VALUE_LIST *valueList;
|
||||
|
||||
valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
|
||||
if (valueList && AQH_Value_List_GetCount(valueList)) {
|
||||
|
||||
GBAA(dbuf,"<h1>Values for Device %s</h1>\n", sDeviceName);
|
||||
_writeValueListToTable(sDeviceName, valueList, perms, dbuf);
|
||||
GBAS(dbuf, "\n");
|
||||
}
|
||||
else {
|
||||
GBAS(dbuf,"<p>No values.</p>\n");
|
||||
}
|
||||
AQH_Value_List_free(valueList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, uint32_t perms, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
const AQH_VALUE *value;
|
||||
|
||||
GBAS(dbuf,
|
||||
"<table class=\"datatable\">\n"
|
||||
"<thead>"
|
||||
"<tr>"
|
||||
"<th>Name</th>"
|
||||
"<th>Type</th>"
|
||||
"<th>Modality</th>"
|
||||
#if 0
|
||||
"<th>Driver</th>"
|
||||
"<th>Device</th>"
|
||||
"<th>Name for System</th>"
|
||||
#endif
|
||||
"</tr>"
|
||||
"</thead>\n"
|
||||
"<tbody>\n");
|
||||
|
||||
value=AQH_Value_List_First(valueList);
|
||||
while(value) {
|
||||
//if (AQH_Value_GetModality(value)!=AQH_ValueModality_Stats)
|
||||
_writeValueToTable(sDeviceName, value, perms, dbuf);
|
||||
value=AQH_Value_List_Next(value);
|
||||
}
|
||||
GBAS(dbuf,
|
||||
"</tbody>\n"
|
||||
"</table>\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, uint32_t perms, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
GBAS(dbuf, "<tr>");
|
||||
|
||||
/* name for system */
|
||||
s=AQH_Value_GetName(value);
|
||||
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
||||
uint32_t pos;
|
||||
|
||||
pos=GWEN_Buffer_GetPos(dbuf);
|
||||
GBAS(dbuf,"<td><a href=\"value.html?device=");
|
||||
GWEN_Text_EscapeToBuffer(sDeviceName, dbuf);
|
||||
GBAS(dbuf,"&value=");
|
||||
GWEN_Text_EscapeToBuffer(s, dbuf);
|
||||
GBAA(dbuf,"\">%s</a></td>", s);
|
||||
}
|
||||
else
|
||||
GBAA(dbuf,"<td>%s</td>", s?s:"");
|
||||
|
||||
s=AQH_ValueType_toString(AQH_Value_GetValueType(value));
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
|
||||
s=AQH_ValueModality_toString(AQH_Value_GetModality(value));
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
|
||||
GBAA(dbuf, "</tr>\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
27
apps/aqhome-cgi/modules/devices/mdevices_values.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_values.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_CGI_MDEVICES_VALUES_H
|
||||
#define AQHOME_CGI_MDEVICES_VALUES_H
|
||||
|
||||
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
|
||||
#include "aqhome/aqhome.h"
|
||||
#include "aqhome/dataclient/client.h"
|
||||
|
||||
#include <aqcgi/request.h>
|
||||
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
|
||||
void AQH_ModDevices_RunValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||
|
||||
|
||||
#endif
|
||||
464
apps/aqhome-cgi/modules/devices/mdevices_vgraph.c
Normal file
464
apps/aqhome-cgi/modules/devices/mdevices_vgraph.c
Normal file
@@ -0,0 +1,464 @@
|
||||
/****************************************************************************
|
||||
* 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_vgraph.h"
|
||||
|
||||
#include "aqhome-cgi/service/module.h"
|
||||
#include "aqhome-cgi/modules/mdataclient.h"
|
||||
|
||||
#include <aqdiagram/graph/timegraph.h>
|
||||
#include <aqdiagram/graph/w_graph.h>
|
||||
#include <aqdiagram/draw/context_cairo.h>
|
||||
//#include <aqdiagram/data/date.h>
|
||||
//#include <aqdiagram/data/floatingavg.h>
|
||||
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/timestamp.h>
|
||||
#include <gwenhywfar/text.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defs and enums
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define GBAS GWEN_Buffer_AppendString
|
||||
#define GBAA GWEN_Buffer_AppendArgs
|
||||
|
||||
|
||||
enum {
|
||||
VALUEGRAPH_PERIOD_4H=1,
|
||||
VALUEGRAPH_PERIOD_1D,
|
||||
VALUEGRAPH_PERIOD_1W,
|
||||
VALUEGRAPH_PERIOD_1M
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _runGraphValueWithArgs(AQH_MODULE *m,
|
||||
AQCGI_REQUEST *rq,
|
||||
AQH_SESSION *session,
|
||||
AQH_DATACLIENT *dc,
|
||||
const char *sDeviceName,
|
||||
const char *sValueName,
|
||||
GWEN_BUFFER *dbuf);
|
||||
static void _createGraph(AQH_DATACLIENT *dc,
|
||||
const AQH_VALUE *v,
|
||||
int period,
|
||||
const char *graphTitle, int precision, const char *curveLabel,
|
||||
const char *sImgFile, int imgWidth, int imgHeight, uint64_t numDataPoints);
|
||||
static int _fileIsCurrent(const char *sPath, int seconds);
|
||||
static AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, int period, int precision);
|
||||
static int _getPeriodFromString(const char *sPeriod);
|
||||
static int _getAcceptedAgeForPeriod(int period);
|
||||
static void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, int pPeriod, GWEN_BUFFER *dbuf);
|
||||
static uint64_t _getStartTimeForPeriod(int period);
|
||||
static const char *_getModifiersForPeriod(int period);
|
||||
static AQH_VALUE *_getValue(AQH_DATACLIENT *dc, const char *sDeviceName, const char *sValueName);
|
||||
|
||||
static AQDG_GRAPH_DATAPAIR_LIST *_requestDataPairList(AQH_DATACLIENT *dc, const char *valueName,
|
||||
uint64_t tsBegin, uint64_t tsEnd, uint64_t num);
|
||||
static AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* code
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void AQH_ModDevices_RunGraphValue(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;
|
||||
|
||||
DBG_ERROR(NULL, "GraphValue");
|
||||
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
||||
sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL);
|
||||
sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL);
|
||||
DBG_ERROR(NULL, "Device=%s, value=%s", sDeviceName?sDeviceName:"<empty>", sValueName?sValueName:"<empty>");
|
||||
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);
|
||||
_runGraphValueWithArgs(m, rq, session, dc,
|
||||
GWEN_Buffer_GetStart(bufDeviceName),
|
||||
GWEN_Buffer_GetStart(bufValueName),
|
||||
dbuf);
|
||||
GWEN_Buffer_free(bufValueName);
|
||||
GWEN_Buffer_free(bufDeviceName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _runGraphValueWithArgs(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 *value;
|
||||
const char *sPeriod;
|
||||
int period;
|
||||
|
||||
DBG_ERROR(NULL, "GraphValue with args");
|
||||
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
||||
sPeriod=GWEN_DB_GetCharValue(dbQuery, "period", 0, NULL);
|
||||
period=sPeriod?_getPeriodFromString(sPeriod):VALUEGRAPH_PERIOD_1D;
|
||||
DBG_ERROR(NULL, "Device=%s, value=%s, period=%s",
|
||||
sDeviceName?sDeviceName:"<empty>", sValueName?sValueName:"<empty>",
|
||||
sPeriod?sPeriod:"<empty>");
|
||||
|
||||
value=_getValue(dc, sDeviceName, sValueName);
|
||||
if (value) {
|
||||
GWEN_BUFFER *fbuf;
|
||||
int rv;
|
||||
|
||||
fbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
_mkPathForValueAndPeriod(m, value, period, fbuf);
|
||||
if (!_fileIsCurrent(GWEN_Buffer_GetStart(fbuf), _getAcceptedAgeForPeriod(period))) {
|
||||
DBG_ERROR(NULL, "Creating graph");
|
||||
_createGraph(dc,
|
||||
value,
|
||||
period,
|
||||
sValueName,
|
||||
2,
|
||||
AQH_ValueModality_toString(AQH_Value_GetModality(value)),
|
||||
GWEN_Buffer_GetStart(fbuf),
|
||||
640, 480,
|
||||
100000);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
GWEN_BUFFER *ibuf;
|
||||
|
||||
ibuf=GWEN_Buffer_new(0, 1024, 0, 1);
|
||||
// return file
|
||||
rv=GWEN_SyncIo_Helper_ReadFile(GWEN_Buffer_GetStart(fbuf), ibuf);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "here (%d)", rv);
|
||||
}
|
||||
else {
|
||||
GWEN_Buffer_Reset(dbuf);
|
||||
GWEN_Buffer_AppendBytes(dbuf, GWEN_Buffer_GetStart(ibuf), GWEN_Buffer_GetUsedBytes(ibuf));
|
||||
AQCGI_Request_AddResponseHeaderData(rq, "Content-type: image/png");
|
||||
AQCGI_Request_AddFlags(rq, AQH_MODSERVICE_RQFLAGS_RAWFILE);
|
||||
}
|
||||
GWEN_Buffer_free(ibuf);
|
||||
}
|
||||
|
||||
GWEN_Buffer_free(fbuf);
|
||||
AQH_Value_free(value);
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Could not get value");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _fileIsCurrent(const char *sPath, int seconds)
|
||||
{
|
||||
struct stat sb;
|
||||
time_t t1;
|
||||
|
||||
if (lstat(sPath, &sb)==-1) {
|
||||
DBG_ERROR(NULL, "Error on lstat(%s): %s (%d)", sPath, strerror(errno), errno);
|
||||
return 0;
|
||||
}
|
||||
t1=time(0);
|
||||
if ((t1-sb.st_mtime)<(time_t) seconds) {
|
||||
DBG_ERROR(NULL, "File %s is current", sPath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _createGraph(AQH_DATACLIENT *dc,
|
||||
const AQH_VALUE *v,
|
||||
int period,
|
||||
const char *graphTitle, int precision,
|
||||
const char *curveLabel,
|
||||
const char *sImgFile, int imgWidth, int imgHeight, uint64_t numDataPoints)
|
||||
{
|
||||
const char *sValue;
|
||||
AQDG_GRAPH *g;
|
||||
AQDG_DRAW_CONTEXT *drawContext;
|
||||
AQDG_OBJECT *graphObject;
|
||||
uint64_t tsBegin;
|
||||
uint64_t tsEnd;
|
||||
const char *sModifier;
|
||||
AQDG_GRAPH_DATAPAIR_LIST *dpList;
|
||||
|
||||
sValue=AQH_Value_GetNameForSystem(v);
|
||||
tsEnd=time(0);
|
||||
tsBegin=_getStartTimeForPeriod(period);
|
||||
g=_mkGraphObjectWithTitle(graphTitle, period, precision);
|
||||
sModifier=_getModifiersForPeriod(period);
|
||||
|
||||
DBG_ERROR(NULL, "Requesting data for %s", sValue);
|
||||
dpList=_requestDataPairList(dc, sValue, tsBegin, tsEnd, numDataPoints);
|
||||
if (dpList) {
|
||||
DBG_ERROR(NULL, "Adding data for %s", sValue);
|
||||
AQDG_TimeGraph_ModifyDataAndAddCurve(g, curveLabel?curveLabel:sValue, sModifier, dpList);
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "No data");
|
||||
AQDG_Graph_free(g);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_ERROR(NULL, "Setup ticks for %s", sValue);
|
||||
AQDG_TimeGraph_SetupTicks(g, 0, 0.0, 0.0);
|
||||
|
||||
DBG_ERROR(NULL, "Draw graph for %s", sValue);
|
||||
drawContext=AQDG_Draw_ContextCairo_Png_new(sImgFile, imgWidth, imgHeight);
|
||||
graphObject=AQDG_GraphWidget_new(NULL, AQDG_OBJECT_OPTIONS_STRETCHX | AQDG_OBJECT_OPTIONS_STRETCHY, drawContext);
|
||||
AQDG_Object_SetWidth(graphObject, imgWidth);
|
||||
AQDG_Object_SetHeight(graphObject, imgHeight);
|
||||
|
||||
AQDG_GraphWidget_SetupDefaultPens(graphObject);
|
||||
AQDG_GraphWidget_SetupDefaultFonts(graphObject);
|
||||
|
||||
AQDG_GraphWidget_FinishWithGraph(graphObject, g);
|
||||
|
||||
AQDG_Object_free(graphObject);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, int period, int precision)
|
||||
{
|
||||
AQDG_GRAPH *g;
|
||||
GWEN_BUFFER *tbuf;
|
||||
const char *s;
|
||||
|
||||
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
|
||||
switch(period) {
|
||||
case VALUEGRAPH_PERIOD_4H: s="last 4 hours"; break;
|
||||
case VALUEGRAPH_PERIOD_1D: s="last 24 hours"; break;
|
||||
case VALUEGRAPH_PERIOD_1W: s="last week"; break;
|
||||
case VALUEGRAPH_PERIOD_1M: s="last month"; break;
|
||||
default: s="last 24 hours"; break;
|
||||
}
|
||||
|
||||
GBAA(tbuf, "%s - %s", graphTitle, s);
|
||||
|
||||
g=AQDG_TimeGraph_new(GWEN_Buffer_GetStart(tbuf), NULL, "Value", NULL, precision);
|
||||
GWEN_Buffer_free(tbuf);
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
int _getPeriodFromString(const char *sPeriod)
|
||||
{
|
||||
if (strcasecmp(sPeriod, "4h")==0)
|
||||
return VALUEGRAPH_PERIOD_4H;
|
||||
else if (strcasecmp(sPeriod, "1d")==0)
|
||||
return VALUEGRAPH_PERIOD_1D;
|
||||
else if (strcasecmp(sPeriod, "1w")==0)
|
||||
return VALUEGRAPH_PERIOD_1W;
|
||||
else if (strcasecmp(sPeriod, "1m")==0)
|
||||
return VALUEGRAPH_PERIOD_1M;
|
||||
return VALUEGRAPH_PERIOD_1D;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, int period, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
const char *s;
|
||||
|
||||
sv=AQH_ModService_GetService(m);
|
||||
|
||||
/* cache folder */
|
||||
s=AQH_Service_GetCacheFolder(sv);
|
||||
GBAA(dbuf, "%s%s", s, GWEN_DIR_SEPARATOR_S);
|
||||
|
||||
/* var name */
|
||||
s=AQH_Value_GetNameForSystem(v);
|
||||
GWEN_Text_EscapeToBuffer(s, dbuf);
|
||||
|
||||
/* period */
|
||||
switch(period) {
|
||||
case VALUEGRAPH_PERIOD_4H: s="4h"; break;
|
||||
case VALUEGRAPH_PERIOD_1D: s="1d"; break;
|
||||
case VALUEGRAPH_PERIOD_1W: s="1w"; break;
|
||||
case VALUEGRAPH_PERIOD_1M: s="1m"; break;
|
||||
default: s="1d"; break;
|
||||
}
|
||||
|
||||
GBAA(dbuf, "-%s.png", s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint64_t _getStartTimeForPeriod(int period)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
t=time(0);
|
||||
|
||||
/* period */
|
||||
switch(period) {
|
||||
case VALUEGRAPH_PERIOD_4H: t-=4*60*60; break;
|
||||
case VALUEGRAPH_PERIOD_1D: t-=24*60*60; break;
|
||||
case VALUEGRAPH_PERIOD_1W: t-=7*24*60*60; break;
|
||||
case VALUEGRAPH_PERIOD_1M: t-=30*24*60*60; break;
|
||||
default: t-=24*60*60; break;
|
||||
}
|
||||
|
||||
return (uint64_t) t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *_getModifiersForPeriod(int period)
|
||||
{
|
||||
/* period */
|
||||
switch(period) {
|
||||
case VALUEGRAPH_PERIOD_4H: return "La5";
|
||||
case VALUEGRAPH_PERIOD_1D: return "La15";
|
||||
case VALUEGRAPH_PERIOD_1W: return "La240";
|
||||
case VALUEGRAPH_PERIOD_1M: return "La480";
|
||||
default: return "La15";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _getAcceptedAgeForPeriod(int period)
|
||||
{
|
||||
/* period */
|
||||
switch(period) {
|
||||
case VALUEGRAPH_PERIOD_4H: return 2*60; /* 2m */
|
||||
case VALUEGRAPH_PERIOD_1D: return 5*60; /* 5m */
|
||||
case VALUEGRAPH_PERIOD_1W: return 15*60; /* 15m */
|
||||
case VALUEGRAPH_PERIOD_1M: return 60*60; /* 1h */
|
||||
default: return 5*60; /* 5m */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
AQH_VALUE *_getValue(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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AQDG_GRAPH_DATAPAIR_LIST *_requestDataPairList(AQH_DATACLIENT *dc, const char *valueName,
|
||||
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, valueName, 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");
|
||||
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_ERROR(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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
27
apps/aqhome-cgi/modules/devices/mdevices_vgraph.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_vgraph.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_CGI_MDEVICES_VGRAPH_H
|
||||
#define AQHOME_CGI_MDEVICES_VGRAPH_H
|
||||
|
||||
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
|
||||
#include "aqhome/aqhome.h"
|
||||
#include "aqhome/dataclient/client.h"
|
||||
|
||||
#include <aqcgi/request.h>
|
||||
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
|
||||
void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,873 +0,0 @@
|
||||
/****************************************************************************
|
||||
* 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/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 void _createPermDefList(AQH_MODULE *m);
|
||||
static void _createRoleList(AQH_MODULE *m);
|
||||
|
||||
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 _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(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);
|
||||
static uint32_t _rgbwToHtmlColor(uint32_t colorIn);
|
||||
static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
||||
static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
||||
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);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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},
|
||||
{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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AQH_ModDevices_Create(AQH_SERVICE *sv)
|
||||
{
|
||||
AQH_MODULE *m;
|
||||
int rv;
|
||||
|
||||
m=AQH_Module_new();
|
||||
AQH_Module_SetName(m, "devices");
|
||||
AQH_Module_SetDescr(m, "device module");
|
||||
AQH_Module_SetGuestPerms(m, 0);
|
||||
|
||||
_createPermDefList(m);
|
||||
_createRoleList(m);
|
||||
|
||||
rv=AQH_Service_AddModule(sv, m);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
}
|
||||
AQH_Module_free(m);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _createPermDefList(AQH_MODULE *m)
|
||||
{
|
||||
AQH_PERMDEF_LIST *permDefList;
|
||||
|
||||
permDefList=AQH_PermDef_List_new();
|
||||
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceRead", 0x001, "Read and list devices");
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceWrite", 0x002, "Modify devices");
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceAdd", 0x004, "Add devices");
|
||||
AQH_ModService_AddPermDef(permDefList, "DeviceDel", 0x008, "Remove devices");
|
||||
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueRead", 0x010, "Read and list values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueWrite", 0x020, "Modify values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueAdd", 0x040, "Add values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueDel", 0x080, "Remove values");
|
||||
AQH_ModService_AddPermDef(permDefList, "ValueSet", 0x100, "Set values");
|
||||
|
||||
AQH_Module_SetPermDefList(m, permDefList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _createRoleList(AQH_MODULE *m)
|
||||
{
|
||||
AQH_ROLE_LIST *roleList;
|
||||
int id=0;
|
||||
|
||||
roleList=AQH_Role_List_new();
|
||||
AQH_ModService_AddRole(roleList, id++, "Reader",
|
||||
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUEREAD,
|
||||
"Read devices and values");
|
||||
AQH_ModService_AddRole(roleList, id++, "Writer",
|
||||
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
||||
AQH_MODDEVICES_PERMS_DEVICEWRITE |
|
||||
AQH_MODDEVICES_PERMS_DEVICEADD |
|
||||
AQH_MODDEVICES_PERMS_DEVICEDEL |
|
||||
AQH_MODDEVICES_PERMS_VALUEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUEWRITE |
|
||||
AQH_MODDEVICES_PERMS_VALUEADD |
|
||||
AQH_MODDEVICES_PERMS_VALUEDEL |
|
||||
AQH_MODDEVICES_PERMS_VALUESET,
|
||||
"Read and write devices and values");
|
||||
AQH_ModService_AddRole(roleList, id++, "Setter",
|
||||
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUEREAD |
|
||||
AQH_MODDEVICES_PERMS_VALUESET,
|
||||
"Set values");
|
||||
AQH_Module_SetRoleList(m, roleList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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, _runIndex, dbuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _handleRqValuesGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
AQH_ModDataClient_HandleRequest(m, rq, session, _runValues, dbuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _runIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
AQH_DEVICE_LIST *deviceList;
|
||||
AQH_DEVICE *device;
|
||||
uint32_t perms;
|
||||
|
||||
perms=AQH_ModService_GetUserPerms(m);
|
||||
|
||||
deviceList=AQH_DataClient_GetDevices(dc, NULL);
|
||||
if (deviceList==NULL) {
|
||||
DBG_ERROR(NULL, "No device received");
|
||||
GBAS(dbuf, "<p>No devices.</p>");
|
||||
return;
|
||||
}
|
||||
|
||||
GBAS(dbuf, "<h1>Devices</h1>\n");
|
||||
GBAS(dbuf,
|
||||
"<table class=\"datatable\">\n"
|
||||
"<thead>\n"
|
||||
"<tr>"
|
||||
"<th>Name For System</th>"
|
||||
"<th>Room</th>"
|
||||
"<th>Location</th>"
|
||||
"<th>Description</th>"
|
||||
#if 0
|
||||
"<th>Type</th>"
|
||||
"<th>Driver</th>"
|
||||
"<th>Name</th>"
|
||||
"<th>GUI Name</th>"
|
||||
"<th>Manufacturer</th>"
|
||||
#endif
|
||||
"</tr>\n"
|
||||
"</thead>\n"
|
||||
"<tbody>\n");
|
||||
|
||||
device=AQH_Device_List_First(deviceList);
|
||||
while(device) {
|
||||
const char *s;
|
||||
|
||||
GBAA(dbuf, "<tr>");
|
||||
/* name for system */
|
||||
s=AQH_Device_GetNameForSystem(device);
|
||||
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
||||
GBAS(dbuf,"<td><a href=\"values.html?device=");
|
||||
GWEN_Text_EscapeToBufferTolerant(s, dbuf);
|
||||
GBAA(dbuf,"\">%s</a></td>", s?s:"");
|
||||
}
|
||||
else
|
||||
GBAA(dbuf,"<td>%s</td>", s?s:"");
|
||||
/* room */
|
||||
s=AQH_Device_GetRoomName(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* location */
|
||||
s=AQH_Device_GetLocation(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* description */
|
||||
s=AQH_Device_GetDescription(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
#if 0
|
||||
/* device type */
|
||||
s=AQH_Device_GetDeviceType(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* driver */
|
||||
s=AQH_Device_GetDriver(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* short device name */
|
||||
s=AQH_Device_GetName(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* GUI name for device */
|
||||
s=AQH_Device_GetNameForGui(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
/* manufacturer */
|
||||
s=AQH_Device_GetManufacturer(device);
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
#endif
|
||||
|
||||
GBAA(dbuf, "</tr>");
|
||||
device=AQH_Device_List_Next(device);
|
||||
}
|
||||
|
||||
GBAS(dbuf,
|
||||
"</tbody>\n"
|
||||
"</table>\n");
|
||||
AQH_Device_List_free(deviceList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
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);
|
||||
if (!(sDeviceName && *sDeviceName))
|
||||
_runIndex(m, rq, session, dc, dbuf);
|
||||
else {
|
||||
AQH_VALUE_LIST *valueList;
|
||||
|
||||
valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
|
||||
if (valueList && AQH_Value_List_GetCount(valueList)) {
|
||||
|
||||
GBAA(dbuf,"<h1>Values for Device %s</h1>\n", sDeviceName);
|
||||
_writeValueListToTable(sDeviceName, valueList, perms, dbuf);
|
||||
GBAS(dbuf, "\n");
|
||||
}
|
||||
else {
|
||||
GBAS(dbuf,"<p>No values.</p>\n");
|
||||
}
|
||||
AQH_Value_List_free(valueList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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:"<empty>", sValueName?sValueName:"<empty>");
|
||||
|
||||
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;
|
||||
|
||||
value=AQH_Value_List_First(valueList);
|
||||
while(value) {
|
||||
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
||||
const char *sValueName;
|
||||
const char *sValue;
|
||||
|
||||
sValueName=AQH_Value_GetName(value);
|
||||
sValue=GWEN_DB_GetCharValue(dbPost, sValueName, 0, NULL);
|
||||
if (sValueName && *sValueName) {
|
||||
DBG_ERROR(NULL, "Setting value %s to %s", sValueName?sValueName:"no name", sValue?sValue:"no value");
|
||||
switch(AQH_Value_GetModality(value)) {
|
||||
case AQH_ValueModality_RGBW: _setRgbwData(dc, value, sValue); break;
|
||||
case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sValue); break;
|
||||
case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break;
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
} /* if (sValueName) */
|
||||
}
|
||||
value=AQH_Value_List_Next(value);
|
||||
} /* while */
|
||||
}
|
||||
AQH_Value_List_free(valueList);
|
||||
|
||||
if (sDeviceName && *sDeviceName) {
|
||||
GWEN_BUFFER *pbuf;
|
||||
|
||||
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
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);
|
||||
}
|
||||
AQCGI_Request_SetResponseCode(rq, 303);
|
||||
AQCGI_Request_SetResponseText(rq, "See other");
|
||||
}
|
||||
|
||||
|
||||
void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, uint32_t perms, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
const AQH_VALUE *value;
|
||||
|
||||
GBAS(dbuf,
|
||||
"<table class=\"datatable\">\n"
|
||||
"<thead>"
|
||||
"<tr>"
|
||||
"<th>Name</th>"
|
||||
"<th>Type</th>"
|
||||
"<th>Modality</th>"
|
||||
#if 0
|
||||
"<th>Driver</th>"
|
||||
"<th>Device</th>"
|
||||
"<th>Name for System</th>"
|
||||
#endif
|
||||
"</tr>"
|
||||
"</thead>\n"
|
||||
"<tbody>\n");
|
||||
|
||||
value=AQH_Value_List_First(valueList);
|
||||
while(value) {
|
||||
if (AQH_Value_GetModality(value)!=AQH_ValueModality_Stats)
|
||||
_writeValueToTable(sDeviceName, value, perms, dbuf);
|
||||
value=AQH_Value_List_Next(value);
|
||||
}
|
||||
GBAS(dbuf,
|
||||
"</tbody>\n"
|
||||
"</table>\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, uint32_t perms, GWEN_BUFFER *dbuf)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
GBAS(dbuf, "<tr>");
|
||||
|
||||
/* name for system */
|
||||
s=AQH_Value_GetName(value);
|
||||
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
||||
uint32_t pos;
|
||||
|
||||
pos=GWEN_Buffer_GetPos(dbuf);
|
||||
GBAS(dbuf,"<td><a href=\"value.html?device=");
|
||||
GWEN_Text_EscapeToBuffer(sDeviceName, dbuf);
|
||||
GBAS(dbuf,"&value=");
|
||||
GWEN_Text_EscapeToBuffer(s, dbuf);
|
||||
GBAA(dbuf,"\">%s</a></td>", s);
|
||||
}
|
||||
else
|
||||
GBAA(dbuf,"<td>%s</td>", s?s:"");
|
||||
|
||||
s=AQH_ValueType_toString(AQH_Value_GetValueType(value));
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
|
||||
s=AQH_ValueModality_toString(AQH_Value_GetModality(value));
|
||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
||||
|
||||
GBAA(dbuf, "</tr>\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t _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 _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 _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 _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
||||
{
|
||||
if (sValue) {
|
||||
const char *sValueSystemName;
|
||||
uint32_t color;
|
||||
int rv;
|
||||
|
||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
||||
color=_colorFromHexString(sValue);
|
||||
DBG_ERROR(NULL, "Send value [#%08x] to %s", color, sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, (double) color);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
||||
{
|
||||
if (sValue) {
|
||||
const char *sValueSystemName;
|
||||
int rv;
|
||||
|
||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
||||
if (strcasecmp(sValue, "unchanged")==0) {
|
||||
DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
|
||||
}
|
||||
else if (strcasecmp(sValue, "on")==0) {
|
||||
DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sValue, "off")==0) {
|
||||
DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
||||
{
|
||||
if (sValue) {
|
||||
const char *sValueSystemName;
|
||||
int rv;
|
||||
|
||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
||||
if (strcasecmp(sValue, "unchanged")==0) {
|
||||
DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
|
||||
}
|
||||
else if (strcasecmp(sValue, "on")==0) {
|
||||
DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sValue, "off")==0) {
|
||||
DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sValue, "auto")==0) {
|
||||
DBG_ERROR(NULL, "Send value 2 to %s", sValueSystemName);
|
||||
rv=AQH_DataClient_SetData(dc, value, 2.0);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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),
|
||||
_rgbwToHtmlColor(u.f),
|
||||
_htmlColorToValueRGBW(_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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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,"<h1>Value %s/%s</h1>\n", sDeviceName, sValueName);
|
||||
|
||||
GBAS(dbuf,"<form action=\"setdata.html\" method=\"post\">\n");
|
||||
GBAA(dbuf, "<input type=\"hidden\" name=\"device\" value=\"%s\">\n", sDeviceName);
|
||||
GBAA(dbuf, "<input type=\"hidden\" name=\"value\" value=\"%s\">\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, "<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 */
|
||||
|
||||
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
||||
GBAS(dbuf, "</form>\n\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "./mroot_p.h"
|
||||
|
||||
#include "aqhome-cgi/service/module.h"
|
||||
#include "aqhome-cgi/modules/mdevices.h"
|
||||
#include "aqhome-cgi/modules/devices/mdevices.h"
|
||||
#include "aqhome-cgi/modules/common/madmin.h"
|
||||
|
||||
#include <gwenhywfar/debug.h>
|
||||
|
||||
@@ -27,7 +27,7 @@ GWEN_LIST_FUNCTIONS(AQH_SERVICE, AQH_Service);
|
||||
|
||||
|
||||
|
||||
AQH_SERVICE *AQH_Service_new(void)
|
||||
AQH_SERVICE *AQH_Service_new(const char *baseFolder, const char *baseUrl)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
|
||||
@@ -35,6 +35,32 @@ AQH_SERVICE *AQH_Service_new(void)
|
||||
GWEN_INHERIT_INIT(AQH_SERVICE, sv);
|
||||
GWEN_LIST_INIT(AQH_SERVICE, sv);
|
||||
|
||||
sv->baseUrl=baseUrl?strdup(baseUrl):NULL;
|
||||
sv->baseFolder=baseFolder?strdup(baseFolder):NULL;
|
||||
|
||||
if (sv->baseFolder) {
|
||||
GWEN_BUFFER *dbuf;
|
||||
uint32_t pos;
|
||||
|
||||
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
GWEN_Buffer_AppendArgs(dbuf, "%s%s", sv->baseFolder, GWEN_DIR_SEPARATOR_S);
|
||||
pos=GWEN_Buffer_GetPos(dbuf);
|
||||
|
||||
/* data folder */
|
||||
GWEN_Buffer_AppendString(dbuf, "data");
|
||||
sv->runtimeFolder=strdup(GWEN_Buffer_GetStart(dbuf));
|
||||
DBG_ERROR(NULL, "Runtime folder: %s", GWEN_Buffer_GetStart(dbuf));
|
||||
GWEN_Buffer_Crop(dbuf, 0, pos);
|
||||
|
||||
/* cache folder */
|
||||
GWEN_Buffer_AppendString(dbuf, "cache");
|
||||
sv->cacheFolder=strdup(GWEN_Buffer_GetStart(dbuf));
|
||||
DBG_ERROR(NULL, "Cache folder: %s", GWEN_Buffer_GetStart(dbuf));
|
||||
GWEN_Buffer_Crop(dbuf, 0, pos);
|
||||
|
||||
GWEN_Buffer_free(dbuf);
|
||||
}
|
||||
|
||||
return sv;
|
||||
}
|
||||
|
||||
@@ -46,11 +72,44 @@ void AQH_Service_free(AQH_SERVICE *sv)
|
||||
GWEN_LIST_FINI(AQH_SERVICE, sv);
|
||||
GWEN_INHERIT_FINI(AQH_SERVICE, sv);
|
||||
|
||||
free(sv->baseUrl);
|
||||
free(sv->baseFolder);
|
||||
free(sv->runtimeFolder);
|
||||
free(sv->cacheFolder);
|
||||
GWEN_FREE_OBJECT(sv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *AQH_Service_GetBaseUrl(const AQH_SERVICE *sv)
|
||||
{
|
||||
return sv?sv->baseUrl:NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *AQH_Service_GetBaseFolder(const AQH_SERVICE *sv)
|
||||
{
|
||||
return sv?sv->baseFolder:NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *AQH_Service_GetRuntimeFolder(const AQH_SERVICE *sv)
|
||||
{
|
||||
return sv?sv->runtimeFolder:NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *AQH_Service_GetCacheFolder(const AQH_SERVICE *sv)
|
||||
{
|
||||
return sv?sv->cacheFolder:NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
AQH_MODULE *AQH_Service_GetModuleByPath(const AQH_SERVICE *sv, const char *s)
|
||||
{
|
||||
|
||||
@@ -52,10 +52,13 @@ typedef GWEN_STRINGLIST* (*AQH_SERVICE_LISTSESSIONS_FN)(AQH_SERVICE *sv);
|
||||
|
||||
|
||||
|
||||
AQH_SERVICE *AQH_Service_new(void);
|
||||
AQH_SERVICE *AQH_Service_new(const char *baseFolder, const char *baseUrl);
|
||||
void AQH_Service_free(AQH_SERVICE *sv);
|
||||
|
||||
|
||||
const char *AQH_Service_GetBaseUrl(const AQH_SERVICE *sv);
|
||||
const char *AQH_Service_GetBaseFolder(const AQH_SERVICE *sv);
|
||||
const char *AQH_Service_GetRuntimeFolder(const AQH_SERVICE *sv);
|
||||
const char *AQH_Service_GetCacheFolder(const AQH_SERVICE *sv);
|
||||
|
||||
int AQH_Service_HandleRequest(AQH_SERVICE *sv, AQCGI_REQUEST *req);
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ struct AQH_SERVICE {
|
||||
GWEN_INHERIT_ELEMENT(AQH_SERVICE);
|
||||
GWEN_LIST_ELEMENT(AQH_SERVICE);
|
||||
|
||||
char *baseUrl;
|
||||
char *baseFolder;
|
||||
char *runtimeFolder;
|
||||
char *cacheFolder;
|
||||
|
||||
AQH_SERVICE_HANDLEREQUEST_FN handleRequestFn;
|
||||
|
||||
AQH_SERVICE_LOADUSER_FN loadUserFn;
|
||||
|
||||
@@ -79,16 +79,15 @@ static GWEN_STRINGLIST *_listGroup(AQH_SERVICE *sv, const char *groupName);
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder)
|
||||
AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder, const char *baseUrl)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
AQH_SERVICE_FILE *xs;
|
||||
GWEN_BUFFER *dbuf;
|
||||
|
||||
sv=AQH_Service_new();
|
||||
sv=AQH_Service_new(baseFolder, baseUrl);
|
||||
GWEN_NEW_OBJECT(AQH_SERVICE_FILE, xs);
|
||||
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv, xs, _freeData);
|
||||
xs->baseFolder=strdup(baseFolder);
|
||||
|
||||
AQH_Service_SetLoadUserFn(sv, _loadUser);
|
||||
AQH_Service_SetSaveUserFn(sv, _saveUser);
|
||||
@@ -109,7 +108,7 @@ AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder)
|
||||
AQH_Service_SetListSessionsFn(sv, _listSessions);
|
||||
|
||||
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
GWEN_Buffer_AppendArgs(dbuf, "dir://%s", baseFolder);
|
||||
GWEN_Buffer_AppendArgs(dbuf, "dir://%s", AQH_Service_GetRuntimeFolder(sv));
|
||||
DBG_ERROR(NULL, "Creating config mgr \"%s\"", GWEN_Buffer_GetStart(dbuf));
|
||||
xs->configMgr=GWEN_ConfigMgr_Factory(GWEN_Buffer_GetStart(dbuf));
|
||||
if (xs->configMgr==NULL) {
|
||||
@@ -131,7 +130,6 @@ void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p)
|
||||
|
||||
xs=(AQH_SERVICE_FILE*) p;
|
||||
GWEN_ConfigMgr_free(xs->configMgr);
|
||||
free(xs->baseFolder);
|
||||
GWEN_FREE_OBJECT(xs);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "aqhome-cgi/service/service.h"
|
||||
|
||||
|
||||
AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder);
|
||||
AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder, const char *baseUrl);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
* 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.
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
typedef struct AQH_SERVICE_FILE AQH_SERVICE_FILE;
|
||||
struct AQH_SERVICE_FILE {
|
||||
char *baseFolder;
|
||||
GWEN_CONFIGMGR *configMgr;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user