Merge branch 'mp-2025_10-setdata_double'
This commit is contained in:
2
0BUILD
2
0BUILD
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<gwbuild>
|
<gwbuild>
|
||||||
|
|
||||||
<project name="aqhome" version="0.0.15" so_current="0" so_age="0" so_revision="15" write_config_h="TRUE">
|
<project name="aqhome" version="0.0.19" so_current="0" so_age="0" so_revision="19" write_config_h="TRUE">
|
||||||
<setVar name="package">$(project_name)</setVar>
|
<setVar name="package">$(project_name)</setVar>
|
||||||
<setVar name="version">
|
<setVar name="version">
|
||||||
$(project_vmajor).$(project_vminor).$(project_vpatchlevel)
|
$(project_vmajor).$(project_vminor).$(project_vpatchlevel)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<includes type="c" >
|
<includes type="c" >
|
||||||
$(gwenhywfar_cflags)
|
$(gwenhywfar_cflags)
|
||||||
$(aqcgi_cflags)
|
$(aqcgi_cflags)
|
||||||
|
$(aqdiagram_cflags)
|
||||||
-I$(topsrcdir)
|
-I$(topsrcdir)
|
||||||
-I$(topbuilddir)
|
-I$(topbuilddir)
|
||||||
-I$(topsrcdir)/apps
|
-I$(topsrcdir)/apps
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
$(gwenhywfar_libs)
|
$(gwenhywfar_libs)
|
||||||
-lm
|
-lm
|
||||||
$(aqcgi_libs)
|
$(aqcgi_libs)
|
||||||
|
$(aqdiagram_libs)
|
||||||
</libraries>
|
</libraries>
|
||||||
|
|
||||||
<subdirs>
|
<subdirs>
|
||||||
@@ -127,6 +129,7 @@
|
|||||||
$(gwenhywfar_libs)
|
$(gwenhywfar_libs)
|
||||||
-lm
|
-lm
|
||||||
$(aqcgi_libs)
|
$(aqcgi_libs)
|
||||||
|
$(aqdiagram_libs)
|
||||||
</libraries>
|
</libraries>
|
||||||
|
|
||||||
<subdirs>
|
<subdirs>
|
||||||
|
|||||||
@@ -5,11 +5,12 @@
|
|||||||
#include "aqhome-cgi/modules/common/madmin.h"
|
#include "aqhome-cgi/modules/common/madmin.h"
|
||||||
#include "aqhome-cgi/modules/common/mmodules.h"
|
#include "aqhome-cgi/modules/common/mmodules.h"
|
||||||
#include "aqhome-cgi/modules/common/musers.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 "aqhome/aqhome.h"
|
||||||
|
|
||||||
#include <aqcgi/cgi.h>
|
#include <aqcgi/cgi.h>
|
||||||
#include <aqcgi/request.h>
|
#include <aqcgi/request.h>
|
||||||
|
#include <aqdiagram/aqdiagram.h>
|
||||||
|
|
||||||
#include <gwenhywfar/gwenhywfar.h>
|
#include <gwenhywfar/gwenhywfar.h>
|
||||||
#include <gwenhywfar/nogui.h>
|
#include <gwenhywfar/nogui.h>
|
||||||
@@ -26,21 +27,34 @@
|
|||||||
|
|
||||||
#define AQHOME_CGI_DEFAULT_STATIC_FILES AQHOME_CGI_WWWDIR"/static"
|
#define AQHOME_CGI_DEFAULT_STATIC_FILES AQHOME_CGI_WWWDIR"/static"
|
||||||
#define AQHOME_CGI_DEFAULT_RUNTIME_FILES AQHOME_CGI_WWWDIR"/data"
|
#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 int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles);
|
||||||
static void logStart(void);
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
GWEN_GUI *gui;
|
GWEN_GUI *gui;
|
||||||
const char *sPathStaticFiles;
|
const char *sPathStaticFiles;
|
||||||
const char *sPathRuntimeFiles;
|
const char *sPathRuntimeFiles;
|
||||||
|
const char *sBaseUrl;
|
||||||
|
|
||||||
sPathStaticFiles=getenv("AQHOME_STATIC_FILES");
|
sPathStaticFiles=getenv("AQHOME_STATIC_FILES");
|
||||||
if (!(sPathStaticFiles && *sPathStaticFiles))
|
if (!(sPathStaticFiles && *sPathStaticFiles))
|
||||||
@@ -50,6 +64,10 @@ int main(int argc, char **argv)
|
|||||||
if (!(sPathRuntimeFiles && *sPathRuntimeFiles))
|
if (!(sPathRuntimeFiles && *sPathRuntimeFiles))
|
||||||
sPathRuntimeFiles=AQHOME_CGI_DEFAULT_RUNTIME_FILES;
|
sPathRuntimeFiles=AQHOME_CGI_DEFAULT_RUNTIME_FILES;
|
||||||
|
|
||||||
|
sBaseUrl=getenv("AQHOME_BASE_URL");
|
||||||
|
if (!(sBaseUrl && *sBaseUrl))
|
||||||
|
sBaseUrl=AQHOME_CGI_DEFAULT_BASE_URL;
|
||||||
|
|
||||||
GWEN_Init();
|
GWEN_Init();
|
||||||
gui=GWEN_NoGui_new();
|
gui=GWEN_NoGui_new();
|
||||||
GWEN_Gui_SetGui(gui);
|
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(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(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(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_Open(NULL, "aqhome-cgi", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon);
|
||||||
|
|
||||||
GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug);
|
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(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug);
|
||||||
GWEN_Logger_SetLevel(AQCGI_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);
|
GWEN_Logger_SetLevel(NULL, GWEN_LoggerLevel_Debug);
|
||||||
|
|
||||||
if (argc>1 && argv[1]) {
|
if (argc>1 && argv[1]) {
|
||||||
if (0==strcasecmp(argv[1], "init")) {
|
if (0==strcasecmp(argv[1], "init")) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv=_init(sPathRuntimeFiles);
|
rv=_init(sPathRuntimeFiles, sBaseUrl);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
fprintf(stderr, "Error on init (%d)\n", rv);
|
fprintf(stderr, "Error on init (%d)\n", rv);
|
||||||
return 2;
|
return 2;
|
||||||
@@ -90,7 +110,7 @@ int main(int argc, char **argv)
|
|||||||
AQCGI_Init();
|
AQCGI_Init();
|
||||||
rq=AQCGI_ReadRequest();
|
rq=AQCGI_ReadRequest();
|
||||||
if (rq) {
|
if (rq) {
|
||||||
_handleRequest(rq, sPathStaticFiles, sPathRuntimeFiles);
|
_handleRequest(rq, sPathStaticFiles, sPathRuntimeFiles, sBaseUrl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stdout, "Content-type: text/plain\n\n");
|
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;
|
AQH_SERVICE *sv;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
sv=AQH_ServiceFiles_new(sPathRuntimeFiles);
|
sv=AQH_ServiceFiles_new(sPathRuntimeFiles, sBaseUrl);
|
||||||
|
|
||||||
rv=_handlePath(sv, rq, sPathStaticFiles);
|
rv=_handlePath(sv, rq, sPathStaticFiles);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
@@ -160,6 +180,7 @@ int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* last, let module handle remaining part */
|
/* last, let module handle remaining part */
|
||||||
|
DBG_ERROR(NULL, "Entry: %s (last)", s);
|
||||||
rv=AQH_ModService_HandleRequest(mParent, rq, session, s);
|
rv=AQH_ModService_HandleRequest(mParent, rq, session, s);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
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;
|
AQH_SERVICE *sv;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
fprintf(stdout, "Creating aqhome-cgi environment in \"%s\"\n", sPathRuntimeFiles);
|
DBG_ERROR(NULL, "Creating aqhome-cgi environment in \"%s\"", sPathRuntimeFiles);
|
||||||
sv=AQH_ServiceFiles_new(sPathRuntimeFiles);
|
sv=AQH_ServiceFiles_new(sPathRuntimeFiles, sBaseUrl);
|
||||||
rv=AQH_ModAdmin_Create(sv);
|
rv=AQH_ModAdmin_Create(sv);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_ERROR(NULL, "Error creating module \"admin\"");
|
DBG_ERROR(NULL, "Error creating module \"admin\"");
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
<headers dist="true" install="$(pkgincludedir)/service" >
|
<headers dist="true" install="$(pkgincludedir)/service" >
|
||||||
mdataclient.h
|
mdataclient.h
|
||||||
mdevices.h
|
|
||||||
mroot.h
|
mroot.h
|
||||||
</headers>
|
</headers>
|
||||||
|
|
||||||
@@ -64,7 +63,6 @@
|
|||||||
$(local/typefiles)
|
$(local/typefiles)
|
||||||
|
|
||||||
mdataclient.c
|
mdataclient.c
|
||||||
mdevices.c
|
|
||||||
mroot.c
|
mroot.c
|
||||||
</sources>
|
</sources>
|
||||||
|
|
||||||
@@ -75,10 +73,12 @@
|
|||||||
|
|
||||||
<useTargets>
|
<useTargets>
|
||||||
aqhcgi_modcom
|
aqhcgi_modcom
|
||||||
|
aqhcgi_mdevices
|
||||||
</useTargets>
|
</useTargets>
|
||||||
|
|
||||||
<subdirs>
|
<subdirs>
|
||||||
common
|
common
|
||||||
|
devices
|
||||||
static
|
static
|
||||||
</subdirs>
|
</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_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>
|
#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 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 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);
|
typedef void (*AQH_MODSERVICE_ADDHEADER_FN)(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf);
|
||||||
|
|||||||
99
apps/aqhome-cgi/modules/devices/0BUILD
Normal file
99
apps/aqhome-cgi/modules/devices/0BUILD
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<?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_valuestable.h
|
||||||
|
mdevices_valuesgraph.h
|
||||||
|
mdevices_value.h
|
||||||
|
mdevices_setdata.h
|
||||||
|
mdevices_vgraph.h
|
||||||
|
mdevices_device.h
|
||||||
|
mdevices_setdevice.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" >
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<sources>
|
||||||
|
$(local/typefiles)
|
||||||
|
|
||||||
|
mdevices.c
|
||||||
|
mdevices_init.c
|
||||||
|
mdevices_index.c
|
||||||
|
mdevices_valuestable.c
|
||||||
|
mdevices_valuesgraph.c
|
||||||
|
mdevices_value.c
|
||||||
|
mdevices_setdata.c
|
||||||
|
mdevices_vgraph.c
|
||||||
|
mdevices_device.c
|
||||||
|
mdevices_setdevice.c
|
||||||
|
</sources>
|
||||||
|
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
|
||||||
|
<useTargets>
|
||||||
|
</useTargets>
|
||||||
|
|
||||||
|
<subdirs>
|
||||||
|
</subdirs>
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
395
apps/aqhome-cgi/modules/devices/mdevices.c
Normal file
395
apps/aqhome-cgi/modules/devices/mdevices.c
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "./mdevices.h"
|
||||||
|
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_index.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_valuestable.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_valuesgraph.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_value.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_setdata.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_vgraph.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_device.h"
|
||||||
|
#include "aqhome-cgi/modules/devices/mdevices_setdevice.h"
|
||||||
|
#include "aqhome-cgi/service/module.h"
|
||||||
|
#include "aqhome-cgi/modules/mdataclient.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/timestamp.h>
|
||||||
|
#include <gwenhywfar/text.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* defs and enums
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GBAS GWEN_Buffer_AppendString
|
||||||
|
#define GBAA GWEN_Buffer_AppendArgs
|
||||||
|
|
||||||
|
#define P_DEVICEREAD AQH_MODDEVICES_PERMS_DEVICEREAD
|
||||||
|
#define P_DEVICEWRITE AQH_MODDEVICES_PERMS_DEVICEWRITE
|
||||||
|
#define P_VALUEREAD AQH_MODDEVICES_PERMS_VALUEREAD
|
||||||
|
#define P_VALUEWRITE AQH_MODDEVICES_PERMS_VALUEWRITE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName);
|
||||||
|
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem);
|
||||||
|
|
||||||
|
static void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqValuesTableGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqValuesGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqDeviceGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
static void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
static void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
||||||
|
static void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* vars
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
|
||||||
|
{"index.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD, _handleRqIndexGet},
|
||||||
|
{"device.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqDeviceGet},
|
||||||
|
{"device.html", AQCGI_REQUEST_METHOD_POST, P_DEVICEWRITE, _handleRqDevicePost},
|
||||||
|
{"vtable.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValuesTableGet},
|
||||||
|
{"vgraph.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValuesGraphGet},
|
||||||
|
{"value.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValueGet},
|
||||||
|
{"setdata.html", AQCGI_REQUEST_METHOD_POST, P_VALUEWRITE, _handleRqSetDataPost},
|
||||||
|
{"graph.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqGraphGet},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder)
|
||||||
|
{
|
||||||
|
AQH_ModService_Extend(m, sv, baseFolder);
|
||||||
|
AQH_ModService_SetHandleRequestFn(m, _handleRequest);
|
||||||
|
AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem)
|
||||||
|
{
|
||||||
|
AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable);
|
||||||
|
return AQCGI_SendResponse(rq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunIndex, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqValuesTableGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsTable, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqValuesGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValuesAsGraph, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunValue, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetData, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqGraphGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunGraphValue, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqDeviceGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunDevice, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _handleRqDevicePost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_ModDataClient_HandleRequest(m, rq, session, AQH_ModDevices_RunSetDevice, dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_VALUE *AQH_ModDevices_GetValueForDevice(AQH_DATACLIENT *dc, const char *sDeviceName, const char *sValueName)
|
||||||
|
{
|
||||||
|
AQH_VALUE_LIST *valueList;
|
||||||
|
|
||||||
|
valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
|
||||||
|
if (valueList) {
|
||||||
|
AQH_VALUE *value;
|
||||||
|
|
||||||
|
value=AQH_Value_List_First(valueList);
|
||||||
|
while(value) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s=AQH_Value_GetName(value);
|
||||||
|
if (s && *s && strcasecmp(s, sValueName)==0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value=AQH_Value_List_Next(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
AQH_Value_List_Del(value);
|
||||||
|
AQH_Value_List_free(valueList);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
AQH_Value_List_free(valueList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_DEVICE *AQH_ModDevices_GetDevice(AQH_DATACLIENT *dc, const char *sDeviceName)
|
||||||
|
{
|
||||||
|
AQH_DEVICE_LIST *deviceList;
|
||||||
|
|
||||||
|
deviceList=AQH_DataClient_GetDevices(dc, sDeviceName);
|
||||||
|
if (deviceList) {
|
||||||
|
AQH_DEVICE *device;
|
||||||
|
|
||||||
|
device=AQH_Device_List_First(deviceList);
|
||||||
|
while(device) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s=AQH_Device_GetNameForSystem(device);
|
||||||
|
if (s && *s && 0==strcasecmp(s, sDeviceName)) {
|
||||||
|
AQH_Device_List_Del(device);
|
||||||
|
AQH_Device_List_free(deviceList);
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
device=AQH_Device_List_Next(device);
|
||||||
|
}
|
||||||
|
AQH_Device_List_free(deviceList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -32,11 +32,22 @@
|
|||||||
#define AQH_MODDEVICES_PERMS_VALUESET 0x100
|
#define AQH_MODDEVICES_PERMS_VALUESET 0x100
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_MODDEVICES_GRAPH_WIDTH 640
|
||||||
|
#define AQH_MODDEVICES_GRAPH_HEIGHT 480
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder);
|
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder);
|
||||||
int AQH_ModDevices_Create(AQH_SERVICE *sv);
|
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);
|
||||||
|
|
||||||
|
AQH_VALUE *AQH_ModDevices_GetValueForDevice(AQH_DATACLIENT *dc, const char *sDeviceName, const char *sValueName);
|
||||||
|
AQH_DEVICE *AQH_ModDevices_GetDevice(AQH_DATACLIENT *dc, const char *sDeviceName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
131
apps/aqhome-cgi/modules/devices/mdevices_device.c
Normal file
131
apps/aqhome-cgi/modules/devices/mdevices_device.c
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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_device.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 I18N(msg) msg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void _runDeviceWithArgs(AQH_MODULE *m,
|
||||||
|
AQCGI_REQUEST *rq,
|
||||||
|
AQH_SESSION *session,
|
||||||
|
AQH_DATACLIENT *dc,
|
||||||
|
const char *sDeviceName,
|
||||||
|
GWEN_BUFFER *dbuf);
|
||||||
|
static void _mkDeviceForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_DEVICE *device, GWEN_BUFFER *dbuf);
|
||||||
|
static void _addFieldToForm(const char *sFieldTitle, const char *sFieldName, const char *sFieldContent, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AQH_ModDevices_RunDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
GWEN_DB_NODE *dbQuery;
|
||||||
|
const char *sDeviceName;
|
||||||
|
|
||||||
|
DBG_ERROR(NULL, "RunValue");
|
||||||
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
||||||
|
sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL);
|
||||||
|
if (sDeviceName && *sDeviceName) {
|
||||||
|
GWEN_BUFFER *bufDeviceName;
|
||||||
|
|
||||||
|
bufDeviceName=GWEN_Buffer_new(0, 64, 0, 1);
|
||||||
|
GWEN_Text_UnescapeToBufferTolerant(sDeviceName, bufDeviceName);
|
||||||
|
_runDeviceWithArgs(m, rq, session, dc, GWEN_Buffer_GetStart(bufDeviceName), dbuf);
|
||||||
|
GWEN_Buffer_free(bufDeviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _runDeviceWithArgs(AQH_MODULE *m,
|
||||||
|
AQCGI_REQUEST *rq,
|
||||||
|
AQH_SESSION *session,
|
||||||
|
AQH_DATACLIENT *dc,
|
||||||
|
const char *sDeviceName,
|
||||||
|
GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
GWEN_DB_NODE *dbQuery;
|
||||||
|
AQH_DEVICE *device;
|
||||||
|
|
||||||
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
||||||
|
DBG_ERROR(NULL, "Device=%s", sDeviceName?sDeviceName:"<empty>");
|
||||||
|
|
||||||
|
GBAA(dbuf,"<h1>Device %s</h1>\n", sDeviceName);
|
||||||
|
|
||||||
|
device=AQH_ModDevices_GetDevice(dc, sDeviceName);
|
||||||
|
if (device) {
|
||||||
|
_mkDeviceForm(dc, sDeviceName, device, dbuf);
|
||||||
|
AQH_Device_free(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _mkDeviceForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_DEVICE *device, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
GBAS(dbuf,"<form action=\"device.html\" method=\"post\">\n");
|
||||||
|
GBAA(dbuf, "<input type=\"hidden\" name=\"device\" value=\"%s\">\n", sDeviceName);
|
||||||
|
|
||||||
|
GBAS(dbuf,"<table>\n");
|
||||||
|
_addFieldToForm(I18N("Room"), "roomName", AQH_Device_GetRoomName(device), dbuf);
|
||||||
|
_addFieldToForm(I18N("GUI Name"), "nameForGui", AQH_Device_GetNameForGui(device), dbuf);
|
||||||
|
_addFieldToForm(I18N("Location"), "location", AQH_Device_GetLocation(device), dbuf);
|
||||||
|
_addFieldToForm(I18N("Description"), "description", AQH_Device_GetDescription(device), dbuf);
|
||||||
|
GBAS(dbuf,"</table>\n");
|
||||||
|
GBAS(dbuf,"<br>\n");
|
||||||
|
|
||||||
|
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
||||||
|
GBAS(dbuf, "</form>\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _addFieldToForm(const char *sFieldTitle, const char *sFieldName, const char *sFieldContent, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
GBAS(dbuf, "<tr>");
|
||||||
|
GBAA(dbuf, "<td><label for=\"%s\">%s</label></td>", sFieldName, sFieldTitle);
|
||||||
|
GBAA(dbuf, "<td><input type=\"text\" name=\"%s\" value=\"%s\"/></td>", sFieldName, sFieldContent?sFieldContent:"");
|
||||||
|
GBAS(dbuf, "</tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
27
apps/aqhome-cgi/modules/devices/mdevices_device.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_device.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_DEVICE_H
|
||||||
|
#define AQHOME_CGI_MDEVICES_DEVICE_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_RunDevice(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
135
apps/aqhome-cgi/modules/devices/mdevices_index.c
Normal file
135
apps/aqhome-cgi/modules/devices/mdevices_index.c
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void _addLinkForDevice(const char *page, const char *sDevice, const char *action, const char *imgName, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* 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>Name For GUI</th>"
|
||||||
|
"<th>Room</th>"
|
||||||
|
"<th>Location</th>"
|
||||||
|
"<th>Description</th>"
|
||||||
|
"<th>Actions</th>"
|
||||||
|
"</tr>\n"
|
||||||
|
"</thead>\n"
|
||||||
|
"<tbody>\n");
|
||||||
|
|
||||||
|
device=AQH_Device_List_First(deviceList);
|
||||||
|
while(device) {
|
||||||
|
const char *s;
|
||||||
|
const char *sDevice;
|
||||||
|
|
||||||
|
GBAA(dbuf, "<tr>");
|
||||||
|
/* name for system */
|
||||||
|
sDevice=AQH_Device_GetNameForSystem(device);
|
||||||
|
GBAA(dbuf,"<td>%s</td>", sDevice?sDevice:"");
|
||||||
|
/* nameForGui */
|
||||||
|
s=AQH_Device_GetNameForGui(device);
|
||||||
|
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:"");
|
||||||
|
|
||||||
|
GBAS(dbuf, "<td>");
|
||||||
|
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
||||||
|
_addLinkForDevice("vtable.html", sDevice, "table view", "/pics/document-table.png", dbuf);
|
||||||
|
_addLinkForDevice("vgraph.html", sDevice, "graph view", "/pics/graph.png", dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (perms & AQH_MODDEVICES_PERMS_DEVICEWRITE) {
|
||||||
|
_addLinkForDevice("device.html", sDevice, "edit device", "/pics/edit.png", dbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
GBAS(dbuf, "</td>");
|
||||||
|
|
||||||
|
GBAA(dbuf, "</tr>");
|
||||||
|
device=AQH_Device_List_Next(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
GBAS(dbuf,
|
||||||
|
"</tbody>\n"
|
||||||
|
"</table>\n");
|
||||||
|
AQH_Device_List_free(deviceList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _addLinkForDevice(const char *page, const char *sDevice, const char *action, const char *imgName, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
GBAA(dbuf,"<a href=\"%s?device=", page);
|
||||||
|
GWEN_Text_EscapeToBufferTolerant(sDevice, dbuf);
|
||||||
|
GBAS(dbuf,"\">");
|
||||||
|
GBAA(dbuf,"<img src=\"%s\" alt=\"%s\" title=\"%s\" />", imgName, action, action);
|
||||||
|
GBAS(dbuf,"</a>");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
194
apps/aqhome-cgi/modules/devices/mdevices_setdata.c
Normal file
194
apps/aqhome-cgi/modules/devices/mdevices_setdata.c
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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;
|
||||||
|
const AQH_VALUE *value;
|
||||||
|
|
||||||
|
/* 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:"");
|
||||||
|
|
||||||
|
value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName);
|
||||||
|
if(value && 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) */
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
105
apps/aqhome-cgi/modules/devices/mdevices_setdevice.c
Normal file
105
apps/aqhome-cgi/modules/devices/mdevices_setdevice.c
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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_setdevice.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 _handleDeviceForm(AQH_DATACLIENT *dc, AQH_DEVICE *device, GWEN_DB_NODE *dbPost, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AQH_ModDevices_RunSetDevice(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;
|
||||||
|
AQH_DEVICE *device;
|
||||||
|
|
||||||
|
DBG_ERROR(NULL, "Post device.html");
|
||||||
|
/* sample data */
|
||||||
|
sv=AQH_ModService_GetService(m);
|
||||||
|
dbPost=AQCGI_Request_GetDbPostBody(rq);
|
||||||
|
sDeviceName=dbPost?GWEN_DB_GetCharValue(dbPost, "device", 0, NULL):NULL;
|
||||||
|
DBG_ERROR(NULL, "Device=[%s]", sDeviceName?sDeviceName:"");
|
||||||
|
|
||||||
|
device=AQH_ModDevices_GetDevice(dc, sDeviceName);
|
||||||
|
if (device) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
DBG_ERROR(NULL, "Reading data from form");
|
||||||
|
_handleDeviceForm(dc, device, dbPost, dbuf);
|
||||||
|
DBG_ERROR(NULL, "Updating device on server");
|
||||||
|
rv=AQH_DataClient_ModDevice(dc, device);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "here (%d)", rv);
|
||||||
|
}
|
||||||
|
AQH_Device_free(device);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "device not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sDeviceName && *sDeviceName) {
|
||||||
|
GWEN_BUFFER *pbuf;
|
||||||
|
|
||||||
|
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
GBAS(pbuf, "Location: /aqbt/devices/device.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 _handleDeviceForm(AQH_DATACLIENT *dc, AQH_DEVICE *device, GWEN_DB_NODE *dbPost, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
AQH_Device_SetRoomName(device, GWEN_DB_GetCharValue(dbPost, "roomName", 0, NULL));
|
||||||
|
AQH_Device_SetNameForGui(device, GWEN_DB_GetCharValue(dbPost, "nameForGui", 0, NULL));
|
||||||
|
AQH_Device_SetLocation(device, GWEN_DB_GetCharValue(dbPost, "location", 0, NULL));
|
||||||
|
AQH_Device_SetDescription(device, GWEN_DB_GetCharValue(dbPost, "description", 0, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
27
apps/aqhome-cgi/modules/devices/mdevices_setdevice.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_setdevice.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_SETDEVICE_H
|
||||||
|
#define AQHOME_CGI_MDEVICES_SETDEVICE_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_RunSetDevice(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
|
||||||
175
apps/aqhome-cgi/modules/devices/mdevices_valuesgraph.c
Normal file
175
apps/aqhome-cgi/modules/devices/mdevices_valuesgraph.c
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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_valuesgraph.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 _writeValueToDetailedTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
||||||
|
static void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf);
|
||||||
|
static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
||||||
|
static void _addGraphLink(const char *sDeviceName, const char *sValueName, const char *sPeriod, GWEN_BUFFER *dbuf, int withLink);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* code
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AQH_ModDevices_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
GWEN_DB_NODE *dbQuery;
|
||||||
|
const char *sDeviceName;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
const char *sValueName;
|
||||||
|
|
||||||
|
sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL);
|
||||||
|
if (sValueName && *sValueName) {
|
||||||
|
AQH_VALUE *value;
|
||||||
|
|
||||||
|
GBAA(dbuf,"<h1>Value %s/%s</h1>\n", sDeviceName, sValueName);
|
||||||
|
value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName);
|
||||||
|
if (value) {
|
||||||
|
_writeValueToDetailedTable(sDeviceName, value, dbuf);
|
||||||
|
AQH_Value_free(value);
|
||||||
|
AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 120");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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, dbuf);
|
||||||
|
GBAS(dbuf, "\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GBAS(dbuf,"<p>No values.</p>\n");
|
||||||
|
}
|
||||||
|
AQH_Value_List_free(valueList);
|
||||||
|
AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 305");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeValueToDetailedTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
const char *sValueName;
|
||||||
|
|
||||||
|
GBAS(dbuf, "<table>\n");
|
||||||
|
sValueName=AQH_Value_GetName(value);
|
||||||
|
|
||||||
|
GBAS(dbuf, "<tr><td>");
|
||||||
|
_addGraphLink(sDeviceName, sValueName, "4h", dbuf, 0);
|
||||||
|
GBAS(dbuf, "</td><td>");
|
||||||
|
_addGraphLink(sDeviceName, sValueName, "1d", dbuf, 0);
|
||||||
|
GBAS(dbuf, "</td></tr><tr><td>");
|
||||||
|
_addGraphLink(sDeviceName, sValueName, "1w", dbuf, 0);
|
||||||
|
GBAS(dbuf, "</td><td>");
|
||||||
|
_addGraphLink(sDeviceName, sValueName, "12m", dbuf, 0);
|
||||||
|
GBAS(dbuf, "</td></tr>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
const AQH_VALUE *value;
|
||||||
|
|
||||||
|
GBAS(dbuf, "<table>\n");
|
||||||
|
|
||||||
|
|
||||||
|
value=AQH_Value_List_First(valueList);
|
||||||
|
while(value) {
|
||||||
|
if (AQH_Value_GetValueType(value)!=AQH_ValueType_Actor)
|
||||||
|
_writeValueToTable(sDeviceName, value, dbuf);
|
||||||
|
value=AQH_Value_List_Next(value);
|
||||||
|
}
|
||||||
|
GBAS(dbuf, "</table>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
const char *sValueName;
|
||||||
|
|
||||||
|
/* name */
|
||||||
|
sValueName=AQH_Value_GetName(value);
|
||||||
|
|
||||||
|
GBAS(dbuf, "<tr><td>");
|
||||||
|
_addGraphLink(sDeviceName, sValueName, "1d", dbuf, 1);
|
||||||
|
GBAS(dbuf, "</td><td>");
|
||||||
|
_addGraphLink(sDeviceName, sValueName, "1w", dbuf, 1);
|
||||||
|
GBAS(dbuf, "</td></tr>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _addGraphLink(const char *sDeviceName, const char *sValueName, const char *sPeriod, GWEN_BUFFER *dbuf, int withLink)
|
||||||
|
{
|
||||||
|
if (withLink) {
|
||||||
|
GBAS(dbuf, "<a href=\"vgraph.html?device=");
|
||||||
|
GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
|
||||||
|
GBAS(dbuf, "&value=");
|
||||||
|
GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
|
||||||
|
GBAS(dbuf, "\">");
|
||||||
|
}
|
||||||
|
|
||||||
|
GBAS(dbuf, "<img src=\"graph.html?device=");
|
||||||
|
GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
|
||||||
|
GBAS(dbuf, "&value=");
|
||||||
|
GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
|
||||||
|
GBAA(dbuf, "&period=%s\"", sPeriod);
|
||||||
|
GBAA(dbuf, " alt=\"%s\" width=\"%d\" height=\"%d\"", sValueName, AQH_MODDEVICES_GRAPH_WIDTH, AQH_MODDEVICES_GRAPH_HEIGHT);
|
||||||
|
GBAS(dbuf, "/>");
|
||||||
|
|
||||||
|
if (withLink) {
|
||||||
|
GBAS(dbuf, "</a>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
27
apps/aqhome-cgi/modules/devices/mdevices_valuesgraph.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_valuesgraph.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_VALUESGRAPH_H
|
||||||
|
#define AQHOME_CGI_MDEVICES_VALUESGRAPH_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_RunValuesAsGraph(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
145
apps/aqhome-cgi/modules/devices/mdevices_valuestable.c
Normal file
145
apps/aqhome-cgi/modules/devices/mdevices_valuestable.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_valuestable.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_RunValuesAsTable(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_valuestable.h
Normal file
27
apps/aqhome-cgi/modules/devices/mdevices_valuestable.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_VALUESTABLE_H
|
||||||
|
#define AQHOME_CGI_MDEVICES_VALUESTABLE_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_RunValuesAsTable(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
384
apps/aqhome-cgi/modules/devices/mdevices_vgraph.c
Normal file
384
apps/aqhome-cgi/modules/devices/mdevices_vgraph.c
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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,
|
||||||
|
VALUEGRAPH_PERIOD_6M,
|
||||||
|
VALUEGRAPH_PERIOD_12M,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* vars
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct MY_GRAPH_PARAMS MY_GRAPH_PARAMS;
|
||||||
|
struct MY_GRAPH_PARAMS {
|
||||||
|
const char *name;
|
||||||
|
const char *title;
|
||||||
|
const char *modifiers;
|
||||||
|
int startTimeDiff;
|
||||||
|
int acceptedAgeInSeconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static MY_GRAPH_PARAMS _graphParams[]={
|
||||||
|
{"4h", "last 4 hours", "Lm5", 4*60*60, 2*60},
|
||||||
|
{"1d", "last 24 hours", "Lm30", 24*60*60, 5*60},
|
||||||
|
{"1w", "last 7 days", "Lm240", 7*24*60*60, 15*60},
|
||||||
|
{"1m", "last 30 days", "Lm480", 30*24*60*60, 60*60},
|
||||||
|
{"6m", "last 6 months", "Lm720", 182*24*60*60, 60*60},
|
||||||
|
{"12m","last 12 months", "Lm1440", 365*24*60*60, 60*60},
|
||||||
|
{NULL, NULL, NULL, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void _runGraphValueWithArgs(AQH_MODULE *m,
|
||||||
|
AQCGI_REQUEST *rq,
|
||||||
|
AQH_DATACLIENT *dc,
|
||||||
|
const char *sDeviceName,
|
||||||
|
const char *sValueName,
|
||||||
|
GWEN_BUFFER *dbuf);
|
||||||
|
static void _createGraph(AQH_DATACLIENT *dc,
|
||||||
|
const AQH_VALUE *v,
|
||||||
|
const MY_GRAPH_PARAMS *graphParams,
|
||||||
|
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, const MY_GRAPH_PARAMS *graphParams, int precision);
|
||||||
|
static void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf);
|
||||||
|
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);
|
||||||
|
static const MY_GRAPH_PARAMS *_getParamsByName(const char *s);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* 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_DEBUG(NULL, "GraphValue");
|
||||||
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
||||||
|
sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL);
|
||||||
|
sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL);
|
||||||
|
DBG_DEBUG(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, 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_DATACLIENT *dc,
|
||||||
|
const char *sDeviceName,
|
||||||
|
const char *sValueName,
|
||||||
|
GWEN_BUFFER *dbuf)
|
||||||
|
{
|
||||||
|
GWEN_DB_NODE *dbQuery;
|
||||||
|
AQH_VALUE *value;
|
||||||
|
const MY_GRAPH_PARAMS *graphParams;
|
||||||
|
const char *sPeriod;
|
||||||
|
|
||||||
|
DBG_DEBUG(NULL, "GraphValue with args");
|
||||||
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
||||||
|
sPeriod=GWEN_DB_GetCharValue(dbQuery, "period", 0, NULL);
|
||||||
|
graphParams=_getParamsByName(sPeriod);
|
||||||
|
if (graphParams==NULL)
|
||||||
|
graphParams=&_graphParams[0];
|
||||||
|
DBG_DEBUG(NULL, "Device=%s, value=%s, period=%s",
|
||||||
|
sDeviceName?sDeviceName:"<empty>", sValueName?sValueName:"<empty>",
|
||||||
|
sPeriod?sPeriod:"<empty>");
|
||||||
|
|
||||||
|
value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName);
|
||||||
|
if (value) {
|
||||||
|
GWEN_BUFFER *fbuf;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
fbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
_mkPathForValueAndPeriod(m, value, graphParams, fbuf);
|
||||||
|
if (!_fileIsCurrent(GWEN_Buffer_GetStart(fbuf), graphParams->acceptedAgeInSeconds)) {
|
||||||
|
DBG_DEBUG(NULL, "Creating graph");
|
||||||
|
_createGraph(dc,
|
||||||
|
value,
|
||||||
|
graphParams,
|
||||||
|
sValueName,
|
||||||
|
2,
|
||||||
|
AQH_ValueModality_toString(AQH_Value_GetModality(value)),
|
||||||
|
GWEN_Buffer_GetStart(fbuf),
|
||||||
|
AQH_MODDEVICES_GRAPH_WIDTH, AQH_MODDEVICES_GRAPH_HEIGHT,
|
||||||
|
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, "Error reading \"%s\" (%d)", GWEN_Buffer_GetStart(fbuf), 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 \"%s/%s\"", sDeviceName, sValueName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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_DEBUG(NULL, "File %s is current", sPath);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _createGraph(AQH_DATACLIENT *dc,
|
||||||
|
const AQH_VALUE *v,
|
||||||
|
const MY_GRAPH_PARAMS *graphParams,
|
||||||
|
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;
|
||||||
|
AQDG_GRAPH_DATAPAIR_LIST *dpList;
|
||||||
|
|
||||||
|
sValue=AQH_Value_GetNameForSystem(v);
|
||||||
|
tsEnd=time(0);
|
||||||
|
tsBegin=time(0)-(graphParams->startTimeDiff);
|
||||||
|
g=_mkGraphObjectWithTitle(graphTitle, graphParams, precision);
|
||||||
|
|
||||||
|
dpList=_requestDataPairList(dc, sValue, tsBegin, tsEnd, numDataPoints);
|
||||||
|
if (dpList) {
|
||||||
|
DBG_DEBUG(NULL, "Adding data for %s", sValue);
|
||||||
|
AQDG_TimeGraph_ModifyDataAndAddCurve(g, curveLabel?curveLabel:sValue, graphParams->modifiers, dpList);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "No data for %s", sValue);
|
||||||
|
AQDG_Graph_free(g);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AQDG_TimeGraph_SetupTicks(g, 0, 0.0, 0.0);
|
||||||
|
|
||||||
|
DBG_DEBUG(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, const MY_GRAPH_PARAMS *graphParams, int precision)
|
||||||
|
{
|
||||||
|
AQDG_GRAPH *g;
|
||||||
|
GWEN_BUFFER *tbuf;
|
||||||
|
|
||||||
|
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
|
||||||
|
GBAA(tbuf, "%s - %s", graphTitle, graphParams->title);
|
||||||
|
|
||||||
|
g=AQDG_TimeGraph_new(GWEN_Buffer_GetStart(tbuf), NULL, "Value", NULL, precision);
|
||||||
|
GWEN_Buffer_free(tbuf);
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, 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);
|
||||||
|
|
||||||
|
GBAA(dbuf, "-%s.png", graphParams->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 for %s", valueName);
|
||||||
|
free(dataPoints);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues)
|
||||||
|
{
|
||||||
|
AQDG_GRAPH_DATAPAIR_LIST *dpList;
|
||||||
|
uint64_t i;
|
||||||
|
|
||||||
|
DBG_DEBUG(NULL, "Got %d datapoints", (int) numValues);
|
||||||
|
dpList=AQDG_Graph_DataPair_List_new();
|
||||||
|
for(i=0; i<numValues; i++) {
|
||||||
|
AQDG_GRAPH_DATAPAIR *dp;
|
||||||
|
double timestamp;
|
||||||
|
union {double f; uint64_t i;} u;
|
||||||
|
|
||||||
|
timestamp=(double)(*(dataPoints++));
|
||||||
|
u.i=*(dataPoints++);
|
||||||
|
dp=AQDG_Graph_DataPair_new();
|
||||||
|
AQDG_Graph_DataPair_SetValueX(dp, timestamp);
|
||||||
|
AQDG_Graph_DataPair_SetValueY(dp, u.f);
|
||||||
|
AQDG_Graph_DataPair_List_Add(dp, dpList);
|
||||||
|
}
|
||||||
|
AQDG_Graph_DataPair_List_SortByValueX(dpList, 1);
|
||||||
|
return dpList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const MY_GRAPH_PARAMS *_getParamsByName(const char *s)
|
||||||
|
{
|
||||||
|
const MY_GRAPH_PARAMS *p;
|
||||||
|
|
||||||
|
p=_graphParams;
|
||||||
|
while(p->name) {
|
||||||
|
if (strcasecmp(p->name, s)==0)
|
||||||
|
return p;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
BIN
apps/aqhome-cgi/modules/html/pics/cancel.png
Normal file
BIN
apps/aqhome-cgi/modules/html/pics/cancel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
apps/aqhome-cgi/modules/html/pics/edit.png
Normal file
BIN
apps/aqhome-cgi/modules/html/pics/edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 912 B |
BIN
apps/aqhome-cgi/modules/html/pics/graph.png
Normal file
BIN
apps/aqhome-cgi/modules/html/pics/graph.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
apps/aqhome-cgi/modules/html/pics/minus.png
Normal file
BIN
apps/aqhome-cgi/modules/html/pics/minus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 356 B |
BIN
apps/aqhome-cgi/modules/html/pics/ok.png
Normal file
BIN
apps/aqhome-cgi/modules/html/pics/ok.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1013 B |
BIN
apps/aqhome-cgi/modules/html/pics/plus.png
Normal file
BIN
apps/aqhome-cgi/modules/html/pics/plus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 834 B |
63
apps/aqhome-cgi/modules/html/style.css
Normal file
63
apps/aqhome-cgi/modules/html/style.css
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
body {
|
||||||
|
background-color: whitesmoke;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.datatable {
|
||||||
|
border: thin solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.datatable th, td {
|
||||||
|
border: thin solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.datatable tbody tr:nth-child(odd) {
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
table.formtable {
|
||||||
|
border: thin solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table.formtable th, td {
|
||||||
|
border: thin solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ul.mainmenu {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul.mainmenu li {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.mainmenu li a {
|
||||||
|
display: block;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 14px 16px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.mainmenu li a:hover {
|
||||||
|
background-color: #111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,584 +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 _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 _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
|
||||||
static void _writeValueListToTable(const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf);
|
|
||||||
static void _writeValueToTable(const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
||||||
static void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
||||||
static uint32_t _colorFromHexString(const char *s);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
|
||||||
* 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},
|
|
||||||
{"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 _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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
GBAS(dbuf,"<form action=\"setdata.html\" method=\"post\">\n");
|
|
||||||
GBAA(dbuf, "<input type=\"hidden\" name=\"device\" value=\"%s\">\n", sDeviceName);
|
|
||||||
_writeValueListToTable(valueList, dbuf);
|
|
||||||
|
|
||||||
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
|
||||||
GBAS(dbuf, "</form>\n\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GBAS(dbuf,"<p>No values.</p>\n");
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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 *sValueSystemName;
|
|
||||||
const char *sValueName;
|
|
||||||
const char *sValue;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
||||||
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:
|
|
||||||
if (sValue) {
|
|
||||||
uint32_t color;
|
|
||||||
char colbuf[16];
|
|
||||||
|
|
||||||
color=_colorFromHexString(sValue);
|
|
||||||
snprintf(colbuf, sizeof(colbuf), "0x%08x", color);
|
|
||||||
DBG_ERROR(NULL, "Send value [%s] to %s", colbuf, sValueSystemName);
|
|
||||||
rv=AQH_DataClient_SetData(dc, value, colbuf);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
||||||
GBAA(dbuf, "<p>Error setting value for %s</p>", sValueSystemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AQH_ValueModality_OnOff:
|
|
||||||
if (sValue) {
|
|
||||||
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");
|
|
||||||
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");
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AQH_ValueModality_OnOffAuto:
|
|
||||||
if (sValue) {
|
|
||||||
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");
|
|
||||||
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");
|
|
||||||
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");
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
GBAS(pbuf, "Location: /aqbt/devices/values.html?device=");
|
|
||||||
GWEN_Text_EscapeToBufferTolerant(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 AQH_VALUE_LIST *valueList, 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
|
|
||||||
"<th>Action</th>"
|
|
||||||
"</tr>"
|
|
||||||
"</thead>\n"
|
|
||||||
"<tbody>\n");
|
|
||||||
|
|
||||||
value=AQH_Value_List_First(valueList);
|
|
||||||
while(value) {
|
|
||||||
_writeValueToTable(value, dbuf);
|
|
||||||
value=AQH_Value_List_Next(value);
|
|
||||||
}
|
|
||||||
GBAS(dbuf,
|
|
||||||
"</tbody>\n"
|
|
||||||
"</table>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _writeValueToTable(const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
GBAS(dbuf, "<tr>");
|
|
||||||
|
|
||||||
s=AQH_Value_GetName(value);
|
|
||||||
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:"");
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
s=AQH_Value_GetDriver(value);
|
|
||||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
||||||
|
|
||||||
s=AQH_Value_GetDeviceNameForSystem(value);
|
|
||||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
||||||
|
|
||||||
s=AQH_Value_GetNameForSystem(value);
|
|
||||||
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GBAS(dbuf, "<td>");
|
|
||||||
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor)
|
|
||||||
_addValueActionToForm(value, dbuf);
|
|
||||||
GBAS(dbuf, "</td>");
|
|
||||||
|
|
||||||
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;
|
|
||||||
uint32_t colorOut;
|
|
||||||
|
|
||||||
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 */
|
|
||||||
colorOut=(colorIn & 0x00ff0000) | ((colorIn & 0x00ff00)<<16) | (colorIn & 0x0000ff);
|
|
||||||
return colorOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "./mroot_p.h"
|
#include "./mroot_p.h"
|
||||||
|
|
||||||
#include "aqhome-cgi/service/module.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 "aqhome-cgi/modules/common/madmin.h"
|
||||||
|
|
||||||
#include <gwenhywfar/debug.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;
|
AQH_SERVICE *sv;
|
||||||
|
|
||||||
@@ -35,6 +35,32 @@ AQH_SERVICE *AQH_Service_new(void)
|
|||||||
GWEN_INHERIT_INIT(AQH_SERVICE, sv);
|
GWEN_INHERIT_INIT(AQH_SERVICE, sv);
|
||||||
GWEN_LIST_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;
|
return sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,11 +72,44 @@ void AQH_Service_free(AQH_SERVICE *sv)
|
|||||||
GWEN_LIST_FINI(AQH_SERVICE, sv);
|
GWEN_LIST_FINI(AQH_SERVICE, sv);
|
||||||
GWEN_INHERIT_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);
|
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
|
#if 0
|
||||||
AQH_MODULE *AQH_Service_GetModuleByPath(const AQH_SERVICE *sv, const char *s)
|
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);
|
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);
|
int AQH_Service_HandleRequest(AQH_SERVICE *sv, AQCGI_REQUEST *req);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ struct AQH_SERVICE {
|
|||||||
GWEN_INHERIT_ELEMENT(AQH_SERVICE);
|
GWEN_INHERIT_ELEMENT(AQH_SERVICE);
|
||||||
GWEN_LIST_ELEMENT(AQH_SERVICE);
|
GWEN_LIST_ELEMENT(AQH_SERVICE);
|
||||||
|
|
||||||
|
char *baseUrl;
|
||||||
|
char *baseFolder;
|
||||||
|
char *runtimeFolder;
|
||||||
|
char *cacheFolder;
|
||||||
|
|
||||||
AQH_SERVICE_HANDLEREQUEST_FN handleRequestFn;
|
AQH_SERVICE_HANDLEREQUEST_FN handleRequestFn;
|
||||||
|
|
||||||
AQH_SERVICE_LOADUSER_FN loadUserFn;
|
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 *sv;
|
||||||
AQH_SERVICE_FILE *xs;
|
AQH_SERVICE_FILE *xs;
|
||||||
GWEN_BUFFER *dbuf;
|
GWEN_BUFFER *dbuf;
|
||||||
|
|
||||||
sv=AQH_Service_new();
|
sv=AQH_Service_new(baseFolder, baseUrl);
|
||||||
GWEN_NEW_OBJECT(AQH_SERVICE_FILE, xs);
|
GWEN_NEW_OBJECT(AQH_SERVICE_FILE, xs);
|
||||||
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv, xs, _freeData);
|
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv, xs, _freeData);
|
||||||
xs->baseFolder=strdup(baseFolder);
|
|
||||||
|
|
||||||
AQH_Service_SetLoadUserFn(sv, _loadUser);
|
AQH_Service_SetLoadUserFn(sv, _loadUser);
|
||||||
AQH_Service_SetSaveUserFn(sv, _saveUser);
|
AQH_Service_SetSaveUserFn(sv, _saveUser);
|
||||||
@@ -109,7 +108,7 @@ AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder)
|
|||||||
AQH_Service_SetListSessionsFn(sv, _listSessions);
|
AQH_Service_SetListSessionsFn(sv, _listSessions);
|
||||||
|
|
||||||
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
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));
|
DBG_ERROR(NULL, "Creating config mgr \"%s\"", GWEN_Buffer_GetStart(dbuf));
|
||||||
xs->configMgr=GWEN_ConfigMgr_Factory(GWEN_Buffer_GetStart(dbuf));
|
xs->configMgr=GWEN_ConfigMgr_Factory(GWEN_Buffer_GetStart(dbuf));
|
||||||
if (xs->configMgr==NULL) {
|
if (xs->configMgr==NULL) {
|
||||||
@@ -131,7 +130,6 @@ void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p)
|
|||||||
|
|
||||||
xs=(AQH_SERVICE_FILE*) p;
|
xs=(AQH_SERVICE_FILE*) p;
|
||||||
GWEN_ConfigMgr_free(xs->configMgr);
|
GWEN_ConfigMgr_free(xs->configMgr);
|
||||||
free(xs->baseFolder);
|
|
||||||
GWEN_FREE_OBJECT(xs);
|
GWEN_FREE_OBJECT(xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "aqhome-cgi/service/service.h"
|
#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.
|
* 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
|
* The license for this file can be found in the file COPYING which you
|
||||||
* should have received along with this file.
|
* should have received along with this file.
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
typedef struct AQH_SERVICE_FILE AQH_SERVICE_FILE;
|
typedef struct AQH_SERVICE_FILE AQH_SERVICE_FILE;
|
||||||
struct AQH_SERVICE_FILE {
|
struct AQH_SERVICE_FILE {
|
||||||
char *baseFolder;
|
|
||||||
GWEN_CONFIGMGR *configMgr;
|
GWEN_CONFIGMGR *configMgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,14 +42,15 @@
|
|||||||
* ------------------------------------------------------------------------------------------------
|
* ------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void _storeDatapoint(AQHOME_SERVER *xo, const AQH_VALUE *v, double valueData);
|
||||||
static AQH_MSG_REQUEST *_mkRequest_SetData(AQH_OBJECT *o,
|
static AQH_MSG_REQUEST *_mkRequest_SetData(AQH_OBJECT *o,
|
||||||
AQH_OBJECT *epSrc, uint32_t requestMsgId,
|
AQH_OBJECT *epSrc, uint32_t requestMsgId,
|
||||||
AQH_OBJECT *epDriver,
|
AQH_OBJECT *epDriver,
|
||||||
const AQH_VALUE *v, const char *data);
|
const AQH_VALUE *v, double data);
|
||||||
static void _rqSubRequestFinished(AQH_MSG_REQUEST *rq, AQH_MSG_REQUEST *subRq, int reason);
|
static void _rqSubRequestFinished(AQH_MSG_REQUEST *rq, AQH_MSG_REQUEST *subRq, int reason);
|
||||||
static void _rqAbort(AQH_MSG_REQUEST *rq, int reason);
|
static void _rqAbort(AQH_MSG_REQUEST *rq, int reason);
|
||||||
|
|
||||||
static AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, const char *data);
|
static AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, double data);
|
||||||
static int _subRqHandleResponse(AQH_MSG_REQUEST *rq, const AQH_MESSAGE *msg);
|
static int _subRqHandleResponse(AQH_MSG_REQUEST *rq, const AQH_MESSAGE *msg);
|
||||||
static void _subRqAbort(AQH_MSG_REQUEST *rq, int reason);
|
static void _subRqAbort(AQH_MSG_REQUEST *rq, int reason);
|
||||||
|
|
||||||
@@ -76,11 +77,11 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_
|
|||||||
recvdValue=AQH_IpcdMessageSetData_ReadValue(tagList);
|
recvdValue=AQH_IpcdMessageSetData_ReadValue(tagList);
|
||||||
if (recvdValue) {
|
if (recvdValue) {
|
||||||
const char *valueName;
|
const char *valueName;
|
||||||
char *valueDataFreeable;
|
double valueData;
|
||||||
AQH_VALUE *systemValue;
|
AQH_VALUE *systemValue;
|
||||||
|
|
||||||
valueName=AQH_Value_GetNameForSystem(recvdValue);
|
valueName=AQH_Value_GetNameForSystem(recvdValue);
|
||||||
valueDataFreeable=AQH_IpcdMessageSetData_ReadData(tagList);
|
valueData=AQH_IpcdMessageSetData_ReadData(tagList);
|
||||||
|
|
||||||
systemValue=AQH_Storage_GetValueByNameForSystem(xo->storage, valueName);
|
systemValue=AQH_Storage_GetValueByNameForSystem(xo->storage, valueName);
|
||||||
if (systemValue) {
|
if (systemValue) {
|
||||||
@@ -96,8 +97,10 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_
|
|||||||
AQH_MSG_REQUEST *rq;
|
AQH_MSG_REQUEST *rq;
|
||||||
|
|
||||||
DBG_ERROR(NULL, "Creating SETDATA request for driver endpoint (%s)", AQH_Endpoint_GetServiceName(epDriver));
|
DBG_ERROR(NULL, "Creating SETDATA request for driver endpoint (%s)", AQH_Endpoint_GetServiceName(epDriver));
|
||||||
rq=_mkRequest_SetData(o, epSrc, msgId, epDriver, systemValue, valueDataFreeable);
|
rq=_mkRequest_SetData(o, epSrc, msgId, epDriver, systemValue, valueData);
|
||||||
AqHomeDataServer_AddRequestToTree(o, rq);
|
AqHomeDataServer_AddRequestToTree(o, rq);
|
||||||
|
|
||||||
|
_storeDatapoint(xo, systemValue, valueData);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Driver \"%s\" not available", driverName);
|
DBG_ERROR(NULL, "Driver \"%s\" not available", driverName);
|
||||||
@@ -119,7 +122,6 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_
|
|||||||
AqHomeDataServer_SendResponseResultToEndpoint(epSrc, msgId, AQH_MSGDATA_RESULT_ERROR_NOTFOUND);
|
AqHomeDataServer_SendResponseResultToEndpoint(epSrc, msgId, AQH_MSGDATA_RESULT_ERROR_NOTFOUND);
|
||||||
}
|
}
|
||||||
AQH_Value_free(recvdValue);
|
AQH_Value_free(recvdValue);
|
||||||
free(valueDataFreeable);
|
|
||||||
} /* if recvdValue */
|
} /* if recvdValue */
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "No value in message");
|
DBG_ERROR(NULL, "No value in message");
|
||||||
@@ -131,6 +133,23 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _storeDatapoint(AQHOME_SERVER *xo, const AQH_VALUE *v, double valueData)
|
||||||
|
{
|
||||||
|
uint64_t timestamp;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
timestamp=(uint64_t) time(NULL);
|
||||||
|
rv=AQH_Storage_AddDatapoint(xo->storage, AQH_Value_GetId(v), timestamp, valueData);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_INFO(NULL, "Datapoint added for value \"%s\"", AQH_Value_GetNameForSystem(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* IPC Request SETDATA
|
* IPC Request SETDATA
|
||||||
*/
|
*/
|
||||||
@@ -138,7 +157,7 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_
|
|||||||
AQH_MSG_REQUEST *_mkRequest_SetData(AQH_OBJECT *o,
|
AQH_MSG_REQUEST *_mkRequest_SetData(AQH_OBJECT *o,
|
||||||
AQH_OBJECT *epSrc, uint32_t requestMsgId,
|
AQH_OBJECT *epSrc, uint32_t requestMsgId,
|
||||||
AQH_OBJECT *epDriver,
|
AQH_OBJECT *epDriver,
|
||||||
const AQH_VALUE *v, const char *data)
|
const AQH_VALUE *v, double data)
|
||||||
{
|
{
|
||||||
AQH_MSG_REQUEST *rq;
|
AQH_MSG_REQUEST *rq;
|
||||||
AQH_MSG_REQUEST *subRq;
|
AQH_MSG_REQUEST *subRq;
|
||||||
@@ -205,7 +224,7 @@ void _rqAbort(AQH_MSG_REQUEST *rq, int reason)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, const char *data)
|
AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, double data)
|
||||||
{
|
{
|
||||||
AQH_MSG_REQUEST *rq;
|
AQH_MSG_REQUEST *rq;
|
||||||
uint16_t msgId;
|
uint16_t msgId;
|
||||||
|
|||||||
@@ -30,8 +30,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *device,
|
static void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *device,
|
||||||
const char *valueName, const char *valueData);
|
const char *valueName, double valueData);
|
||||||
static void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData);
|
static void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo,
|
||||||
|
const AQHMQTT_DEVICE *device,
|
||||||
|
const AQHMQTT_TOPIC *topic,
|
||||||
|
const AQHMQTT_VALUE *value,
|
||||||
|
double valueData);
|
||||||
|
static const char *_valueTranslatedForDriver(const AQHMQTT_VALUE *value, double valueData);
|
||||||
static GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic);
|
static GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic);
|
||||||
|
|
||||||
|
|
||||||
@@ -65,12 +70,11 @@ void AQH_MqttLogServer_HandleSetData(AQH_OBJECT *o,
|
|||||||
|
|
||||||
device=AQH_MqttLogServer_FindRegisteredDevice(o, deviceName);
|
device=AQH_MqttLogServer_FindRegisteredDevice(o, deviceName);
|
||||||
if (device) {
|
if (device) {
|
||||||
char *valueDataFreeable;
|
double valueData;
|
||||||
|
|
||||||
DBG_ERROR(NULL, "Sending data to value \"%s\" of device \"%s\"", valueName, deviceName);
|
DBG_ERROR(NULL, "Sending data to value \"%s\" of device \"%s\"", valueName, deviceName);
|
||||||
valueDataFreeable=AQH_IpcdMessageSetData_ReadData(tagList);
|
valueData=AQH_IpcdMessageSetData_ReadData(tagList);
|
||||||
_sendDataForDevice(xo, device, valueName, valueDataFreeable);
|
_sendDataForDevice(xo, device, valueName, valueData);
|
||||||
free(valueDataFreeable);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Device \"%s\" not found", deviceName);
|
DBG_ERROR(NULL, "Device \"%s\" not found", deviceName);
|
||||||
@@ -93,7 +97,7 @@ void AQH_MqttLogServer_HandleSetData(AQH_OBJECT *o,
|
|||||||
|
|
||||||
void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo,
|
void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo,
|
||||||
const AQHMQTT_DEVICE *device,
|
const AQHMQTT_DEVICE *device,
|
||||||
const char *valueName, const char *valueData)
|
const char *valueName, double valueData)
|
||||||
{
|
{
|
||||||
const char *deviceId;
|
const char *deviceId;
|
||||||
|
|
||||||
@@ -116,7 +120,7 @@ void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo,
|
|||||||
if (value) {
|
if (value) {
|
||||||
/* found value, create publish msg, send */
|
/* found value, create publish msg, send */
|
||||||
DBG_ERROR(NULL, "Topic \"%s\" contains value \"%s\"", AQHMQTT_Topic_GetName(topic), valueName);
|
DBG_ERROR(NULL, "Topic \"%s\" contains value \"%s\"", AQHMQTT_Topic_GetName(topic), valueName);
|
||||||
_sendValueToMqtt(xo, deviceId, topic, valueData);
|
_sendValueToMqtt(xo, device, topic, value, valueData);
|
||||||
}
|
}
|
||||||
} /* if out */
|
} /* if out */
|
||||||
topic=AQHMQTT_Topic_List_Next(topic);
|
topic=AQHMQTT_Topic_List_Next(topic);
|
||||||
@@ -130,32 +134,82 @@ void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData)
|
void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo,
|
||||||
|
const AQHMQTT_DEVICE *device,
|
||||||
|
const AQHMQTT_TOPIC *topic,
|
||||||
|
const AQHMQTT_VALUE *value,
|
||||||
|
double valueData)
|
||||||
{
|
{
|
||||||
|
const char *deviceId;
|
||||||
|
const char *translatedValue;
|
||||||
GWEN_BUFFER *buf;
|
GWEN_BUFFER *buf;
|
||||||
#if !DEBUG_DRY_RUN
|
#if !DEBUG_DRY_RUN
|
||||||
AQH_MESSAGE *msgOut;
|
AQH_MESSAGE *msgOut;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
deviceId=AQHMQTT_Device_GetId(device);
|
||||||
buf=_createBufferForTopic(deviceId, topic);
|
buf=_createBufferForTopic(deviceId, topic);
|
||||||
|
translatedValue=_valueTranslatedForDriver(value, valueData);
|
||||||
|
if (translatedValue && *translatedValue) {
|
||||||
|
DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), translatedValue);
|
||||||
|
msgOut=AQH_MqttMessagePublish_new(0, 0, GWEN_Buffer_GetStart(buf), (const uint8_t*)translatedValue, strlen(translatedValue));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GWEN_BUFFER *vbuf;
|
||||||
|
|
||||||
|
vbuf=GWEN_Buffer_new(0, 64, 0, 1);
|
||||||
|
GWEN_Buffer_AppendArgs(vbuf, "%f", valueData);
|
||||||
|
DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetStart(vbuf));
|
||||||
|
msgOut=AQH_MqttMessagePublish_new(0, 0,
|
||||||
|
GWEN_Buffer_GetStart(buf),
|
||||||
|
(const uint8_t*)GWEN_Buffer_GetStart(vbuf),
|
||||||
|
GWEN_Buffer_GetUsedBytes(vbuf));
|
||||||
|
GWEN_Buffer_free(vbuf);
|
||||||
|
}
|
||||||
|
|
||||||
#if !DEBUG_DRY_RUN
|
#if !DEBUG_DRY_RUN
|
||||||
DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), valueData?valueData:"<empty>");
|
|
||||||
msgOut=AQH_MqttMessagePublish_new(0, 0, GWEN_Buffer_GetStart(buf),
|
|
||||||
(const uint8_t*) (valueData?valueData:NULL),
|
|
||||||
valueData?strlen(valueData):0);
|
|
||||||
if (msgOut)
|
if (msgOut)
|
||||||
AQH_Endpoint_AddMsgOut(xo->mqttEndpoint, msgOut);
|
AQH_Endpoint_AddMsgOut(xo->mqttEndpoint, msgOut);
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Error creating message");
|
DBG_ERROR(NULL, "Error creating message");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
DBG_ERROR(NULL, "Would MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), valueData?valueData:"<empty>");
|
|
||||||
#endif
|
#endif
|
||||||
GWEN_Buffer_free(buf);
|
GWEN_Buffer_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *_valueTranslatedForDriver(const AQHMQTT_VALUE *value, double valueData)
|
||||||
|
{
|
||||||
|
const AQHMQTT_TRANSLATION_LIST *translationList;
|
||||||
|
|
||||||
|
translationList=AQHMQTT_Value_GetTranslationList(value);
|
||||||
|
if (translationList) {
|
||||||
|
const AQHMQTT_TRANSLATION *t;
|
||||||
|
int valueAsInt;
|
||||||
|
|
||||||
|
valueAsInt=(int) valueData;
|
||||||
|
t=AQHMQTT_Translation_List_GetByAqhValue(translationList, valueAsInt);
|
||||||
|
if (t) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s=AQHMQTT_Translation_GetDriverValue(t);
|
||||||
|
DBG_ERROR(NULL, "Translated value %d to %s", valueAsInt, s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "No translation found for %d", valueAsInt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "No translation list");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic)
|
GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic)
|
||||||
{
|
{
|
||||||
GWEN_BUFFER *buf;
|
GWEN_BUFFER *buf;
|
||||||
|
|||||||
@@ -32,18 +32,18 @@
|
|||||||
|
|
||||||
<members>
|
<members>
|
||||||
|
|
||||||
<member name="aqhValue" type="char_ptr" maxlen="128">
|
<member name="aqhValue" type="int" maxlen="8">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>own</flags>
|
<flags>with_getByMember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="driverValue" type="char_ptr" maxlen="128">
|
<member name="driverValue" type="char_ptr" maxlen="128">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>own</flags>
|
<flags>own with_getByMember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ static AQHMQTT_TRANSLATION *_readXmlTranslation(GWEN_XMLNODE *translationNode);
|
|||||||
|
|
||||||
AQHMQTT_DEVICE_LIST *AQH_MqttLogServer_ReadDeviceFile(AQH_OBJECT *o, const char *sFilename)
|
AQHMQTT_DEVICE_LIST *AQH_MqttLogServer_ReadDeviceFile(AQH_OBJECT *o, const char *sFilename)
|
||||||
{
|
{
|
||||||
|
DBG_ERROR(NULL, "Reading device file \"%s\"", sFilename);
|
||||||
if (o) {
|
if (o) {
|
||||||
AQH_MQTTLOG_SERVER *xo;
|
AQH_MQTTLOG_SERVER *xo;
|
||||||
|
|
||||||
@@ -390,13 +391,15 @@ AQHMQTT_VALUE_LIST *_readXmlValueList(GWEN_XMLNODE *parentNode)
|
|||||||
|
|
||||||
AQHMQTT_VALUE *_readXmlValue(GWEN_XMLNODE *valueNode)
|
AQHMQTT_VALUE *_readXmlValue(GWEN_XMLNODE *valueNode)
|
||||||
{
|
{
|
||||||
|
const char *sValueName;
|
||||||
AQHMQTT_VALUE *value;
|
AQHMQTT_VALUE *value;
|
||||||
GWEN_XMLNODE *translationNode;
|
GWEN_XMLNODE *translationNode;
|
||||||
const char *s;
|
const char *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
sValueName=GWEN_XMLNode_GetProperty(valueNode, "name", NULL);
|
||||||
value=AQHMQTT_Value_new();
|
value=AQHMQTT_Value_new();
|
||||||
AQHMQTT_Value_SetName(value, GWEN_XMLNode_GetProperty(valueNode, "name", NULL));
|
AQHMQTT_Value_SetName(value, sValueName);
|
||||||
AQHMQTT_Value_SetValueUnits(value, GWEN_XMLNode_GetProperty(valueNode, "units", NULL));
|
AQHMQTT_Value_SetValueUnits(value, GWEN_XMLNode_GetProperty(valueNode, "units", NULL));
|
||||||
AQHMQTT_Value_SetPath(value, GWEN_XMLNode_GetProperty(valueNode, "path", NULL));
|
AQHMQTT_Value_SetPath(value, GWEN_XMLNode_GetProperty(valueNode, "path", NULL));
|
||||||
|
|
||||||
@@ -415,12 +418,12 @@ AQHMQTT_VALUE *_readXmlValue(GWEN_XMLNODE *valueNode)
|
|||||||
|
|
||||||
translationList=_readXmlTranslationList(translationNode);
|
translationList=_readXmlTranslationList(translationNode);
|
||||||
if (translationList) {
|
if (translationList) {
|
||||||
DBG_INFO(NULL, "Translations read");
|
DBG_ERROR(NULL, "Translations read for value \"%s\"", sValueName);
|
||||||
AQHMQTT_Value_SetTranslationList(value, translationList);
|
AQHMQTT_Value_SetTranslationList(value, translationList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_INFO(NULL, "No <translations> element");
|
DBG_ERROR(NULL, "No <translations> element in value %s", sValueName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@@ -440,7 +443,7 @@ AQHMQTT_TRANSLATION_LIST *_readXmlTranslationList(GWEN_XMLNODE *parentNode)
|
|||||||
if (translation)
|
if (translation)
|
||||||
AQHMQTT_Translation_List_Add(translation, translationList);
|
AQHMQTT_Translation_List_Add(translation, translationList);
|
||||||
else {
|
else {
|
||||||
DBG_INFO(NULL, "Error reading <translation> element");
|
DBG_ERROR(NULL, "Error reading <translation> element");
|
||||||
AQHMQTT_Translation_List_free(translationList);
|
AQHMQTT_Translation_List_free(translationList);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -458,16 +461,16 @@ AQHMQTT_TRANSLATION_LIST *_readXmlTranslationList(GWEN_XMLNODE *parentNode)
|
|||||||
|
|
||||||
AQHMQTT_TRANSLATION *_readXmlTranslation(GWEN_XMLNODE *translationNode)
|
AQHMQTT_TRANSLATION *_readXmlTranslation(GWEN_XMLNODE *translationNode)
|
||||||
{
|
{
|
||||||
const char *sAqhValue;
|
int aqhValue;
|
||||||
const char *sDriverValue;
|
const char *sDriverValue;
|
||||||
|
|
||||||
sAqhValue=GWEN_XMLNode_GetProperty(translationNode, "aqhValue", NULL);
|
aqhValue=GWEN_XMLNode_GetIntProperty(translationNode, "aqhValue", 0);
|
||||||
sDriverValue=GWEN_XMLNode_GetProperty(translationNode, "driverValue", NULL);
|
sDriverValue=GWEN_XMLNode_GetProperty(translationNode, "driverValue", NULL);
|
||||||
if (sAqhValue && *sAqhValue && sDriverValue && *sDriverValue) {
|
if (sDriverValue && *sDriverValue) {
|
||||||
AQHMQTT_TRANSLATION *translation;
|
AQHMQTT_TRANSLATION *translation;
|
||||||
|
|
||||||
translation=AQHMQTT_Translation_new();
|
translation=AQHMQTT_Translation_new();
|
||||||
AQHMQTT_Translation_SetAqhValue(translation, sAqhValue);
|
AQHMQTT_Translation_SetAqhValue(translation, aqhValue);
|
||||||
AQHMQTT_Translation_SetDriverValue(translation, sDriverValue);
|
AQHMQTT_Translation_SetDriverValue(translation, sDriverValue);
|
||||||
return translation;
|
return translation;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ void _writeValueToXml(const AQHMQTT_VALUE *value, GWEN_XMLNODE *node)
|
|||||||
|
|
||||||
void _writeTranslationToXml(const AQHMQTT_TRANSLATION *t, GWEN_XMLNODE *nTranslation)
|
void _writeTranslationToXml(const AQHMQTT_TRANSLATION *t, GWEN_XMLNODE *nTranslation)
|
||||||
{
|
{
|
||||||
_setXmlPropertyIfNotNull(nTranslation, "aqhValue", AQHMQTT_Translation_GetAqhValue(t));
|
GWEN_XMLNode_SetIntProperty(nTranslation, "aqhValue", AQHMQTT_Translation_GetAqhValue(t));
|
||||||
_setXmlPropertyIfNotNull(nTranslation, "driverValue", AQHMQTT_Translation_GetDriverValue(t));
|
_setXmlPropertyIfNotNull(nTranslation, "driverValue", AQHMQTT_Translation_GetDriverValue(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,69 +92,61 @@ void AQH_NodeServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSA
|
|||||||
|
|
||||||
varName=AQH_Value_GetName(value);
|
varName=AQH_Value_GetName(value);
|
||||||
if (varName) {
|
if (varName) {
|
||||||
char *data;
|
double data;
|
||||||
|
AQH_NODE_INFO *nodeInfo;
|
||||||
|
|
||||||
data=AQH_IpcdMessageSetData_ReadData(tagList);
|
data=AQH_IpcdMessageSetData_ReadData(tagList);
|
||||||
if (data) {
|
nodeInfo=_getNodeInfoFromValue(xo, value);
|
||||||
AQH_NODE_INFO *nodeInfo;
|
if (nodeInfo) {
|
||||||
|
const char *devName;
|
||||||
|
|
||||||
nodeInfo=_getNodeInfoFromValue(xo, value);
|
devName=AQH_NodeInfo_GetDeviceId(nodeInfo);
|
||||||
if (nodeInfo) {
|
if (devName) {
|
||||||
const char *devName;
|
const AQHNODE_DEVICE *devInfo;
|
||||||
|
|
||||||
devName=AQH_NodeInfo_GetDeviceId(nodeInfo);
|
devInfo=AQH_NodeServer_GetDeviceDefByName(o, devName);
|
||||||
if (devName) {
|
if (devInfo) {
|
||||||
const AQHNODE_DEVICE *devInfo;
|
const AQHNODE_VALUE *devValue;
|
||||||
|
|
||||||
devInfo=AQH_NodeServer_GetDeviceDefByName(o, devName);
|
devValue=AQHNODE_Value_List_GetByName(AQHNODE_Device_GetValueList(devInfo), varName);
|
||||||
if (devInfo) {
|
if (devValue) {
|
||||||
const AQHNODE_VALUE *devValue;
|
uint16_t dataVal=0;
|
||||||
|
uint16_t dataDenom=0;
|
||||||
|
|
||||||
devValue=AQHNODE_Value_List_GetByName(AQHNODE_Device_GetValueList(devInfo), varName);
|
if (AQH_ReadDataFromDouble(AQHNODE_Value_GetDataType(devValue), data, &dataVal, &dataDenom)==0) {
|
||||||
if (devValue) {
|
AQH_MSG_REQUEST *rq;
|
||||||
uint16_t dataVal=0;
|
int destAddr;
|
||||||
uint16_t dataDenom=0;
|
|
||||||
|
|
||||||
if (AQH_ReadDataFromString(AQHNODE_Value_GetDataType(devValue), data, &dataVal, &dataDenom)==0) {
|
destAddr=AQH_NodeInfo_GetBusAddress(nodeInfo);
|
||||||
AQH_MSG_REQUEST *rq;
|
DBG_DEBUG(NULL, "Creating SETDATA request");
|
||||||
int destAddr;
|
|
||||||
|
|
||||||
destAddr=AQH_NodeInfo_GetBusAddress(nodeInfo);
|
rq=_mkRequest_SetData(o, xo, ep, msgId, destAddr, AQHNODE_Value_GetId(devValue), dataVal, dataDenom);
|
||||||
DBG_DEBUG(NULL, "Creating SETDATA request");
|
AQH_NodeServer_AddRequestToTree(o, rq);
|
||||||
|
/* done */
|
||||||
rq=_mkRequest_SetData(o, xo, ep, msgId, destAddr, AQHNODE_Value_GetId(devValue), dataVal, dataDenom);
|
|
||||||
AQH_NodeServer_AddRequestToTree(o, rq);
|
|
||||||
/* done */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DBG_ERROR(NULL, "Bad data \"%s\"", data);
|
|
||||||
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_BADDATA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Invalid value name \"%s\"", varName);
|
DBG_ERROR(NULL, "Bad data \"%.2f\"", data);
|
||||||
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID);
|
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_BADDATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Unknown node \"%s\"", devName);
|
DBG_ERROR(NULL, "Invalid value name \"%s\"", varName);
|
||||||
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID);
|
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Node not yet fully identified, come back later");
|
DBG_ERROR(NULL, "Unknown node \"%s\"", devName);
|
||||||
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_TRYAGAIN);
|
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "No matching nodeinfo");
|
DBG_ERROR(NULL, "Node not yet fully identified, come back later");
|
||||||
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID);
|
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_TRYAGAIN);
|
||||||
}
|
}
|
||||||
free(data);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "No data");
|
DBG_ERROR(NULL, "No matching nodeinfo");
|
||||||
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_NODATA);
|
_sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -26,15 +26,6 @@
|
|||||||
|
|
||||||
<unit id="and1" type="and" />
|
<unit id="and1" type="and" />
|
||||||
|
|
||||||
<unit id="zeroPosNegString1" type="zeroPosNegString">
|
|
||||||
<params>
|
|
||||||
<param name="valueIfNegative">OFF</param>
|
|
||||||
<param name="valueIfZero">OFF</param>
|
|
||||||
<param name="valueIfPositive">ON</param>
|
|
||||||
</params>
|
|
||||||
</unit>
|
|
||||||
|
|
||||||
|
|
||||||
<unit id="valueSetOutPlug1" type="valueSet">
|
<unit id="valueSetOutPlug1" type="valueSet">
|
||||||
<params>
|
<params>
|
||||||
<param name="valueName">mqtt/109C2F/power</param>
|
<param name="valueName">mqtt/109C2F/power</param>
|
||||||
@@ -49,7 +40,6 @@
|
|||||||
<link sourceUnit=".timer" sourcePort="output" targetUnit="suntime1" targetPort="timer" />
|
<link sourceUnit=".timer" sourcePort="output" targetUnit="suntime1" targetPort="timer" />
|
||||||
<link sourceUnit="suntime1" sourcePort="output" targetUnit="and1" targetPort="input" />
|
<link sourceUnit="suntime1" sourcePort="output" targetUnit="and1" targetPort="input" />
|
||||||
<link sourceUnit="delayedOff1" sourcePort="output" targetUnit="and1" targetPort="input" />
|
<link sourceUnit="delayedOff1" sourcePort="output" targetUnit="and1" targetPort="input" />
|
||||||
<link sourceUnit="and1" sourcePort="output" targetUnit="zeroPosNegString1" targetPort="input" />
|
<link sourceUnit="and1" sourcePort="output" targetUnit="valueSetOutPlug1" targetPort="input" />
|
||||||
<link sourceUnit="zeroPosNegString1" sourcePort="output" targetUnit="valueSetOutPlug1" targetPort="input" />
|
|
||||||
</links>
|
</links>
|
||||||
</network>
|
</network>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</inputPorts>
|
</inputPorts>
|
||||||
|
|
||||||
<outputPorts>
|
<outputPorts>
|
||||||
<outputPort name="output" dataType="string" />
|
<outputPort name="output" dataType="double" />
|
||||||
</outputPorts>
|
</outputPorts>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -349,13 +349,35 @@ const char *_readDouble(const char *s, double *ptrDouble)
|
|||||||
while(*s && isspace(*s))
|
while(*s && isspace(*s))
|
||||||
s++;
|
s++;
|
||||||
sStart=s;
|
sStart=s;
|
||||||
while(*s && (isdigit(*s) || *s=='.' || *s=='+' || *s=='-'))
|
if (*s=='#') {
|
||||||
s++;
|
uint32_t v=0;
|
||||||
|
|
||||||
rv=GWEN_Text_StringToDouble(sStart, ptrDouble);
|
s++;
|
||||||
if (rv<0) {
|
while(*s) {
|
||||||
DBG_ERROR(NULL, "Error reading double: %d", rv);
|
unsigned char c;
|
||||||
return NULL;
|
|
||||||
|
c=tolower(*s);
|
||||||
|
if ((c>='0' && c<='9') || (c>='a' && c<='f')) {
|
||||||
|
c-='0';
|
||||||
|
if (c>9)
|
||||||
|
c-=7;
|
||||||
|
v<<=4;
|
||||||
|
v+=c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*ptrDouble=(double) v;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while(*s && (isdigit(*s) || *s=='.' || *s=='+' || *s=='-'))
|
||||||
|
s++;
|
||||||
|
rv=GWEN_Text_StringToDouble(sStart, ptrDouble);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "Error reading double: %d", rv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
|
static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject);
|
||||||
static AQH_MESSAGE *_mkSetDataMsgString(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject);
|
|
||||||
static AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject);
|
static AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject);
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +61,7 @@ AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQH_OBJECT *aqh)
|
|||||||
port=AQHREACT_Port_new();
|
port=AQHREACT_Port_new();
|
||||||
AQHREACT_Port_SetName(port, "input");
|
AQHREACT_Port_SetName(port, "input");
|
||||||
AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE);
|
AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE);
|
||||||
AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_STRING);
|
AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE);
|
||||||
AQHREACT_Unit_AddInputPort(unit, port);
|
AQHREACT_Unit_AddInputPort(unit, port);
|
||||||
|
|
||||||
param=AQHREACT_Param_new();
|
param=AQHREACT_Param_new();
|
||||||
@@ -92,9 +91,6 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO
|
|||||||
case AQHREACT_DATAOBJECTTYPE_DOUBLE:
|
case AQHREACT_DATAOBJECTTYPE_DOUBLE:
|
||||||
msgOut=_mkSetDataMsgDouble(brokerEndpoint, sValueName, dataObject);
|
msgOut=_mkSetDataMsgDouble(brokerEndpoint, sValueName, dataObject);
|
||||||
break;
|
break;
|
||||||
case AQHREACT_DATAOBJECTTYPE_STRING:
|
|
||||||
msgOut=_mkSetDataMsgString(brokerEndpoint, sValueName, dataObject);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
DBG_ERROR(NULL, "Unhandled data type (%d)", AQHREACT_DataObject_GetDataType(dataObject));
|
DBG_ERROR(NULL, "Unhandled data type (%d)", AQHREACT_DataObject_GetDataType(dataObject));
|
||||||
msgOut=NULL;
|
msgOut=NULL;
|
||||||
@@ -130,47 +126,20 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MESSAGE *_mkSetDataMsgString(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject)
|
|
||||||
{
|
|
||||||
AQH_MESSAGE *msgOut;
|
|
||||||
AQH_VALUE *v;
|
|
||||||
|
|
||||||
v=AQH_Value_new();
|
|
||||||
AQH_Value_SetNameForSystem(v, sValueName);
|
|
||||||
|
|
||||||
msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA,
|
|
||||||
AQH_Endpoint_GetNextMessageId(brokerEndpoint), 0,
|
|
||||||
v, AQHREACT_DataObject_GetStringData(dataObject));
|
|
||||||
AQH_Value_free(v);
|
|
||||||
return msgOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject)
|
AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject)
|
||||||
{
|
{
|
||||||
AQH_MESSAGE *msgOut;
|
AQH_MESSAGE *msgOut;
|
||||||
AQH_VALUE *v;
|
AQH_VALUE *v;
|
||||||
double data;
|
double data;
|
||||||
GWEN_BUFFER *buf;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
v=AQH_Value_new();
|
v=AQH_Value_new();
|
||||||
AQH_Value_SetNameForSystem(v, sValueName);
|
AQH_Value_SetNameForSystem(v, sValueName);
|
||||||
|
|
||||||
data=AQHREACT_DataObject_GetDoubleData(dataObject);
|
data=AQHREACT_DataObject_GetDoubleData(dataObject);
|
||||||
buf=GWEN_Buffer_new(0, 64, 0, 1);
|
|
||||||
rv=GWEN_Text_DoubleToBuffer(data, buf);
|
|
||||||
if (rv<0) {
|
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
AQH_Value_free(v);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA,
|
msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA,
|
||||||
AQH_Endpoint_GetNextMessageId(brokerEndpoint), 0,
|
AQH_Endpoint_GetNextMessageId(brokerEndpoint), 0,
|
||||||
v, GWEN_Buffer_GetStart(buf));
|
v, data);
|
||||||
GWEN_Buffer_free(buf);
|
|
||||||
AQH_Value_free(v);
|
AQH_Value_free(v);
|
||||||
return msgOut;
|
return msgOut;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static AQH_MESSAGE *_createRequestMessage(AQH_OBJECT *o, uint32_t msgId);
|
static AQH_MESSAGE *_createRequestMessage(AQH_OBJECT *o, uint32_t msgId);
|
||||||
|
static int _readValueFromString(const char *s, double *pDouble);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -93,18 +94,30 @@ AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId)
|
|||||||
GWEN_DB_NODE *dbArgs;
|
GWEN_DB_NODE *dbArgs;
|
||||||
const char *valueName;
|
const char *valueName;
|
||||||
const char *valueUnits;
|
const char *valueUnits;
|
||||||
const char *valueData;
|
const char *valueDataAsString;
|
||||||
|
double valueData;
|
||||||
AQH_VALUE *v;
|
AQH_VALUE *v;
|
||||||
|
int rv;
|
||||||
|
|
||||||
dbArgs=AQH_ToolClient_GetDbLocalArgs(o);
|
dbArgs=AQH_ToolClient_GetDbLocalArgs(o);
|
||||||
valueName=GWEN_DB_GetCharValue(dbArgs, "valueName", 0, NULL);
|
valueName=GWEN_DB_GetCharValue(dbArgs, "valueName", 0, NULL);
|
||||||
valueUnits=GWEN_DB_GetCharValue(dbArgs, "valueUnits", 0, NULL);
|
valueUnits=GWEN_DB_GetCharValue(dbArgs, "valueUnits", 0, NULL);
|
||||||
valueData=GWEN_DB_GetCharValue(dbArgs, "value", 0, NULL);
|
valueDataAsString=GWEN_DB_GetCharValue(dbArgs, "value", 0, NULL);
|
||||||
|
|
||||||
|
if (valueDataAsString && *valueDataAsString) {
|
||||||
|
rv=_readValueFromString(valueDataAsString, &valueData);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "ERROR: Bad value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(valueName && *valueName)) {
|
if (!(valueName && *valueName)) {
|
||||||
DBG_ERROR(NULL, "ERROR: Missing value name");
|
DBG_ERROR(NULL, "ERROR: Missing value name");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
v=AQH_Value_new();
|
v=AQH_Value_new();
|
||||||
AQH_Value_SetNameForSystem(v, valueName);
|
AQH_Value_SetNameForSystem(v, valueName);
|
||||||
AQH_Value_SetValueUnits(v, valueUnits);
|
AQH_Value_SetValueUnits(v, valueUnits);
|
||||||
@@ -116,3 +129,40 @@ AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readValueFromString(const char *s, double *pDouble)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
|
||||||
|
l=strlen(s);
|
||||||
|
if (l) {
|
||||||
|
if (*s=='#') {
|
||||||
|
unsigned int h;
|
||||||
|
|
||||||
|
if (1==sscanf(s+1, "%x", &h)) {
|
||||||
|
*pDouble=(double) h;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (l>1 && s[0]=='0' && ((tolower(s[1])=='x') || tolower(s[1])=='b')) {
|
||||||
|
unsigned int h;
|
||||||
|
|
||||||
|
if (1==sscanf(s, "%u", &h)) {
|
||||||
|
*pDouble=(double) h;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
double d;
|
||||||
|
|
||||||
|
if (1==sscanf(s, "%lf", &d)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG_ERROR(NULL, "Bad value \"%s\"", s);
|
||||||
|
return GWEN_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ static void _definePath(const char *pathName, const char *pathValue);
|
|||||||
static GWEN_STRINGLIST *_getListOfMatchingFiles(const char *pathName, const char *subFolder, const char *mask);
|
static GWEN_STRINGLIST *_getListOfMatchingFiles(const char *pathName, const char *subFolder, const char *mask);
|
||||||
static GWEN_BUFFER *_getRuntimeFilePath(const char *pathName, const char *sFilename);
|
static GWEN_BUFFER *_getRuntimeFilePath(const char *pathName, const char *sFilename);
|
||||||
static GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename);
|
static GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename);
|
||||||
|
static int _readUint8DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
|
static int _readUint16DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
|
static int _readUint32DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
|
|
||||||
static int _readUint8DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
static int _readUint8DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
static int _readUint16DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
static int _readUint16DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
static int _readUint32DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
static int _readUint32DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
@@ -469,6 +473,59 @@ GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_ReadDataFromDouble(int dataType, double d, uint16_t *pDataVal, uint16_t *pDataDenom)
|
||||||
|
{
|
||||||
|
switch(dataType) {
|
||||||
|
case AQH_ValueDataType_Uint8: return _readUint8DataFromDouble(d, pDataVal, pDataDenom);
|
||||||
|
case AQH_ValueDataType_Int:
|
||||||
|
case AQH_ValueDataType_Uint16: return _readUint16DataFromDouble(d, pDataVal, pDataDenom);
|
||||||
|
case AQH_ValueDataType_Uint32: return _readUint32DataFromDouble(d, pDataVal, pDataDenom);
|
||||||
|
case AQH_ValueDataType_Rational: break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GWEN_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readUint8DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom)
|
||||||
|
{
|
||||||
|
uint8_t v;
|
||||||
|
|
||||||
|
v=((uint8_t) (d)) & 0xff;
|
||||||
|
*pDataVal=v & 0xff;
|
||||||
|
*pDataDenom=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readUint16DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom)
|
||||||
|
{
|
||||||
|
uint16_t v;
|
||||||
|
|
||||||
|
v=((uint16_t) d) & 0xffff;
|
||||||
|
*pDataVal=v;
|
||||||
|
*pDataDenom=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readUint32DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom)
|
||||||
|
{
|
||||||
|
uint32_t v;
|
||||||
|
|
||||||
|
v=((uint32_t) d) & 0xffffffff;
|
||||||
|
|
||||||
|
*pDataVal=(v>>16) & 0xffff;
|
||||||
|
*pDataDenom=v & 0xffff;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_ReadDataFromString(int dataType, const char *s, uint16_t *pDataVal, uint16_t *pDataDenom)
|
int AQH_ReadDataFromString(int dataType, const char *s, uint16_t *pDataVal, uint16_t *pDataDenom)
|
||||||
{
|
{
|
||||||
if (s && *s) {
|
if (s && *s) {
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ AQHOME_API int AQH_ValueModality_fromString(const char *s);
|
|||||||
AQHOME_API const char *AQH_ValueModality_toString(int i);
|
AQHOME_API const char *AQH_ValueModality_toString(int i);
|
||||||
|
|
||||||
AQHOME_API int AQH_ReadDataFromString(int dataType, const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
AQHOME_API int AQH_ReadDataFromString(int dataType, const char *s, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
|
AQHOME_API int AQH_ReadDataFromDouble(int dataType, double d, uint16_t *pDataVal, uint16_t *pDataDenom);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -404,7 +404,6 @@ uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t
|
|||||||
uint64_t *arrayPtr;
|
uint64_t *arrayPtr;
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
|
|
||||||
DBG_ERROR(NULL, "Requested %d entries", (int) maxDataPointsRequested);
|
|
||||||
df=_getDataFileByValueId(sto, valueId);
|
df=_getDataFileByValueId(sto, valueId);
|
||||||
if (df==NULL) {
|
if (df==NULL) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No file for value id %lu", (unsigned long int) valueId);
|
DBG_ERROR(AQH_LOGDOMAIN, "No file for value id %lu", (unsigned long int) valueId);
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ uint64_t AQH_DataClient_GetPeriodData(AQH_DATACLIENT *dc, const char *valueName,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, const char *data)
|
int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, double data)
|
||||||
{
|
{
|
||||||
if (dc) {
|
if (dc) {
|
||||||
AQH_MESSAGE *msgOut;
|
AQH_MESSAGE *msgOut;
|
||||||
@@ -379,6 +379,24 @@ int AQH_DataClient_UpdateData(AQH_DATACLIENT *dc, const AQH_VALUE *v, uint64_t t
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_DataClient_ModDevice(AQH_DATACLIENT *dc, const AQH_DEVICE *d)
|
||||||
|
{
|
||||||
|
if (dc) {
|
||||||
|
AQH_MESSAGE *msgOut;
|
||||||
|
uint32_t msgId;
|
||||||
|
|
||||||
|
msgId=++(dc->lastMsgId);
|
||||||
|
msgOut=AQH_IpcdMessageDevices_newForOneDevice(AQH_MSGTYPE_IPC_DATA_MODDEVICE_REQ, msgId, 0, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG, d);
|
||||||
|
AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut);
|
||||||
|
|
||||||
|
return _handleResult(dc, msgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GWEN_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,9 @@ AQHOME_API uint64_t AQH_DataClient_GetPeriodData(AQH_DATACLIENT *dc, const char
|
|||||||
uint64_t *dataPtr, uint64_t maxNum,
|
uint64_t *dataPtr, uint64_t maxNum,
|
||||||
uint64_t tsBegin, uint64_t tsEnd);
|
uint64_t tsBegin, uint64_t tsEnd);
|
||||||
|
|
||||||
AQHOME_API int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, const char *data);
|
AQHOME_API int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, double data);
|
||||||
AQHOME_API int AQH_DataClient_UpdateData(AQH_DATACLIENT *dc, const AQH_VALUE *v, uint64_t timeStamp, double dataPoint);
|
AQHOME_API int AQH_DataClient_UpdateData(AQH_DATACLIENT *dc, const AQH_VALUE *v, uint64_t timeStamp, double dataPoint);
|
||||||
|
AQHOME_API int AQH_DataClient_ModDevice(AQH_DATACLIENT *dc, const AQH_DEVICE *d);
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_DataClient_ReadLocalArgs(AQH_DATACLIENT *dc,
|
AQHOME_API int AQH_DataClient_ReadLocalArgs(AQH_DATACLIENT *dc,
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ int AQH_FdObject_Read(AQH_OBJECT *o, uint8_t *ptrBuffer, uint32_t lenBuffer)
|
|||||||
return GWEN_ERROR_TRY_AGAIN;
|
return GWEN_ERROR_TRY_AGAIN;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error on read: %s (%d)", strerror(errno), errno);
|
DBG_INFO(AQH_LOGDOMAIN, "Error on read(%d): %s (%d)", xo->fd, strerror(errno), errno);
|
||||||
close(xo->fd);
|
close(xo->fd);
|
||||||
xo->fd=-1;
|
xo->fd=-1;
|
||||||
return GWEN_ERROR_IO;
|
return GWEN_ERROR_IO;
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ int _handleMsgSent(AQH_OBJECT *o)
|
|||||||
if (xo) {
|
if (xo) {
|
||||||
AQH_MESSAGE *msg;
|
AQH_MESSAGE *msg;
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Messages in outlist: %d", AQH_Message_List_GetCount(xo->msgOutList));
|
DBG_DEBUG(AQH_LOGDOMAIN, "Messages in outlist: %d", AQH_Message_List_GetCount(xo->msgOutList));
|
||||||
msg=AQH_Message_List_First(xo->msgOutList);
|
msg=AQH_Message_List_First(xo->msgOutList);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
/* remove sent message from list */
|
/* remove sent message from list */
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ int _fillRingbuffer(AQH_OBJECT *o, AQH_MSG_READER *xo, AQH_OBJECT *fdObject)
|
|||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
if (rv!=GWEN_ERROR_TRY_AGAIN) {
|
if (rv!=GWEN_ERROR_TRY_AGAIN) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
AQH_Object_EmitSignal(o, AQH_MSG_READER_SIGNAL_CLOSED, 0, NULL);
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code,
|
AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code,
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
uint32_t msgId, uint32_t refMsgId,
|
||||||
const AQH_VALUE *value, const char *data)
|
const AQH_VALUE *value, double data)
|
||||||
{
|
{
|
||||||
AQH_MESSAGE *msg;
|
AQH_MESSAGE *msg;
|
||||||
GWEN_BUFFER *buf;
|
GWEN_BUFFER *buf;
|
||||||
@@ -51,8 +51,7 @@ AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code,
|
|||||||
GWEN_Buffer_free(buf);
|
GWEN_Buffer_free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (data && *data)
|
GWEN_Tag16_WriteDoubleTagToBuffer(AQH_MSGDATA_SET_TAGS_DATA, data, buf);
|
||||||
GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_SET_TAGS_DATA, data, buf);
|
|
||||||
|
|
||||||
msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId,
|
||||||
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf));
|
||||||
@@ -78,9 +77,9 @@ AQH_VALUE *AQH_IpcdMessageSetData_ReadValue(const GWEN_TAG16_LIST *tagList)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList)
|
double AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList)
|
||||||
{
|
{
|
||||||
return AQH_Tag16_GetTagDataAsNewString(tagList, AQH_MSGDATA_SET_TAGS_DATA, NULL);
|
return AQH_Tag16_GetTagDataAsDouble(tagList, AQH_MSGDATA_SET_TAGS_DATA, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -92,16 +91,16 @@ void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG1
|
|||||||
const char *valueName;
|
const char *valueName;
|
||||||
const char *valueUnits;
|
const char *valueUnits;
|
||||||
int valueType;
|
int valueType;
|
||||||
char *data;
|
double data;
|
||||||
|
|
||||||
value=tagList?AQH_IpcdMessageSetData_ReadValue(tagList):NULL;
|
value=tagList?AQH_IpcdMessageSetData_ReadValue(tagList):NULL;
|
||||||
valueName=value?AQH_Value_GetNameForSystem(value):NULL;
|
valueName=value?AQH_Value_GetNameForSystem(value):NULL;
|
||||||
valueUnits=value?AQH_Value_GetValueUnits(value):NULL;
|
valueUnits=value?AQH_Value_GetValueUnits(value):NULL;
|
||||||
valueType=value?AQH_Value_GetValueType(value):0;
|
valueType=value?AQH_Value_GetValueType(value):0;
|
||||||
data=tagList?AQH_IpcdMessageSetData_ReadData(tagList):NULL;
|
data=tagList?AQH_IpcdMessageSetData_ReadData(tagList):0.0;
|
||||||
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf,
|
GWEN_Buffer_AppendArgs(dbuf,
|
||||||
"SETDATA(%s) %s (code=%d, proto=%d, proto version=%d, name=%s, units=%s, type=%d, value=%s)\n",
|
"SETDATA(%s) %s (code=%d, proto=%d, proto version=%d, name=%s, units=%s, type=%d, value=%.2f)\n",
|
||||||
AQH_IpcdMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)),
|
AQH_IpcdMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)),
|
||||||
sText?sText:"",
|
sText?sText:"",
|
||||||
AQH_IpcMessage_GetCode(msg),
|
AQH_IpcMessage_GetCode(msg),
|
||||||
@@ -110,8 +109,7 @@ void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG1
|
|||||||
valueName?valueName:"<empty>",
|
valueName?valueName:"<empty>",
|
||||||
valueUnits?valueUnits:"<empty>",
|
valueUnits?valueUnits:"<empty>",
|
||||||
valueType,
|
valueType,
|
||||||
data?data:"<empty>");
|
data);
|
||||||
free(data);
|
|
||||||
AQH_Value_free(value);
|
AQH_Value_free(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
|
|
||||||
AQHOME_API AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code,
|
AQHOME_API AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code,
|
||||||
uint32_t msgId, uint32_t refMsgId,
|
uint32_t msgId, uint32_t refMsgId,
|
||||||
const AQH_VALUE *value, const char *data);
|
const AQH_VALUE *value, double data);
|
||||||
|
|
||||||
AQHOME_API AQH_VALUE *AQH_IpcdMessageSetData_ReadValue(const GWEN_TAG16_LIST *tagList);
|
AQHOME_API AQH_VALUE *AQH_IpcdMessageSetData_ReadValue(const GWEN_TAG16_LIST *tagList);
|
||||||
AQHOME_API char *AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList);
|
AQHOME_API double AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList);
|
||||||
|
|
||||||
AQHOME_API void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList,
|
AQHOME_API void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList,
|
||||||
GWEN_BUFFER *dbuf, const char *sText);
|
GWEN_BUFFER *dbuf, const char *sText);
|
||||||
|
|||||||
@@ -161,6 +161,19 @@ uint64_t AQH_Tag16_GetTagDataAsUint64(const GWEN_TAG16_LIST *tagList, unsigned i
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double AQH_Tag16_GetTagDataAsDouble(const GWEN_TAG16_LIST *tagList, unsigned int tagType, double defaultValue)
|
||||||
|
{
|
||||||
|
if (tagList) {
|
||||||
|
const GWEN_TAG16 *tag;
|
||||||
|
|
||||||
|
tag=GWEN_Tag16_List_FindFirstByTagType(tagList, tagType);
|
||||||
|
return tag?GWEN_Tag16_GetTagDataAsDouble(tag, defaultValue):defaultValue;
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AQH_Tag16_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf)
|
int AQH_Tag16_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf)
|
||||||
{
|
{
|
||||||
if (valueList) {
|
if (valueList) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ AQHOME_API GWEN_TAG16_LIST *AQH_Tag16_ParseTags(const uint8_t *payloadPtr, uint3
|
|||||||
AQHOME_API char *AQH_Tag16_GetTagDataAsNewString(const GWEN_TAG16_LIST *tagList, unsigned int tagType, const char *defaultValue);
|
AQHOME_API char *AQH_Tag16_GetTagDataAsNewString(const GWEN_TAG16_LIST *tagList, unsigned int tagType, const char *defaultValue);
|
||||||
AQHOME_API uint32_t AQH_Tag16_GetTagDataAsUint32(const GWEN_TAG16_LIST *tagList, unsigned int tagType, uint32_t defaultValue);
|
AQHOME_API uint32_t AQH_Tag16_GetTagDataAsUint32(const GWEN_TAG16_LIST *tagList, unsigned int tagType, uint32_t defaultValue);
|
||||||
AQHOME_API uint64_t AQH_Tag16_GetTagDataAsUint64(const GWEN_TAG16_LIST *tagList, unsigned int tagType, uint64_t defaultValue);
|
AQHOME_API uint64_t AQH_Tag16_GetTagDataAsUint64(const GWEN_TAG16_LIST *tagList, unsigned int tagType, uint64_t defaultValue);
|
||||||
|
AQHOME_API double AQH_Tag16_GetTagDataAsDouble(const GWEN_TAG16_LIST *tagList, unsigned int tagType, double defaultValue);
|
||||||
|
|
||||||
/* utils */
|
/* utils */
|
||||||
AQHOME_API int AQH_Tag16_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf);
|
AQHOME_API int AQH_Tag16_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf);
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_c01.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_c02.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -7,11 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n14.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
eeprom.asm
|
eeprom.asm
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n16.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -12,10 +12,5 @@
|
|||||||
README
|
README
|
||||||
</extradist>
|
</extradist>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n21.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
|
|
||||||
</gwbuild>
|
</gwbuild>
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n24.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n25.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
eeprom.asm
|
eeprom.asm
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n26.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n27.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -12,10 +12,5 @@
|
|||||||
README
|
README
|
||||||
</extradist>
|
</extradist>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_n28.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
|
|
||||||
</gwbuild>
|
</gwbuild>
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,6 @@
|
|||||||
README
|
README
|
||||||
</extradist>
|
</extradist>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_r05.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
|
|
||||||
</gwbuild>
|
</gwbuild>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_r06.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_s03.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -9,10 +9,6 @@
|
|||||||
uartfd
|
uartfd
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_t03.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -7,10 +7,6 @@
|
|||||||
main
|
main
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
|
||||||
aqua_t04.xml
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<extradist>
|
<extradist>
|
||||||
defs.asm
|
defs.asm
|
||||||
README
|
README
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ NET_Interface_ResetStats:
|
|||||||
mov xl, yl
|
mov xl, yl
|
||||||
mov xh, yh
|
mov xh, yh
|
||||||
adiw xh:xl, NET_IFACE_OFFS_PACKETSIN_LOW
|
adiw xh:xl, NET_IFACE_OFFS_PACKETSIN_LOW
|
||||||
ldi r17, ((NET_IFACE_OFFS_ERR_BUSY_HIGH+1)-NET_IFACE_OFFS_PACKETSIN_LOW)
|
ldi r17, ((NET_IFACE_OFFS_ERR_MISSED_HIGH+1)-NET_IFACE_OFFS_PACKETSIN_LOW)
|
||||||
clr r16
|
clr r16
|
||||||
rcall Utils_FillSram ; (R17, X)
|
rcall Utils_FillSram ; (R17, X)
|
||||||
out SREG, r15
|
out SREG, r15
|
||||||
|
|||||||
@@ -148,8 +148,9 @@ SK6812_SetMode:
|
|||||||
sts sk6812Mode, r18
|
sts sk6812Mode, r18
|
||||||
cpi r18, SK6812_MODE_OFF
|
cpi r18, SK6812_MODE_OFF
|
||||||
breq SK6812_SetState_off
|
breq SK6812_SetState_off
|
||||||
cpi r18, SK6812_MODE_ON
|
; cpi r18, SK6812_MODE_ON
|
||||||
breq SK6812_SetState_on
|
; breq SK6812_SetState_on
|
||||||
|
rjmp SK6812_SetState_on
|
||||||
ret
|
ret
|
||||||
SK6812_SetState_off:
|
SK6812_SetState_off:
|
||||||
clr r18
|
clr r18
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
<values>
|
<values>
|
||||||
<value name="power" type="actor">
|
<value name="power" type="actor">
|
||||||
<translations>
|
<translations>
|
||||||
<translation aqhValue="0.0" driverValue="off"/>
|
<translation aqhValue="0" driverValue="off"/>
|
||||||
<translation aqhValue="1.0" driverValue="on"/>
|
<translation aqhValue="1" driverValue="on"/>
|
||||||
</translations>
|
</translations>
|
||||||
</value>
|
</value>
|
||||||
</values>
|
</values>
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
<values>
|
<values>
|
||||||
<value name="power" type="actor">
|
<value name="power" type="actor">
|
||||||
<translations>
|
<translations>
|
||||||
<translation aqhValue="0.0" driverValue="off"/>
|
<translation aqhValue="0" driverValue="off"/>
|
||||||
<translation aqhValue="1.0" driverValue="on"/>
|
<translation aqhValue="1" driverValue="on"/>
|
||||||
</translations>
|
</translations>
|
||||||
</value>
|
</value>
|
||||||
</values>
|
</values>
|
||||||
|
|||||||
@@ -2,15 +2,30 @@
|
|||||||
|
|
||||||
<gwbuild>
|
<gwbuild>
|
||||||
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
<data dist="true" install="$(datadir)/aqhome/devices/nodes">
|
||||||
|
aqua_c01.xml
|
||||||
|
aqua_c02.xml
|
||||||
aqua_n06.xml
|
aqua_n06.xml
|
||||||
aqua_n11.xml
|
aqua_n11.xml
|
||||||
aqua_n12.xml
|
aqua_n12.xml
|
||||||
|
aqua_n14.xml
|
||||||
aqua_n15.xml
|
aqua_n15.xml
|
||||||
|
aqua_n16.xml
|
||||||
aqua_n17.xml
|
aqua_n17.xml
|
||||||
aqua_n18.xml
|
aqua_n18.xml
|
||||||
aqua_n19.xml
|
aqua_n19.xml
|
||||||
aqua_n20.xml
|
aqua_n20.xml
|
||||||
|
aqua_n21.xml
|
||||||
aqua_n22.xml
|
aqua_n22.xml
|
||||||
|
aqua_n24.xml
|
||||||
|
aqua_n25.xml
|
||||||
|
aqua_n26.xml
|
||||||
|
aqua_n27.xml
|
||||||
|
aqua_n28.xml
|
||||||
|
aqua_r05.xml
|
||||||
|
aqua_r06.xml
|
||||||
|
aqua_s03.xml
|
||||||
|
aqua_t03.xml
|
||||||
|
aqua_t04.xml
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
</gwbuild>
|
</gwbuild>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user