diff --git a/apps/aqhome-data/main.c b/apps/aqhome-data/main.c index b397bca..8dec81a 100644 --- a/apps/aqhome-data/main.c +++ b/apps/aqhome-data/main.c @@ -67,7 +67,7 @@ static int _diffInSeconds(time_t t1, time_t t0); */ #ifdef HAVE_SIGNAL_H -static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT; +static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT, saPIPE; #endif static int stopService=0; @@ -210,6 +210,10 @@ int _setSignalHandlers(void) if (rv) return rv; + rv=_setupSigAction(&saPIPE, SIGPIPE); + if (rv) + return rv; + # ifdef SIGTSTP rv=_setupSigAction(&saTSTP, SIGTSTP); if (rv) @@ -251,6 +255,9 @@ void _signalHandler(int s) DBG_WARN(0, "Received signal %d, stopping service in next loop.",s); stopService=1; break; + case SIGPIPE: + DBG_WARN(0, "Received PIPE signal"); + break; default: DBG_WARN(0, "Unknown signal %d",s); break; diff --git a/apps/aqhome-data/server.c b/apps/aqhome-data/server.c index ed8e037..3a3c313 100644 --- a/apps/aqhome-data/server.c +++ b/apps/aqhome-data/server.c @@ -100,6 +100,7 @@ AQH_OBJECT *AqHomeDataServer_new(AQH_EVENT_LOOP *eventLoop) GWEN_INHERIT_SETDATA(AQH_OBJECT, AQHOME_SERVER, o, xo, _freeData); xo->storageMutex=GWEN_Mutex_new(); xo->tcpClientList=AQH_Object_List_new(); + xo->requestTree=AQH_MsgRequest_new(); AQH_Object_SetSignalHandlerFn(o, _handleSignal); diff --git a/apps/aqhome-mqttlog/main.c b/apps/aqhome-mqttlog/main.c index a9b3f06..c8ded28 100644 --- a/apps/aqhome-mqttlog/main.c +++ b/apps/aqhome-mqttlog/main.c @@ -63,7 +63,7 @@ static int _diffInSeconds(time_t t1, time_t t0); static int _setSignalHandlers(void); static int _setupSigAction(struct sigaction *sa, int sig); static void _signalHandler(int s); -static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT; +static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT, saPIPE; #endif @@ -218,6 +218,10 @@ int _setSignalHandlers(void) if (rv) return rv; + rv=_setupSigAction(&saPIPE, SIGPIPE); + if (rv) + return rv; + # ifdef SIGTSTP rv=_setupSigAction(&saTSTP, SIGTSTP); if (rv) @@ -259,6 +263,9 @@ void _signalHandler(int s) DBG_WARN(0, "Received signal %d, stopping service in next loop.",s); stopService=1; break; + case SIGPIPE: + DBG_WARN(0, "Received PIPE signal"); + break; default: DBG_WARN(0, "Unknown signal %d",s); break; diff --git a/apps/aqhome-mqttlog/s_setdata.c b/apps/aqhome-mqttlog/s_setdata.c index 83b6b90..de7c0d9 100644 --- a/apps/aqhome-mqttlog/s_setdata.c +++ b/apps/aqhome-mqttlog/s_setdata.c @@ -20,6 +20,9 @@ #include +#define DEBUG_DRY_RUN 1 /* don't actually set value if "1" */ + + /* ------------------------------------------------------------------------------------------------ * forward declarations @@ -131,9 +134,12 @@ void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData) { GWEN_BUFFER *buf; +#if !DEBUG_DRY_RUN AQH_MESSAGE *msgOut; +#endif buf=_createBufferForTopic(deviceId, topic); +#if !DEBUG_DRY_RUN DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), valueData?valueData:""); msgOut=AQH_MqttMessagePublish_new(0, 0, GWEN_Buffer_GetStart(buf), (const uint8_t*) (valueData?valueData:NULL), @@ -143,6 +149,9 @@ void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQ else { DBG_ERROR(NULL, "Error creating message"); } +#else + DBG_ERROR(NULL, "Would MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), valueData?valueData:""); +#endif GWEN_Buffer_free(buf); } diff --git a/apps/aqhome-mqttlog/server_p.h b/apps/aqhome-mqttlog/server_p.h index 34f6ad3..9ce2b8d 100644 --- a/apps/aqhome-mqttlog/server_p.h +++ b/apps/aqhome-mqttlog/server_p.h @@ -13,7 +13,6 @@ #include "./server.h" #include "aqhome-nodes/types/device.h" -#include "aqhome/nodes/nodedb.h" #include "aqhome/ipc2/msgrequest.h" #include diff --git a/apps/aqhome-nodes/main.c b/apps/aqhome-nodes/main.c index ea559b4..342bfd4 100644 --- a/apps/aqhome-nodes/main.c +++ b/apps/aqhome-nodes/main.c @@ -60,7 +60,7 @@ static int _diffInSeconds(time_t t1, time_t t0); */ #ifdef HAVE_SIGNAL_H -static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT; +static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT, saPIPE; #endif static int stopService=0; @@ -187,6 +187,10 @@ int _setSignalHandlers(void) if (rv) return rv; + rv=_setupSigAction(&saPIPE, SIGPIPE); + if (rv) + return rv; + # ifdef SIGTSTP rv=_setupSigAction(&saTSTP, SIGTSTP); if (rv) @@ -228,6 +232,9 @@ void _signalHandler(int s) DBG_WARN(0, "Received signal %d, stopping service in next loop.",s); stopService=1; break; + case SIGPIPE: + DBG_WARN(0, "Received PIPE signal"); + break; default: DBG_WARN(0, "Unknown signal %d",s); break; diff --git a/apps/aqhome-nodes/server.c b/apps/aqhome-nodes/server.c index 5d5f010..418ae5c 100644 --- a/apps/aqhome-nodes/server.c +++ b/apps/aqhome-nodes/server.c @@ -98,7 +98,7 @@ static int readIntConfigWithAlt(GWEN_DB_NODE *dbArgs, const char *varName, const static int _startIpc(AQH_OBJECT *o, AQH_NODE_SERVER *xo); static int _startTty(AQH_OBJECT *o, AQH_NODE_SERVER *xo); static int _startBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo); -static int _exchangeConnect(AQH_OBJECT *o, AQH_NODE_SERVER *xo, uint32_t flags); +static int _exchangeConnect(AQH_NODE_SERVER *xo, uint32_t flags); static void _setupDb(AQH_NODE_SERVER *xo); static int _loadDeviceList(AQH_NODE_SERVER *xo); @@ -117,7 +117,7 @@ static void _forwardTtyMsgToBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH static void _forwardValueMessageToBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _forwardDataFromSendStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _forwardDataFromRecvStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); -static void _forwardTtyMsgToClients(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); +static void _forwardTtyMsgToClients(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _publishInt(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v); static void _publishDouble(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int vModality, const char *vUnits, double v); static void _setDeviceName(AQH_VALUE *value, uint32_t uid); @@ -151,6 +151,7 @@ AQH_OBJECT *AQH_NodeServer_new(AQH_EVENT_LOOP *eventLoop) GWEN_NEW_OBJECT(AQH_NODE_SERVER, xo); GWEN_INHERIT_SETDATA(AQH_OBJECT, AQH_NODE_SERVER, o, xo, _freeData); xo->ipcClientList=AQH_Object_List_new(); + xo->requestTree=AQH_MsgRequest_new(); AQH_Object_SetSignalHandlerFn(o, _handleSignal); @@ -569,7 +570,7 @@ int _startBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo) AQH_Object_Enable(ep); xo->brokerEndpoint=ep; - rv=_exchangeConnect(o, xo, 0); + rv=_exchangeConnect(xo, 0); if (rv!=0) { DBG_ERROR(NULL, "Error connecting to broker: %d", rv); return (rv<0)?rv:GWEN_ERROR_PERMISSIONS; @@ -587,7 +588,7 @@ int _startBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo) -int _exchangeConnect(AQH_OBJECT *o, AQH_NODE_SERVER *xo, uint32_t flags) +int _exchangeConnect(AQH_NODE_SERVER *xo, uint32_t flags) { AQH_MESSAGE *msgOut; uint32_t msgId; @@ -642,6 +643,42 @@ int _loadDeviceList(AQH_NODE_SERVER *xo) +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * fini + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +void AQH_NodeServer_Fini(AQH_OBJECT *o) +{ + AQH_NODE_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_NODE_SERVER, o); + if (xo) { + AQH_OBJECT *ep; + + ep=AQH_Object_List_First(xo->ipcClientList); + while(ep) { + AQH_OBJECT *epNext; + + epNext=AQH_Object_List_Next(ep); + AQH_Object_List_Del(ep); + AQH_Object_free(ep); + ep=epNext; + } /* while */ + AQH_Object_free(xo->brokerEndpoint); + xo->brokerEndpoint=NULL; + AQH_Object_free(xo->ttyEndpoint); + xo->ttyEndpoint=NULL; + AQH_NodeServer_WriteNodeDb(o); + if (xo->pidFile) + remove(xo->pidFile); + } + +} + + + + /* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx * client management functions * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -763,7 +800,7 @@ void _handleMsgFromTty(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *ms AQH_NodeServer_NodeMsgToDb(o, msg); _writeTtyMsgToLogFile(xo, msg); _forwardTtyMsgToBroker(o, xo, msg); - _forwardTtyMsgToClients(o, xo, msg); + _forwardTtyMsgToClients(xo, msg); } @@ -783,7 +820,7 @@ void _forwardTtyMsgToBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAG -void _forwardTtyMsgToClients(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg) +void _forwardTtyMsgToClients(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg) { uint8_t code; uint32_t msgGroup; diff --git a/apps/aqhome-nodes/server.h b/apps/aqhome-nodes/server.h index 2ce1bbf..086215b 100644 --- a/apps/aqhome-nodes/server.h +++ b/apps/aqhome-nodes/server.h @@ -36,6 +36,7 @@ AQH_OBJECT *AQH_NodeServer_new(AQH_EVENT_LOOP *eventLoop); int AQH_NodeServer_Init(AQH_OBJECT *o, int argc, char **argv); +void AQH_NodeServer_Fini(AQH_OBJECT *o); /* loop functions */ void AQH_NodeServer_CleanupClients(AQH_OBJECT *o); diff --git a/apps/aqhome-react/0BUILD b/apps/aqhome-react/0BUILD index 18f6087..543ef81 100644 --- a/apps/aqhome-react/0BUILD +++ b/apps/aqhome-react/0BUILD @@ -2,6 +2,7 @@ + @@ -37,24 +38,80 @@ - aqhome_react.h - aqhome_react_p.h - init.h - fini.h - loop.h + + + + $(local/typefiles) + main.c + + + + aqhomereact + aqhome + + + + $(gwenhywfar_libs) + -lm + + + + + + + + + + + + + + + + + + $(gwenhywfar_cflags) + -I$(topsrcdir) + -I$(topbuilddir) + -I$(topsrcdir)/apps + -I$(topbuilddir)/apps + -I$(builddir) + -I$(srcdir) + + + + --include=$(builddir) + --include=$(srcdir) + + + $(visibility_cflags) + + + + + + + + + + + + + + + + + + server.h net_read.h suntimes.h $(local/typefiles) - aqhome_react.c - init.c - fini.c - loop.c + server.c net_read.c suntimes.c - main.c diff --git a/apps/aqhome-react/aqhome_react.c b/apps/aqhome-react/aqhome_react.c deleted file mode 100644 index baf0695..0000000 --- a/apps/aqhome-react/aqhome_react.c +++ /dev/null @@ -1,385 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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 -#endif - -#include "./aqhome_react_p.h" -#include "./net_read.h" -#include "aqhome-react/units/u_logical.h" -#include "aqhome-react/units/u_valuefilter.h" -#include "aqhome-react/units/u_valueset.h" -#include "aqhome-react/units/u_varset.h" -#include "aqhome-react/units/u_stabilize.h" -#include "aqhome-react/units/u_lowpass.h" -#include "aqhome-react/units/u_highpass.h" -#include "aqhome-react/units/u_zeroposnegstring.h" -#include "aqhome-react/units/u_suntime.h" -#include "aqhome-react/units/u_varchanges.h" -#include "aqhome-react/units/u_timeprogram.h" -#include "aqhome-react/units/u_statfns.h" - -#include "aqhome/data/vars_dbwrite.h" - -#include -#include - - - -AQHOME_REACT *AqHomeReact_new() -{ - AQHOME_REACT *aqh; - - GWEN_NEW_OBJECT(AQHOME_REACT, aqh); - aqh->unitList=AQHREACT_Unit_List_new(); - - return aqh; -} - - - -void AqHomeReact_free(AQHOME_REACT *aqh) -{ - if (aqh) { - AQHREACT_Unit_List_free(aqh->unitList); - GWEN_MsgEndpoint_free(aqh->brokerEndpoint); - GWEN_DB_Group_free(aqh->dbArgs); - free(aqh->varsFile); - free(aqh->pidFile); - - GWEN_FREE_OBJECT(aqh); - - } -} - - - -GWEN_MSG_ENDPOINT *AqHomeReact_GetBrokerEndpoint(const AQHOME_REACT *aqh) -{ - return aqh?(aqh->brokerEndpoint):NULL; -} - - - -GWEN_DB_NODE *AqHomeReact_GetDbArgs(const AQHOME_REACT *aqh) -{ - return aqh?(aqh->dbArgs):NULL; -} - - - -const char *AqHomeReact_GetPidFile(const AQHOME_REACT *aqh) -{ - return aqh?aqh->pidFile:NULL; -} - - - -void AqHomeReact_SetPidFile(AQHOME_REACT *aqh, const char *s) -{ - if (aqh) { - free(aqh->pidFile); - aqh->pidFile=s?strdup(s):NULL; - } -} - - - -const char *AqHomeReact_GetVarsFile(const AQHOME_REACT *aqh) -{ - return aqh?aqh->varsFile:NULL; -} - - - -void AqHomeReact_SetVarsFile(AQHOME_REACT *aqh, const char *s) -{ - if (aqh) { - free(aqh->varsFile); - aqh->varsFile=s?strdup(s):NULL; - } -} - - - -int AqHomeReact_GetTimeout(const AQHOME_REACT *aqh) -{ - return aqh?aqh->timeout:0; -} - - - -time_t AqHomeReact_GetLatestNetworkFileTime(const AQHOME_REACT *aqh) -{ - return aqh?aqh->latestNetworkFileTime:0; -} - - - -void AqHomeReact_SetLatestNetworkFileTime(AQHOME_REACT *aqh, time_t t) -{ - if (aqh) - aqh->latestNetworkFileTime=t; -} - - - -AQHREACT_UNIT *AqHomeReact_GetTimerUnit(const AQHOME_REACT *aqh) -{ - return aqh?aqh->timerUnit:NULL; -} - - - -AQHREACT_UNIT *AqHomeReact_GetServerVarChangeUnit(const AQHOME_REACT *aqh) -{ - return aqh?aqh->serverVarChangeUnit:NULL; -} - - - -AQHREACT_UNIT *AqHomeReact_FindUnitByUnitId(const AQHOME_REACT *aqh, const char *unitId) -{ - if (aqh && unitId && *unitId) { - AQHREACT_UNIT *unit; - - unit=AQHREACT_Unit_List_GetById(aqh->unitList, unitId); - if (unit==NULL) { - DBG_ERROR(NULL, "Unit \"%s\" not found", unitId); - return NULL; - } - return unit; - } - - return NULL; -} - - - -void AqHomeReact_AddUnit(AQHOME_REACT *aqh, AQHREACT_UNIT *unit) -{ - if (aqh && unit) - AQHREACT_Unit_List_Add(unit, aqh->unitList); -} - - - -AQH_VARS *AqHomeReact_GetLocalVars(const AQHOME_REACT *aqh) -{ - return aqh?aqh->localVars:NULL; -} - - - -int AqHomeReact_SetCharValue(AQHOME_REACT *aqh, const char *path, const char *value) -{ - if (aqh && aqh->localVars && path && *path) { - int rv; - uint64_t timestamp; - - timestamp=(uint64_t) time(NULL); - rv=AQH_Vars_SetCharValue(aqh->localVars, AQH_VARS_PATHFLAGS_OVERWRITE_VARS, path, value); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - AqHomeReact_UnitVarChanges_StringVarUpdated(aqh->localVarChangeUnit, path, timestamp, value); - return 0; - } - return GWEN_ERROR_INVALID; -} - - - -const char *AqHomeReact_GetCharValue(AQHOME_REACT *aqh, const char *path, int idx, const char *defaultValue) -{ - if (aqh && aqh->localVars && path && *path) { - return AQH_Vars_GetCharValue(aqh->localVars, path, idx, defaultValue); - } - return defaultValue; -} - - - -int AqHomeReact_SetDoubleValue(AQHOME_REACT *aqh, const char *path, double value) -{ - if (aqh && aqh->localVars && path && *path) { - int rv; - uint64_t timestamp; - - timestamp=(uint64_t) time(NULL); - rv=AQH_Vars_SetDoubleValue(aqh->localVars, AQH_VARS_PATHFLAGS_OVERWRITE_VARS, path, value); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - AqHomeReact_UnitVarChanges_DoubleVarUpdated(aqh->localVarChangeUnit, path, timestamp, value); - return 0; - } - return GWEN_ERROR_INVALID; -} - - - -double AqHomeReact_GetDoubleValue(AQHOME_REACT *aqh, const char *path, int idx, double defaultValue) -{ - if (aqh && aqh->localVars && path && *path) { - return AQH_Vars_GetDoubleValue(aqh->localVars, path, idx, defaultValue); - } - return defaultValue; -} - - - -int AqHomeReact_SetIntValue(AQHOME_REACT *aqh, const char *path, int value) -{ - if (aqh && aqh->localVars && path && *path) { - int rv; - uint64_t timestamp; - - timestamp=(uint64_t) time(NULL); - rv=AQH_Vars_SetIntValue(aqh->localVars, AQH_VARS_PATHFLAGS_OVERWRITE_VARS, path, value); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - AqHomeReact_UnitVarChanges_IntVarUpdated(aqh->localVarChangeUnit, path, timestamp, value); - return 0; - } - return GWEN_ERROR_INVALID; -} - - - -int AqHomeReact_GetIntValue(AQHOME_REACT *aqh, const char *path, int idx, int defaultValue) -{ - if (aqh && aqh->localVars && path && *path) { - return AQH_Vars_GetIntValue(aqh->localVars, path, idx, defaultValue); - } - return defaultValue; -} - - - -int AqHomeReact_IncIntValue(AQHOME_REACT *aqh, const char *path, int startValue, int defaultValue) -{ - if (aqh && aqh->localVars && path && *path) { - int v; - - v=AQH_Vars_GetIntValue(aqh->localVars, path, 0, startValue); - v++; - AqHomeReact_SetIntValue(aqh, path, v); - return v; - } - return defaultValue; -} - - - -int AqHomeReact_DecIntValue(AQHOME_REACT *aqh, const char *path, int startValue, int defaultValue) -{ - if (aqh && aqh->localVars && path && *path) { - int v; - - v=AQH_Vars_GetIntValue(aqh->localVars, path, 0, startValue); - v--; - AqHomeReact_SetIntValue(aqh, path, v); - return v; - } - return defaultValue; -} - - - -int AqHomeReact_WriteVarsFile(AQHOME_REACT *aqh) -{ - if (aqh && aqh->localVars && aqh->varsFile) { - int rv; - - rv=AQH_Vars_WriteDbFile(aqh->localVars, aqh->varsFile); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - } - return 0; -} - - - -AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitType) -{ - /* this does not include u_timer and u_varchanges, because those are only created once globally in init.c */ - if (aqh && unitType && *unitType) { - if (strcasecmp(unitType, "or")==0) - return AqHomeReact_UnitOr_new(aqh); - else if (strcasecmp(unitType, "and")==0) - return AqHomeReact_UnitAnd_new(aqh); - else if (strcasecmp(unitType, "xor")==0) - return AqHomeReact_UnitXor_new(aqh); - else if (strcasecmp(unitType, "valueFilter")==0) - return AqHomeReact_UnitValueFilter_new(aqh); - else if (strcasecmp(unitType, "valueSet")==0) - return AqHomeReact_UnitValueSet_new(aqh); - else if (strcasecmp(unitType, "varSet")==0) - return AqHomeReact_UnitVarSet_new(aqh); - else if (strcasecmp(unitType, "stabilize")==0) - return AqHomeReact_UnitStabilize_new(aqh); - else if (strcasecmp(unitType, "lowPass")==0) - return AqHomeReact_UnitLowPass_new(aqh); - else if (strcasecmp(unitType, "highPass")==0) - return AqHomeReact_UnitHighPass_new(aqh); - else if (strcasecmp(unitType, "zeroPosNegString")==0) - return AqHomeReact_UnitZeroPosNegString_new(aqh); - else if (strcasecmp(unitType, "suntime")==0) - return AqHomeReact_UnitSuntime_new(aqh); - else if (strcasecmp(unitType, "timeraction")==0) - return AqHomeReact_UnitTimeProgram_new(aqh); - else if (strcasecmp(unitType, "average")==0) - return AqHomeReact_UnitAverage_new(aqh); - else if (strcasecmp(unitType, "minvalue")==0) - return AqHomeReact_UnitMinValue_new(aqh); - else if (strcasecmp(unitType, "maxvalue")==0) - return AqHomeReact_UnitMaxValue_new(aqh); - else { - AQHREACT_UNIT *unit; - - DBG_INFO(NULL, "Trying to load network \"%s\"", unitType); - unit=AQHomeReact_FindAndReadDataDirNetwork(aqh, unitType); - if (unit==NULL) { - DBG_ERROR(NULL, "Unknown unit type \"%s\"", unitType); - return NULL; - } - else { - const char *s; - - s=AQHREACT_Unit_GetTypeName(unit); - if (!(s && *s && strcasecmp(s, unitType)==0)) { - DBG_ERROR(NULL, "ERROR: Network file for type \"%s\" contains type \"%s\" instead", unitType, s?s:""); - AQHREACT_Unit_free(unit); - return NULL; - } - } - return unit; - } - } - - return NULL; -} - - - - - - - - - - - diff --git a/apps/aqhome-react/aqhome_react.h b/apps/aqhome-react/aqhome_react.h deleted file mode 100644 index 66085e5..0000000 --- a/apps/aqhome-react/aqhome_react.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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_REACT_H -#define AQHOME_REACT_H - -#include - - -typedef struct AQHOME_REACT AQHOME_REACT; - -#include "aqhome-react/types/unit.h" -#include "aqhome/data/vars.h" - - -AQHOME_REACT *AqHomeReact_new(); -void AqHomeReact_free(AQHOME_REACT *aqh); - -GWEN_MSG_ENDPOINT *AqHomeReact_GetBrokerEndpoint(const AQHOME_REACT *aqh); - -GWEN_DB_NODE *AqHomeReact_GetDbArgs(const AQHOME_REACT *aqh); - -const char *AqHomeReact_GetPidFile(const AQHOME_REACT *aqh); -void AqHomeReact_SetPidFile(AQHOME_REACT *aqh, const char *s); - -const char *AqHomeReact_GetVarsFile(const AQHOME_REACT *aqh); -void AqHomeReact_SetVarsFile(AQHOME_REACT *aqh, const char *s); - -int AqHomeReact_GetTimeout(const AQHOME_REACT *aqh); - -time_t AqHomeReact_GetLatestNetworkFileTime(const AQHOME_REACT *aqh); -void AqHomeReact_SetLatestNetworkFileTime(AQHOME_REACT *aqh, time_t t); - - -AQHREACT_UNIT *AqHomeReact_GetTimerUnit(const AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_GetServerVarChangeUnit(const AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_GetLocalVarChangeUnit(const AQHOME_REACT *aqh); - -AQHREACT_UNIT *AqHomeReact_FindUnitByUnitId(const AQHOME_REACT *aqh, const char *unitId); -void AqHomeReact_AddUnit(AQHOME_REACT *aqh, AQHREACT_UNIT *unit); - -AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitType); - -AQH_VARS *AqHomeReact_GetLocalVars(const AQHOME_REACT *aqh); - -int AqHomeReact_SetCharValue(AQHOME_REACT *aqh, const char *path, const char *value); -const char *AqHomeReact_GetCharValue(AQHOME_REACT *aqh, const char *path, int idx, const char *defaultValue); - -int AqHomeReact_SetDoubleValue(AQHOME_REACT *aqh, const char *path, double value); -double AqHomeReact_GetDoubleValue(AQHOME_REACT *aqh, const char *path, int idx, double defaultValue); - -int AqHomeReact_SetIntValue(AQHOME_REACT *aqh, const char *path, int value); -int AqHomeReact_GetIntValue(AQHOME_REACT *aqh, const char *path, int idx, int defaultValue); - -int AqHomeReact_IncIntValue(AQHOME_REACT *aqh, const char *path, int startValue, int defaultValue); -int AqHomeReact_DecIntValue(AQHOME_REACT *aqh, const char *path, int startValue, int defaultValue); - -int AqHomeReact_WriteVarsFile(AQHOME_REACT *aqh); - -#endif - diff --git a/apps/aqhome-react/fini.c b/apps/aqhome-react/fini.c deleted file mode 100644 index c986810..0000000 --- a/apps/aqhome-react/fini.c +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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 -#endif - -#include "./fini.h" -#include "aqhome-react/aqhome_react_p.h" - -#include -#include -#include -#include - -#include - - - -/* ------------------------------------------------------------------------------------------------ - * defines - * ------------------------------------------------------------------------------------------------ - */ - - - -/* ------------------------------------------------------------------------------------------------ - * forward declarations - * ------------------------------------------------------------------------------------------------ - */ - - - -/* ------------------------------------------------------------------------------------------------ - * implementations - * ------------------------------------------------------------------------------------------------ - */ - -int AqHomeReact_Fini(AQHOME_REACT *aqh) -{ - if (aqh) { - GWEN_MsgEndpoint_Disconnect(aqh->brokerEndpoint); - GWEN_MsgEndpoint_free(aqh->brokerEndpoint); - aqh->brokerEndpoint=NULL; - - AQHREACT_Unit_List_Clear(aqh->unitList); - aqh->timerUnit=NULL; - aqh->serverVarChangeUnit=NULL; - aqh->localVarChangeUnit=NULL; - - if (aqh->pidFile) - remove(aqh->pidFile); - - AQH_Vars_free(aqh->localVars); - } - - return 0; -} - - - - - - diff --git a/apps/aqhome-react/fini.h b/apps/aqhome-react/fini.h deleted file mode 100644 index 8531d37..0000000 --- a/apps/aqhome-react/fini.h +++ /dev/null @@ -1,21 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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 AQHOMEREACT_FINI_H -#define AQHOMEREACT_FINI_H - - -#include "./aqhome_react.h" - - -int AqHomeReact_Fini(AQHOME_REACT *aqh); - - -#endif - - diff --git a/apps/aqhome-react/init.c b/apps/aqhome-react/init.c deleted file mode 100644 index 2887033..0000000 --- a/apps/aqhome-react/init.c +++ /dev/null @@ -1,430 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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 -#endif - -#include "./init.h" -#include "./net_read.h" -#include "./aqhome_react_p.h" -#include "aqhome-react/units/u_timer.h" -#include "aqhome-react/units/u_varchanges.h" - -#include "aqhome/aqhome.h" -#include "aqhome/ipc/endpoint_ipc.h" -#include "aqhome/ipc/endpoint_ipcclient.h" -#include "aqhome/mqtt/endpoint_mqttc.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - - -/* ------------------------------------------------------------------------------------------------ - * defines - * ------------------------------------------------------------------------------------------------ - */ - -#define I18N(msg) msg -#define I18S(msg) msg - - - -/* ------------------------------------------------------------------------------------------------ - * forward declarations - * ------------------------------------------------------------------------------------------------ - */ - -static int _createPidFile(const char *pidFilename); -static int _setupBroker(AQHOME_REACT *aqh, GWEN_DB_NODE *dbArgs); -static void _setupBuiltinUnits(AQHOME_REACT *aqh); -static int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs); - - - -/* ------------------------------------------------------------------------------------------------ - * implementations - * ------------------------------------------------------------------------------------------------ - */ - -int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv) -{ - int rv; - GWEN_DB_NODE *dbArgs; - const char *s; - - dbArgs=GWEN_DB_Group_new("args"); - rv=_readArgs(argc, argv, dbArgs); - if (rv<0) { - DBG_ERROR(NULL, "Error reading args (%d)", rv); - return rv; - } - - s=GWEN_DB_GetCharValue(dbArgs, "params", 0, NULL); - if (s && *s && strcasecmp(s, "modtest")==0) { - aqh->dbArgs=dbArgs; - return rv; - } - - AQH_MergeConfigFileIntoConfig(dbArgs, "ConfigFile"); - aqh->dbArgs=dbArgs; - - s=GWEN_DB_GetCharValue(dbArgs, "loglevel", 0, NULL); - if (s && *s) { - GWEN_LOGGER_LEVEL ll; - - ll=GWEN_Logger_Name2Level(s); - GWEN_Logger_SetLevel(NULL, ll); - } - - aqh->timeout=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 0); - - s=GWEN_DB_GetCharValue(dbArgs, "pidfile", 0, AQHOME_REACT_DEFAULT_PIDFILE); - if (s && *s) { - AqHomeReact_SetPidFile(aqh, s); - rv=_createPidFile(s); - if (rv<0) { - DBG_ERROR(NULL, "Error creating PID file (%d)", rv); - return rv; - } - } - - s=GWEN_DB_GetCharValue(dbArgs, "varsfile", 0, NULL); - if (s && *s) { - AqHomeReact_SetVarsFile(aqh, s); - } - else { - GWEN_BUFFER *bufFilename; - - bufFilename=AQH_GetRuntimeFilePath(AQHOME_REACT_DEFAULT_VARSFILE); - if (bufFilename) { - AqHomeReact_SetVarsFile(aqh, GWEN_Buffer_GetStart(bufFilename)); - GWEN_Buffer_free(bufFilename); - } - else { - DBG_ERROR(NULL, "Could not setup filename for vars, please specify via command line argument"); - return GWEN_ERROR_GENERIC; - } - } - - aqh->localVars=AQH_Vars_CreateGroup("localVars"); - - // @TODO: read vars from file - - rv=AqHomeReact_ReloadUnitNets(aqh); - if (rv<0) { - DBG_ERROR(NULL, "Error reading unit network files (%d)", rv); - return rv; - } - - rv=_setupBroker(aqh, dbArgs); - if (rv<0) { - DBG_ERROR(NULL, "Error setting up connection to broker (%d)", rv); - return rv; - } - - return 0; -} - - - -int AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh) -{ - int rv; - - AQHREACT_Unit_List_Clear(aqh->unitList); - aqh->timerUnit=NULL; - aqh->serverVarChangeUnit=NULL; - - _setupBuiltinUnits(aqh); - - rv=AQHomeReact_ReadUnitNetFiles(aqh); - if (rv<0) { - DBG_ERROR(NULL, "Error reading network files (%d)", rv); - return rv; - } - { - GWEN_BUFFER *dbuf; - - dbuf=GWEN_Buffer_new(0, 256, 0, 1); - AQHREACT_Unit_List_Dump(aqh->unitList, dbuf, 2, "Loaded networks:"); - fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(dbuf)); - GWEN_Buffer_free(dbuf); - } - - return 0; -} - - - -int _createPidFile(const char *pidFilename) -{ - FILE *f; - int pidfd; - - if (remove(pidFilename)==0) { - DBG_ERROR(0, "Old PID file existed, removed. (Unclean shutdown?)"); - } - -#ifdef HAVE_SYS_STAT_H - pidfd = open(pidFilename, O_EXCL|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (pidfd < 0) { - DBG_ERROR(NULL, "Could not create PID file \"%s\" (%s), aborting.", pidFilename, strerror(errno)); - return GWEN_ERROR_IO; - } - - f = fdopen(pidfd, "w"); -#else /* HAVE_STAT_H */ - f=fopen(pidFilename,"w+"); -#endif /* HAVE_STAT_H */ - - /* write pid */ -#ifdef HAVE_GETPID - fprintf(f,"%d\n",getpid()); -#else - fprintf(f,"-1\n"); -#endif - if (fclose(f)) { - DBG_ERROR(0, "Could not close PID file \"%s\" (%s), aborting.", pidFilename, strerror(errno)); - return GWEN_ERROR_IO; - } - return 0; -} - - - -int _setupBroker(AQHOME_REACT *aqh, GWEN_DB_NODE *dbArgs) -{ - const char *brokerAddress; - int brokerPort; - const char *brokerClientId; - - brokerAddress=GWEN_DB_GetCharValue(dbArgs, "brokerAddress", 0, NULL); - if (!(brokerAddress && *brokerAddress)) - brokerAddress=GWEN_DB_GetCharValue(dbArgs, "ConfigFile/brokerAddress", 0, "127.0.0.1"); - - brokerPort=GWEN_DB_GetIntValue(dbArgs, "brokerPort", 0, -1); - if (brokerPort<0) - brokerPort=GWEN_DB_GetIntValue(dbArgs, "ConfigFile/brokerPort", 0, AQHOME_REACT_DEFAULT_BROKER_PORT); - - brokerClientId=GWEN_DB_GetCharValue(dbArgs, "brokerClientId", 0, AQHOME_REACT_DEFAULT_BROKER_CLIENTID); - - if (brokerAddress && *brokerAddress && brokerPort) { - GWEN_MSG_ENDPOINT *ep; - GWEN_MSG_ENDPOINT *ipcBaseEndpoint; - int rv; - - ep=AQH_ClientIpcEndpoint_new("brokerIpcClient", 0); - GWEN_MsgEndpoint_AddFlags(ep, AQH_IPCENDPOINT_FLAGS_WANTUPDATES); - ipcBaseEndpoint=AQH_IpcEndpoint_CreateIpcTcpClient(brokerAddress, brokerPort, "brokerPhysEndpoint", 0); - AQH_IpcEndpoint_SetServiceName(ipcBaseEndpoint, brokerClientId); - GWEN_MsgEndpoint_Tree2_AddChild(ep, ipcBaseEndpoint); - - aqh->brokerEndpoint=ep; - - rv=GWEN_MultilayerEndpoint_StartConnect(ep); - if (rv<0 && rv!=GWEN_ERROR_IN_PROGRESS) { - DBG_ERROR(NULL, "Error connecting to broker server %s:%d (%d), will retry later", brokerAddress, brokerPort, rv); - return rv; - } - } - - return 0; -} - - - -void _setupBuiltinUnits(AQHOME_REACT *aqh) -{ - AQHREACT_UNIT *unit; - - unit=AqHomeReact_UnitTimer_new(aqh); - AQHREACT_Unit_SetId(unit, ".timer"); - AQHREACT_Unit_List_Add(unit, aqh->unitList); - aqh->timerUnit=unit; - - unit=AqHomeReact_UnitVarChanges_new(aqh); - AQHREACT_Unit_SetId(unit, ".updatedValue"); - AQHREACT_Unit_List_Add(unit, aqh->unitList); - aqh->serverVarChangeUnit=unit; - - unit=AqHomeReact_UnitVarChanges_new(aqh); - AQHREACT_Unit_SetId(unit, ".updatedVar"); - AQHREACT_Unit_List_Add(unit, aqh->unitList); - aqh->localVarChangeUnit=unit; -} - - - -int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs) -{ - int rv; - const GWEN_ARGS args[]= { - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "loglevel", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "L", /* short option */ - "loglevel", /* long option */ - I18S("Specify loglevel"), /* short description */ - I18S("Specify loglevel") /* long description */ - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "cfgdir", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "D", /* short option */ - "cfgdir", /* long option */ - I18S("Specify the configuration folder"), - I18S("Specify the configuration folder") - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "charset", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - 0, /* short option */ - "charset", /* long option */ - I18S("Specify the output character set"), /* short description */ - I18S("Specify the output character set") /* long description */ - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "brokerAddress", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "ba", /* short option */ - "brokeraddress", /* long option */ - I18S("Specify the address of the broker server to connect to (disabled if missing)"), - I18S("Specify the address of the broker server to connect to (disabled if missing)") - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Int, /* type */ - "brokerPort", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "bp", /* short option */ - "brokerport", /* long option */ - I18S("Specify the port of the broker server (default: 1899)"), - I18S("Specify the port of the broker server (default: 1899)") - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "brokerClientId", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - NULL, /* short option */ - "brokerclientid", /* long option */ - I18S("Specify client id for the broker server (default: \"nodes\")"), - I18S("Specify client id for the broker server (default: \"nodes\")") - }, - - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "pidfile", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "p", /* short option */ - "pidfile", /* long option */ - I18S("Specify the PID file"), - I18S("Specify the PID file") - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Int, /* type */ - "timeout", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "T", /* short option */ - "timeout", /* long option */ - I18S("Specify timeout in second (default: no timeout)"), - I18S("Specify timeout in second (default: no timeout)") - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "devicefile", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "d", /* short option */ - "devicefile", /* long option */ - I18S("Specify the device file"), - I18S("Specify the device file") - }, - { - GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ - GWEN_ArgsType_Char, /* type */ - "varsfile", /* name */ - 0, /* minnum */ - 1, /* maxnum */ - "V", /* short option */ - "varsfile", /* long option */ - I18S("Specify the vars file"), - I18S("Specify the vars file") - }, - { - GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */ - GWEN_ArgsType_Int, /* type */ - "help", /* name */ - 0, /* minnum */ - 0, /* maxnum */ - "h", /* short option */ - "help", - I18S("Show this help screen."), - I18S("Show this help screen.") - } - }; - - rv=GWEN_Args_Check(argc, argv, 1, GWEN_ARGS_MODE_ALLOW_FREEPARAM | GWEN_ARGS_MODE_STOP_AT_FREEPARAM, args, dbArgs); - if (rv==GWEN_ARGS_RESULT_ERROR) { - fprintf(stderr, "ERROR: Could not parse arguments main\n"); - return GWEN_ERROR_INVALID; - } - else if (rv==GWEN_ARGS_RESULT_HELP) { - GWEN_BUFFER *ubuf; - - ubuf=GWEN_Buffer_new(0, 1024, 0, 1); - GWEN_Buffer_AppendArgs(ubuf, - I18N("This is version %s.\nUsage: %s [OPTIONS]\n\nOptions:\n"), - AQHOME_VERSION_STRING, - argv[0]); - if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) { - fprintf(stderr, "ERROR: Could not create help string\n"); - return 1; - } - GWEN_Buffer_AppendString(ubuf, "\n"); - - fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf)); - GWEN_Buffer_free(ubuf); - return GWEN_ERROR_CLOSE; - } - return rv; -} - - - - - diff --git a/apps/aqhome-react/init.h b/apps/aqhome-react/init.h deleted file mode 100644 index 0cd8f13..0000000 --- a/apps/aqhome-react/init.h +++ /dev/null @@ -1,22 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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 AQHOMEREACT_INIT_H -#define AQHOMEREACT_INIT_H - - -#include "./aqhome_react.h" - - -int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv); - -int AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh); - -#endif - - diff --git a/apps/aqhome-react/loop.c b/apps/aqhome-react/loop.c deleted file mode 100644 index 8f2041d..0000000 --- a/apps/aqhome-react/loop.c +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqHome. - * AqHome (c) by 2024 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 -#endif - -#include "./loop.h" -#include "./aqhome_react_p.h" -#include "aqhome-react/units/u_varchanges.h" - -#include "aqhome/ipc/data/ipc_data.h" -#include "aqhome/ipc/data/msg_data_multidata.h" -#include "aqhome/ipc/msg_ipc_tag16.h" - -#include - -#include - - - -/* ------------------------------------------------------------------------------------------------ - * defines - * ------------------------------------------------------------------------------------------------ - */ - - - -/* ------------------------------------------------------------------------------------------------ - * forward declarations - * ------------------------------------------------------------------------------------------------ - */ - -static void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg); -static int _processAllUnits(AQHOME_REACT *aqh); - - - -/* ------------------------------------------------------------------------------------------------ - * implementations - * ------------------------------------------------------------------------------------------------ - */ - -void AqHomeReact_IoLoop(AQHOME_REACT *aqh, int timeoutInMilliSecs) -{ - GWEN_MSG *msg; - - GWEN_MsgEndpoint_IoLoop(aqh->brokerEndpoint, timeoutInMilliSecs); - - while( (msg=GWEN_MsgEndpoint_TakeFirstReceivedMessage(aqh->brokerEndpoint)) ) { - uint16_t code; - - code=GWEN_IpcMsg_GetCode(msg); - if (code==AQH_MSGTYPE_IPC_DATA_DATACHANGED) { - DBG_DEBUG(NULL, "Received expected IPC message"); - _handleDataResponse(aqh->serverVarChangeUnit, msg); - } - else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) { - DBG_INFO(NULL, "Received IPC result message, ignoring"); - } - else { - DBG_INFO(NULL, "Received unexpected message %d (%x)", code, code); - } - GWEN_Msg_free(msg); - } /* while */ -} - - - -void AqHomeReact_ProcessAllUnits(AQHOME_REACT *aqh) -{ - int rv; - - do { - rv=_processAllUnits(aqh); - } while (rv==1); -} - - - -int _processAllUnits(AQHOME_REACT *aqh) -{ - int result=0; - AQHREACT_UNIT *unit; - - unit=AQHREACT_Unit_List_First(aqh->unitList); - while(unit) { - int rv; - - rv=AQHREACT_Unit_Process(unit); - if (rv>0) - result=1; - unit=AQHREACT_Unit_List_Next(unit); - } - - return result; -} - - -void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg) -{ - AQH_VALUE *value; - const GWEN_TAG16 *tag; - unsigned int numberOfPoints; - const uint64_t *dataPoints; - - AQH_MultiDataDataIpcMsg_Parse(msg, 0); - value=AQH_MultiDataDataIpcMsg_ReadValue(msg); - - tag=AQH_Tag16IpcMsg_FindFirstTagByType(msg, AQH_MSGDATA_MULTIDATA_TAGS_DATA); - numberOfPoints=(tag?GWEN_Tag16_GetTagLength(tag):0)/(2*sizeof(uint64_t)); - dataPoints=tag?((const uint64_t*) GWEN_Tag16_GetTagData(tag)):NULL; - if (numberOfPoints>0 && dataPoints) { - uint32_t i; - - for(i=0; i #endif -#include "./init.h" -#include "./fini.h" -#include "./loop.h" +#include "./server.h" #include "./net_read.h" #include "aqhome-react/units/u_timer.h" -#include "aqhome-react/types/prgrule-t.h" +#include "aqhome-react/types/prgrule.h" +//#include "aqhome-react/types/prgrule-t.h" #include "aqhome/aqhome.h" #include "aqhome/data/path-t.h" #include "aqhome/data/vars-t.h" -#include "aqhome/data/vars_dbread-t.h" -#include "aqhome/data/vars_dbwrite-t.h" +//#include "aqhome/data/vars_dbread-t.h" +//#include "aqhome/data/vars_dbwrite-t.h" #include #include @@ -59,20 +58,24 @@ #define AQHOME_REACT_READNET_INTERVAL 300 #define AQHOME_REACT_SAVE_INTERVAL 300 +#define CONNCLEAN_INTERVAL_IN_SECS 2 +#define CONNCHECK_INTERVAL_IN_SECS 10 + /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ -static void _serve(AQHOME_REACT *aqh); -static int _testModules(int argc, char **argv); +static void _runService(AQH_OBJECT *aqh, AQH_EVENT_LOOP *eventLoop); +static int _diffInSeconds(time_t t1, time_t t0); +//static int _testModules(int argc, char **argv); #ifdef HAVE_SIGNAL_H static int _setSignalHandlers(void); static int _setupSigAction(struct sigaction *sa, int sig); static void _signalHandler(int s); -static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT; +static struct sigaction saINT,saTERM, saHUP, saTSTP, saCONT, saPIPE; #endif @@ -93,11 +96,10 @@ static int stopService=0; int main(int argc, char **argv) { - AQHOME_REACT *aqh; - GWEN_DB_NODE *dbArgs; int rv; + AQH_EVENT_LOOP *eventLoop; + AQH_OBJECT *aqh; GWEN_GUI *gui; - const char *s; rv=GWEN_Init(); if (rv) { @@ -106,7 +108,14 @@ int main(int argc, char **argv) } GWEN_Logger_Open(0, "aqhome-react", 0, GWEN_LoggerType_Console, GWEN_LoggerFacility_User); - GWEN_Logger_SetLevel(0, GWEN_LoggerLevel_Warning); + //GWEN_Logger_SetLevel(0, GWEN_LoggerLevel_Warning); + GWEN_Logger_SetLevel(0, GWEN_LoggerLevel_Info); + + rv=_setSignalHandlers(); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } rv=AQH_Init(); if (rv<0) { @@ -115,127 +124,93 @@ int main(int argc, char **argv) } gui=GWEN_Gui_CGui_new(); + GWEN_Gui_SetGui(gui); - aqh=AqHomeReact_new(); - rv=AqHomeReact_Init(aqh, argc, argv); - dbArgs=AqHomeReact_GetDbArgs(aqh); - DBG_ERROR(NULL, "RV=%d", rv); + eventLoop=AQH_EventLoop_new(); + aqh=AQH_ReactServer_new(eventLoop); + rv=AQH_ReactServer_Init(aqh, argc, argv); if (rv<0) { if (rv==GWEN_ERROR_CLOSE) return 1; DBG_INFO(NULL, "here (%d)", rv); return 2; } - else if (rv>0) { - argc-=rv; - argv+=rv; - s=GWEN_DB_GetCharValue(dbArgs, "params", 0, NULL); - if (s && *s && strcasecmp(s, "modtest")==0) - rv=_testModules(argc, argv); - else { - DBG_ERROR(NULL, "Invalid command \"%s\"", s?s:""); - return 1; - } - } - else { - s=GWEN_DB_GetCharValue(dbArgs, "charset", 0, NULL); - if (s && *s) - GWEN_Gui_SetCharSet(gui, s); - GWEN_Gui_SetGui(gui); + _runService(aqh, eventLoop); - _serve(aqh); - rv=0; - } - - AqHomeReact_Fini(aqh); - AqHomeReact_free(aqh); + //AQH_NodeServer_Fini(aqh); + AQH_Object_free(aqh); GWEN_Gui_SetGui(NULL); GWEN_Gui_free(gui); - return rv; + return 0; } -void _serve(AQHOME_REACT *aqh) +void _runService(AQH_OBJECT *aqh, AQH_EVENT_LOOP *eventLoop) { - int rv; + time_t timeStart; int timeout; - time_t startTime; - time_t lastTimerTime; + time_t timeLastConnCheck; time_t lastFileScanTime; time_t lastSaveTime; - GWEN_DB_NODE *dbArgs; - AQHREACT_UNIT *timerUnit; - startTime=time(NULL); - lastTimerTime=startTime; - lastFileScanTime=startTime; - lastSaveTime=startTime; + timeout=AQH_ReactServer_GetTimeout(aqh); + timeStart=time(NULL); + timeLastConnCheck=time(NULL); + lastFileScanTime=timeStart; + lastSaveTime=timeStart; - AqHomeReact_SetLatestNetworkFileTime(aqh, AQHomeReact_GetNewestUnitNetFiletime()); - - dbArgs=AqHomeReact_GetDbArgs(aqh); - timerUnit=AqHomeReact_GetTimerUnit(aqh); - - rv=_setSignalHandlers(); - if (rv<0) { - DBG_ERROR(NULL, "Error setting signal handlers (%d)", rv); - return; - } - - timeout=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 0); + AQH_ReactServer_SetLatestNetworkFileTime(aqh, AQH_ReactServer_GetNewestUnitNetFiletime()); while(!stopService) { time_t now; + int rv; - DBG_DEBUG(NULL, "Next loop"); - - AqHomeReact_IoLoop(aqh, 500); + AQH_EventLoop_Run(eventLoop, 2000); + AQH_ReactServer_HandleBrokerMsgs(aqh); now=time(NULL); - if (now!=lastTimerTime) { - lastTimerTime=now; - AqHomeReact_UnitTimer_GenerateTick(timerUnit); + + if (_diffInSeconds(now, timeLastConnCheck)>CONNCHECK_INTERVAL_IN_SECS) { + DBG_ERROR(NULL, "Check connections"); + AQH_ReactServer_CheckBrokerConnection(aqh); + timeLastConnCheck=now; } - AqHomeReact_ProcessAllUnits(aqh); + AQH_ReactServer_ProcessAllUnits(aqh); - if ((now-lastFileScanTime)>AQHOME_REACT_READNET_INTERVAL) { + if (_diffInSeconds(now, lastFileScanTime)>AQHOME_REACT_READNET_INTERVAL) { time_t tNew; time_t t; DBG_INFO(NULL, "Checking network files"); - tNew=AQHomeReact_GetNewestUnitNetFiletime(); - t=AqHomeReact_GetLatestNetworkFileTime(aqh); + tNew=AQH_ReactServer_GetNewestUnitNetFiletime(); + t=AQH_ReactServer_GetLatestNetworkFileTime(aqh); if (tNew && tNew>t) { DBG_INFO(NULL, "Reloading network files"); - AqHomeReact_ReloadUnitNets(aqh); - AqHomeReact_SetLatestNetworkFileTime(aqh, tNew); + AQH_ReactServer_ReloadUnitNets(aqh); + AQH_ReactServer_SetLatestNetworkFileTime(aqh, tNew); } lastFileScanTime=now; } - if (now-lastSaveTime>AQHOME_REACT_SAVE_INTERVAL) { + if (_diffInSeconds(now, lastSaveTime)>AQHOME_REACT_SAVE_INTERVAL) { DBG_ERROR(NULL, "Writing var file"); - rv=AqHomeReact_WriteVarsFile(aqh); + rv=AQH_ReactServer_WriteVarsFile(aqh); if (rv<0) { DBG_INFO(NULL, "Error writing runtime data"); } lastSaveTime=time(NULL); } - if (timeout) { - if ((now-startTime)>timeout) { - DBG_ERROR(NULL, "Timeout, stopping service"); - break; - } + if (timeout && (_diffInSeconds(now, timeStart)>timeout)) { + DBG_INFO(NULL, "Timeout"); + break; } - } /* while */ - } @@ -257,6 +232,10 @@ int _setSignalHandlers(void) if (rv) return rv; + rv=_setupSigAction(&saPIPE, SIGPIPE); + if (rv) + return rv; + # ifdef SIGTSTP rv=_setupSigAction(&saTSTP, SIGTSTP); if (rv) @@ -298,6 +277,9 @@ void _signalHandler(int s) DBG_WARN(0, "Received signal %d, stopping service in next loop.",s); stopService=1; break; + case SIGPIPE: + DBG_WARN(0, "Received PIPE signal"); + break; default: DBG_WARN(0, "Unknown signal %d",s); break; @@ -305,7 +287,7 @@ void _signalHandler(int s) } - +#if 0 int _testModules(int argc, char **argv) { GWEN_GUI *gui; @@ -362,7 +344,13 @@ int _testModules(int argc, char **argv) GWEN_Gui_free(gui); return 0; } +#endif +int _diffInSeconds(time_t t1, time_t t0) +{ + return t1-t0; +} + diff --git a/apps/aqhome-react/net_read.c b/apps/aqhome-react/net_read.c index a5a7583..dad8496 100644 --- a/apps/aqhome-react/net_read.c +++ b/apps/aqhome-react/net_read.c @@ -1,6 +1,6 @@ /**************************************************************************** * This file is part of the project AqHome. - * AqHome (c) by 2024 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 * should have received along with this file. @@ -11,6 +11,7 @@ #endif #include "./net_read.h" +#include "./server_p.h" #include "aqhome-react/aqhome_react_p.h" #include "aqhome-react/types/unit.h" #include "aqhome-react/units/u_module.h" @@ -35,9 +36,9 @@ */ static time_t _getNewestFiletimeFromFileList(const GWEN_STRINGLIST *sl); -static AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename); +static AQHREACT_UNIT *_readNetworkFromFile(AQH_OBJECT *o, const char *filename); static GWEN_XMLNODE *_readUnitNetFileToXml(const char *sFilename); -static int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList); +static int _readUnitNetFilesIntoList(AQH_OBJECT *o, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList); @@ -47,7 +48,7 @@ static int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *s */ -time_t AQHomeReact_GetNewestUnitNetFiletime(void) +time_t AQH_ReactServer_GetNewestUnitNetFiletime(void) { GWEN_STRINGLIST *sl; time_t t1; @@ -66,62 +67,73 @@ time_t AQHomeReact_GetNewestUnitNetFiletime(void) -int AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh) +int AQH_ReactServer_ReadUnitNetFiles(AQH_OBJECT *aqh) { - GWEN_STRINGLIST *sl; + AQH_REACT_SERVER *xo; - sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml"); - if (sl) { - int rv; + xo=AQH_ReactServer_GetServerData(aqh); + if (xo) { + GWEN_STRINGLIST *sl; - GWEN_StringList_Sort(sl, 1, GWEN_StringList_SortModeNoCase); - rv=_readUnitNetFilesIntoList(aqh, sl, aqh->unitList); - GWEN_StringList_free(sl); - if (rv<0) { - DBG_INFO(NULL, "Error reading unit network files (%d)", rv); - return rv; + sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml"); + if (sl) { + int rv; + + GWEN_StringList_Sort(sl, 1, GWEN_StringList_SortModeNoCase); + rv=_readUnitNetFilesIntoList(aqh, sl, xo->unitList); + GWEN_StringList_free(sl); + if (rv<0) { + DBG_INFO(NULL, "Error reading unit network files (%d)", rv); + return rv; + } } + else { + DBG_ERROR(NULL, "No unit network files"); + } + return 0; } - else { - DBG_ERROR(NULL, "No unit network files"); - } - return 0; + return GWEN_ERROR_INVALID; } -AQHREACT_UNIT *AQHomeReact_FindAndReadDataDirNetwork(AQHOME_REACT *aqh, const char *networkName) +AQHREACT_UNIT *AQH_ReactServer_FindAndReadDataDirNetwork(AQH_OBJECT *o, const char *networkName) { - if (aqh && networkName) { - AQHREACT_UNIT *unit; - GWEN_BUFFER *bufFilename; - GWEN_BUFFER *bufPath; - const char *s; + if (o && networkName) { + AQH_REACT_SERVER *xo; + + xo=AQH_ReactServer_GetServerData(o); + if (xo) { + AQHREACT_UNIT *unit; + GWEN_BUFFER *bufFilename; + GWEN_BUFFER *bufPath; + const char *s; - bufFilename=GWEN_Buffer_new(0, 256, 0, 1); - GWEN_Buffer_AppendString(bufFilename, "aqhome/react/networks/"); - s=networkName; - while(*s) - GWEN_Buffer_AppendByte(bufFilename, tolower((unsigned char) *(s++))); - GWEN_Buffer_AppendString(bufFilename, ".xml"); + bufFilename=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendString(bufFilename, "aqhome/react/networks/"); + s=networkName; + while(*s) + GWEN_Buffer_AppendByte(bufFilename, tolower((unsigned char) *(s++))); + GWEN_Buffer_AppendString(bufFilename, ".xml"); - bufPath=AQH_FindPathOfDataFile(GWEN_Buffer_GetStart(bufFilename)); - if (bufPath==NULL) { - DBG_ERROR(NULL, "Network file \"%s\" not found in data folders", GWEN_Buffer_GetStart(bufFilename)); + bufPath=AQH_FindPathOfDataFile(GWEN_Buffer_GetStart(bufFilename)); + if (bufPath==NULL) { + DBG_ERROR(NULL, "Network file \"%s\" not found in data folders", GWEN_Buffer_GetStart(bufFilename)); + GWEN_Buffer_free(bufFilename); + return NULL; + } GWEN_Buffer_free(bufFilename); - return NULL; - } - GWEN_Buffer_free(bufFilename); - unit=_readNetworkFromFile(aqh, GWEN_Buffer_GetStart(bufPath)); - if (unit==NULL) { - DBG_ERROR(NULL, "Error reading network from file \"%s\"", GWEN_Buffer_GetStart(bufPath)); + unit=_readNetworkFromFile(o, GWEN_Buffer_GetStart(bufPath)); + if (unit==NULL) { + DBG_ERROR(NULL, "Error reading network from file \"%s\"", GWEN_Buffer_GetStart(bufPath)); + GWEN_Buffer_free(bufPath); + return NULL; + } + GWEN_Buffer_free(bufPath); - return NULL; + return unit; } - - GWEN_Buffer_free(bufPath); - return unit; } return NULL; } @@ -162,7 +174,7 @@ time_t _getNewestFiletimeFromFileList(const GWEN_STRINGLIST *sl) -AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename) +AQHREACT_UNIT *_readNetworkFromFile(AQH_OBJECT *o, const char *filename) { GWEN_XMLNODE *n; AQHREACT_UNIT *unit; @@ -173,7 +185,7 @@ AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename) return NULL; } - unit=AqHomeReact_UnitModule_fromXml(aqh, n); + unit=AqHomeReact_UnitModule_fromXml(o, n); if (unit==NULL) { DBG_ERROR(NULL, "Error reading network from file \"%s\"", filename); GWEN_XMLNode_free(n); @@ -214,7 +226,7 @@ GWEN_XMLNODE *_readUnitNetFileToXml(const char *sFilename) -int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList) +int _readUnitNetFilesIntoList(AQH_OBJECT *o, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList) { GWEN_STRINGLISTENTRY *se; @@ -227,7 +239,7 @@ int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHR AQHREACT_UNIT *unit; DBG_INFO(NULL, "Reading unit network file \"%s\"", s); - unit=_readNetworkFromFile(aqh, s); + unit=_readNetworkFromFile(o, s); if (unit==NULL) { DBG_WARN(NULL, "No network read from network file \"%s\"", s); return GWEN_ERROR_GENERIC; diff --git a/apps/aqhome-react/net_read.h b/apps/aqhome-react/net_read.h index 3773e3a..52ebff5 100644 --- a/apps/aqhome-react/net_read.h +++ b/apps/aqhome-react/net_read.h @@ -1,6 +1,6 @@ /**************************************************************************** * This file is part of the project AqHome. - * AqHome (c) by 2024 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 * should have received along with this file. @@ -13,10 +13,10 @@ #include "./aqhome_react.h" -int AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh); -AQHREACT_UNIT *AQHomeReact_FindAndReadDataDirNetwork(AQHOME_REACT *aqh, const char *networkName); +int AQH_ReactServer_ReadUnitNetFiles(AQH_OBJECT *aqh); +AQHREACT_UNIT *AQH_ReactServer_FindAndReadDataDirNetwork(AQH_OBJECT *aqh, const char *networkName); -time_t AQHomeReact_GetNewestUnitNetFiletime(void); +time_t AQH_ReactServer_GetNewestUnitNetFiletime(void); #endif diff --git a/apps/aqhome-react/server.c b/apps/aqhome-react/server.c new file mode 100644 index 0000000..693eca1 --- /dev/null +++ b/apps/aqhome-react/server.c @@ -0,0 +1,1207 @@ +/**************************************************************************** + * 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 +#endif + +#include "./server_p.h" +#include "./net_read.h" + +#include "aqhome-react/units/u_timer.h" +#include "aqhome-react/units/u_logical.h" +#include "aqhome-react/units/u_valuefilter.h" +#include "aqhome-react/units/u_valueset.h" +#include "aqhome-react/units/u_varset.h" +#include "aqhome-react/units/u_stabilize.h" +#include "aqhome-react/units/u_lowpass.h" +#include "aqhome-react/units/u_highpass.h" +#include "aqhome-react/units/u_zeroposnegstring.h" +#include "aqhome-react/units/u_suntime.h" +#include "aqhome-react/units/u_varchanges.h" +#include "aqhome-react/units/u_timeprogram.h" +#include "aqhome-react/units/u_statfns.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define I18N(msg) msg +#define I18S(msg) 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 + +#define AQH_REACT_SERVER_BROKER_RESTARTTIME 10 + + +enum { + AQH_REACT_SERVER_SLOT_BROKERCLOSED=1, +}; + + + +/* ------------------------------------------------------------------------------------------------ + * global vars + * ------------------------------------------------------------------------------------------------ + */ + +GWEN_INHERIT(AQH_OBJECT, AQH_REACT_SERVER) + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p); + +static void _setBrokerAddress(AQH_OBJECT *o, const char *s); +static void _setBrokerPort(AQH_OBJECT *o, int i); +static void _setBrokerClientId(AQH_OBJECT *o, const char *s); + +static void _readConfig(AQH_OBJECT *o, AQH_REACT_SERVER *xo, GWEN_DB_NODE *dbArgs); +static const char *readCharConfigWithAlt(GWEN_DB_NODE *dbArgs, const char *varName, const char *altVarName, const char *defaultValue); +static int readIntConfigWithAlt(GWEN_DB_NODE *dbArgs, const char *varName, const char *altVarName, int defaultValue, int nonValue); + +static int _startBroker(AQH_OBJECT *o, AQH_REACT_SERVER *xo); +static int _exchangeBrokerConnect(AQH_REACT_SERVER *xo, uint32_t flags); + +static void _handleMsgFromBroker(AQH_REACT_SERVER *xo, const AQH_MESSAGE *msg); +static void _handleBrokerChangeData(AQHREACT_UNIT *varChangeUnit, const GWEN_TAG16_LIST *tagList); + +static int _handleSignal(AQH_OBJECT *o, uint32_t slotId, AQH_OBJECT *senderObject, GWEN_UNUSED int param1, void *param2); +static int _handleBrokerDown(AQH_REACT_SERVER *xo); + +static void _setupBuiltinUnits(AQH_OBJECT *o, AQH_REACT_SERVER *xo); +static int _processAllUnits(AQH_OBJECT *o); + +static int _createPidFile(const char *pidFilename); +static int _diffInSeconds(time_t t1, time_t t0); + +static int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs); + + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * constructor, destructor + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +AQH_OBJECT *AQH_ReactServer_new(AQH_EVENT_LOOP *eventLoop) +{ + AQH_OBJECT *o; + AQH_REACT_SERVER *xo; + + o=AQH_Object_new(eventLoop); + GWEN_NEW_OBJECT(AQH_REACT_SERVER, xo); + GWEN_INHERIT_SETDATA(AQH_OBJECT, AQH_REACT_SERVER, o, xo, _freeData); + + AQH_Object_SetSignalHandlerFn(o, _handleSignal); + xo->timeoutInSeconds=5; + xo->unitList=AQHREACT_Unit_List_new(); + + return o; +} + + + +void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p) +{ + AQH_REACT_SERVER *xo; + + xo=(AQH_REACT_SERVER*) p; + + AQH_Object_free(xo->brokerEndpoint); + + + GWEN_FREE_OBJECT(xo); +} + + + +AQH_REACT_SERVER *AQH_ReactServer_GetServerData(const AQH_OBJECT *o) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + return xo; + } + return NULL; +} + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * getter, setter + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +int AQH_ReactServer_GetTimeout(const AQH_OBJECT *o) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) + return xo->timeout; + } + return 0; +} + + + +void _setPidFile(AQH_OBJECT *o, const char *s) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + free(xo->pidFile); + xo->pidFile=s?strdup(s):NULL; + } + } +} + + + +void _setBrokerAddress(AQH_OBJECT *o, const char *s) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + free(xo->brokerAddress); + xo->brokerAddress=s?strdup(s):NULL; + } + } +} + + + +void _setBrokerPort(AQH_OBJECT *o, int i) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) + xo->brokerPort=i; + } +} + + + +void _setBrokerClientId(AQH_OBJECT *o, const char *s) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + free(xo->brokerClientId); + xo->brokerClientId=s?strdup(s):NULL; + } + } +} + + + +void AQH_ReactServer_SetVarsFile(AQH_OBJECT *o, const char *s) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + free(xo->varsFile); + xo->varsFile=s?strdup(s):NULL; + } + } +} + + + +AQH_OBJECT *AQH_ReactServer_GetBrokerEndpoint(const AQH_OBJECT *o) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) + return xo->brokerEndpoint; + } + return 0; +} + + + +time_t AQH_ReactServer_GetLatestNetworkFileTime(const AQH_OBJECT *aqh) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo) + return xo->latestNetworkFileTime; + } + return 0; +} + + + +void AQH_ReactServer_SetLatestNetworkFileTime(AQH_OBJECT *aqh, time_t t) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo) + xo->latestNetworkFileTime=t; + } +} + + + +AQHREACT_UNIT *AQH_ReactServer_GetTimerUnit(const AQH_OBJECT *aqh) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo) + return xo->timerUnit; + } + return NULL; +} + + + +AQHREACT_UNIT *AQH_ReactServer_GetServerVarChangeUnit(const AQH_OBJECT *aqh) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo) + return xo->serverVarChangeUnit; + } + return NULL; +} + + + + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * init + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +int AQH_ReactServer_Init(AQH_OBJECT *o, int argc, char **argv) +{ + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + GWEN_DB_NODE *dbArgs; + int rv; + const char *s; + + dbArgs=GWEN_DB_Group_new("args"); + rv=_readArgs(argc, argv, dbArgs); + if (rv<0) { + DBG_ERROR(NULL, "Error reading args (%d)", rv); + return rv; + } + AQH_MergeConfigFileIntoConfig(dbArgs, "ConfigFile"); + _readConfig(o, xo, dbArgs); + + s=GWEN_DB_GetCharValue(dbArgs, "loglevel", 0, NULL); + if (s && *s) { + GWEN_LOGGER_LEVEL ll; + + ll=GWEN_Logger_Name2Level(s); + GWEN_Logger_SetLevel(NULL, ll); + } + + s=GWEN_DB_GetCharValue(dbArgs, "pidfile", 0, AQHOME_REACT_DEFAULT_PIDFILE); + if (s && *s) { + _setPidFile(o, s); + rv=_createPidFile(s); + if (rv<0) { + DBG_ERROR(NULL, "Error creating PID file (%d)", rv); + return rv; + } + } + + s=GWEN_DB_GetCharValue(dbArgs, "varsfile", 0, NULL); + if (s && *s) { + AQH_ReactServer_SetVarsFile(o, s); + } + else { + GWEN_BUFFER *bufFilename; + + bufFilename=AQH_GetRuntimeFilePath(AQHOME_REACT_DEFAULT_VARSFILE); + if (bufFilename) { + AQH_ReactServer_SetVarsFile(o, GWEN_Buffer_GetStart(bufFilename)); + GWEN_Buffer_free(bufFilename); + } + else { + DBG_ERROR(NULL, "Could not setup filename for vars, please specify via command line argument"); + return GWEN_ERROR_GENERIC; + } + } + + xo->localVars=AQH_Vars_CreateGroup("localVars"); + + // @TODO: read vars from file + + rv=AQH_ReactServer_ReloadUnitNets(o); + if (rv<0) { + DBG_ERROR(NULL, "Error reading unit network files (%d)", rv); + return rv; + } + + DBG_INFO(NULL, "Starting Broker Connection"); + rv=_startBroker(o, xo); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + return 0; + } + else { + DBG_ERROR(NULL, "Not of type AQH_REACT_SERVER object"); + return GWEN_ERROR_INVALID; + } +} + + + +void _readConfig(AQH_OBJECT *o, AQH_REACT_SERVER *xo, GWEN_DB_NODE *dbArgs) +{ + xo->dbArgs=dbArgs; + + xo->timeout=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 0); + + AQH_ReactServer_SetVarsFile(o, readCharConfigWithAlt(dbArgs, "varsfile", "ConfigFile/reactVarsFile", NULL)); + + _setBrokerAddress(o, readCharConfigWithAlt(dbArgs, "brokerAddress", "ConfigFile/brokerAddress", "127.0.0.1")); + _setBrokerPort(o, readIntConfigWithAlt(dbArgs, "brokerPort", "ConfigFile/brokerPort", AQHOME_REACT_DEFAULT_BROKER_PORT, -1)); + _setBrokerClientId(o, GWEN_DB_GetCharValue(dbArgs, "brokerClientId", 0, AQHOME_REACT_DEFAULT_BROKER_CLIENTID)); + +} + + + +const char *readCharConfigWithAlt(GWEN_DB_NODE *dbArgs, const char *varName, const char *altVarName, const char *defaultValue) +{ + const char *s; + + s=GWEN_DB_GetCharValue(dbArgs, varName, 0, NULL); + if (!(s && *s)) + s=GWEN_DB_GetCharValue(dbArgs, altVarName, 0, NULL); + return (s && *s)?s:defaultValue; +} + + + +int readIntConfigWithAlt(GWEN_DB_NODE *dbArgs, const char *varName, const char *altVarName, int defaultValue, int nonValue) +{ + int i; + + i=GWEN_DB_GetIntValue(dbArgs, varName, 0, nonValue); + if (i==nonValue) + i=GWEN_DB_GetIntValue(dbArgs, altVarName, 0, nonValue); + return (i!=nonValue)?i:defaultValue; +} + + + +int _startBroker(AQH_OBJECT *o, AQH_REACT_SERVER *xo) +{ + if (xo->brokerEndpoint) { + AQH_Object_Disable(xo->brokerEndpoint); + AQH_Object_free(xo->brokerEndpoint); + xo->brokerEndpoint=NULL; + } + + if (xo->brokerAddress && *(xo->brokerAddress) && xo->brokerPort) { + AQH_OBJECT *ep; + int fd; + int rv; + + fd=AQH_TcpObject_CreateConnectedSocket(xo->brokerAddress, xo->brokerPort); + if (fd<0) { + DBG_ERROR(NULL, "Error connecting to broker server %s:%d", xo->brokerAddress, xo->brokerPort); + return GWEN_ERROR_IO; + } + DBG_ERROR(NULL, "Physically connected to broker server %s:%d", xo->brokerAddress, xo->brokerPort); + + ep=AQH_IpcClientObject_new(AQH_Object_GetEventLoop(o), fd); + assert(ep); + AQH_Endpoint_SetServiceName(ep, xo->brokerClientId); + AQH_Object_AddLink(ep, AQH_ENDPOINT_SIGNAL_CLOSED, AQH_REACT_SERVER_SLOT_BROKERCLOSED, o); + AQH_Object_Enable(ep); + xo->brokerEndpoint=ep; + + rv=_exchangeBrokerConnect(xo, AQH_MSG_CONNECT_FLAGS_WANTUPDATES); + if (rv!=0) { + DBG_ERROR(NULL, "Error connecting to broker: %d", rv); + return (rv<0)?rv:GWEN_ERROR_PERMISSIONS; + } + DBG_ERROR(NULL, "Connected to broker at %s:%d", xo->brokerAddress, xo->brokerPort); + return 0; + } + else { + DBG_ERROR(NULL, "No server settings"); + return GWEN_ERROR_BAD_DATA; + } + + return 0; +} + + + +int _exchangeBrokerConnect(AQH_REACT_SERVER *xo, uint32_t flags) +{ + AQH_MESSAGE *msgOut; + uint32_t msgId; + + msgId=AQH_Endpoint_GetNextMessageId(xo->brokerEndpoint); + msgOut=AQH_IpcMessageConnect_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, + AQH_MSGTYPE_IPC_CONNECT_REQ, + msgId, 0, + xo->brokerClientId, NULL, NULL, flags); + AQH_Endpoint_AddMsgOut(xo->brokerEndpoint, msgOut); + return AQH_IpcEndpoint_WaitForResultMsg(xo->brokerEndpoint, + AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, AQH_MSGTYPE_IPC_RESULT, + msgId, xo->timeoutInSeconds); +} + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * fini + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +void AQH_ReactServer_Fini(AQH_OBJECT *o) +{ + if (o) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo && xo->brokerEndpoint) { + if (xo->brokerEndpoint) { + AQH_Object_free(xo->brokerEndpoint); + xo->brokerEndpoint=NULL; + } + + AQHREACT_Unit_List_Clear(xo->unitList); + xo->timerUnit=NULL; + xo->serverVarChangeUnit=NULL; + xo->localVarChangeUnit=NULL; + AQH_Vars_free(xo->localVars); + xo->localVars=NULL; + if (xo->pidFile) + remove(xo->pidFile); + } + } +} + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * broker management functions + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +void AQH_ReactServer_HandleBrokerMsgs(AQH_OBJECT *o) +{ + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo && xo->brokerEndpoint) { + AQH_MESSAGE *msg; + + while( (msg=AQH_Endpoint_GetNextMsgIn(xo->brokerEndpoint)) ) { + AQH_Message_SetObject(msg, xo->brokerEndpoint); + _handleMsgFromBroker(xo, msg); + AQH_Message_free(msg); + } + } +} + + + +void _handleMsgFromBroker(AQH_REACT_SERVER *xo, const AQH_MESSAGE *msg) +{ + uint16_t code; + uint8_t protoId; + + /* exec IPC message */ + code=AQH_IpcMessage_GetCode(msg); + protoId=AQH_IpcMessage_GetProtoId(msg); + if (protoId==AQH_IPC_PROTOCOL_DATA_ID) { + GWEN_TAG16_LIST *tagList; + + tagList=AQH_IpcMessageTag16_ParsePayload(msg, 0); + if (tagList) { + DBG_ERROR(NULL, "Received IPC packet %d (%x)", (int) code, code); + switch(code) { + case AQH_MSGTYPE_IPC_DATA_DATACHANGED: _handleBrokerChangeData(xo->serverVarChangeUnit, tagList); break; + default: break; + } + GWEN_Tag16_List_free(tagList); + } + } + else { + DBG_ERROR(NULL, "Invalid IPC protocol %d (%02x)", protoId, protoId); + } +} + + + +void _handleBrokerChangeData(AQHREACT_UNIT *varChangeUnit, const GWEN_TAG16_LIST *tagList) +{ + AQH_VALUE *value; + uint64_t numberOfPoints; + const uint64_t *dataPoints; + + value=AQH_IpcdMessageMultiData_ReadValue(tagList); + if (value) { + AQH_IpcdMessageMultiData_ReadDatapoints(tagList, &dataPoints, &numberOfPoints); + DBG_ERROR(NULL, "Value changed on server: %s (%d data points)", + AQH_Value_GetNameForSystem(value), + (int) numberOfPoints); + if (numberOfPoints>0 && dataPoints) { + uint32_t i; + + for(i=0; idbArgs) { + if (xo->brokerEndpoint) { + if (AQH_Object_GetFlags(xo->brokerEndpoint) & AQH_OBJECT_FLAGS_DELETE) { + DBG_ERROR(NULL, "Deleting broker connection"); + AQH_Object_Disable(xo->brokerEndpoint); + AQH_Object_free(xo->brokerEndpoint); + xo->brokerEndpoint=NULL; + } + } + + if (xo->brokerEndpoint==NULL) { + time_t now; + + now=time(NULL); + if (_diffInSeconds(now, xo->timestampBrokerDown)>AQH_REACT_SERVER_BROKER_RESTARTTIME) { + int rv; + + DBG_ERROR(NULL, "Restarting broker connection"); + rv=_startBroker(o, xo); + if (rv<0) { + DBG_ERROR(NULL, "here (%d)", rv); + } + } + } + } +} + + + + + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * signal handler + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +int _handleSignal(AQH_OBJECT *o, uint32_t slotId, GWEN_UNUSED AQH_OBJECT *senderObject, GWEN_UNUSED int param1, GWEN_UNUSED void *param2) +{ + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + switch(slotId) { + case AQH_REACT_SERVER_SLOT_BROKERCLOSED: return _handleBrokerDown(xo); + default: + break; + } + } + + return 0; /* not handled */ +} + + + +int _handleBrokerDown(AQH_REACT_SERVER *xo) +{ + if (xo->brokerEndpoint) { + DBG_ERROR(NULL, "Broker connection down"); + AQH_Object_AddFlags(xo->brokerEndpoint, AQH_OBJECT_FLAGS_DELETE); + xo->timestampBrokerDown=time(NULL); + } + return 1; +} + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * unit management + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + + +int AQH_ReactServer_ReloadUnitNets(AQH_OBJECT *o) +{ + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + int rv; + + AQHREACT_Unit_List_Clear(xo->unitList); + xo->timerUnit=NULL; + xo->serverVarChangeUnit=NULL; + + _setupBuiltinUnits(o, xo); + + rv=AQH_ReactServer_ReadUnitNetFiles(o); + if (rv<0) { + DBG_ERROR(NULL, "Error reading network files (%d)", rv); + return rv; + } + { + GWEN_BUFFER *dbuf; + + dbuf=GWEN_Buffer_new(0, 256, 0, 1); + AQHREACT_Unit_List_Dump(xo->unitList, dbuf, 2, "Loaded networks:"); + fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(dbuf)); + GWEN_Buffer_free(dbuf); + } + return 0; + } + return GWEN_ERROR_INVALID; +} + + + +void _setupBuiltinUnits(AQH_OBJECT *aqh, AQH_REACT_SERVER *xo) +{ + AQHREACT_UNIT *unit; + + unit=AqHomeReact_UnitTimer_new(aqh); + AQHREACT_Unit_SetId(unit, ".timer"); + AQHREACT_Unit_List_Add(unit, xo->unitList); + xo->timerUnit=unit; + + unit=AqHomeReact_UnitVarChanges_new(aqh); + AQHREACT_Unit_SetId(unit, ".updatedValue"); + AQHREACT_Unit_List_Add(unit, xo->unitList); + xo->serverVarChangeUnit=unit; + + unit=AqHomeReact_UnitVarChanges_new(aqh); + AQHREACT_Unit_SetId(unit, ".updatedVar"); + AQHREACT_Unit_List_Add(unit, xo->unitList); + xo->localVarChangeUnit=unit; +} + + + +void AQH_ReactServer_ProcessAllUnits(AQH_OBJECT *o) +{ + int rv; + + do { + rv=_processAllUnits(o); + } while (rv==1); +} + + + +int _processAllUnits(AQH_OBJECT *o) +{ + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, o); + if (xo) { + int result=0; + AQHREACT_UNIT *unit; + + unit=AQHREACT_Unit_List_First(xo->unitList); + while(unit) { + int rv; + + rv=AQHREACT_Unit_Process(unit); + if (rv>0) + result=1; + unit=AQHREACT_Unit_List_Next(unit); + } + + return result; + } + return GWEN_ERROR_INVALID; +} + + + +AQHREACT_UNIT *AQH_ReactServer_CreateUnitByName(AQH_OBJECT *aqh, const char *unitType) +{ + /* this does not include u_timer and u_varchanges, because those are only created once globally in init.c */ + if (aqh && unitType && *unitType) { + if (strcasecmp(unitType, "or")==0) + return AqHomeReact_UnitOr_new(aqh); + else if (strcasecmp(unitType, "and")==0) + return AqHomeReact_UnitAnd_new(aqh); + else if (strcasecmp(unitType, "xor")==0) + return AqHomeReact_UnitXor_new(aqh); + else if (strcasecmp(unitType, "valueFilter")==0) + return AqHomeReact_UnitValueFilter_new(aqh); + else if (strcasecmp(unitType, "valueSet")==0) + return AqHomeReact_UnitValueSet_new(aqh); + else if (strcasecmp(unitType, "varSet")==0) + return AqHomeReact_UnitVarSet_new(aqh); + else if (strcasecmp(unitType, "stabilize")==0) + return AqHomeReact_UnitStabilize_new(aqh); + else if (strcasecmp(unitType, "lowPass")==0) + return AqHomeReact_UnitLowPass_new(aqh); + else if (strcasecmp(unitType, "highPass")==0) + return AqHomeReact_UnitHighPass_new(aqh); + else if (strcasecmp(unitType, "zeroPosNegString")==0) + return AqHomeReact_UnitZeroPosNegString_new(aqh); + else if (strcasecmp(unitType, "suntime")==0) + return AqHomeReact_UnitSuntime_new(aqh); + else if (strcasecmp(unitType, "timeraction")==0) + return AqHomeReact_UnitTimeProgram_new(aqh); + else if (strcasecmp(unitType, "average")==0) + return AqHomeReact_UnitAverage_new(aqh); + else if (strcasecmp(unitType, "minvalue")==0) + return AqHomeReact_UnitMinValue_new(aqh); + else if (strcasecmp(unitType, "maxvalue")==0) + return AqHomeReact_UnitMaxValue_new(aqh); + else { + AQHREACT_UNIT *unit; + + DBG_INFO(NULL, "Trying to load network \"%s\"", unitType); + unit=AQH_ReactServer_FindAndReadDataDirNetwork(aqh, unitType); + if (unit==NULL) { + DBG_ERROR(NULL, "Unknown unit type \"%s\"", unitType); + return NULL; + } + else { + const char *s; + + s=AQHREACT_Unit_GetTypeName(unit); + if (!(s && *s && strcasecmp(s, unitType)==0)) { + DBG_ERROR(NULL, "ERROR: Network file for type \"%s\" contains type \"%s\" instead", unitType, s?s:""); + AQHREACT_Unit_free(unit); + return NULL; + } + } + return unit; + } + } + + return NULL; +} + + + +AQHREACT_UNIT *AQH_ReactServer_FindUnitByUnitId(const AQH_OBJECT *aqh, const char *unitId) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && unitId && *unitId) { + AQHREACT_UNIT *unit; + + unit=AQHREACT_Unit_List_GetById(xo->unitList, unitId); + if (unit==NULL) { + DBG_ERROR(NULL, "Unit \"%s\" not found", unitId); + return NULL; + } + return unit; + } + } + + return NULL; +} + + + +void AQH_ReactServer_AddUnit(AQH_OBJECT *aqh, AQHREACT_UNIT *unit) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->unitList) + AQHREACT_Unit_List_Add(unit, xo->unitList); + } +} + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * localvar management + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +int AQH_ReactServer_SetCharValue(AQH_OBJECT *aqh, const char *path, const char *value) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo) { + if (xo->localVars && path && *path) { + int rv; + uint64_t timestamp; + + timestamp=(uint64_t) time(NULL); + rv=AQH_Vars_SetCharValue(xo->localVars, AQH_VARS_PATHFLAGS_OVERWRITE_VARS, path, value); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + AqHomeReact_UnitVarChanges_StringVarUpdated(xo->localVarChangeUnit, path, timestamp, value); + return 0; + } + } + } + return GWEN_ERROR_INVALID; +} + + + +const char *AQH_ReactServer_GetCharValue(AQH_OBJECT *aqh, const char *path, int idx, const char *defaultValue) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo) { + if (xo->localVars && path && *path) { + return AQH_Vars_GetCharValue(xo->localVars, path, idx, defaultValue); + } + } + } + return defaultValue; +} + + + +int AQH_ReactServer_SetDoubleValue(AQH_OBJECT *aqh, const char *path, double value) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && path && *path) { + int rv; + uint64_t timestamp; + + timestamp=(uint64_t) time(NULL); + rv=AQH_Vars_SetDoubleValue(xo->localVars, AQH_VARS_PATHFLAGS_OVERWRITE_VARS, path, value); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + AqHomeReact_UnitVarChanges_DoubleVarUpdated(xo->localVarChangeUnit, path, timestamp, value); + return 0; + } + } + return GWEN_ERROR_INVALID; +} + + + +double AQH_ReactServer_GetDoubleValue(AQH_OBJECT *aqh, const char *path, int idx, double defaultValue) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && path && *path) { + return AQH_Vars_GetDoubleValue(xo->localVars, path, idx, defaultValue); + } + } + return defaultValue; +} + + + +int AQH_ReactServer_SetIntValue(AQH_OBJECT *aqh, const char *path, int value) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && path && *path) { + int rv; + uint64_t timestamp; + + timestamp=(uint64_t) time(NULL); + rv=AQH_Vars_SetIntValue(xo->localVars, AQH_VARS_PATHFLAGS_OVERWRITE_VARS, path, value); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + AqHomeReact_UnitVarChanges_IntVarUpdated(xo->localVarChangeUnit, path, timestamp, value); + return 0; + } + } + return GWEN_ERROR_INVALID; +} + + + +int AQH_ReactServer_GetIntValue(AQH_OBJECT *aqh, const char *path, int idx, int defaultValue) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && path && *path) { + return AQH_Vars_GetIntValue(xo->localVars, path, idx, defaultValue); + } + } + return defaultValue; +} + + + +int AQH_ReactServer_IncIntValue(AQH_OBJECT *aqh, const char *path, int startValue, int defaultValue) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && path && *path) { + int v; + + v=AQH_Vars_GetIntValue(xo->localVars, path, 0, startValue); + v++; + AQH_ReactServer_SetIntValue(aqh, path, v); + return v; + } + } + return defaultValue; +} + + + +int AQH_ReactServer_DecIntValue(AQH_OBJECT *aqh, const char *path, int startValue, int defaultValue) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && path && *path) { + int v; + + v=AQH_Vars_GetIntValue(xo->localVars, path, 0, startValue); + v--; + AQH_ReactServer_SetIntValue(aqh, path, v); + return v; + } + } + return defaultValue; +} + + + +int AQH_ReactServer_WriteVarsFile(AQH_OBJECT *aqh) +{ + if (aqh) { + AQH_REACT_SERVER *xo; + + xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_REACT_SERVER, aqh); + if (xo && xo->localVars && xo->varsFile) { + int rv; + + rv=AQH_Vars_WriteDbFile(xo->localVars, xo->varsFile); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + } + return 0; + } + return GWEN_ERROR_INVALID; +} + + + + + +/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + * helper functions + * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + */ + +int _createPidFile(const char *pidFilename) +{ + FILE *f; + int pidfd; + + if (remove(pidFilename)==0) { + DBG_ERROR(0, "Old PID file existed, removed. (Unclean shutdown?)"); + } + +#ifdef HAVE_SYS_STAT_H + pidfd = open(pidFilename, O_EXCL|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (pidfd < 0) { + DBG_ERROR(NULL, "Could not create PID file \"%s\" (%s), aborting.", pidFilename, strerror(errno)); + return GWEN_ERROR_IO; + } + + f = fdopen(pidfd, "w"); +#else /* HAVE_STAT_H */ + f=fopen(pidFilename,"w+"); +#endif /* HAVE_STAT_H */ + + /* write pid */ +#ifdef HAVE_GETPID + fprintf(f,"%d\n",getpid()); +#else + fprintf(f,"-1\n"); +#endif + if (fclose(f)) { + DBG_ERROR(0, "Could not close PID file \"%s\" (%s), aborting.", pidFilename, strerror(errno)); + return GWEN_ERROR_IO; + } + return 0; +} + + + +int _diffInSeconds(time_t t1, time_t t0) +{ + return t1-t0; +} + + + +int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs) +{ + int rv; + const GWEN_ARGS args[]= { + /* flags type name min max s long short_descr, long_descr */ + { A_ARG, A_CHAR, "loglevel", 0, 1, "L", "loglevel", I18S("Specify loglevel"), NULL}, + { A_ARG, A_CHAR, "cfgdir", 0, 1, "D", "cfgdir", I18S("Specify the configuration folder"), NULL}, + { A_ARG, A_CHAR, "charset", 0, 1, NULL, "charset", I18S("Specify the output character set"), NULL}, + { A_ARG, A_CHAR, "brokerAddress", 0, 1, "ba", "brokerddress", I18S("Broker address [127.0.0.1]"), NULL}, + { A_ARG, A_INT, "brokerPort", 0, 1, "bp", "brokerport", I18S("Broker port [1899]"), NULL}, + { A_ARG, A_CHAR, "brokerClientId", 0, 1, NULL, "brokerclientid", I18S("Broker client id"), NULL}, + { A_ARG, A_CHAR, "deviceFile", 0, 1, "d", "devicefile", I18S("Device file"), NULL}, + { A_ARG, A_CHAR, "varsFile", 0, 1, "V", "varsfile", I18S("File to store status variables"), NULL}, + { A_ARG, A_CHAR, "pidfile", 0, 1, "p", "pidfile", I18S("PID file"), NULL}, + { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("timeout in seconds [0]"), NULL}, + { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL} + }; + + rv=GWEN_Args_Check(argc, argv, 1, 0, args, dbArgs); + if (rv==GWEN_ARGS_RESULT_ERROR) { + fprintf(stderr, "ERROR: Could not parse arguments main\n"); + return GWEN_ERROR_INVALID; + } + else if (rv==GWEN_ARGS_RESULT_HELP) { + GWEN_BUFFER *ubuf; + + ubuf=GWEN_Buffer_new(0, 1024, 0, 1); + GWEN_Buffer_AppendArgs(ubuf, + I18N("This is version %s.\nUsage: %s [OPTIONS]\n\nOptions:\n"), + AQHOME_VERSION_STRING, + argv[0]); + if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) { + fprintf(stderr, "ERROR: Could not create help string\n"); + return 1; + } + GWEN_Buffer_AppendString(ubuf, "\n"); + + fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf)); + GWEN_Buffer_free(ubuf); + return GWEN_ERROR_CLOSE; + } + return 0; +} + + + diff --git a/apps/aqhome-react/server.h b/apps/aqhome-react/server.h new file mode 100644 index 0000000..d6fd79c --- /dev/null +++ b/apps/aqhome-react/server.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * 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_REACT_SERVER_H +#define AQHOME_REACT_SERVER_H + +#include + +#include "aqhome-react/types/unit.h" +#include "aqhome/data/vars.h" + + + +AQH_OBJECT *AQH_ReactServer_new(AQH_EVENT_LOOP *eventLoop); +int AQH_ReactServer_Init(AQH_OBJECT *o, int argc, char **argv); +void AQH_ReactServer_Fini(AQH_OBJECT *o); + +int AQH_ReactServer_GetTimeout(const AQH_OBJECT *o); +void AQH_ReactServer_SetVarsFile(AQH_OBJECT *o, const char *s); +time_t AQH_ReactServer_GetLatestNetworkFileTime(const AQH_OBJECT *aqh); +void AQH_ReactServer_SetLatestNetworkFileTime(AQH_OBJECT *aqh, time_t t); + +AQHREACT_UNIT *AQH_ReactServer_GetTimerUnit(const AQH_OBJECT *aqh); +AQHREACT_UNIT *AQH_ReactServer_GetServerVarChangeUnit(const AQH_OBJECT *aqh); +AQH_OBJECT *AQH_ReactServer_GetBrokerEndpoint(const AQH_OBJECT *o); + +void AQH_ReactServer_HandleBrokerMsgs(AQH_OBJECT *o); +void AQH_ReactServer_CheckBrokerConnection(AQH_OBJECT *o); +void AQH_ReactServer_ProcessAllUnits(AQH_OBJECT *o); + +AQHREACT_UNIT *AQH_ReactServer_CreateUnitByName(AQH_OBJECT *aqh, const char *unitType); +int AQH_ReactServer_ReloadUnitNets(AQH_OBJECT *o); +AQHREACT_UNIT *AQH_ReactServer_FindUnitByUnitId(const AQH_OBJECT *aqh, const char *unitId); +void AQH_ReactServer_AddUnit(AQH_OBJECT *aqh, AQHREACT_UNIT *unit); + + + +int AQH_ReactServer_SetCharValue(AQH_OBJECT *aqh, const char *path, const char *value); +const char *AQH_ReactServer_GetCharValue(AQH_OBJECT *aqh, const char *path, int idx, const char *defaultValue); +int AQH_ReactServer_SetDoubleValue(AQH_OBJECT *aqh, const char *path, double value); +double AQH_ReactServer_GetDoubleValue(AQH_OBJECT *aqh, const char *path, int idx, double defaultValue); +int AQH_ReactServer_SetIntValue(AQH_OBJECT *aqh, const char *path, int value); +int AQH_ReactServer_GetIntValue(AQH_OBJECT *aqh, const char *path, int idx, int defaultValue); +int AQH_ReactServer_IncIntValue(AQH_OBJECT *aqh, const char *path, int startValue, int defaultValue); +int AQH_ReactServer_DecIntValue(AQH_OBJECT *aqh, const char *path, int startValue, int defaultValue); + +int AQH_ReactServer_WriteVarsFile(AQH_OBJECT *aqh); + + + +#endif + diff --git a/apps/aqhome-react/aqhome_react_p.h b/apps/aqhome-react/server_p.h similarity index 66% rename from apps/aqhome-react/aqhome_react_p.h rename to apps/aqhome-react/server_p.h index 3867d90..13f5b5f 100644 --- a/apps/aqhome-react/aqhome_react_p.h +++ b/apps/aqhome-react/server_p.h @@ -1,21 +1,22 @@ /**************************************************************************** * 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 * should have received along with this file. ****************************************************************************/ -#ifndef AQHOME_REACT_P_H -#define AQHOME_REACT_P_H +#ifndef AQHOME_REACT_SERVER_P_H +#define AQHOME_REACT_SERVER_P_H -#include "./aqhome_react.h" +#include "./server.h" -#include +#include +/* default values */ #define AQHOME_REACT_DEFAULT_PIDFILE "/var/run/aqhome-react.pid" #define AQHOME_REACT_DEFAULT_DATADIR "/var/lib/aqhome-react" #define AQHOME_REACT_DEFAULT_VARSFILE "vars.conf" @@ -25,8 +26,9 @@ -struct AQHOME_REACT { - GWEN_MSG_ENDPOINT *brokerEndpoint; +typedef struct AQH_REACT_SERVER AQH_REACT_SERVER; +struct AQH_REACT_SERVER { + AQH_OBJECT *brokerEndpoint; GWEN_DB_NODE *dbArgs; char *pidFile; @@ -34,6 +36,10 @@ struct AQHOME_REACT { int timeout; /* timeout for run e.g. inside valgrind */ + char *brokerAddress; + int brokerPort; + char *brokerClientId; + AQHREACT_UNIT *timerUnit; AQHREACT_UNIT *serverVarChangeUnit; AQHREACT_UNIT *localVarChangeUnit; @@ -42,8 +48,17 @@ struct AQHOME_REACT { AQH_VARS *localVars; time_t latestNetworkFileTime; + + time_t timestampBrokerDown; + + int timeoutInSeconds; + }; +AQH_REACT_SERVER *AQH_ReactServer_GetServerData(const AQH_OBJECT *o); + + #endif + diff --git a/apps/aqhome-react/suntimes.h b/apps/aqhome-react/suntimes.h index ea50526..5c0d9fd 100644 --- a/apps/aqhome-react/suntimes.h +++ b/apps/aqhome-react/suntimes.h @@ -10,8 +10,6 @@ #define AQHOMEREACT_SUNTIMES_H -#include "./aqhome_react.h" - #include #include diff --git a/apps/aqhome-react/types/prgrule.c b/apps/aqhome-react/types/prgrule.c index 7c1016b..5d80ea1 100644 --- a/apps/aqhome-react/types/prgrule.c +++ b/apps/aqhome-react/types/prgrule.c @@ -419,7 +419,7 @@ void _setBitField(uint64_t *ptrBitField, int startValue, int endValue) -#include "prgrule-t.c" +//#include "prgrule-t.c" diff --git a/apps/aqhome-react/types/unit.c b/apps/aqhome-react/types/unit.c index e3e7f9e..0deee87 100644 --- a/apps/aqhome-react/types/unit.c +++ b/apps/aqhome-react/types/unit.c @@ -21,7 +21,7 @@ GWEN_INHERIT_FUNCTIONS(AQHREACT_UNIT) -AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AQHREACT_Unit_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -55,7 +55,7 @@ void AQHREACT_Unit_free(AQHREACT_UNIT *unit) -AQHOME_REACT *AQHREACT_Unit_GetAqHomeReact(const AQHREACT_UNIT *unit) +AQH_OBJECT *AQHREACT_Unit_GetAqHomeReact(const AQHREACT_UNIT *unit) { return unit?unit->aqHomeReact:NULL; } diff --git a/apps/aqhome-react/types/unit.h b/apps/aqhome-react/types/unit.h index e64e1ad..b4570b8 100644 --- a/apps/aqhome-react/types/unit.h +++ b/apps/aqhome-react/types/unit.h @@ -25,6 +25,7 @@ GWEN_INHERIT_FUNCTION_DEFS(AQHREACT_UNIT) #define AQHREACT_UNIT_FLAGS_INVERT 0x10000000 /** invert output of boolean units */ +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/port.h" #include "aqhome-react/types/param.h" @@ -40,10 +41,10 @@ typedef void (*AQHREACT_UNIT_DUMP_FN)(const AQHREACT_UNIT *unit, GWEN_BUFFER *bu -AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AQHREACT_Unit_new(AQH_OBJECT *aqh); void AQHREACT_Unit_free(AQHREACT_UNIT *unit); -AQHOME_REACT *AQHREACT_Unit_GetAqHomeReact(const AQHREACT_UNIT *unit); +AQH_OBJECT *AQHREACT_Unit_GetAqHomeReact(const AQHREACT_UNIT *unit); const char *AQHREACT_Unit_GetTypeName(const AQHREACT_UNIT *unit); void AQHREACT_Unit_SetTypeName(AQHREACT_UNIT *unit, const char *s); diff --git a/apps/aqhome-react/types/unit_p.h b/apps/aqhome-react/types/unit_p.h index 1bd7301..2461e51 100644 --- a/apps/aqhome-react/types/unit_p.h +++ b/apps/aqhome-react/types/unit_p.h @@ -17,7 +17,7 @@ struct AQHREACT_UNIT { GWEN_INHERIT_ELEMENT(AQHREACT_UNIT) GWEN_LIST_ELEMENT(AQHREACT_UNIT) - AQHOME_REACT *aqHomeReact; + AQH_OBJECT *aqHomeReact; char *typeName; char *description; char *id; diff --git a/apps/aqhome-react/units/u_highpass.c b/apps/aqhome-react/units/u_highpass.c index 2c42085..b5c413f 100644 --- a/apps/aqhome-react/units/u_highpass.c +++ b/apps/aqhome-react/units/u_highpass.c @@ -40,7 +40,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREAC * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_highpass.h b/apps/aqhome-react/units/u_highpass.h index 7452d3f..8636a3d 100644 --- a/apps/aqhome-react/units/u_highpass.h +++ b/apps/aqhome-react/units/u_highpass.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_HIGHPASS_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -19,7 +20,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_logical.c b/apps/aqhome-react/units/u_logical.c index ec2e934..8a601f6 100644 --- a/apps/aqhome-react/units/u_logical.c +++ b/apps/aqhome-react/units/u_logical.c @@ -33,7 +33,7 @@ * ------------------------------------------------------------------------------------------------ */ -static AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh); +static AQHREACT_UNIT *_unitLogical_new(AQH_OBJECT *aqh); static int _outputResult(AQHREACT_UNIT *unit, AQHREACT_PORT *port, int result); static int _cbProcessOr(AQHREACT_UNIT *unit); static int _cbProcessAnd(AQHREACT_UNIT *unit); @@ -48,7 +48,7 @@ static int _cbProcessInvert(AQHREACT_UNIT *unit); */ -AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -61,7 +61,7 @@ AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitNor_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitNor_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -75,7 +75,7 @@ AQHREACT_UNIT *AqHomeReact_UnitNor_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -88,7 +88,7 @@ AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitNand_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitNand_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -102,7 +102,7 @@ AQHREACT_UNIT *AqHomeReact_UnitNand_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -115,7 +115,7 @@ AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitInvert_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitInvert_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -129,7 +129,7 @@ AQHREACT_UNIT *AqHomeReact_UnitInvert_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *_unitLogical_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_logical.h b/apps/aqhome-react/units/u_logical.h index a0ed0b4..cd6bf43 100644 --- a/apps/aqhome-react/units/u_logical.h +++ b/apps/aqhome-react/units/u_logical.h @@ -10,18 +10,19 @@ #define AQHOMEREACT_U_LOGICAL_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" -AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitNor_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitOr_new(AQH_OBJECT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitNor_new(AQH_OBJECT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitNand_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitAnd_new(AQH_OBJECT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitNand_new(AQH_OBJECT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitInvert_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQH_OBJECT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitInvert_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_lowpass.c b/apps/aqhome-react/units/u_lowpass.c index 0aa1a1e..b2aa8ac 100644 --- a/apps/aqhome-react/units/u_lowpass.c +++ b/apps/aqhome-react/units/u_lowpass.c @@ -40,7 +40,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREAC * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_lowpass.h b/apps/aqhome-react/units/u_lowpass.h index f2a9d2a..82fe5d2 100644 --- a/apps/aqhome-react/units/u_lowpass.h +++ b/apps/aqhome-react/units/u_lowpass.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_LOWPASS_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -18,7 +19,7 @@ #define AQHOMEREACT_UNIT_LOWPASS_PARAM_NEWVALUE "newValue" -AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_module.c b/apps/aqhome-react/units/u_module.c index 7e94d68..093ae89 100644 --- a/apps/aqhome-react/units/u_module.c +++ b/apps/aqhome-react/units/u_module.c @@ -50,24 +50,24 @@ static void _readProxyFromXml(GWEN_XMLNODE *xmlNode, static int _readInputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); static int _readOutputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); static int _finishParams(AQHREACT_UNIT *unit); -static void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); -static AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode); +static void _readUnitsFromXml(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); +static AQHREACT_UNIT *_readOneUnitFromXml(AQH_OBJECT *aqh, GWEN_XMLNODE *xmlNode); static int _readParamsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNodeUnit, const char *mainGroupName); static int _readParamFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode); static int _setParamDataFromString(AQHREACT_PARAM *param, const char *value); -static int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); -static int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode); -static int _linkFromThisModulesInput(AQHOME_REACT *aqh, +static int _readLinksFromXml(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); +static int _readLinkFromXml(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode); +static int _linkFromThisModulesInput(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, const char *emittingPortName, const char *receivingUnitName, const char *receivingPortName); -static int _linkToThisModulesOutput(AQHOME_REACT *aqh, +static int _linkToThisModulesOutput(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, const char *emittingUnitName, const char *emittingPortName, const char *receivingPortName); -static int _linkBetweenUnits(AQHOME_REACT *aqh, +static int _linkBetweenUnits(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, const char *emittingUnitName, const char *emittingPortName, @@ -140,7 +140,7 @@ MODULE_PROXY_DESCR *ModuleProxyDescr_List_FindByName(const MODULE_PROXY_DESCR_LI * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_UNIT_MODULE *xunit; @@ -176,7 +176,7 @@ void _freeData(GWEN_UNUSED void *bp, void *p) -AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode) +AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQH_OBJECT *aqh, GWEN_XMLNODE *xmlNode) { AQHREACT_UNIT *unit; AQHREACT_UNIT_MODULE *xunit; @@ -452,7 +452,7 @@ int _finishParams(AQHREACT_UNIT *unit) -void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) +void _readUnitsFromXml(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) { GWEN_XMLNODE *nGroup; AQHREACT_UNIT_MODULE *xunit; @@ -481,7 +481,7 @@ void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xml -AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode) +AQHREACT_UNIT *_readOneUnitFromXml(AQH_OBJECT *aqh, GWEN_XMLNODE *xmlNode) { const char *id; const char *t; @@ -495,7 +495,7 @@ AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode) AQHREACT_UNIT *subUnit; int rv; - subUnit=AqHomeReact_CreateUnitByName(aqh, t); + subUnit=AQH_ReactServer_CreateUnitByName(aqh, t); if (subUnit==NULL) { DBG_INFO(NULL, "Could not create unit of type \"%s\"", t); return NULL; @@ -610,7 +610,7 @@ int _setParamDataFromString(AQHREACT_PARAM *param, const char *value) -int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) +int _readLinksFromXml(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) { GWEN_XMLNODE *nGroup; @@ -635,7 +635,7 @@ int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlN -int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode) +int _readLinkFromXml(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode) { const char *emittingUnitName; const char *emittingPortName; @@ -673,7 +673,7 @@ int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkN -int _linkFromThisModulesInput(AQHOME_REACT *aqh, +int _linkFromThisModulesInput(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, const char *emittingPortName, const char *receivingUnitName, @@ -689,7 +689,7 @@ int _linkFromThisModulesInput(AQHOME_REACT *aqh, receivingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, receivingUnitName); if (receivingUnit==NULL) - receivingUnit=AqHomeReact_FindUnitByUnitId(aqh, receivingUnitName); + receivingUnit=AQH_ReactServer_FindUnitByUnitId(aqh, receivingUnitName); if (receivingUnit==NULL) { DBG_ERROR(NULL, "Target unit \"%s\" not found", receivingUnitName); return GWEN_ERROR_NOT_FOUND; @@ -718,7 +718,7 @@ int _linkFromThisModulesInput(AQHOME_REACT *aqh, -int _linkToThisModulesOutput(AQHOME_REACT *aqh, +int _linkToThisModulesOutput(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, const char *emittingUnitName, const char *emittingPortName, @@ -735,7 +735,7 @@ int _linkToThisModulesOutput(AQHOME_REACT *aqh, emittingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, emittingUnitName); if (emittingUnit==NULL) - emittingUnit=AqHomeReact_FindUnitByUnitId(aqh, emittingUnitName); + emittingUnit=AQH_ReactServer_FindUnitByUnitId(aqh, emittingUnitName); if (emittingUnit==NULL) { DBG_ERROR(NULL, "Source unit \"%s\" not found", emittingUnitName); return GWEN_ERROR_NOT_FOUND; @@ -764,7 +764,7 @@ int _linkToThisModulesOutput(AQHOME_REACT *aqh, -int _linkBetweenUnits(AQHOME_REACT *aqh, +int _linkBetweenUnits(AQH_OBJECT *aqh, AQHREACT_UNIT *unit, const char *emittingUnitName, const char *emittingPortName, @@ -782,7 +782,7 @@ int _linkBetweenUnits(AQHOME_REACT *aqh, emittingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, emittingUnitName); if (emittingUnit==NULL) - emittingUnit=AqHomeReact_FindUnitByUnitId(aqh, emittingUnitName); + emittingUnit=AQH_ReactServer_FindUnitByUnitId(aqh, emittingUnitName); if (emittingUnit==NULL) { DBG_ERROR(NULL, "Source unit \"%s\" not found", emittingUnitName); return GWEN_ERROR_NOT_FOUND; @@ -790,7 +790,7 @@ int _linkBetweenUnits(AQHOME_REACT *aqh, receivingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, receivingUnitName); if (receivingUnit==NULL) - receivingUnit=AqHomeReact_FindUnitByUnitId(aqh, receivingUnitName); + receivingUnit=AQH_ReactServer_FindUnitByUnitId(aqh, receivingUnitName); if (receivingUnit==NULL) { DBG_ERROR(NULL, "Target unit \"%s\" not found", receivingUnitName); return GWEN_ERROR_NOT_FOUND; diff --git a/apps/aqhome-react/units/u_module.h b/apps/aqhome-react/units/u_module.h index d74479a..72072e2 100644 --- a/apps/aqhome-react/units/u_module.h +++ b/apps/aqhome-react/units/u_module.h @@ -1,6 +1,6 @@ /**************************************************************************** * This file is part of the project AqHome. - * AqHome (c) by 2024 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 * should have received along with this file. @@ -10,15 +10,16 @@ #define AQHOMEREACT_U_MODULE_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" #include -AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQH_OBJECT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode); +AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQH_OBJECT *aqh, GWEN_XMLNODE *xmlNode); #endif diff --git a/apps/aqhome-react/units/u_passthrough.c b/apps/aqhome-react/units/u_passthrough.c index 853aa0c..85bdc2f 100644 --- a/apps/aqhome-react/units/u_passthrough.c +++ b/apps/aqhome-react/units/u_passthrough.c @@ -37,7 +37,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREAC * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_passthrough.h b/apps/aqhome-react/units/u_passthrough.h index 867f657..4fff34e 100644 --- a/apps/aqhome-react/units/u_passthrough.h +++ b/apps/aqhome-react/units/u_passthrough.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_PASSTHROUGH_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -19,7 +20,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_stabilize.c b/apps/aqhome-react/units/u_stabilize.c index d0e6452..3047f97 100644 --- a/apps/aqhome-react/units/u_stabilize.c +++ b/apps/aqhome-react/units/u_stabilize.c @@ -62,7 +62,7 @@ static void _setOutput(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQH_OBJECT *aqh) { AQHREACT_UNIT_STABILIZE *xunit; AQHREACT_UNIT *unit; diff --git a/apps/aqhome-react/units/u_stabilize.h b/apps/aqhome-react/units/u_stabilize.h index 6cf9ab6..6f51dd7 100644 --- a/apps/aqhome-react/units/u_stabilize.h +++ b/apps/aqhome-react/units/u_stabilize.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_STABILIZE_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -17,7 +18,7 @@ #define AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_LOW "holdTimeLow" -AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_statfns.c b/apps/aqhome-react/units/u_statfns.c index 3fe5f7f..2ece42e 100644 --- a/apps/aqhome-react/units/u_statfns.c +++ b/apps/aqhome-react/units/u_statfns.c @@ -33,7 +33,7 @@ * ------------------------------------------------------------------------------------------------ */ -static AQHREACT_UNIT *_unitStatFns_new(AQHOME_REACT *aqh); +static AQHREACT_UNIT *_unitStatFns_new(AQH_OBJECT *aqh); static int _outputResult(AQHREACT_UNIT *unit, AQHREACT_PORT *port, double result); static int _cbProcessAvg(AQHREACT_UNIT *unit); static int _cbProcessMin(AQHREACT_UNIT *unit); @@ -47,7 +47,7 @@ static int _cbProcessMax(AQHREACT_UNIT *unit); */ -AQHREACT_UNIT *AqHomeReact_UnitAverage_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitAverage_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -60,7 +60,7 @@ AQHREACT_UNIT *AqHomeReact_UnitAverage_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitMinValue_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitMinValue_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -73,7 +73,7 @@ AQHREACT_UNIT *AqHomeReact_UnitMinValue_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *AqHomeReact_UnitMaxValue_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitMaxValue_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; @@ -86,7 +86,7 @@ AQHREACT_UNIT *AqHomeReact_UnitMaxValue_new(AQHOME_REACT *aqh) -AQHREACT_UNIT *_unitStatFns_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *_unitStatFns_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_statfns.h b/apps/aqhome-react/units/u_statfns.h index 3a7c7a2..86e5306 100644 --- a/apps/aqhome-react/units/u_statfns.h +++ b/apps/aqhome-react/units/u_statfns.h @@ -10,13 +10,14 @@ #define AQHOMEREACT_U_STATFNS_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" -AQHREACT_UNIT *AqHomeReact_UnitAverage_new(AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitMinValue_new(AQHOME_REACT *aqh); -AQHREACT_UNIT *AqHomeReact_UnitMaxValue_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitAverage_new(AQH_OBJECT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitMinValue_new(AQH_OBJECT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitMaxValue_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_suntime.c b/apps/aqhome-react/units/u_suntime.c index a30e629..593f1c8 100644 --- a/apps/aqhome-react/units/u_suntime.c +++ b/apps/aqhome-react/units/u_suntime.c @@ -52,7 +52,7 @@ static void _readParams(AQHREACT_UNIT *unit); * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitSuntime_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitSuntime_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_UNIT_SUNTIME *xunit; @@ -125,7 +125,7 @@ int _cbProcess(AQHREACT_UNIT *unit) xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_SUNTIME, unit); if (xunit) { - if (unit && AQHREACT_Unit_InputHasChanged(unit)) { + if (unit /* && AQHREACT_Unit_InputHasChanged(unit)*/) { int rv; if (AQHREACT_Unit_GetGpInt(unit)==-1) @@ -184,7 +184,7 @@ int _isInsideSuntime(AQHREACT_UNIT *unit) endTimeInMinutes=xunit->sunSetTimeInMinutes+xunit->offsetMinsForSunset; result=(nowInMinutes>=startTimeInMinutes && nowInMinutes<=endTimeInMinutes)?1:0; - DBG_DEBUG(NULL, "Is inside suntime: %d", result); + DBG_ERROR(NULL, "Is inside suntime: %d", result); return result; } return 0; @@ -205,14 +205,14 @@ void _updateSuntimes(AQHREACT_UNIT *unit) t=AQHomeReact_GetSunriseTimeForDateAndLoc(xunit->date, xunit->latitude, xunit->longitude); xunit->sunRiseTimeInMinutes=_gwenTimeToMinutes(t); - DBG_INFO(NULL, "%s: Sunrise today at %02d:%02d UTC", - GWEN_Date_GetString(xunit->date), xunit->sunRiseTimeInMinutes/60, xunit->sunRiseTimeInMinutes%60); + DBG_ERROR(NULL, "%s: Sunrise today at %02d:%02d UTC", + GWEN_Date_GetString(xunit->date), xunit->sunRiseTimeInMinutes/60, xunit->sunRiseTimeInMinutes%60); GWEN_Time_free(t); t=AQHomeReact_GetSunsetTimeForDateAndLoc(xunit->date, xunit->latitude, xunit->longitude); xunit->sunSetTimeInMinutes=_gwenTimeToMinutes(t); - DBG_INFO(NULL, "%s: Sunset today at %02d:%02d UTC", - GWEN_Date_GetString(xunit->date), xunit->sunSetTimeInMinutes/60, xunit->sunSetTimeInMinutes%60); + DBG_ERROR(NULL, "%s: Sunset today at %02d:%02d UTC", + GWEN_Date_GetString(xunit->date), xunit->sunSetTimeInMinutes/60, xunit->sunSetTimeInMinutes%60); GWEN_Time_free(t); } @@ -261,7 +261,7 @@ void _readParams(AQHREACT_UNIT *unit) xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_SUNTIME, unit); if (xunit) { - DBG_INFO(NULL, "Reading parameters"); + DBG_ERROR(NULL, "Reading parameters"); /* default to "Neues Rathaus" Celle ;-) */ xunit->latitude=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_SUNTIME_PARAM_LAT, 52.619425); xunit->longitude=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_SUNTIME_PARAM_LONG, 10.087891); diff --git a/apps/aqhome-react/units/u_suntime.h b/apps/aqhome-react/units/u_suntime.h index f5f1049..3cf8d9c 100644 --- a/apps/aqhome-react/units/u_suntime.h +++ b/apps/aqhome-react/units/u_suntime.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_SUNTIME_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -22,7 +23,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitSuntime_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitSuntime_new(AQH_OBJECT *aqh); #endif diff --git a/apps/aqhome-react/units/u_timeprogram.c b/apps/aqhome-react/units/u_timeprogram.c index c137d99..194af19 100644 --- a/apps/aqhome-react/units/u_timeprogram.c +++ b/apps/aqhome-react/units/u_timeprogram.c @@ -12,6 +12,8 @@ #include "./u_timeprogram_p.h" +#include "aqhome-react/types/prgrule.h" + #include #include #include @@ -96,7 +98,7 @@ void ModuleTimerAction_free(MODULE_TIMER_ACTION *act) * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -AQHREACT_UNIT *AqHomeReact_UnitTimeProgram_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitTimeProgram_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_UNIT_TIMEPROGRAM *xunit; diff --git a/apps/aqhome-react/units/u_timeprogram.h b/apps/aqhome-react/units/u_timeprogram.h index 31a5b3f..6450d3b 100644 --- a/apps/aqhome-react/units/u_timeprogram.h +++ b/apps/aqhome-react/units/u_timeprogram.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_TIMEPROGRAM_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -18,7 +19,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitTimeProgram_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitTimeProgram_new(AQH_OBJECT *aqh); #endif diff --git a/apps/aqhome-react/units/u_timer.c b/apps/aqhome-react/units/u_timer.c index f4781a7..caa0bc0 100644 --- a/apps/aqhome-react/units/u_timer.c +++ b/apps/aqhome-react/units/u_timer.c @@ -17,7 +17,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitTimer_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitTimer_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; diff --git a/apps/aqhome-react/units/u_timer.h b/apps/aqhome-react/units/u_timer.h index 8375a83..5a6cf59 100644 --- a/apps/aqhome-react/units/u_timer.h +++ b/apps/aqhome-react/units/u_timer.h @@ -10,11 +10,12 @@ #define AQHOMEREACT_U_TIMER_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" -AQHREACT_UNIT *AqHomeReact_UnitTimer_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitTimer_new(AQH_OBJECT *aqh); void AqHomeReact_UnitTimer_GenerateTick(AQHREACT_UNIT *unit); diff --git a/apps/aqhome-react/units/u_valuefilter.c b/apps/aqhome-react/units/u_valuefilter.c index 93b7c8d..19bd41d 100644 --- a/apps/aqhome-react/units/u_valuefilter.c +++ b/apps/aqhome-react/units/u_valuefilter.c @@ -41,7 +41,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREAC * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_valuefilter.h b/apps/aqhome-react/units/u_valuefilter.h index 183ac53..621ef62 100644 --- a/apps/aqhome-react/units/u_valuefilter.h +++ b/apps/aqhome-react/units/u_valuefilter.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_VALUEFILTER_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -17,7 +18,7 @@ #define AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME "valueName" -AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_valueset.c b/apps/aqhome-react/units/u_valueset.c index 624f60d..160a29f 100644 --- a/apps/aqhome-react/units/u_valueset.c +++ b/apps/aqhome-react/units/u_valueset.c @@ -12,14 +12,15 @@ #include "./u_valueset.h" -#include "aqhome/ipc/data/msg_data_set.h" -#include "aqhome/ipc/data/ipc_data.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/data/m_ipcd_setdata.h" +#include "aqhome/ipc2/endpoint.h" #include #include -//#define DEBUG_DRY_RUN 1 /* don't actually set value if "1" */ +#define DEBUG_DRY_RUN 0 /* don't actually set value if "1" */ /* ------------------------------------------------------------------------------------------------ @@ -37,10 +38,8 @@ */ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); -static GWEN_MSG *_mkSetDataMsgString(GWEN_MSG_ENDPOINT *brokerEndpoint, - const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); -static GWEN_MSG *_mkSetDataMsgDouble(GWEN_MSG_ENDPOINT *brokerEndpoint, - const char *sValueName, 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); @@ -49,7 +48,7 @@ static GWEN_MSG *_mkSetDataMsgDouble(GWEN_MSG_ENDPOINT *brokerEndpoint, * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; @@ -83,11 +82,11 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO sValueName=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME, NULL); if (sValueName && *sValueName) { - GWEN_MSG_ENDPOINT *brokerEndpoint; + AQH_OBJECT *brokerEndpoint; - brokerEndpoint=AqHomeReact_GetBrokerEndpoint(AQHREACT_Unit_GetAqHomeReact(unit)); + brokerEndpoint=AQH_ReactServer_GetBrokerEndpoint(AQHREACT_Unit_GetAqHomeReact(unit)); if (brokerEndpoint) { - GWEN_MSG *msgOut; + AQH_MESSAGE *msgOut; switch(AQHREACT_DataObject_GetDataType(dataObject)) { case AQHREACT_DATAOBJECTTYPE_DOUBLE: @@ -110,10 +109,10 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO AQHREACT_DataObject_Dump(dataObject, dbuf, 0); DBG_ERROR(NULL, "%s\n", GWEN_Buffer_GetStart(dbuf)); GWEN_Buffer_free(dbuf); - GWEN_Msg_free(msgOut); + AQH_Message_free(msgOut); #else DBG_INFO(NULL, "Sending data for value \"%s\"", sValueName); - GWEN_MsgEndpoint_AddSendMessage(brokerEndpoint, msgOut); + AQH_Endpoint_AddMsgOut(brokerEndpoint, msgOut); #endif } } @@ -122,26 +121,27 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO } -GWEN_MSG *_mkSetDataMsgString(GWEN_MSG_ENDPOINT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) + +AQH_MESSAGE *_mkSetDataMsgString(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { - GWEN_MSG *msgOut; + AQH_MESSAGE *msgOut; AQH_VALUE *v; v=AQH_Value_new(); AQH_Value_SetNameForSystem(v, sValueName); - msgOut=AQH_SetDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_SETDATA, - GWEN_MsgEndpoint_GetNextMessageId(brokerEndpoint), 0, - v, AQHREACT_DataObject_GetStringData(dataObject)); + 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; } -GWEN_MSG *_mkSetDataMsgDouble(GWEN_MSG_ENDPOINT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) +AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { - GWEN_MSG *msgOut; + AQH_MESSAGE *msgOut; AQH_VALUE *v; double data; GWEN_BUFFER *buf; @@ -159,9 +159,9 @@ GWEN_MSG *_mkSetDataMsgDouble(GWEN_MSG_ENDPOINT *brokerEndpoint, const char *sVa return NULL; } - msgOut=AQH_SetDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_SETDATA, - GWEN_MsgEndpoint_GetNextMessageId(brokerEndpoint), 0, - v, GWEN_Buffer_GetStart(buf)); + msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA, + AQH_Endpoint_GetNextMessageId(brokerEndpoint), 0, + v, GWEN_Buffer_GetStart(buf)); GWEN_Buffer_free(buf); AQH_Value_free(v); return msgOut; diff --git a/apps/aqhome-react/units/u_valueset.h b/apps/aqhome-react/units/u_valueset.h index 3cef416..9b57df6 100644 --- a/apps/aqhome-react/units/u_valueset.h +++ b/apps/aqhome-react/units/u_valueset.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_VALUESET_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -17,7 +18,7 @@ #define AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME "valueName" -AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_varchanges.c b/apps/aqhome-react/units/u_varchanges.c index 7f2a462..85ff78d 100644 --- a/apps/aqhome-react/units/u_varchanges.c +++ b/apps/aqhome-react/units/u_varchanges.c @@ -16,7 +16,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitVarChanges_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitVarChanges_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_varchanges.h b/apps/aqhome-react/units/u_varchanges.h index b61190c..a034b88 100644 --- a/apps/aqhome-react/units/u_varchanges.h +++ b/apps/aqhome-react/units/u_varchanges.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_VARCHANGES_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -22,7 +23,7 @@ -AQHREACT_UNIT *AqHomeReact_UnitVarChanges_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitVarChanges_new(AQH_OBJECT *aqh); /** * Called from AqHomeReact when a value on the server changed. diff --git a/apps/aqhome-react/units/u_varset.c b/apps/aqhome-react/units/u_varset.c index 2f68a30..48852a2 100644 --- a/apps/aqhome-react/units/u_varset.c +++ b/apps/aqhome-react/units/u_varset.c @@ -47,7 +47,7 @@ static void _setStringValue(AQHREACT_UNIT *unit, const char *sValueName, const A * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitVarSet_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitVarSet_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; @@ -100,11 +100,11 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO void _setDoubleValue(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { - AQHOME_REACT *aqh; + AQH_OBJECT *aqh; int rv; aqh=AQHREACT_Unit_GetAqHomeReact(unit); - rv=AqHomeReact_SetDoubleValue(aqh, sValueName, AQHREACT_DataObject_GetDoubleData(dataObject)); + rv=AQH_ReactServer_SetDoubleValue(aqh, sValueName, AQHREACT_DataObject_GetDoubleData(dataObject)); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); } @@ -114,11 +114,11 @@ void _setDoubleValue(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT void _setStringValue(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { - AQHOME_REACT *aqh; + AQH_OBJECT *aqh; int rv; aqh=AQHREACT_Unit_GetAqHomeReact(unit); - rv=AqHomeReact_SetCharValue(aqh, sValueName, AQHREACT_DataObject_GetStringData(dataObject)); + rv=AQH_ReactServer_SetCharValue(aqh, sValueName, AQHREACT_DataObject_GetStringData(dataObject)); if (rv<0) { DBG_INFO(NULL, "here (%d)", rv); } diff --git a/apps/aqhome-react/units/u_varset.h b/apps/aqhome-react/units/u_varset.h index a811b7d..879cd88 100644 --- a/apps/aqhome-react/units/u_varset.h +++ b/apps/aqhome-react/units/u_varset.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_VARSET_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -17,7 +18,7 @@ #define AQHOMEREACT_UNIT_VARSET_PARAM_VALUENAME "varName" -AQHREACT_UNIT *AqHomeReact_UnitVarSet_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitVarSet_new(AQH_OBJECT *aqh); diff --git a/apps/aqhome-react/units/u_zeroposnegstring.c b/apps/aqhome-react/units/u_zeroposnegstring.c index 721f260..feb77c2 100644 --- a/apps/aqhome-react/units/u_zeroposnegstring.c +++ b/apps/aqhome-react/units/u_zeroposnegstring.c @@ -41,7 +41,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREAC * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh) +AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQH_OBJECT *aqh) { AQHREACT_UNIT *unit; AQHREACT_PORT *port; diff --git a/apps/aqhome-react/units/u_zeroposnegstring.h b/apps/aqhome-react/units/u_zeroposnegstring.h index d635cfa..761389b 100644 --- a/apps/aqhome-react/units/u_zeroposnegstring.h +++ b/apps/aqhome-react/units/u_zeroposnegstring.h @@ -10,6 +10,7 @@ #define AQHOMEREACT_U_ZEROPOSNEGSTRING_H +#include "aqhome-react/server.h" #include "aqhome-react/aqhome_react.h" #include "aqhome-react/types/unit.h" @@ -19,7 +20,7 @@ #define AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO "valueIfZero" -AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh); +AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQH_OBJECT *aqh);