874 lines
27 KiB
C
874 lines
27 KiB
C
/****************************************************************************
|
|
* This file is part of the project AqHome.
|
|
* AqHome (c) by 2025 Martin Preuss, all rights reserved.
|
|
*
|
|
* The license for this file can be found in the file COPYING which you
|
|
* should have received along with this file.
|
|
****************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
|
|
#include "./mdevices.h"
|
|
|
|
#include "aqhome-cgi/service/module.h"
|
|
#include "aqhome-cgi/modules/mdataclient.h"
|
|
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/timestamp.h>
|
|
#include <gwenhywfar/text.h>
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* defs and enums
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#define GBAS GWEN_Buffer_AppendString
|
|
#define GBAA GWEN_Buffer_AppendArgs
|
|
|
|
#define P_DEVICEREAD AQH_MODDEVICES_PERMS_DEVICEREAD
|
|
#define P_VALUEREAD AQH_MODDEVICES_PERMS_VALUEREAD
|
|
#define P_VALUEWRITE AQH_MODDEVICES_PERMS_VALUEWRITE
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static void _createPermDefList(AQH_MODULE *m);
|
|
static void _createRoleList(AQH_MODULE *m);
|
|
|
|
static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName);
|
|
static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem);
|
|
|
|
static void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqValuesGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
static void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf);
|
|
|
|
static void _runIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
|
static void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
|
static void _runValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
|
static void _runValueWithArgs(AQH_MODULE *m,
|
|
AQCGI_REQUEST *rq,
|
|
AQH_SESSION *session,
|
|
AQH_DATACLIENT *dc,
|
|
const char *sDeviceName,
|
|
const char *sValueName,
|
|
GWEN_BUFFER *dbuf);
|
|
|
|
static void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf);
|
|
static void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, uint32_t perms, GWEN_BUFFER *dbuf);
|
|
static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, uint32_t perms, GWEN_BUFFER *dbuf);
|
|
static void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
static uint32_t _colorFromHexString(const char *s);
|
|
static uint32_t _htmlColorToValueRGBW(uint32_t colorIn);
|
|
static uint32_t _rgbwToHtmlColor(uint32_t colorIn);
|
|
static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
|
static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
|
static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
|
static void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
|
|
static void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* vars
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static AQH_MODSERVICE_HANDLER_ENTRY _requestTable[]={
|
|
{"index.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD, _handleRqIndexGet},
|
|
{"values.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValuesGet},
|
|
{"value.html", AQCGI_REQUEST_METHOD_GET, P_DEVICEREAD | P_VALUEREAD, _handleRqValueGet},
|
|
{"setdata.html", AQCGI_REQUEST_METHOD_POST, P_VALUEWRITE, _handleRqSetDataPost},
|
|
{NULL, 0, 0, NULL}
|
|
};
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* code
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void AQH_ModDevices_Extend(AQH_MODULE *m, AQH_SERVICE *sv, const char *baseFolder)
|
|
{
|
|
AQH_ModService_Extend(m, sv, baseFolder);
|
|
AQH_ModService_SetHandleRequestFn(m, _handleRequest);
|
|
AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule);
|
|
}
|
|
|
|
|
|
|
|
int AQH_ModDevices_Create(AQH_SERVICE *sv)
|
|
{
|
|
AQH_MODULE *m;
|
|
int rv;
|
|
|
|
m=AQH_Module_new();
|
|
AQH_Module_SetName(m, "devices");
|
|
AQH_Module_SetDescr(m, "device module");
|
|
AQH_Module_SetGuestPerms(m, 0);
|
|
|
|
_createPermDefList(m);
|
|
_createRoleList(m);
|
|
|
|
rv=AQH_Service_AddModule(sv, m);
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "here (%d)", rv);
|
|
}
|
|
AQH_Module_free(m);
|
|
return rv;
|
|
}
|
|
|
|
|
|
|
|
void _createPermDefList(AQH_MODULE *m)
|
|
{
|
|
AQH_PERMDEF_LIST *permDefList;
|
|
|
|
permDefList=AQH_PermDef_List_new();
|
|
|
|
AQH_ModService_AddPermDef(permDefList, "DeviceRead", 0x001, "Read and list devices");
|
|
AQH_ModService_AddPermDef(permDefList, "DeviceWrite", 0x002, "Modify devices");
|
|
AQH_ModService_AddPermDef(permDefList, "DeviceAdd", 0x004, "Add devices");
|
|
AQH_ModService_AddPermDef(permDefList, "DeviceDel", 0x008, "Remove devices");
|
|
|
|
AQH_ModService_AddPermDef(permDefList, "ValueRead", 0x010, "Read and list values");
|
|
AQH_ModService_AddPermDef(permDefList, "ValueWrite", 0x020, "Modify values");
|
|
AQH_ModService_AddPermDef(permDefList, "ValueAdd", 0x040, "Add values");
|
|
AQH_ModService_AddPermDef(permDefList, "ValueDel", 0x080, "Remove values");
|
|
AQH_ModService_AddPermDef(permDefList, "ValueSet", 0x100, "Set values");
|
|
|
|
AQH_Module_SetPermDefList(m, permDefList);
|
|
}
|
|
|
|
|
|
|
|
void _createRoleList(AQH_MODULE *m)
|
|
{
|
|
AQH_ROLE_LIST *roleList;
|
|
int id=0;
|
|
|
|
roleList=AQH_Role_List_new();
|
|
AQH_ModService_AddRole(roleList, id++, "Reader",
|
|
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
|
AQH_MODDEVICES_PERMS_VALUEREAD,
|
|
"Read devices and values");
|
|
AQH_ModService_AddRole(roleList, id++, "Writer",
|
|
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
|
AQH_MODDEVICES_PERMS_DEVICEWRITE |
|
|
AQH_MODDEVICES_PERMS_DEVICEADD |
|
|
AQH_MODDEVICES_PERMS_DEVICEDEL |
|
|
AQH_MODDEVICES_PERMS_VALUEREAD |
|
|
AQH_MODDEVICES_PERMS_VALUEWRITE |
|
|
AQH_MODDEVICES_PERMS_VALUEADD |
|
|
AQH_MODDEVICES_PERMS_VALUEDEL |
|
|
AQH_MODDEVICES_PERMS_VALUESET,
|
|
"Read and write devices and values");
|
|
AQH_ModService_AddRole(roleList, id++, "Setter",
|
|
AQH_MODDEVICES_PERMS_DEVICEREAD |
|
|
AQH_MODDEVICES_PERMS_VALUEREAD |
|
|
AQH_MODDEVICES_PERMS_VALUESET,
|
|
"Set values");
|
|
AQH_Module_SetRoleList(m, roleList);
|
|
}
|
|
|
|
|
|
|
|
AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sModuleName)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, const char *sLastPathElem)
|
|
{
|
|
AQH_ModService_HandleRequestWithTable(m, rq, session, sLastPathElem, _requestTable);
|
|
return AQCGI_SendResponse(rq);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqIndexGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, _runIndex, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqValuesGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, _runValues, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqValueGet(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, _runValue, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _handleRqSetDataPost(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_ModDataClient_HandleRequest(m, rq, session, _runSetData, dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _runIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_DEVICE_LIST *deviceList;
|
|
AQH_DEVICE *device;
|
|
uint32_t perms;
|
|
|
|
perms=AQH_ModService_GetUserPerms(m);
|
|
|
|
deviceList=AQH_DataClient_GetDevices(dc, NULL);
|
|
if (deviceList==NULL) {
|
|
DBG_ERROR(NULL, "No device received");
|
|
GBAS(dbuf, "<p>No devices.</p>");
|
|
return;
|
|
}
|
|
|
|
GBAS(dbuf, "<h1>Devices</h1>\n");
|
|
GBAS(dbuf,
|
|
"<table class=\"datatable\">\n"
|
|
"<thead>\n"
|
|
"<tr>"
|
|
"<th>Name For System</th>"
|
|
"<th>Room</th>"
|
|
"<th>Location</th>"
|
|
"<th>Description</th>"
|
|
#if 0
|
|
"<th>Type</th>"
|
|
"<th>Driver</th>"
|
|
"<th>Name</th>"
|
|
"<th>GUI Name</th>"
|
|
"<th>Manufacturer</th>"
|
|
#endif
|
|
"</tr>\n"
|
|
"</thead>\n"
|
|
"<tbody>\n");
|
|
|
|
device=AQH_Device_List_First(deviceList);
|
|
while(device) {
|
|
const char *s;
|
|
|
|
GBAA(dbuf, "<tr>");
|
|
/* name for system */
|
|
s=AQH_Device_GetNameForSystem(device);
|
|
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
|
GBAS(dbuf,"<td><a href=\"values.html?device=");
|
|
GWEN_Text_EscapeToBufferTolerant(s, dbuf);
|
|
GBAA(dbuf,"\">%s</a></td>", s?s:"");
|
|
}
|
|
else
|
|
GBAA(dbuf,"<td>%s</td>", s?s:"");
|
|
/* room */
|
|
s=AQH_Device_GetRoomName(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
/* location */
|
|
s=AQH_Device_GetLocation(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
/* description */
|
|
s=AQH_Device_GetDescription(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
#if 0
|
|
/* device type */
|
|
s=AQH_Device_GetDeviceType(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
/* driver */
|
|
s=AQH_Device_GetDriver(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
/* short device name */
|
|
s=AQH_Device_GetName(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
/* GUI name for device */
|
|
s=AQH_Device_GetNameForGui(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
/* manufacturer */
|
|
s=AQH_Device_GetManufacturer(device);
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
#endif
|
|
|
|
GBAA(dbuf, "</tr>");
|
|
device=AQH_Device_List_Next(device);
|
|
}
|
|
|
|
GBAS(dbuf,
|
|
"</tbody>\n"
|
|
"</table>\n");
|
|
AQH_Device_List_free(deviceList);
|
|
}
|
|
|
|
|
|
|
|
void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_DB_NODE *dbQuery;
|
|
const char *sDeviceName;
|
|
uint32_t perms;
|
|
|
|
perms=AQH_ModService_GetUserPerms(m);
|
|
|
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
|
sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL);
|
|
if (!(sDeviceName && *sDeviceName))
|
|
_runIndex(m, rq, session, dc, dbuf);
|
|
else {
|
|
AQH_VALUE_LIST *valueList;
|
|
|
|
valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
|
|
if (valueList && AQH_Value_List_GetCount(valueList)) {
|
|
|
|
GBAA(dbuf,"<h1>Values for Device %s</h1>\n", sDeviceName);
|
|
_writeValueListToTable(sDeviceName, valueList, perms, dbuf);
|
|
GBAS(dbuf, "\n");
|
|
}
|
|
else {
|
|
GBAS(dbuf,"<p>No values.</p>\n");
|
|
}
|
|
AQH_Value_List_free(valueList);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _runValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_DB_NODE *dbQuery;
|
|
const char *sDeviceName;
|
|
const char *sValueName;
|
|
|
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
|
sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL);
|
|
sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL);
|
|
if (sDeviceName && *sDeviceName && sValueName && *sValueName) {
|
|
GWEN_BUFFER *bufDeviceName;
|
|
GWEN_BUFFER *bufValueName;
|
|
|
|
bufDeviceName=GWEN_Buffer_new(0, 64, 0, 1);
|
|
GWEN_Text_UnescapeToBufferTolerant(sDeviceName, bufDeviceName);
|
|
bufValueName=GWEN_Buffer_new(0, 64, 0, 1);
|
|
GWEN_Text_UnescapeToBufferTolerant(sValueName, bufValueName);
|
|
_runValueWithArgs(m, rq, session, dc,
|
|
GWEN_Buffer_GetStart(bufDeviceName),
|
|
GWEN_Buffer_GetStart(bufValueName),
|
|
dbuf);
|
|
GWEN_Buffer_free(bufValueName);
|
|
GWEN_Buffer_free(bufDeviceName);
|
|
}
|
|
|
|
#if 0
|
|
if (sDeviceName && *sDeviceName && sValueName && *sValueName) {
|
|
GWEN_BUFFER *pbuf;
|
|
|
|
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
GBAS(pbuf, "Location: /aqbt/devices/value.html?device=");
|
|
GWEN_Text_EscapeToBufferTolerant(sDeviceName, pbuf);
|
|
GBAS(pbuf, "&value=");
|
|
GWEN_Text_EscapeToBufferTolerant(sValueName, pbuf);
|
|
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(pbuf));
|
|
GWEN_Buffer_free(pbuf);
|
|
}
|
|
AQCGI_Request_SetResponseCode(rq, 303);
|
|
AQCGI_Request_SetResponseText(rq, "See other");
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
void _runValueWithArgs(AQH_MODULE *m,
|
|
AQCGI_REQUEST *rq,
|
|
AQH_SESSION *session,
|
|
AQH_DATACLIENT *dc,
|
|
const char *sDeviceName,
|
|
const char *sValueName,
|
|
GWEN_BUFFER *dbuf)
|
|
{
|
|
GWEN_DB_NODE *dbQuery;
|
|
AQH_VALUE_LIST *valueList;
|
|
|
|
dbQuery=AQCGI_Request_GetDbQuery(rq);
|
|
DBG_ERROR(NULL, "Device=%s, value=%s", sDeviceName?sDeviceName:"<empty>", sValueName?sValueName:"<empty>");
|
|
|
|
valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
|
|
if (valueList) {
|
|
const AQH_VALUE *value;
|
|
|
|
value=AQH_Value_List_First(valueList);
|
|
while(value) {
|
|
const char *s;
|
|
|
|
s=AQH_Value_GetName(value);
|
|
if (s && *s && strcasecmp(s, sValueName)==0)
|
|
break;
|
|
value=AQH_Value_List_Next(value);
|
|
}
|
|
if (value && AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
|
_mkValueForm(dc, sDeviceName, value, dbuf);
|
|
}
|
|
else {
|
|
}
|
|
AQH_Value_List_free(valueList);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
|
|
{
|
|
AQH_SERVICE *sv;
|
|
GWEN_DB_NODE *dbPost;
|
|
const char *sDeviceName;
|
|
const char *sValueName;
|
|
AQH_VALUE_LIST *valueList;
|
|
|
|
/* sample data */
|
|
sv=AQH_ModService_GetService(m);
|
|
dbPost=AQCGI_Request_GetDbPostBody(rq);
|
|
sDeviceName=dbPost?GWEN_DB_GetCharValue(dbPost, "device", 0, NULL):NULL;
|
|
sValueName=dbPost?GWEN_DB_GetCharValue(dbPost, "value", 0, NULL):NULL;
|
|
DBG_ERROR(NULL, "Device=[%s], value=[%s]", sDeviceName?sDeviceName:"", sValueName?sValueName:"");
|
|
valueList=sDeviceName?AQH_DataClient_GetValues(dc, sDeviceName, 0):NULL;
|
|
if (valueList && AQH_Value_List_GetCount(valueList)) {
|
|
const AQH_VALUE *value;
|
|
|
|
value=AQH_Value_List_First(valueList);
|
|
while(value) {
|
|
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
|
const char *sValueName;
|
|
const char *sValue;
|
|
|
|
sValueName=AQH_Value_GetName(value);
|
|
sValue=GWEN_DB_GetCharValue(dbPost, sValueName, 0, NULL);
|
|
if (sValueName && *sValueName) {
|
|
DBG_ERROR(NULL, "Setting value %s to %s", sValueName?sValueName:"no name", sValue?sValue:"no value");
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW: _setRgbwData(dc, value, sValue); break;
|
|
case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sValue); break;
|
|
case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break;
|
|
default:
|
|
break;
|
|
} /* switch */
|
|
} /* if (sValueName) */
|
|
}
|
|
value=AQH_Value_List_Next(value);
|
|
} /* while */
|
|
}
|
|
AQH_Value_List_free(valueList);
|
|
|
|
if (sDeviceName && *sDeviceName) {
|
|
GWEN_BUFFER *pbuf;
|
|
|
|
pbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
if (sValueName && *sValueName) {
|
|
GBAS(pbuf, "Location: /aqbt/devices/value.html?device=");
|
|
GWEN_Text_EscapeToBuffer(sDeviceName, pbuf);
|
|
GBAS(pbuf, "&value=");
|
|
GWEN_Text_EscapeToBuffer(sValueName, pbuf);
|
|
}
|
|
else {
|
|
GBAS(pbuf, "Location: /aqbt/devices/values.html?device=");
|
|
GWEN_Text_EscapeToBuffer(sDeviceName, pbuf);
|
|
}
|
|
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(pbuf));
|
|
GWEN_Buffer_free(pbuf);
|
|
}
|
|
AQCGI_Request_SetResponseCode(rq, 303);
|
|
AQCGI_Request_SetResponseText(rq, "See other");
|
|
}
|
|
|
|
|
|
void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, uint32_t perms, GWEN_BUFFER *dbuf)
|
|
{
|
|
const AQH_VALUE *value;
|
|
|
|
GBAS(dbuf,
|
|
"<table class=\"datatable\">\n"
|
|
"<thead>"
|
|
"<tr>"
|
|
"<th>Name</th>"
|
|
"<th>Type</th>"
|
|
"<th>Modality</th>"
|
|
#if 0
|
|
"<th>Driver</th>"
|
|
"<th>Device</th>"
|
|
"<th>Name for System</th>"
|
|
#endif
|
|
"</tr>"
|
|
"</thead>\n"
|
|
"<tbody>\n");
|
|
|
|
value=AQH_Value_List_First(valueList);
|
|
while(value) {
|
|
if (AQH_Value_GetModality(value)!=AQH_ValueModality_Stats)
|
|
_writeValueToTable(sDeviceName, value, perms, dbuf);
|
|
value=AQH_Value_List_Next(value);
|
|
}
|
|
GBAS(dbuf,
|
|
"</tbody>\n"
|
|
"</table>\n");
|
|
}
|
|
|
|
|
|
|
|
void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, uint32_t perms, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *s;
|
|
|
|
GBAS(dbuf, "<tr>");
|
|
|
|
/* name for system */
|
|
s=AQH_Value_GetName(value);
|
|
if (perms & AQH_MODDEVICES_PERMS_VALUEREAD) {
|
|
uint32_t pos;
|
|
|
|
pos=GWEN_Buffer_GetPos(dbuf);
|
|
GBAS(dbuf,"<td><a href=\"value.html?device=");
|
|
GWEN_Text_EscapeToBuffer(sDeviceName, dbuf);
|
|
GBAS(dbuf,"&value=");
|
|
GWEN_Text_EscapeToBuffer(s, dbuf);
|
|
GBAA(dbuf,"\">%s</a></td>", s);
|
|
}
|
|
else
|
|
GBAA(dbuf,"<td>%s</td>", s?s:"");
|
|
|
|
s=AQH_ValueType_toString(AQH_Value_GetValueType(value));
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
|
|
s=AQH_ValueModality_toString(AQH_Value_GetModality(value));
|
|
GBAA(dbuf, "<td>%s</td>", s?s:"");
|
|
|
|
GBAA(dbuf, "</tr>\n");
|
|
}
|
|
|
|
|
|
|
|
void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sValueName;
|
|
|
|
sValueName=AQH_Value_GetName(value);
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW:
|
|
GBAA(dbuf, "<input type=\"color\" name=\"%s\" value=\"refresh\"/>", sValueName);
|
|
break;
|
|
case AQH_ValueModality_OnOff:
|
|
GBAA(dbuf,
|
|
"<select name=\"%s\">"
|
|
"<option value=\"unchanged\">unchanged</option>"
|
|
"<option value=\"off\">off</option>"
|
|
"<option value=\"on\">on</option>"
|
|
"</select>",
|
|
sValueName);
|
|
break;
|
|
case AQH_ValueModality_OnOffAuto:
|
|
GBAA(dbuf,
|
|
"<select name=\"%s\">"
|
|
"<option value=\"unchanged\">unchanged</option>"
|
|
"<option value=\"off\">off</option>"
|
|
"<option value=\"on\">on</option>"
|
|
"<option value=\"auto\">auto</option>"
|
|
"</select>",
|
|
sValueName);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
uint32_t _colorFromHexString(const char *s)
|
|
{
|
|
uint32_t colorIn=0;
|
|
|
|
while(*s && *s<33)
|
|
s++;
|
|
if (*s=='#')
|
|
s++;
|
|
while(*s) {
|
|
uint c;
|
|
|
|
c=(*s)-'0';
|
|
if (c>9)
|
|
c-=7;
|
|
colorIn<<=4;
|
|
colorIn|=c & 0xf;
|
|
s++;
|
|
}
|
|
|
|
/* hex 00RRGGBB -> GGRRWWBB */
|
|
//return _htmlColorToValueRGBW(colorIn);
|
|
return colorIn;
|
|
}
|
|
|
|
|
|
|
|
uint32_t _htmlColorToValueRGBW(uint32_t colorIn)
|
|
{
|
|
uint32_t colorOut;
|
|
/* hex 00RRGGBB -> GGRRWWBB */
|
|
/* RGBW GGRRWWBB GGRRWWBB GGRRWWBB */
|
|
/* html 00RRGGBB 00RRGGBB 00RRGGBB*/
|
|
colorOut=(colorIn & 0x00ff0000) | ((colorIn<<16) & 0xff000000) | (colorIn & 0x000000ff);
|
|
return colorOut;
|
|
}
|
|
|
|
|
|
|
|
uint32_t _rgbwToHtmlColor(uint32_t colorIn)
|
|
{
|
|
uint32_t colorOut;
|
|
/* RGBW GGRRWWBB GGRRWWBB GGRRWWBB */
|
|
/* hex 00RRGGBB 00RRGGBB 00RRGGBB*/
|
|
colorOut=(colorIn & 0x00ff0000) | ( (colorIn>>16) & 0x0000ff00) | (colorIn & 0x000000ff);
|
|
return colorOut;
|
|
}
|
|
|
|
|
|
|
|
void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
|
{
|
|
if (sValue) {
|
|
const char *sValueSystemName;
|
|
uint32_t color;
|
|
int rv;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
color=_colorFromHexString(sValue);
|
|
DBG_ERROR(NULL, "Send value [#%08x] to %s", color, sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, (double) color);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
|
{
|
|
if (sValue) {
|
|
const char *sValueSystemName;
|
|
int rv;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
if (strcasecmp(sValue, "unchanged")==0) {
|
|
DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
|
|
}
|
|
else if (strcasecmp(sValue, "on")==0) {
|
|
DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else if (strcasecmp(sValue, "off")==0) {
|
|
DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else {
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
|
{
|
|
if (sValue) {
|
|
const char *sValueSystemName;
|
|
int rv;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
if (strcasecmp(sValue, "unchanged")==0) {
|
|
DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
|
|
}
|
|
else if (strcasecmp(sValue, "on")==0) {
|
|
DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else if (strcasecmp(sValue, "off")==0) {
|
|
DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else if (strcasecmp(sValue, "auto")==0) {
|
|
DBG_ERROR(NULL, "Send value 2 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 2.0);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sValueSystemName;
|
|
const char *sValueName;
|
|
uint64_t dataPoints[2];
|
|
uint64_t recvdNum;
|
|
// uint64_t timestamp;
|
|
union {double f; uint64_t i;} u;
|
|
int intVal;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
sValueName=AQH_Value_GetName(value);
|
|
recvdNum=AQH_DataClient_GetLastData(dc, sValueSystemName, &dataPoints[0], 1);
|
|
if (recvdNum>0) {
|
|
// timestamp=dataPoints[0];
|
|
u.i=dataPoints[1];
|
|
intVal=(int) u.f;
|
|
}
|
|
else {
|
|
u.i=0;
|
|
intVal=-1;
|
|
}
|
|
|
|
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
|
|
DBG_ERROR(NULL, "Adding actor");
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW:
|
|
DBG_ERROR(NULL, "Color: %.f RGBW=%08x HTML=%08x, RGBW2=%08x",
|
|
u.f,
|
|
(uint32_t) (u.f),
|
|
_rgbwToHtmlColor(u.f),
|
|
_htmlColorToValueRGBW(_rgbwToHtmlColor(u.f)));
|
|
#if 1
|
|
GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"#%08x\"/>", sValueName, (uint32_t) (u.f));
|
|
#else
|
|
GBAA(dbuf, "<input type=\"color\" name=\"%s\" value=\"#%08x\"/>#%08x (#%08x)",
|
|
sValueName,
|
|
_rgbwToHtmlColor((unsigned int) (u.f)),
|
|
_rgbwToHtmlColor((unsigned int) (u.f)),
|
|
(uint32_t) (u.f));
|
|
#endif
|
|
break;
|
|
case AQH_ValueModality_OnOff:
|
|
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
|
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
|
GBAS(dbuf, "</select>");
|
|
break;
|
|
case AQH_ValueModality_OnOffAuto:
|
|
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
|
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"auto\" %s>auto</option>", (intVal==2)?"selected":"");
|
|
GBAS(dbuf, "</select>");
|
|
break;
|
|
default:
|
|
// GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"%.2f\"/>", sValueName, u.f);
|
|
GBAA(dbuf, "%.2f", u.f);
|
|
break;
|
|
} /* switch */
|
|
} /* if actor */
|
|
else {
|
|
DBG_ERROR(NULL, "Adding sensor (%s=%.2f)", sValueName, u.f);
|
|
GBAA(dbuf, "%.2f", u.f);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _mkValueForm(AQH_DATACLIENT *dc, const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sValueSystemName;
|
|
const char *sValueName;
|
|
uint64_t dataPoints[2];
|
|
uint64_t recvdNum;
|
|
// uint64_t timestamp;
|
|
union {double f; uint64_t i;} u;
|
|
int intVal;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
sValueName=AQH_Value_GetName(value);
|
|
recvdNum=AQH_DataClient_GetLastData(dc, sValueSystemName, &dataPoints[0], 1);
|
|
if (recvdNum>0) {
|
|
// timestamp=dataPoints[0];
|
|
u.i=dataPoints[1];
|
|
intVal=(int) u.f;
|
|
}
|
|
else {
|
|
u.i=0;
|
|
intVal=-1;
|
|
}
|
|
|
|
GBAA(dbuf,"<h1>Value %s/%s</h1>\n", sDeviceName, sValueName);
|
|
|
|
GBAS(dbuf,"<form action=\"setdata.html\" method=\"post\">\n");
|
|
GBAA(dbuf, "<input type=\"hidden\" name=\"device\" value=\"%s\">\n", sDeviceName);
|
|
GBAA(dbuf, "<input type=\"hidden\" name=\"value\" value=\"%s\">\n", sValueName);
|
|
|
|
DBG_ERROR(NULL, "Adding actor");
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW:
|
|
DBG_ERROR(NULL, "Color: %.f RGBW=%08x HTML=%08x, RGBW2=%08x",
|
|
u.f,
|
|
(uint32_t) (u.f),
|
|
_rgbwToHtmlColor(u.f),
|
|
_htmlColorToValueRGBW(_rgbwToHtmlColor(u.f)));
|
|
#if 1
|
|
GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"#%08x\"/>", sValueName, (uint32_t) (u.f));
|
|
#else
|
|
GBAA(dbuf, "<input type=\"color\" name=\"%s\" value=\"#%08x\"/>#%08x (#%08x)",
|
|
sValueName,
|
|
_rgbwToHtmlColor((unsigned int) (u.f)),
|
|
_rgbwToHtmlColor((unsigned int) (u.f)),
|
|
(uint32_t) (u.f));
|
|
#endif
|
|
break;
|
|
case AQH_ValueModality_OnOff:
|
|
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
|
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
|
GBAS(dbuf, "</select>");
|
|
break;
|
|
case AQH_ValueModality_OnOffAuto:
|
|
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
|
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
|
GBAA(dbuf, "<option value=\"auto\" %s>auto</option>", (intVal==2)?"selected":"");
|
|
GBAS(dbuf, "</select>");
|
|
break;
|
|
default:
|
|
// GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"%.2f\"/>", sValueName, u.f);
|
|
GBAA(dbuf, "%.2f", u.f);
|
|
break;
|
|
} /* switch */
|
|
|
|
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
|
GBAS(dbuf, "</form>\n\n");
|
|
}
|
|
|
|
|
|
|