572 lines
16 KiB
C
572 lines
16 KiB
C
/****************************************************************************
|
|
* This file is part of the project AqHome.
|
|
* AqHome (c) by 2026 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_page2.h"
|
|
#include "./mdevices_page2_graph.h"
|
|
#include "./mdevices_page2_actor.h"
|
|
|
|
#include "aqhome-cgi/modules/mdataclient.h"
|
|
#include "aqhome-cgi/modules/devices/mdevices_pagectx.h"
|
|
|
|
#include <aqcgi/service/module.h>
|
|
|
|
#include <aqdiagram/graph/timegraph.h>
|
|
#include <aqdiagram/graph/w_graph.h>
|
|
#include <aqdiagram/draw/context_cairo.h>
|
|
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/timestamp.h>
|
|
#include <gwenhywfar/text.h>
|
|
#include <gwenhywfar/directory.h>
|
|
|
|
#include <sys/stat.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* defs and enums
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#define GBAS GWEN_Buffer_AppendString
|
|
#define GBAA GWEN_Buffer_AppendArgs
|
|
|
|
|
|
#define DOC_PAGE2 "page.html"
|
|
|
|
#define FOLDER_PAGES "pages2"
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static void _sendPageList(AQCGI_MODULE *m, GWEN_BUFFER *dbuf);
|
|
static GWEN_STRINGLIST *_listPageFiles(AQCGI_MODULE *m);
|
|
static GWEN_XMLNODE *_readPage(AQCGI_MODULE *m, const char *sPageName);
|
|
static GWEN_XMLNODE *_readPageFile(const char *sFilename);
|
|
static void _writePage(AQCGI_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUFFER *dbuf);
|
|
static void _writePageChildElements(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *n, GWEN_BUFFER *dbuf);
|
|
static void _writeHtmlElement(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf);
|
|
static void _writePageElement(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *n, GWEN_BUFFER *dbuf);
|
|
static void _writePageForEveryValue(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf);
|
|
static void _writePageDataSet(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf);
|
|
static void _writePageItem(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf);
|
|
static AQH_MD_PAGECTX *_createInitialCtx(AQCGI_MODULE *m, AQH_DATACLIENT *dc);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* code
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void AQH_ModDevices_RunPage2Get(AQCGI_MODULE *m, AQCGI_REQUEST *rq,
|
|
GWEN_UNUSED AQCGI_SESSION *session,
|
|
AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_DB_NODE *dbQuery;
|
|
const char *sPageId;
|
|
|
|
DBG_INFO(NULL, "RunPage2Get");
|
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
|
sPageId=dbQuery?GWEN_DB_GetCharValue(dbQuery, "page", 0, NULL):NULL;
|
|
if (sPageId && *sPageId) {
|
|
GWEN_XMLNODE *fileNode;
|
|
|
|
DBG_INFO(NULL, "Reading page \"%s\"", sPageId);
|
|
fileNode=_readPage(m, sPageId);
|
|
if (fileNode) {
|
|
GWEN_XMLNODE *nPage;
|
|
|
|
nPage=GWEN_XMLNode_FindFirstTag(fileNode, "page", NULL, NULL);
|
|
if (nPage) {
|
|
_writePage(m, dc, nPage, dbuf);
|
|
//AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 120");
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "No page element in file for \"%s\"", sPageId);
|
|
}
|
|
GWEN_XMLNode_free(fileNode);
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "here");
|
|
}
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "Reading page list");
|
|
_sendPageList(m, dbuf);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModDevices_RunPage2Graph(AQCGI_MODULE *m, AQCGI_REQUEST *rq,
|
|
GWEN_UNUSED AQCGI_SESSION *session,
|
|
AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_DB_NODE *dbQuery;
|
|
const char *sPageId;
|
|
const char *sGraphId;
|
|
|
|
DBG_INFO(NULL, "RunPageGraphGet");
|
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
|
sPageId=GWEN_DB_GetCharValue(dbQuery, "page", 0, NULL);
|
|
sGraphId=GWEN_DB_GetCharValue(dbQuery, "graph", 0, NULL);
|
|
if (sPageId && *sPageId && sGraphId && *sGraphId)
|
|
AQH_ModDevices_HandleGraph(m, rq, dc, sPageId, sGraphId, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModDevices_RunPage2Post(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_DB_NODE *dbPost;
|
|
const char *sPageId;
|
|
const char *sActorId;
|
|
|
|
DBG_INFO(NULL, "RunPagePost");
|
|
dbPost=AQCGI_Request_GetDbPostBody(rq);
|
|
sPageId=GWEN_DB_GetCharValue(dbPost, "page", 0, NULL);
|
|
sActorId=GWEN_DB_GetCharValue(dbPost, "actor", 0, NULL);
|
|
if (sPageId && *sPageId && sActorId && *sActorId) {
|
|
GWEN_XMLNODE *fileNode;
|
|
|
|
fileNode=_readPage(m, sPageId);
|
|
if (fileNode) {
|
|
GWEN_XMLNODE *nPage;
|
|
GWEN_XMLNODE *nActor;
|
|
|
|
nPage=GWEN_XMLNode_FindFirstTag(fileNode, "page", "id", sPageId);
|
|
nActor=AQH_ModDevices_FindXmlElement(nPage, "actor", "id", sActorId);
|
|
if (nPage && nActor) {
|
|
AQH_MD_PAGECTX *ctx;
|
|
|
|
ctx=_createInitialCtx(m, dc);
|
|
AQH_ModDevices_HandlePageActor(ctx, rq, sActorId, nActor);
|
|
AQH_MDPageCtx_free(ctx);
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "Actor %s/%s not found", sPageId, sActorId);
|
|
}
|
|
GWEN_XMLNode_free(fileNode);
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "here");
|
|
}
|
|
}
|
|
|
|
AQH_ModDevices_RedirectToPage(rq, DOC_PAGE2, sPageId);
|
|
}
|
|
|
|
|
|
|
|
|
|
void AQH_ModDevices_SetCharValue(GWEN_DB_NODE *dbDest, uint32_t flags, const char *sVar, const char *sValue, GWEN_DB_NODE *dbContext)
|
|
{
|
|
if (sValue && *sValue) {
|
|
GWEN_BUFFER *tbuf;
|
|
int rv;
|
|
|
|
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
rv=GWEN_DB_ReplaceVars(dbContext, sValue, tbuf);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error replacing vars for %s=[%s]", sVar, sValue);
|
|
}
|
|
else {
|
|
/*DBG_ERROR(NULL, "Setting value [%s]=[%s] (%s)", sVar, GWEN_Buffer_GetStart(tbuf), sValue);*/
|
|
GWEN_DB_SetCharValue(dbDest, flags, sVar, GWEN_Buffer_GetStart(tbuf));
|
|
}
|
|
GWEN_Buffer_free(tbuf);
|
|
}
|
|
else
|
|
GWEN_DB_DeleteVar(dbDest, sVar);
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModDevices_SetupDbForDeviceAndValue(const AQH_VALUE *v, GWEN_DB_NODE *dbCtx)
|
|
{
|
|
GWEN_DB_NODE *db;
|
|
AQH_DEVICE *device;
|
|
|
|
db=GWEN_DB_GetGroup(dbCtx, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "value");
|
|
AQH_Value_toDb(v, db);
|
|
|
|
device=AQH_Value_GetDevicePtr(v);
|
|
if (device) {
|
|
const char *sNameForSystem;
|
|
const char *sLocation;
|
|
const char *sDescription;
|
|
GWEN_BUFFER *tbuf;
|
|
|
|
db=GWEN_DB_GetGroup(dbCtx, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "device");
|
|
AQH_Device_toDb(device, db);
|
|
/* generate descriptive name */
|
|
sNameForSystem=AQH_Device_GetNameForSystem(device);
|
|
sLocation=AQH_Device_GetLocation(device);
|
|
sDescription=AQH_Device_GetDescription(device);
|
|
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
if (sLocation && sDescription)
|
|
GBAA(tbuf, "%s - %s", sDescription, sLocation);
|
|
else if (sLocation)
|
|
GBAA(tbuf, "%s", sLocation);
|
|
else if (sDescription)
|
|
GBAA(tbuf, "%s", sDescription);
|
|
else
|
|
GBAA(tbuf, "%s", sNameForSystem);
|
|
|
|
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "descriptiveName", GWEN_Buffer_GetStart(tbuf));
|
|
GWEN_Buffer_free(tbuf);
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "No device pointer in device %s", AQH_Value_GetNameForSystem(v));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// TODO: sort
|
|
void _sendPageList(AQCGI_MODULE *m, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_STRINGLIST *sl;
|
|
|
|
GBAS(dbuf, "<h1>Page List</h1>\n");
|
|
sl=_listPageFiles(m);
|
|
if (sl) {
|
|
GWEN_STRINGLISTENTRY *se;
|
|
|
|
GWEN_StringList_Sort(sl, 1, GWEN_StringList_SortModeNoCase);
|
|
GBAS(dbuf,
|
|
"<table class=\"datatable\">\n"
|
|
"<thead><tr><th>Page</th><th>Title</th></tr></thead>\n"
|
|
"<tbody>\n");
|
|
se=GWEN_StringList_FirstEntry(sl);
|
|
while(se) {
|
|
const char *filename;
|
|
|
|
filename=GWEN_StringListEntry_Data(se);
|
|
if (filename && *filename) {
|
|
GWEN_XMLNODE *node;
|
|
|
|
DBG_INFO(NULL, "Reading file \"%s\"", filename);
|
|
node=_readPageFile(filename);
|
|
if (node) {
|
|
GWEN_XMLNODE *nPage;
|
|
|
|
nPage=GWEN_XMLNode_FindFirstTag(node, "page", NULL, NULL);
|
|
if (nPage) {
|
|
const char *sId;
|
|
const char *sTitle;
|
|
|
|
sId=GWEN_XMLNode_GetProperty(nPage, "id", NULL);
|
|
sTitle=GWEN_XMLNode_GetProperty(nPage, "title", sId);
|
|
if (sId && *sId)
|
|
GBAA(dbuf, "<tr><td><a href=\""DOC_PAGE2"?page=%s\">%s</a></td><td>%s</td></tr>\n", sId, sId, sTitle);
|
|
}
|
|
GWEN_XMLNode_free(node);
|
|
}
|
|
}
|
|
se=GWEN_StringListEntry_Next(se);
|
|
}
|
|
GBAS(dbuf, "</tbody></table>");
|
|
GWEN_StringList_free(sl);
|
|
}
|
|
else {
|
|
GBAS(dbuf, "No pages.");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
GWEN_STRINGLIST *_listPageFiles(AQCGI_MODULE *m)
|
|
{
|
|
GWEN_BUFFER *fbuf;
|
|
AQCGI_SERVICE *sv;
|
|
GWEN_STRINGLIST *sl;
|
|
int rv;
|
|
|
|
sv=AQH_ModService_GetService(m);
|
|
fbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
GBAA(fbuf, "%s%s"FOLDER_PAGES, AQCGI_Service_GetRuntimeFolder(sv), GWEN_DIR_SEPARATOR_S);
|
|
sl=GWEN_StringList_new();
|
|
rv=GWEN_Directory_GetMatchingFilesRecursively(GWEN_Buffer_GetStart(fbuf), sl, "*.xml");
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "Error reading pages (%d)", rv);
|
|
GWEN_StringList_free(sl);
|
|
GWEN_Buffer_free(fbuf);
|
|
return NULL;
|
|
}
|
|
if (GWEN_StringList_Count(sl)<1) {
|
|
GWEN_StringList_free(sl);
|
|
GWEN_Buffer_free(fbuf);
|
|
return NULL;
|
|
}
|
|
GWEN_Buffer_free(fbuf);
|
|
|
|
return sl;
|
|
}
|
|
|
|
|
|
|
|
GWEN_XMLNODE *_readPage(AQCGI_MODULE *m, const char *sPageName)
|
|
{
|
|
GWEN_BUFFER *fbuf;
|
|
AQCGI_SERVICE *sv;
|
|
GWEN_XMLNODE *fileNode;
|
|
|
|
sv=AQH_ModService_GetService(m);
|
|
fbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
GBAA(fbuf, "%s%s"FOLDER_PAGES"%s", AQCGI_Service_GetRuntimeFolder(sv), GWEN_DIR_SEPARATOR_S, GWEN_DIR_SEPARATOR_S);
|
|
AQH_ModService_EscapeToBuffer(sPageName, fbuf);
|
|
GBAS(fbuf, ".xml");
|
|
|
|
fileNode=_readPageFile(GWEN_Buffer_GetStart(fbuf));
|
|
if (fileNode==NULL) {
|
|
DBG_INFO(NULL, "here");
|
|
GWEN_Buffer_free(fbuf);
|
|
return NULL;
|
|
}
|
|
|
|
GWEN_Buffer_free(fbuf);
|
|
return fileNode;
|
|
}
|
|
|
|
|
|
|
|
GWEN_XMLNODE *_readPageFile(const char *sFilename)
|
|
{
|
|
GWEN_XMLNODE *fileNode;
|
|
int rv;
|
|
|
|
fileNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, sFilename);
|
|
rv=GWEN_XML_ReadFile(fileNode, sFilename, GWEN_XML_FLAGS_DEFAULT);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error reading \"%s\": %s (%d)", sFilename?sFilename:"<no name>", strerror(errno), errno);
|
|
GWEN_XMLNode_free(fileNode);
|
|
return NULL;
|
|
}
|
|
|
|
return fileNode;
|
|
}
|
|
|
|
|
|
|
|
|
|
void _writePage(AQCGI_MODULE *m, AQH_DATACLIENT *dc, GWEN_XMLNODE *nPage, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sPageId;
|
|
const char *s;
|
|
AQH_MD_PAGECTX *ctx;
|
|
|
|
ctx=_createInitialCtx(m, dc);
|
|
sPageId=GWEN_XMLNode_GetProperty(nPage, "id", NULL);
|
|
|
|
/* title */
|
|
s=GWEN_XMLNode_GetProperty(nPage, "title", NULL);
|
|
if (s && *s)
|
|
GBAA(dbuf, "<h1>%s</h1>\n", s);
|
|
|
|
_writePageChildElements(ctx, sPageId, nPage, dbuf);
|
|
|
|
AQH_MDPageCtx_free(ctx);
|
|
}
|
|
|
|
|
|
|
|
void _writePageChildElements(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_XMLNODE *n;
|
|
|
|
n=GWEN_XMLNode_GetChild(nElement);
|
|
while(n) {
|
|
_writePageElement(ctx, sPageId, n, dbuf);
|
|
n=GWEN_XMLNode_Next(n);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _writePageElement(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf)
|
|
{
|
|
if (GWEN_XMLNode_GetType(nElement)==GWEN_XMLNodeTypeTag) {
|
|
const char *sElementName;
|
|
|
|
sElementName=GWEN_XMLNode_GetData(nElement);
|
|
if (sElementName && *sElementName) {
|
|
/* DBG_INFO(NULL, "Reading element \"%s\"", sElementName); */
|
|
if (strcasecmp(sElementName, "dataset")==0)
|
|
_writePageDataSet(ctx, sPageId, nElement, dbuf);
|
|
else if (strcasecmp(sElementName, "item")==0)
|
|
_writePageItem(ctx, sPageId, nElement, dbuf);
|
|
else if (strcasecmp(sElementName, "graph")==0)
|
|
AQH_ModDevices_PageWriteGraph(ctx, sPageId, nElement, dbuf);
|
|
else if (strcasecmp(sElementName, "actor")==0)
|
|
AQH_ModDevices_PageWriteActor(ctx, sPageId, nElement, dbuf);
|
|
// else if (strcasecmp(sName, "valueTable")==0)
|
|
// _writePageValueTable(ctx, sPageId, n, dbuf);
|
|
else if (strcasecmp(sElementName, "forEveryValue")==0)
|
|
_writePageForEveryValue(ctx, sPageId, nElement, dbuf);
|
|
else if (strcasecmp(sElementName, "table")==0 ||
|
|
strcasecmp(sElementName, "tr")==0 ||
|
|
strcasecmp(sElementName, "td")==0 ||
|
|
strcasecmp(sElementName, "p")==0)
|
|
_writeHtmlElement(ctx, sPageId, nElement, dbuf);
|
|
/* DBG_INFO(NULL, "Done with element \"%s\"", sElementName); */
|
|
}
|
|
}
|
|
else if (GWEN_XMLNode_GetType(nElement)==GWEN_XMLNodeTypeData) {
|
|
const char *s;
|
|
|
|
/* copy data after stripping unnecessary blanks */
|
|
s=GWEN_XMLNode_GetData(nElement);
|
|
if (s && *s) {
|
|
GWEN_BUFFER *tbuf;
|
|
|
|
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
GWEN_DB_ReplaceVars(AQH_MDPageCtx_GetDbVars(ctx), s, tbuf);
|
|
GWEN_Text_CondenseBuffer(tbuf);
|
|
GBAS(dbuf, GWEN_Buffer_GetStart(tbuf));
|
|
GWEN_Buffer_free(tbuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _writeHtmlElement(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sElementName;
|
|
|
|
sElementName=GWEN_XMLNode_GetData(nElement);
|
|
if (sElementName) { /* ugly hack because GWEN_XML does not expose raw attributes */
|
|
GWEN_XMLNODE *newRoot;
|
|
GWEN_XMLNODE *newElement;
|
|
GWEN_BUFFER *tbuf;
|
|
char *p;
|
|
|
|
newRoot=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
|
|
newElement=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, sElementName);
|
|
GWEN_XMLNode_AddChild(newRoot, newElement);
|
|
GWEN_XMLNode_CopyProperties(newElement, nElement, 0);
|
|
GWEN_XMLNode_ExpandProperties(newElement, AQH_MDPageCtx_GetDbVars(ctx));
|
|
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
GWEN_XMLNode_toBuffer(newRoot, tbuf, GWEN_XML_FLAGS_SIMPLE);
|
|
p=strchr(GWEN_Buffer_GetStart(tbuf), '>');
|
|
if (p && *p) {
|
|
p[1]=0;
|
|
GBAS(dbuf, GWEN_Buffer_GetStart(tbuf));
|
|
}
|
|
GWEN_Buffer_free(tbuf);
|
|
}
|
|
|
|
_writePageChildElements(ctx, sPageId, nElement, dbuf);
|
|
GBAA(dbuf, "</%s>", sElementName);
|
|
}
|
|
|
|
|
|
|
|
void _writePageForEveryValue(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_VALUE_LIST *valueList;
|
|
|
|
valueList=AQH_MDPageCtx_GetValues(ctx);
|
|
if (valueList) {
|
|
const AQH_VALUE *v;
|
|
GWEN_DB_NODE *dbCtx;
|
|
|
|
dbCtx=AQH_MDPageCtx_GetDbVars(ctx);
|
|
v=AQH_Value_List_First(valueList);
|
|
while(v) {
|
|
DBG_INFO(NULL, "Writing for value %s", AQH_Value_GetNameForSystem(v));
|
|
AQH_ModDevices_SetupDbForDeviceAndValue(v, dbCtx);
|
|
_writePageChildElements(ctx, sPageId, nElement, dbuf);
|
|
v=AQH_Value_List_Next(v);
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "No values");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _writePageDataSet(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sRoom;
|
|
const char *sVarType;
|
|
const char *sModality;
|
|
const char *sVarName;
|
|
const char *sLastChange;
|
|
int modality;
|
|
int varType;
|
|
uint64_t lastChange;
|
|
AQH_MD_PAGECTX *newCtx;
|
|
|
|
/* prepare new context */
|
|
sVarType=GWEN_XMLNode_GetProperty(nElement, "vartype", NULL);
|
|
sRoom=GWEN_XMLNode_GetProperty(nElement, "room", NULL);
|
|
sModality=GWEN_XMLNode_GetProperty(nElement, "modality", NULL);
|
|
sVarName=GWEN_XMLNode_GetProperty(nElement, "varname", NULL);
|
|
sLastChange=GWEN_XMLNode_GetProperty(nElement, "lastChange", NULL);
|
|
modality=sModality?AQH_ValueModality_fromString(sModality):AQH_ValueModality_Unknown;
|
|
varType=sVarType?AQH_ValueType_fromString(sVarType):AQH_ValueType_Sensor;
|
|
lastChange=sLastChange?AQH_ParseTime(sLastChange):0;
|
|
newCtx=AQH_MDPageCtx_CopyWithMatchingVars(ctx, varType, sRoom, modality, sVarName, lastChange);
|
|
/* enter context */
|
|
_writePageChildElements(newCtx, sPageId, nElement, dbuf);
|
|
/* free new context */
|
|
AQH_MDPageCtx_free(newCtx);
|
|
}
|
|
|
|
|
|
|
|
void _writePageItem(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *nElement, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sTitle;
|
|
|
|
/* write title */
|
|
sTitle=GWEN_XMLNode_GetProperty(nElement, "title", NULL);
|
|
if (sTitle && *sTitle)
|
|
GBAA(dbuf, "<h2>%s</h2>\n", sTitle);
|
|
_writePageChildElements(ctx, sPageId, nElement, dbuf);
|
|
}
|
|
|
|
|
|
|
|
AQH_MD_PAGECTX *_createInitialCtx(AQCGI_MODULE *m, AQH_DATACLIENT *dc)
|
|
{
|
|
AQH_DEVICE_LIST *deviceList;
|
|
AQH_VALUE_LIST *valueList;
|
|
AQH_MD_PAGECTX *ctx;
|
|
|
|
AQH_ModDevices_ReadDevicesAndValues(m, dc);
|
|
|
|
deviceList=AQH_ModDevices_GetDeviceList(m);
|
|
valueList=AQH_ModDevices_GetValueList(m);
|
|
|
|
ctx=AQH_MDPageCtx_new(m, dc);
|
|
AQH_MDPageCtx_SetDevices(ctx, deviceList);
|
|
if (valueList)
|
|
AQH_MDPageCtx_SetValues(ctx, AQH_Value_List_dup(valueList));
|
|
|
|
return ctx;
|
|
}
|
|
|
|
|
|
|