Files
aqhomecontrol/apps/aqhome-tool/data/setdata.c
Martin Preuss d0c8b3b284 let setData use double values instead of strings.
this allows for storing value set with setData which can then be used in
the cgi module to retrieve the last value set.
2025-10-07 23:50:50 +02:00

169 lines
5.2 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 "./setdata.h"
#include "../client.h"
#include "../utils.h"
#include "aqhome/msg/ipc/m_ipc.h"
#include "aqhome/msg/ipc/m_ipc_result.h"
#include "aqhome/msg/ipc/data/m_ipcd.h"
#include "aqhome/msg/ipc/data/m_ipcd_setdata.h"
#include <gwenhywfar/args.h>
#include <gwenhywfar/i18n.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>
/* ------------------------------------------------------------------------------------------------
* defs
* ------------------------------------------------------------------------------------------------
*/
#define I18S(msg) msg
#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg)
#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT
#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST)
#define A_CHAR GWEN_ArgsType_Char
#define A_INT GWEN_ArgsType_Int
/* ------------------------------------------------------------------------------------------------
* forward declarations
* ------------------------------------------------------------------------------------------------
*/
static AQH_MESSAGE *_createRequestMessage(AQH_OBJECT *o, uint32_t msgId);
static int _readValueFromString(const char *s, double *pDouble);
/* ------------------------------------------------------------------------------------------------
* implementations
* ------------------------------------------------------------------------------------------------
*/
int AQH_Tool_SetData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
{
AQH_EVENT_LOOP *eventLoop;
AQH_OBJECT *o;
int rv;
const GWEN_ARGS args[]= {
/* flags type name min max s long short_descr, long_descr */
{ A_ARG, A_CHAR, "brokerAddress", 0, 1, "t", "tcpaddress", I18S("TCP address to connect to [127.0.0.1]"), NULL},
{ A_ARG, A_INT, "brokerPort", 0, 1, "P", "tcpport", I18S("Specify the TCP port to listen on"), NULL},
{ A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL},
{ A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL},
{ A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL},
{ A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL},
{ A_ARG, A_CHAR, "valueName", 1, 1, "N", "valuename", I18S("Value name (e.g. server/temp/system)"), NULL},
{ A_ARG, A_CHAR, "valueUnits", 0, 1, "U", "valueunits", I18S("Value units (e.g. \"Grad Celsius\")"), NULL},
{ A_ARG, A_CHAR, "value", 1, 1, "v", "value", I18S("Value to set"), NULL},
{ A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL}
};
eventLoop=AQH_EventLoop_new();
o=AQH_ToolClient_new(eventLoop, AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, dbGlobalArgs, args);
AQH_ToolClient_AddFlags(o, AQH_TOOL_CLIENT_CONNECTFLAGS_WITHCONNECTMSG);
AQH_ToolClient_SetCreateRequestMessageFn(o, _createRequestMessage);
rv=AQH_ToolClient_ReadLocalArgs(o, argc, argv);
if (rv!=0)
return rv;
rv=AQH_ToolClient_Run(o);
AQH_Object_free(o);
AQH_EventLoop_free(eventLoop);
return rv;
}
AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId)
{
AQH_MESSAGE *msg;
GWEN_DB_NODE *dbArgs;
const char *valueName;
const char *valueUnits;
const char *valueDataAsString;
double valueData;
AQH_VALUE *v;
int rv;
dbArgs=AQH_ToolClient_GetDbLocalArgs(o);
valueName=GWEN_DB_GetCharValue(dbArgs, "valueName", 0, NULL);
valueUnits=GWEN_DB_GetCharValue(dbArgs, "valueUnits", 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)) {
DBG_ERROR(NULL, "ERROR: Missing value name");
return NULL;
}
v=AQH_Value_new();
AQH_Value_SetNameForSystem(v, valueName);
AQH_Value_SetValueUnits(v, valueUnits);
msg=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA, msgId, 0, v, valueData);
AQH_Value_free(v);
return msg;
}
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;
}
}