348 lines
11 KiB
C
348 lines
11 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_actor.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/directory.h>
|
|
#include <gwenhywfar/debug.h>
|
|
|
|
|
|
#define DOC_PAGE2 "page.html"
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* defs and enums
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#define GBAS GWEN_Buffer_AppendString
|
|
#define GBAA GWEN_Buffer_AppendArgs
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static void _writeIntToForm(const char *sValueName, int v, 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);
|
|
|
|
static void _setIntData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
|
|
static void _setRgbwData(AQH_DATACLIENT *dc, GWEN_DB_NODE *dbPost, const char *sValueName, const AQH_VALUE *value);
|
|
static int _getColorComponent(GWEN_DB_NODE *dbPost, const char *sValueName, const char *sComponent, int defaultValue);
|
|
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_PageWriteActor(AQH_MD_PAGECTX *ctx, const char *sPageId, GWEN_XMLNODE *n, GWEN_BUFFER *dbuf)
|
|
{
|
|
const char *sActorId;
|
|
const char *sValueName;
|
|
const char *sLabel;
|
|
|
|
sActorId=GWEN_XMLNode_GetProperty(n, "id", NULL);
|
|
sLabel=GWEN_XMLNode_GetProperty(n, "label", NULL);
|
|
sValueName=GWEN_XMLNode_GetProperty(n, "value", NULL);
|
|
DBG_ERROR(NULL, "Writing page for actor \"%s\"", sValueName);
|
|
if (sActorId && *sActorId && sValueName && *sValueName) {
|
|
AQH_VALUE *value;
|
|
|
|
value=AQH_MDPageCtx_GetValue(ctx, sValueName);
|
|
if (value) {
|
|
uint32_t lastData;
|
|
|
|
lastData=AQH_ModDevices_ValueGetLastDataAsUint32(AQH_MDPageCtx_GetDataClient(ctx), value, 0);
|
|
GBAS(dbuf,"<form action=\""DOC_PAGE2"\" method=\"post\">\n");
|
|
GBAA(dbuf, "<input type=\"hidden\" name=\"page\" value=\"%s\">\n", sPageId);
|
|
GBAA(dbuf, "<input type=\"hidden\" name=\"actor\" value=\"%s\">\n", sActorId);
|
|
|
|
if (sLabel && *sLabel)
|
|
GBAA(dbuf,"<label for=\"%s\">%s</label>", sActorId, sLabel);
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW: _writeRgbwToForm(sActorId, lastData, dbuf); break;
|
|
case AQH_ValueModality_OnOff: _writeOnOffToForm(sActorId, lastData, dbuf); break;
|
|
case AQH_ValueModality_OnOffAuto: _writeOnOffAutoToForm(sActorId, lastData, dbuf); break;
|
|
default: _writeIntToForm(sActorId, lastData, dbuf); break;
|
|
} /* switch */
|
|
|
|
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
|
GBAS(dbuf, "</form>\n\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* TODO: share this with mdevices_value!! */
|
|
|
|
|
|
|
|
void _writeIntToForm(const char *sValueName, int v, GWEN_BUFFER *dbuf)
|
|
{
|
|
GBAA(dbuf, "<input type=\"number\" name=\"%s\" value=\"%d\"/>", sValueName, v);
|
|
}
|
|
|
|
|
|
|
|
void _writeRgbwToForm(const char *sValueName, uint32_t color, GWEN_BUFFER *dbuf)
|
|
{
|
|
#if 1
|
|
DBG_ERROR(NULL, "Color=%08x (%d, %d, %d, %d)",
|
|
color,
|
|
AQH_ModDevices_RgbwGetR(color),
|
|
AQH_ModDevices_RgbwGetG(color),
|
|
AQH_ModDevices_RgbwGetB(color),
|
|
AQH_ModDevices_RgbwGetW(color));
|
|
GBAA(dbuf, "<label for=\"%s_r\">R:</label>", sValueName);
|
|
GBAA(dbuf, "<input type=\"number\" min=\"0\" max=\"255\" name=\"%s_r\" id=name=\"%s_r\" value=\"%d\">",
|
|
sValueName, sValueName, AQH_ModDevices_RgbwGetR(color));
|
|
|
|
GBAA(dbuf, "<label for=\"%s_g\">G:</label>", sValueName);
|
|
GBAA(dbuf, "<input type=\"number\" min=\"0\" max=\"255\" name=\"%s_g\" id=name=\"%s_g\" value=\"%d\">",
|
|
sValueName, sValueName, AQH_ModDevices_RgbwGetG(color));
|
|
|
|
GBAA(dbuf, "<label for=\"%s_b\">B:</label>", sValueName);
|
|
GBAA(dbuf, "<input type=\"number\" min=\"0\" max=\"255\" name=\"%s_b\" id=name=\"%s_b\" value=\"%d\">",
|
|
sValueName, sValueName, AQH_ModDevices_RgbwGetB(color));
|
|
|
|
GBAA(dbuf, "<label for=\"%s_w\">W:</label>", sValueName);
|
|
GBAA(dbuf, "<input type=\"number\" min=\"0\" max=\"255\" name=\"%s_w\" id=name=\"%s_w\" value=\"%d\">",
|
|
sValueName, sValueName, AQH_ModDevices_RgbwGetW(color));
|
|
|
|
#else
|
|
GBAA(dbuf, "<input type=\"text\" name=\"%s\" id=\"%s\" value=\"#%08x\"/>", sValueName, sValueName, color);
|
|
// else
|
|
GBAA(dbuf, "<input type=\"color\" name=\"%s\" id=\"%s\" value=\"#%08x\"/>#%08x (#%08x)",
|
|
sValueName, 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\" id=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName, 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\" id=\"%s\" >" "<option value=\"unchanged\" >unchanged</option>", sValueName, 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>");
|
|
}
|
|
|
|
|
|
|
|
void AQH_ModDevices_HandlePageActor(AQH_MD_PAGECTX *ctx, AQCGI_REQUEST *rq, const char *sActorId, GWEN_XMLNODE *nActor)
|
|
{
|
|
AQH_DATACLIENT *dc;
|
|
GWEN_DB_NODE *dbPost;
|
|
const char *sValueName;
|
|
|
|
dc=AQH_MDPageCtx_GetDataClient(ctx);
|
|
dbPost=AQCGI_Request_GetDbPostBody(rq);
|
|
sValueName=GWEN_XMLNode_GetProperty(nActor, "value", NULL);
|
|
|
|
if (sValueName && *sValueName) {
|
|
AQH_VALUE *value;
|
|
|
|
value=AQH_MDPageCtx_GetValue(ctx, sValueName);
|
|
if (value) {
|
|
const char *sData;
|
|
|
|
sData=GWEN_DB_GetCharValue(dbPost, sActorId, 0, NULL);
|
|
DBG_INFO(NULL, "Setting value %s to %s", sValueName, sData?sData:"empty/no value");
|
|
switch(AQH_Value_GetModality(value)) {
|
|
case AQH_ValueModality_RGBW: _setRgbwData(dc, dbPost, sActorId, value); break;
|
|
case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sData); break;
|
|
case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sData); break;
|
|
default: _setIntData(dc, value, sData); break;
|
|
} /* switch */
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _setIntData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
|
|
{
|
|
if (sValue) {
|
|
const char *sValueSystemName;
|
|
int intVal;
|
|
int rv;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
if (1==sscanf(sValue, "%d", &intVal)) {
|
|
DBG_ERROR(NULL, "Send value [%d] to %s", intVal, sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, (double) intVal);
|
|
if (rv<0) {
|
|
DBG_ERROR(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "Not an integer value: [%s]", sValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _setRgbwData(AQH_DATACLIENT *dc, GWEN_DB_NODE *dbPost, const char *sValueName, const AQH_VALUE *value)
|
|
{
|
|
const char *sValueSystemName;
|
|
uint32_t color;
|
|
int rv;
|
|
|
|
sValueSystemName=AQH_Value_GetNameForSystem(value);
|
|
DBG_INFO(NULL, "Set value %s", sValueName);
|
|
color=AQH_ModDevices_RgbwFromComponents(_getColorComponent(dbPost, sValueName, "r", 0),
|
|
_getColorComponent(dbPost, sValueName, "g", 0),
|
|
_getColorComponent(dbPost, sValueName, "b", 0),
|
|
_getColorComponent(dbPost, sValueName, "w", 0));
|
|
DBG_INFO(NULL, "Send value [#%08x] to %s", color, sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, (double) color);
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int _getColorComponent(GWEN_DB_NODE *dbPost, const char *sValueName, const char *sComponent, int defaultValue)
|
|
{
|
|
GWEN_BUFFER *buf;
|
|
const char *sData;
|
|
int result;
|
|
|
|
buf=GWEN_Buffer_new(0, 64, 0, 1);
|
|
GBAA(buf, "%s_%s", sValueName, sComponent);
|
|
DBG_INFO(NULL, "Read value %s", GWEN_Buffer_GetStart(buf));
|
|
sData=GWEN_DB_GetCharValue(dbPost, GWEN_Buffer_GetStart(buf), 0, NULL);
|
|
GWEN_Buffer_free(buf);
|
|
if (sData) {
|
|
if (1==sscanf(sData, "%u", &result))
|
|
return result;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
|
|
|
|
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_INFO(NULL, "Value %s unchanged", sValueSystemName);
|
|
}
|
|
else if (strcasecmp(sValue, "on")==0) {
|
|
DBG_INFO(NULL, "Send value 1 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else if (strcasecmp(sValue, "off")==0) {
|
|
DBG_INFO(NULL, "Send value 0 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
|
if (rv<0) {
|
|
DBG_INFO(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_INFO(NULL, "Value %s unchanged", sValueSystemName);
|
|
}
|
|
else if (strcasecmp(sValue, "on")==0) {
|
|
DBG_INFO(NULL, "Send value 1 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 1.0);
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else if (strcasecmp(sValue, "off")==0) {
|
|
DBG_INFO(NULL, "Send value 0 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 0.0);
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else if (strcasecmp(sValue, "auto")==0) {
|
|
DBG_INFO(NULL, "Send value 2 to %s", sValueSystemName);
|
|
rv=AQH_DataClient_SetData(dc, value, 2.0);
|
|
if (rv<0) {
|
|
DBG_INFO(NULL, "Error sending data: %d", rv);
|
|
}
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|