From 1050ee1c752a93d2ab5cdd93f8e45fa9cda290ef Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Wed, 17 Apr 2024 22:26:17 +0200 Subject: [PATCH] aqhome-react: major rebuild of unit handling. now nested networks are allowed to allow for complex networks. --- apps/aqhome-react/aqhome_react.c | 78 +- apps/aqhome-react/aqhome_react.h | 6 +- apps/aqhome-react/aqhome_react_p.h | 1 - apps/aqhome-react/fini.c | 1 - apps/aqhome-react/init.c | 40 +- apps/aqhome-react/init.h | 3 +- apps/aqhome-react/loop.c | 57 +- apps/aqhome-react/main.c | 4 +- apps/aqhome-react/net_read.c | 741 ++----------------- apps/aqhome-react/net_read.h | 5 +- apps/aqhome-react/types/0BUILD | 12 +- apps/aqhome-react/types/dataobject.c | 14 + apps/aqhome-react/types/dataobject.h | 1 + apps/aqhome-react/types/link.c | 15 + apps/aqhome-react/types/link.h | 4 + apps/aqhome-react/types/link_p.h | 1 + apps/aqhome-react/types/port.c | 313 ++++++++ apps/aqhome-react/types/port.h | 67 ++ apps/aqhome-react/types/port_p.h | 31 + apps/aqhome-react/types/unit.c | 321 +++----- apps/aqhome-react/types/unit.h | 40 +- apps/aqhome-react/types/unit_p.h | 6 +- apps/aqhome-react/units/u_highpass.c | 48 +- apps/aqhome-react/units/u_logical.c | 240 +++--- apps/aqhome-react/units/u_lowpass.c | 48 +- apps/aqhome-react/units/u_module.c | 582 +++++++-------- apps/aqhome-react/units/u_module_p.h | 4 +- apps/aqhome-react/units/u_passthrough.c | 36 +- apps/aqhome-react/units/u_stabilize.c | 60 +- apps/aqhome-react/units/u_timer.c | 6 +- apps/aqhome-react/units/u_valuefilter.c | 56 +- apps/aqhome-react/units/u_valueset.c | 30 +- apps/aqhome-react/units/u_varchanges.c | 25 +- apps/aqhome-react/units/u_zeroposnegstring.c | 56 +- 34 files changed, 1336 insertions(+), 1616 deletions(-) create mode 100644 apps/aqhome-react/types/port.c create mode 100644 apps/aqhome-react/types/port.h create mode 100644 apps/aqhome-react/types/port_p.h diff --git a/apps/aqhome-react/aqhome_react.c b/apps/aqhome-react/aqhome_react.c index 23c7d5b..cbc01e4 100644 --- a/apps/aqhome-react/aqhome_react.c +++ b/apps/aqhome-react/aqhome_react.c @@ -11,6 +11,7 @@ #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" @@ -30,7 +31,6 @@ AQHOME_REACT *AqHomeReact_new() AQHOME_REACT *aqh; GWEN_NEW_OBJECT(AQHOME_REACT, aqh); - aqh->unitNetList=AQHREACT_UnitNet_List_new(); aqh->unitList=AQHREACT_Unit_List_new(); return aqh; @@ -41,7 +41,6 @@ AQHOME_REACT *AqHomeReact_new() void AqHomeReact_free(AQHOME_REACT *aqh) { if (aqh) { - AQHREACT_UnitNet_List_free(aqh->unitNetList); AQHREACT_Unit_List_free(aqh->unitList); GWEN_MsgEndpoint_free(aqh->brokerEndpoint); GWEN_DB_Group_free(aqh->dbArgs); @@ -121,57 +120,17 @@ AQHREACT_UNIT *AqHomeReact_GetVarChangeUnit(const AQHOME_REACT *aqh) -AQHREACT_UNIT_NET_LIST *AqHomeReact_GetUnitNetList(const AQHOME_REACT *aqh) -{ - return aqh?aqh->unitNetList:NULL; -} - - - -void AqHomeReact_AddUnitNet(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet) -{ - if (aqh) - AQHREACT_UnitNet_List_Add(unitNet, aqh->unitNetList); -} - - - -AQHREACT_UNIT_NET *AqHomeReact_GetUnitNetByName(const AQHOME_REACT *aqh, const char *s) -{ - return (aqh && s && *s)?AQHREACT_UnitNet_List_GetByName(aqh->unitNetList, s):NULL; -} - - - -AQHREACT_UNIT *AqHomeReact_FindUnitByNetNameAndUnitId(const AQHOME_REACT *aqh, const char *netName, const char *unitId) +AQHREACT_UNIT *AqHomeReact_FindUnitByUnitId(const AQHOME_REACT *aqh, const char *unitId) { if (aqh && unitId && *unitId) { - AQHREACT_UNIT_LIST *unitList=NULL; + AQHREACT_UNIT *unit; - if (netName && *netName) { - AQHREACT_UNIT_NET *unitNet; - - unitNet=AQHREACT_UnitNet_List_GetByName(aqh->unitNetList, netName); - if (unitNet) - unitList=AQHREACT_UnitNet_GetUnitList(unitNet); - else { - DBG_ERROR(NULL, "Unit net \"%s\" not found", netName); - return NULL; - } - } - else - unitList=aqh->unitList; - - if (unitList) { - AQHREACT_UNIT *unit; - - unit=AQHREACT_Unit_List_GetById(unitList, unitId); - if (unit==NULL) { - DBG_ERROR(NULL, "Unit \"%s/%s\" not found", netName, unitId); - return NULL; - } - return 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; @@ -210,8 +169,25 @@ AQHREACT_UNIT *AqHomeReact_CreateUnitByName(AQHOME_REACT *aqh, const char *unitT else if (strcasecmp(unitType, "zeroPosNegString")==0) return AqHomeReact_UnitZeroPosNegString_new(aqh); else { - DBG_ERROR(NULL, "Unknown unit type \"%s\"", unitType); - return NULL; + 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_GetName(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; } } diff --git a/apps/aqhome-react/aqhome_react.h b/apps/aqhome-react/aqhome_react.h index 499fcda..b58f04e 100644 --- a/apps/aqhome-react/aqhome_react.h +++ b/apps/aqhome-react/aqhome_react.h @@ -37,11 +37,7 @@ void AqHomeReact_SetLatestNetworkFileTime(AQHOME_REACT *aqh, time_t t); AQHREACT_UNIT *AqHomeReact_GetTimerUnit(const AQHOME_REACT *aqh); AQHREACT_UNIT *AqHomeReact_GetVarChangeUnit(const AQHOME_REACT *aqh); -AQHREACT_UNIT_NET_LIST *AqHomeReact_GetUnitNetList(const AQHOME_REACT *aqh); -void AqHomeReact_AddUnitNet(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet); -AQHREACT_UNIT_NET *AqHomeReact_GetUnitNetById(const AQHOME_REACT *aqh); - -AQHREACT_UNIT *AqHomeReact_FindUnitByNetNameAndUnitId(const AQHOME_REACT *aqh, const char *netName, const char *unitId); +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); diff --git a/apps/aqhome-react/aqhome_react_p.h b/apps/aqhome-react/aqhome_react_p.h index a017a64..a4896c6 100644 --- a/apps/aqhome-react/aqhome_react_p.h +++ b/apps/aqhome-react/aqhome_react_p.h @@ -34,7 +34,6 @@ struct AQHOME_REACT { AQHREACT_UNIT *timerUnit; AQHREACT_UNIT *varChangeUnit; AQHREACT_UNIT_LIST *unitList; - AQHREACT_UNIT_NET_LIST *unitNetList; time_t latestNetworkFileTime; }; diff --git a/apps/aqhome-react/fini.c b/apps/aqhome-react/fini.c index 4947aa1..114753a 100644 --- a/apps/aqhome-react/fini.c +++ b/apps/aqhome-react/fini.c @@ -48,7 +48,6 @@ int AqHomeReact_Fini(AQHOME_REACT *aqh) GWEN_MsgEndpoint_free(aqh->brokerEndpoint); aqh->brokerEndpoint=NULL; - AQHREACT_UnitNet_List_Clear(aqh->unitNetList); AQHREACT_Unit_List_Clear(aqh->unitList); aqh->timerUnit=NULL; aqh->varChangeUnit=NULL; diff --git a/apps/aqhome-react/init.c b/apps/aqhome-react/init.c index 6224655..551dc31 100644 --- a/apps/aqhome-react/init.c +++ b/apps/aqhome-react/init.c @@ -96,7 +96,11 @@ int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv) } } - AqHomeReact_ReloadUnitNets(aqh); + 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) { @@ -109,33 +113,31 @@ int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv) -void AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh) +int AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh) { - AQHREACT_UNIT_NET_LIST *unitNetList; + int rv; - AQHREACT_UnitNet_List_Clear(aqh->unitNetList); AQHREACT_Unit_List_Clear(aqh->unitList); aqh->timerUnit=NULL; aqh->varChangeUnit=NULL; _setupBuiltinUnits(aqh); - unitNetList=AQHomeReact_ReadUnitNetFiles(aqh); - if (unitNetList) { - AQHREACT_UnitNet_List_free(aqh->unitNetList); - aqh->unitNetList=unitNetList; - { - GWEN_BUFFER *dbuf; + 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_UnitNet_List_Dump(unitNetList, dbuf, 2, "Loaded networks:"); - fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(dbuf)); - GWEN_Buffer_free(dbuf); - } - } - else { - DBG_INFO(NULL, "No unit nets read"); - } + 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; } diff --git a/apps/aqhome-react/init.h b/apps/aqhome-react/init.h index 800a83b..0cd8f13 100644 --- a/apps/aqhome-react/init.h +++ b/apps/aqhome-react/init.h @@ -15,8 +15,7 @@ int AqHomeReact_Init(AQHOME_REACT *aqh, int argc, char **argv); -void AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh); - +int AqHomeReact_ReloadUnitNets(AQHOME_REACT *aqh); #endif diff --git a/apps/aqhome-react/loop.c b/apps/aqhome-react/loop.c index cb4c6c9..9d92f52 100644 --- a/apps/aqhome-react/loop.c +++ b/apps/aqhome-react/loop.c @@ -37,8 +37,7 @@ */ static void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg); -static int _processAllNets(AQHOME_REACT *aqh); -static int _processNet(AQHREACT_UNIT_NET *unitNet); +static int _processAllUnits(AQHOME_REACT *aqh); @@ -78,69 +77,31 @@ void AqHomeReact_ProcessAllUnits(AQHOME_REACT *aqh) int rv; do { - rv=_processAllNets(aqh); + rv=_processAllUnits(aqh); } while (rv==1); } -int _processAllNets(AQHOME_REACT *aqh) +int _processAllUnits(AQHOME_REACT *aqh) { int result=0; - int rv; - AQHREACT_UNIT_NET *unitNet; + AQHREACT_UNIT *unit; - rv=AQHREACT_Unit_Process(aqh->varChangeUnit); - if (rv>0) - result=1; + unit=AQHREACT_Unit_List_First(aqh->unitList); + while(unit) { + int rv; - rv=AQHREACT_Unit_Process(aqh->timerUnit); - if (rv>0) - result=1; - - unitNet=AQHREACT_UnitNet_List_First(aqh->unitNetList); - while(unitNet) { - rv=_processNet(unitNet); + rv=AQHREACT_Unit_Process(unit); if (rv>0) result=1; - - unitNet=AQHREACT_UnitNet_List_Next(unitNet); + unit=AQHREACT_Unit_List_Next(unit); } return result; } - -int _processNet(AQHREACT_UNIT_NET *unitNet) -{ - AQHREACT_UNIT_LIST *unitList; - const char *netName; - - netName=AQHREACT_UnitNet_GetName(unitNet); - DBG_DEBUG(NULL, "Processing net \"%s\"", netName?netName:""); - unitList=AQHREACT_UnitNet_GetUnitList(unitNet); - if (unitList) { - int result=0; - AQHREACT_UNIT *unit; - - unit=AQHREACT_Unit_List_First(unitList); - while(unit) { - int rv; - - rv=AQHREACT_Unit_Process(unit); - if (rv>0) - result=1; - unit=AQHREACT_Unit_List_Next(unit); - } - return result; - } - - return 0; -} - - - void _handleDataResponse(AQHREACT_UNIT *varChangeUnit, GWEN_MSG *msg) { AQH_VALUE *value; diff --git a/apps/aqhome-react/main.c b/apps/aqhome-react/main.c index b267409..2d8159c 100644 --- a/apps/aqhome-react/main.c +++ b/apps/aqhome-react/main.c @@ -151,7 +151,7 @@ void _serve(AQHOME_REACT *aqh) lastTimerTime=startTime; lastFileScanTime=startTime; - AqHomeReact_SetLatestNetworkFileTime(aqh, AQHomeReact_GetNewestUnitNetFiletime(aqh)); + AqHomeReact_SetLatestNetworkFileTime(aqh, AQHomeReact_GetNewestUnitNetFiletime()); dbArgs=AqHomeReact_GetDbArgs(aqh); timerUnit=AqHomeReact_GetTimerUnit(aqh); @@ -184,7 +184,7 @@ void _serve(AQHOME_REACT *aqh) time_t t; DBG_INFO(NULL, "Checking network files"); - tNew=AQHomeReact_GetNewestUnitNetFiletime(aqh); + tNew=AQHomeReact_GetNewestUnitNetFiletime(); t=AqHomeReact_GetLatestNetworkFileTime(aqh); if (tNew && tNew>t) { DBG_INFO(NULL, "Reloading network files"); diff --git a/apps/aqhome-react/net_read.c b/apps/aqhome-react/net_read.c index a2def5e..c85363c 100644 --- a/apps/aqhome-react/net_read.c +++ b/apps/aqhome-react/net_read.c @@ -11,8 +11,10 @@ #endif #include "./net_read.h" +#include "aqhome-react/aqhome_react_p.h" #include "aqhome-react/types/unit.h" #include "aqhome-react/types/unitnet.h" +#include "aqhome-react/units/u_module.h" #include "aqhome/aqhome.h" @@ -32,25 +34,10 @@ * ------------------------------------------------------------------------------------------------ */ -static time_t _getNewestFiletimeFromFileList(const AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl); -static AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl); -static int _readAllNetworksFromFileIntoList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList); -static GWEN_XMLNODE *_readNetworkFromDatadirIntoXml(AQHOME_REACT *aqh, const char *networkName); -static AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode); -static AQHREACT_UNIT_NET *_readUnitNetWithTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode); -static AQHREACT_UNIT_NET *_readUnitNetNoTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode); -static GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename); -static void _readNetParamDefsWithList(AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *unitNetNode); -static int _readUnits(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams); -static int _readLinks(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams); -static AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode, GWEN_DB_NODE *dbNetParams); -static int _readParamValuesForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *parentNode, GWEN_DB_NODE *dbNetParams); -static int _readParamValueForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *paramNode, GWEN_DB_NODE *dbNetParams); -static int _setParamDataFromString(AQHREACT_PARAM *param, const char *value); -static AQHREACT_PARAM *_readNetParamDef(GWEN_XMLNODE *paramNode); -static int _readLink(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *linkNode); -static int _setParamDoubleValueFromString(AQHREACT_PARAM *param, const char *s); -static int _treeExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars); +static time_t _getNewestFiletimeFromFileList(const GWEN_STRINGLIST *sl); +static AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename); +static GWEN_XMLNODE *_readUnitNetFileToXml(const char *sFilename); +static int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList); @@ -60,18 +47,18 @@ static int _treeExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars); */ -time_t AQHomeReact_GetNewestUnitNetFiletime(const AQHOME_REACT *aqh) +time_t AQHomeReact_GetNewestUnitNetFiletime(void) { GWEN_STRINGLIST *sl; time_t t1; time_t t2; sl=AQH_GetListOfMatchingDataFiles("aqhome/react/networks", "*.xml"); - t1=_getNewestFiletimeFromFileList(aqh, sl); + t1=_getNewestFiletimeFromFileList(sl); GWEN_StringList_free(sl); sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml"); - t2=_getNewestFiletimeFromFileList(aqh, sl); + t2=_getNewestFiletimeFromFileList(sl); GWEN_StringList_free(sl); return (t1>t2)?t1:t2; @@ -79,32 +66,60 @@ time_t AQHomeReact_GetNewestUnitNetFiletime(const AQHOME_REACT *aqh) -AQHREACT_UNIT_NET_LIST *AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh) +int AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh) { GWEN_STRINGLIST *sl; sl=AQH_GetListOfMatchingSysconfFiles("aqhome/react/networks", "*.xml"); if (sl) { - AQHREACT_UNIT_NET_LIST *unitNetList; + int rv; GWEN_StringList_Sort(sl, 1, GWEN_StringList_SortModeNoCase); - unitNetList=_readUnitNetFiles(aqh, sl); + rv=_readUnitNetFilesIntoList(aqh, sl, aqh->unitList); GWEN_StringList_free(sl); - if (unitNetList==NULL) { - DBG_INFO(NULL, "Error reading unit network files"); - return NULL; + if (rv<0) { + DBG_INFO(NULL, "Error reading unit network files (%d)", rv); + return rv; } - return unitNetList; } else { DBG_ERROR(NULL, "No unit network files"); - return NULL; } + return 0; } -time_t _getNewestFiletimeFromFileList(const AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl) +AQHREACT_UNIT *AQHomeReact_FindAndReadDataDirNetwork(AQHOME_REACT *aqh, const char *networkName) +{ + AQHREACT_UNIT *unit; + GWEN_BUFFER *bufFilename; + GWEN_BUFFER *bufPath; + + bufFilename=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendArgs(bufFilename, "aqhome/react/networks/%s.xml", networkName); + 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); + + unit=_readNetworkFromFile(aqh, 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 unit; +} + + + +time_t _getNewestFiletimeFromFileList(const GWEN_STRINGLIST *sl) { time_t resultTime=0; @@ -138,263 +153,31 @@ time_t _getNewestFiletimeFromFileList(const AQHOME_REACT *aqh, const GWEN_STRING -GWEN_XMLNODE *_readNetworkFromDatadirIntoXml(AQHOME_REACT *aqh, const char *networkName) +AQHREACT_UNIT *_readNetworkFromFile(AQHOME_REACT *aqh, const char *filename) { GWEN_XMLNODE *n; - GWEN_BUFFER *bufFilename; - GWEN_BUFFER *bufPath; + AQHREACT_UNIT *unit; - bufFilename=GWEN_Buffer_new(0, 256, 0, 1); - GWEN_Buffer_AppendString(bufFilename, "aqhome/react/networks/"); - GWEN_Buffer_AppendString(bufFilename, networkName); - GWEN_Buffer_AppendString(bufFilename, ".xml"); - - bufPath=AQH_FindPathOfDataFile(GWEN_Buffer_GetStart(bufFilename)); - if (bufPath==NULL) { - DBG_ERROR(NULL, "Network file \"%s\" not found in sysconf folders", GWEN_Buffer_GetStart(bufFilename)); - GWEN_Buffer_free(bufFilename); - return NULL; - } - GWEN_Buffer_free(bufFilename); - - n=_readUnitNetFileToXml(aqh, GWEN_Buffer_GetStart(bufPath)); + n=_readUnitNetFileToXml(filename); if (n==NULL) { - DBG_ERROR(NULL, "Error reading network file \"%s\" from sysconf dir", GWEN_Buffer_GetStart(bufPath)); - GWEN_Buffer_free(bufPath); + DBG_ERROR(NULL, "Error reading network file \"%s\"", filename); return NULL; } - GWEN_Buffer_free(bufPath); - return n; + + unit=AqHomeReact_UnitModule_fromXml(aqh, n); + if (unit==NULL) { + DBG_ERROR(NULL, "Error reading network from file \"%s\"", filename); + GWEN_XMLNode_free(n); + return NULL; + } + + GWEN_XMLNode_free(n); + return unit; } -AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl) -{ - GWEN_STRINGLISTENTRY *se; - AQHREACT_UNIT_NET_LIST *unitNetList; - - unitNetList=AQHREACT_UnitNet_List_new(); - se=GWEN_StringList_FirstEntry(sl); - while(se) { - const char *s; - - s=GWEN_StringListEntry_Data(se); - if (s && *s) { - int rv; - - DBG_INFO(NULL, "Reading unit network file \"%s\"", s); - rv=_readAllNetworksFromFileIntoList(aqh, s, unitNetList); - if (rv<0 && rv!=GWEN_ERROR_NO_DATA) { - DBG_WARN(NULL, "Error reading unit network file \"%s\" (%d), ignoring", s, rv); - } - } - se=GWEN_StringListEntry_Next(se); - } - - if (AQHREACT_UnitNet_List_GetCount(unitNetList)<1) { - AQHREACT_UnitNet_List_free(unitNetList); - return NULL; - } - - return unitNetList; -} - - - -int _readAllNetworksFromFileIntoList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList) -{ - GWEN_XMLNODE *rootNode; - GWEN_XMLNODE *netListNode; - GWEN_XMLNODE *netNode; - int rv; - - rootNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, NULL); - rv=GWEN_XML_ReadFile(rootNode, sFilename, GWEN_XML_FLAGS_DEFAULT); - if (rv<0) { - DBG_ERROR(NULL, "Error reading XML file \"%s\": %d", sFilename, rv); - GWEN_XMLNode_free(rootNode); - return rv; - } - - netListNode=GWEN_XMLNode_FindFirstTag(rootNode, "networks", NULL, NULL); - if (netListNode==NULL) - netListNode=rootNode; - - netNode=GWEN_XMLNode_FindFirstTag(netListNode, "network", NULL, NULL); - while(netNode) { - AQHREACT_UNIT_NET *unitNet; - - unitNet=_readUnitNetFromXml(aqh, netNode); - if (unitNet) - AQHREACT_UnitNet_List_Add(unitNet, unitNetList); - else { - DBG_ERROR(NULL, "Error loading network from file \"%s\", ignoring.", sFilename); - } - netNode=GWEN_XMLNode_FindNextTag(netNode, "network", NULL, NULL); - } - - return 0; -} - - - -AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode) -{ - AQHREACT_UNIT_NET *unitNet; - const char *s; - - s=GWEN_XMLNode_GetProperty(unitNetNode, "type", NULL); - if (s && *s) - unitNet=_readUnitNetWithTemplate(aqh, unitNetNode); - else - unitNet=_readUnitNetNoTemplate(aqh, unitNetNode); - if (unitNet==NULL) { - DBG_INFO(NULL, "Error reading unit"); - return NULL; - } - return unitNet; -} - - - -AQHREACT_UNIT_NET *_readUnitNetWithTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetXml) -{ - AQHREACT_UNIT_NET *unitNet; - GWEN_XMLNODE *templateNetXml; - const char *s; - int rv; - GWEN_DB_NODE *dbNetParams=NULL; - - unitNet=AQHREACT_UnitNet_new(); - s=GWEN_XMLNode_GetProperty(unitNetXml, "id", NULL); - AQHREACT_UnitNet_SetName(unitNet, s); - - s=GWEN_XMLNode_GetProperty(unitNetXml, "type", NULL); - DBG_INFO(NULL, "Loading base network \"%s\"", s); - templateNetXml=_readNetworkFromDatadirIntoXml(aqh, s); - if (templateNetXml==NULL) { - DBG_ERROR(NULL, "Base network \"%s\" not available (error or missing)", s); - AQHREACT_UnitNet_free(unitNet); - return NULL; - } - - /* read netParam definitions from template file */ - _readNetParamDefsWithList(AQHREACT_UnitNet_GetParamList(unitNet), templateNetXml); - - /* also read netParams from this file (after reading from template) */ - rv=_readParamValuesForList(AQHREACT_UnitNet_GetParamList(unitNet), unitNetXml, NULL); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_UnitNet_free(unitNet); - GWEN_XMLNode_free(templateNetXml); - return NULL; - } - - dbNetParams=GWEN_DB_Group_new("params"); - rv=AQHREACT_Param_List_WriteIntoDb(AQHREACT_UnitNet_GetParamList(unitNet), dbNetParams, GWEN_DB_FLAGS_OVERWRITE_VARS); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - GWEN_XMLNode_free(templateNetXml); - return NULL; - } - - /* first read units from this file (if any) */ - rv=_readUnits(aqh, unitNet, unitNetXml, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - GWEN_XMLNode_free(templateNetXml); - return NULL; - } - - /* then read units from template file */ - rv=_readUnits(aqh, unitNet, templateNetXml, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - GWEN_XMLNode_free(templateNetXml); - return NULL; - } - - /* read links from template file */ - rv=_readLinks(aqh, unitNet, templateNetXml, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - GWEN_XMLNode_free(templateNetXml); - return NULL; - } - - /* read additional links from this file (if any) */ - rv=_readLinks(aqh, unitNet, unitNetXml, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - GWEN_XMLNode_free(templateNetXml); - return NULL; - } - - GWEN_DB_Group_free(dbNetParams); - GWEN_XMLNode_free(templateNetXml); - - return unitNet; -} - - - -AQHREACT_UNIT_NET *_readUnitNetNoTemplate(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetNode) -{ - AQHREACT_UNIT_NET *unitNet; - const char *s; - int rv; - GWEN_DB_NODE *dbNetParams=NULL; - - unitNet=AQHREACT_UnitNet_new(); - s=GWEN_XMLNode_GetProperty(unitNetNode, "id", NULL); - AQHREACT_UnitNet_SetName(unitNet, s); - - /* just directly read network from given XML node (no need to load a template file) */ - _readNetParamDefsWithList(AQHREACT_UnitNet_GetParamList(unitNet), unitNetNode); - - dbNetParams=GWEN_DB_Group_new("params"); - rv=AQHREACT_Param_List_WriteIntoDb(AQHREACT_UnitNet_GetParamList(unitNet), dbNetParams, GWEN_DB_FLAGS_OVERWRITE_VARS); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - return NULL; - } - - rv=_readUnits(aqh, unitNet, unitNetNode, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - return NULL; - } - - rv=_readLinks(aqh, unitNet, unitNetNode, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - GWEN_DB_Group_free(dbNetParams); - AQHREACT_UnitNet_free(unitNet); - return NULL; - } - GWEN_DB_Group_free(dbNetParams); - - return unitNet; -} - - - -GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename) +GWEN_XMLNODE *_readUnitNetFileToXml(const char *sFilename) { GWEN_XMLNODE *rootNode; GWEN_XMLNODE *netNode; @@ -422,404 +205,30 @@ GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename) -int _readUnits(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams) +int _readUnitNetFilesIntoList(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl, AQHREACT_UNIT_LIST *unitList) { - GWEN_XMLNODE *nGroup; + GWEN_STRINGLISTENTRY *se; - nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "units", NULL, NULL); - if (nGroup) { - GWEN_XMLNODE *n; + se=GWEN_StringList_FirstEntry(sl); + while(se) { + const char *s; - if (dbNetParams) { - int rv; - - rv=_treeExpandProperties(nGroup, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - } - - n=GWEN_XMLNode_FindFirstTag(nGroup, "unit", NULL, NULL); - while(n) { + s=GWEN_StringListEntry_Data(se); + if (s && *s) { AQHREACT_UNIT *unit; - unit=_readUnit(aqh, n, dbNetParams); - if (unit) - AQHREACT_UnitNet_AddUnit(unitNet, unit); - else { - DBG_ERROR(NULL, "Error reading unit in net \"%s\"", AQHREACT_UnitNet_GetName(unitNet)); - return GWEN_ERROR_BAD_DATA; + DBG_INFO(NULL, "Reading unit network file \"%s\"", s); + unit=_readNetworkFromFile(aqh, s); + if (unit==NULL) { + DBG_WARN(NULL, "No network read from network file \"%s\"", s); + return GWEN_ERROR_GENERIC; } - n=GWEN_XMLNode_FindNextTag(n, "unit", NULL, NULL); - } - } - - return 0; -} - - - -int _readLinks(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode, GWEN_DB_NODE *dbNetParams) -{ - GWEN_XMLNODE *nGroup; - - nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "links", NULL, NULL); - if (nGroup) { - GWEN_XMLNODE *n; - - if (dbNetParams) { - int rv; - - rv=_treeExpandProperties(nGroup, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - } - - n=GWEN_XMLNode_FindFirstTag(nGroup, "link", NULL, NULL); - while(n) { - int rv; - - rv=_readLink(aqh, unitNet, n); - if (rv<0) { - DBG_ERROR(NULL, "Error reading link in net \"%s\" (%d)", AQHREACT_UnitNet_GetName(unitNet), rv); - return GWEN_ERROR_BAD_DATA; - } - n=GWEN_XMLNode_FindNextTag(n, "link", NULL, NULL); + AQHREACT_Unit_List_Add(unit, unitList); } + se=GWEN_StringListEntry_Next(se); } return 0; } -AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode, GWEN_DB_NODE *dbNetParams) -{ - AQHREACT_UNIT *unit; - const char *unitType; - const char *unitId; - int rv; - - unitType=GWEN_XMLNode_GetProperty(unitNode, "type", NULL); - if (!(unitType && *unitType)) { - DBG_ERROR(NULL, "No type name in unit node"); - return NULL; - } - unit=AqHomeReact_CreateUnitByName(aqh, unitType); - - unitId=GWEN_XMLNode_GetProperty(unitNode, "id", NULL); - AQHREACT_Unit_SetId(unit, unitId); - - rv=_readParamValuesForList(AQHREACT_Unit_GetParamList(unit), unitNode, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - - return unit; -} - - - -int _readParamValuesForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *parentNode, GWEN_DB_NODE *dbNetParams) -{ - GWEN_XMLNODE *nGroup; - - nGroup=GWEN_XMLNode_FindFirstTag(parentNode, "params", NULL, NULL); - if (nGroup) { - GWEN_XMLNODE *n; - - n=GWEN_XMLNode_FindFirstTag(nGroup, "param", NULL, NULL); - while(n) { - int rv; - - rv=_readParamValueForList(paramList, n, dbNetParams); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - n=GWEN_XMLNode_FindNextTag(n, "param", NULL, NULL); - } - } - return 0; -} - - - -int _readParamValueForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *paramNode, GWEN_DB_NODE *dbNetParams) -{ - const char *paramName; - - paramName=GWEN_XMLNode_GetProperty(paramNode, "name", NULL); - if (paramName && *paramName) { - AQHREACT_PARAM *param; - - param=AQHREACT_Param_List_GetParamByName(paramList, paramName); - if (param) { - const char *value; - - value=GWEN_XMLNode_GetCharValue(paramNode, NULL, NULL); - if (value && *value) { - if (dbNetParams) { - GWEN_BUFFER *buf; - int rv; - - buf=GWEN_Buffer_new(0, 64, 0, 1); - rv=GWEN_DB_ReplaceVars(dbNetParams, value, buf); - if (rv<0) { - DBG_ERROR(NULL, "Error replacing vars for param \"%s\" (%d)", paramName, rv); - GWEN_Buffer_free(buf); - return rv; - } - rv=_setParamDataFromString(param, GWEN_Buffer_GetStart(buf)); - if (rv<0) { - DBG_ERROR(NULL, "Error setting param data for param \"%s\" (%d)", paramName, rv); - GWEN_Buffer_free(buf); - return rv; - } - GWEN_Buffer_free(buf); - } - else { - int rv; - - rv=_setParamDataFromString(param, value); - if (rv<0) { - DBG_ERROR(NULL, "Error setting param data for param \"%s\" (%d)", paramName, rv); - return rv; - } - } - } /* if value */ - } - else { - DBG_ERROR(NULL, "No param name \"%s\" in list", paramName); - return GWEN_ERROR_BAD_DATA; - } - } - - return 0; -} - - - -int _setParamDataFromString(AQHREACT_PARAM *param, const char *value) -{ - if (value && *value) { - int dataType; - - dataType=AQHREACT_Param_GetDataType(param); - switch(dataType) { - case AQHREACT_DATAOBJECTTYPE_DOUBLE: - { - int rv; - double valueAsDouble; - - rv=GWEN_Text_StringToDouble(value, &valueAsDouble); - if (rv<0) { - DBG_ERROR(NULL, "Not a DOUBLE value for param \"%s\" [%s]", AQHREACT_Param_GetName(param), value); - return rv; - } - AQHREACT_Param_SetDoubleValue(param, valueAsDouble); - break; - } - case AQHREACT_DATAOBJECTTYPE_STRING: - default: - AQHREACT_Param_SetStringValue(param, value); - break; - } - } - return 0; -} - - - -void _readNetParamDefsWithList(AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *unitNetNode) -{ - GWEN_XMLNODE *nGroup; - - nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "params", NULL, NULL); - if (nGroup) { - GWEN_XMLNODE *n; - - n=GWEN_XMLNode_FindFirstTag(nGroup, "param", NULL, NULL); - while(n) { - AQHREACT_PARAM *param; - - param=_readNetParamDef(n); - if (param) - AQHREACT_Param_List_Add(param, paramList); - n=GWEN_XMLNode_FindNextTag(n, "param", NULL, NULL); - } - } -} - - - -AQHREACT_PARAM *_readNetParamDef(GWEN_XMLNODE *paramNode) -{ - const char *paramName; - const char *paramType; - const char *paramValue; - - paramName=GWEN_XMLNode_GetProperty(paramNode, "name", NULL); - paramType=GWEN_XMLNode_GetProperty(paramNode, "type", "string"); - paramValue=GWEN_XMLNode_GetCharValue(paramNode, NULL, NULL); - - if (paramName && *paramName) { - int t=AQHREACT_DATAOBJECTTYPE_STRING; - AQHREACT_PARAM *param; - - if (paramType) { - if (strcasecmp(paramType, "string")==0) - t=AQHREACT_DATAOBJECTTYPE_STRING; - else if (strcasecmp(paramType, "double")==0) - t=AQHREACT_DATAOBJECTTYPE_DOUBLE; - else { - DBG_ERROR(NULL, "Invalid data type in parameter (%s), assuming string", paramType); - t=AQHREACT_DATAOBJECTTYPE_STRING; - } - } - - param=AQHREACT_Param_new(); - AQHREACT_Param_SetName(param, paramName); - AQHREACT_Param_SetDataType(param, t); - if (paramValue && *paramValue) { - int rv; - - switch(t) { - case AQHREACT_DATAOBJECTTYPE_STRING: - AQHREACT_Param_SetStringValue(param, paramValue); - break; - case AQHREACT_DATAOBJECTTYPE_DOUBLE: - rv=_setParamDoubleValueFromString(param, paramValue); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Param_free(param); - return NULL; - } - break; - default: - break; - } - } - - return param; - } - - return NULL; -} - - - -int _setParamDoubleValueFromString(AQHREACT_PARAM *param, const char *s) -{ - int rv; - double value; - - rv=GWEN_Text_StringToDouble(s, &value); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - AQHREACT_Param_SetDoubleValue(param, value); - return 0; -} - - - -int _readLink(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *linkNode) -{ - const char *sourceNetName; - const char *sourceUnitName; - const char *sourceSlotName; - const char *targetNetName; - const char *targetUnitName; - const char *targetSlotName; - AQHREACT_UNIT *sourceUnit; - AQHREACT_UNIT *targetUnit; - AQHREACT_INPUT_SLOT *inputSlot; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_LINK *link; - - sourceNetName=GWEN_XMLNode_GetProperty(linkNode, "sourceNet", NULL); - sourceUnitName=GWEN_XMLNode_GetProperty(linkNode, "sourceUnit", NULL); - sourceSlotName=GWEN_XMLNode_GetProperty(linkNode, "sourceSlot", NULL); - targetNetName=GWEN_XMLNode_GetProperty(linkNode, "targetNet", NULL); - targetUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", NULL); - targetSlotName=GWEN_XMLNode_GetProperty(linkNode, "targetSlot", NULL); - - if (!(sourceUnitName && *sourceUnitName && sourceSlotName && *sourceSlotName && - targetUnitName && *targetUnitName && targetSlotName && *targetSlotName)) { - DBG_ERROR(NULL, - "Link in net \"%s\" needs properties sourceUnit, sourceSlot, targetUnit and targetSlot", - AQHREACT_UnitNet_GetName(unitNet)); - return GWEN_ERROR_BAD_DATA; - } - - sourceUnit=AQHREACT_UnitNet_GetUnitById(unitNet, sourceUnitName); - if (sourceUnit==NULL && sourceNetName && *sourceNetName) - sourceUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, sourceNetName, sourceUnitName); - if (sourceUnit==NULL) - sourceUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, sourceUnitName); - if (sourceUnit==NULL) { - DBG_ERROR(NULL, "Source unit \"%s\" not found", sourceUnitName); - return GWEN_ERROR_NOT_FOUND; - } - outputSlot=AQHREACT_Unit_GetOutputSlotByName(sourceUnit, sourceSlotName); - if (outputSlot==NULL) { - DBG_ERROR(NULL, "Output slot \"%s\" not found for source unit \"%s\"", sourceSlotName, sourceUnitName); - return GWEN_ERROR_NOT_FOUND; - } - - targetUnit=AQHREACT_UnitNet_GetUnitById(unitNet, targetUnitName); - if (targetUnit==NULL && targetNetName && *targetNetName) - targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, targetNetName, targetUnitName); - if (targetUnit==NULL) - targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, targetUnitName); - if (targetUnit==NULL) { - DBG_ERROR(NULL, "Target unit \"%s\" not found", targetUnitName); - return GWEN_ERROR_NOT_FOUND; - } - inputSlot=AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(targetUnit, targetSlotName); - if (inputSlot==NULL) { - DBG_ERROR(NULL, "Input slot \"%s\" not found for target unit \"%s\"", targetSlotName, targetUnitName); - return GWEN_ERROR_NOT_FOUND; - } - - link=AQHREACT_Link_new(); - AQHREACT_Link_SetTargetUnitId(link, targetUnitName); - AQHREACT_Link_SetTargetUnit(link, targetUnit); - AQHREACT_Link_SetTargetInputSlotIdForUnit(link, AQHREACT_InputSlot_GetIdForUnit(inputSlot)); - AQHREACT_OutputSlot_AddLink(outputSlot, link); - return 0; -} - - -int _treeExpandProperties(const GWEN_XMLNODE *n, GWEN_DB_NODE *dbVars) -{ - int rv; - const GWEN_XMLNODE *nn; - - rv=GWEN_XMLNode_ExpandProperties(n, dbVars); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - - nn=GWEN_XMLNode_GetFirstTag(n); - while(nn) { - rv=_treeExpandProperties(nn, dbVars); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - return rv; - } - nn=GWEN_XMLNode_GetNextTag(nn); - } - - return 0; -} - - - diff --git a/apps/aqhome-react/net_read.h b/apps/aqhome-react/net_read.h index 219342b..3773e3a 100644 --- a/apps/aqhome-react/net_read.h +++ b/apps/aqhome-react/net_read.h @@ -13,9 +13,10 @@ #include "./aqhome_react.h" -AQHREACT_UNIT_NET_LIST *AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh); +int AQHomeReact_ReadUnitNetFiles(AQHOME_REACT *aqh); +AQHREACT_UNIT *AQHomeReact_FindAndReadDataDirNetwork(AQHOME_REACT *aqh, const char *networkName); -time_t AQHomeReact_GetNewestUnitNetFiletime(const AQHOME_REACT *aqh); +time_t AQHomeReact_GetNewestUnitNetFiletime(void); #endif diff --git a/apps/aqhome-react/types/0BUILD b/apps/aqhome-react/types/0BUILD index 75b9733..e04d968 100644 --- a/apps/aqhome-react/types/0BUILD +++ b/apps/aqhome-react/types/0BUILD @@ -39,29 +39,23 @@ dataobject.h dataobject_p.h - inputslot.h - inputslot_p.h - outputslot.h - outputslot_p.h + port.h + port_p.h link.h link_p.h param.h param_p.h unit.h unit_p.h - unitnet.h - unitnet_p.h $(local/typefiles) dataobject.c - inputslot.c - outputslot.c + port.c link.c param.c unit.c - unitnet.c diff --git a/apps/aqhome-react/types/dataobject.c b/apps/aqhome-react/types/dataobject.c index 747df6a..5cb675f 100644 --- a/apps/aqhome-react/types/dataobject.c +++ b/apps/aqhome-react/types/dataobject.c @@ -199,6 +199,20 @@ const char *AQHREACT_DataObjectType_toString(int t) +int AQHREACT_DataObjectType_fromString(const char *s) +{ + if (s && *s) { + if (strcasecmp(s, "double")==0) + return AQHREACT_DATAOBJECTTYPE_DOUBLE; + else if (strcasecmp(s, "string")==0) + return AQHREACT_DATAOBJECTTYPE_STRING; + } + + return AQHREACT_DATAOBJECTTYPE_UNKNOWN; +} + + + void AQHREACT_DataObject_Dump(const AQHREACT_DATAOBJECT *dataObject, GWEN_BUFFER *buf, int indent) { if (dataObject && buf) { diff --git a/apps/aqhome-react/types/dataobject.h b/apps/aqhome-react/types/dataobject.h index 9aeb409..9ef08d7 100644 --- a/apps/aqhome-react/types/dataobject.h +++ b/apps/aqhome-react/types/dataobject.h @@ -59,6 +59,7 @@ void AQHREACT_DataObject_Dump(const AQHREACT_DATAOBJECT *dataObject, GWEN_BUFFER const char *AQHREACT_DataObjectType_toString(int t); +int AQHREACT_DataObjectType_fromString(const char *s); #endif diff --git a/apps/aqhome-react/types/link.c b/apps/aqhome-react/types/link.c index 47b2c50..57c5843 100644 --- a/apps/aqhome-react/types/link.c +++ b/apps/aqhome-react/types/link.c @@ -90,6 +90,21 @@ void AQHREACT_Link_SetTargetUnit(AQHREACT_LINK *lnk, AQHREACT_UNIT *unit) +AQHREACT_PORT *AQHREACT_Link_GetTargetPort(const AQHREACT_LINK *lnk) +{ + return lnk?lnk->targetPort:NULL; +} + + + +void AQHREACT_Link_SetTargetPort(AQHREACT_LINK *lnk, AQHREACT_PORT *port) +{ + if (lnk) + lnk->targetPort=port; +} + + + void AQHREACT_Link_Dump(const AQHREACT_LINK *lnk, GWEN_BUFFER *buf, int indent) { if (lnk && buf) { diff --git a/apps/aqhome-react/types/link.h b/apps/aqhome-react/types/link.h index 6c1f72a..d7e5cd0 100644 --- a/apps/aqhome-react/types/link.h +++ b/apps/aqhome-react/types/link.h @@ -18,6 +18,7 @@ GWEN_LIST_FUNCTION_DEFS(AQHREACT_LINK, AQHREACT_Link) #include "aqhome-react/types/unit.h" +#include "aqhome-react/types/port.h" AQHREACT_LINK *AQHREACT_Link_new(); @@ -33,6 +34,9 @@ void AQHREACT_Link_SetTargetInputSlotIdForUnit(AQHREACT_LINK *lnk, int i); AQHREACT_UNIT *AQHREACT_Link_GetTargetUnit(const AQHREACT_LINK *lnk); void AQHREACT_Link_SetTargetUnit(AQHREACT_LINK *lnk, AQHREACT_UNIT *unit); +AQHREACT_PORT *AQHREACT_Link_GetTargetPort(const AQHREACT_LINK *lnk); +void AQHREACT_Link_SetTargetPort(AQHREACT_LINK *lnk, AQHREACT_PORT *port); + void AQHREACT_Link_Dump(const AQHREACT_LINK *lnk, GWEN_BUFFER *buf, int indent); void AQHREACT_Link_List_Dump(const AQHREACT_LINK_LIST *lnkList, GWEN_BUFFER *buf, int indent, const char *title); diff --git a/apps/aqhome-react/types/link_p.h b/apps/aqhome-react/types/link_p.h index 538b467..dfb8a6b 100644 --- a/apps/aqhome-react/types/link_p.h +++ b/apps/aqhome-react/types/link_p.h @@ -20,6 +20,7 @@ struct AQHREACT_LINK { int targetInputSlotIdForUnit; AQHREACT_UNIT *targetUnit; + AQHREACT_PORT *targetPort; }; diff --git a/apps/aqhome-react/types/port.c b/apps/aqhome-react/types/port.c new file mode 100644 index 0000000..635f49b --- /dev/null +++ b/apps/aqhome-react/types/port.c @@ -0,0 +1,313 @@ +/**************************************************************************** + * 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 "./port_p.h" +#include "aqhome-react/types/dataobject.h" + +#include + + + +GWEN_LIST_FUNCTIONS(AQHREACT_PORT, AQHREACT_Port) + + +AQHREACT_PORT *AQHREACT_Port_new() +{ + AQHREACT_PORT *port; + + GWEN_NEW_OBJECT(AQHREACT_PORT, port); + GWEN_LIST_INIT(AQHREACT_PORT, port); + port->linkList=AQHREACT_Link_List_new(); + return port; +} + + + +AQHREACT_PORT *AQHREACT_Port_dup(const AQHREACT_PORT *srcPort) +{ + if (srcPort) { + AQHREACT_PORT *newPort; + + newPort=AQHREACT_Port_new(); + AQHREACT_Port_SetName(newPort, srcPort->name); + newPort->idForUnit=srcPort->idForUnit; + AQHREACT_Port_SetDescription(newPort, srcPort->description); + newPort->flags=srcPort->flags; + newPort->dataType=srcPort->dataType; + /* don't copy current dataObject */ + /* don't copy current links */ + return newPort; + } + return NULL; +} + + + +void AQHREACT_Port_free(AQHREACT_PORT *port) +{ + if (port) { + GWEN_LIST_FINI(AQHREACT_PORT, port); + AQHREACT_DataObject_free(port->currentDataObject); + AQHREACT_Link_List_free(port->linkList); + free(port->name); + free(port->description); + GWEN_FREE_OBJECT(port); + } +} + + + +const char *AQHREACT_Port_GetName(const AQHREACT_PORT *port) +{ + return port?port->name:NULL; +} + + + +void AQHREACT_Port_SetName(AQHREACT_PORT *port, const char *s) +{ + if (port) { + free(port->name); + port->name=s?strdup(s):NULL; + } +} + + + +int AQHREACT_Port_GetIdForUnit(const AQHREACT_PORT *port) +{ + return port?port->idForUnit:0; +} + + + +void AQHREACT_Port_SetIdForUnit(AQHREACT_PORT *port, int i) +{ + if (port) + port->idForUnit=i; +} + + + +const char *AQHREACT_Port_GetDescription(const AQHREACT_PORT *port) +{ + return port?port->description:NULL; +} + + + +void AQHREACT_Port_SetDescription(AQHREACT_PORT *port, const char *s) +{ + if (port) { + free(port->description); + port->description=s?strdup(s):NULL; + } +} + + + +uint32_t AQHREACT_Port_GetFlags(const AQHREACT_PORT *port) +{ + return port?port->flags:0; +} + + + +void AQHREACT_Port_SetFlags(AQHREACT_PORT *port, uint32_t f) +{ + if (port) + port->flags=f; +} + + + +void AQHREACT_Port_AddFlags(AQHREACT_PORT *port, uint32_t f) +{ + if (port) + port->flags|=f; +} + + + +void AQHREACT_Port_SubFlags(AQHREACT_PORT *port, uint32_t f) +{ + if (port) + port->flags&=~f; +} + + + +int AQHREACT_Port_GetDataType(const AQHREACT_PORT *port) +{ + return port?port->dataType:AQHREACT_DATAOBJECTTYPE_UNKNOWN; +} + + + +void AQHREACT_Port_SetDataType(AQHREACT_PORT *port, int i) +{ + if (port) + port->dataType=i; +} + + + +AQHREACT_DATAOBJECT *AQHREACT_Port_GetCurrentDataObject(const AQHREACT_PORT *port) +{ + return port?port->currentDataObject:NULL; +} + + + +void AQHREACT_Port_SetCurrentDataObject(AQHREACT_PORT *port, AQHREACT_DATAOBJECT *dataObject) +{ + if (port){ + AQHREACT_DataObject_free(port->currentDataObject); + port->currentDataObject=dataObject; + } +} + + + +AQHREACT_LINK_LIST *AQHREACT_Port_GetLinkList(const AQHREACT_PORT *port) +{ + return port?port->linkList:NULL; +} + + + +void AQHREACT_Port_AddLink(AQHREACT_PORT *port, AQHREACT_LINK *lnk) +{ + if (port) + AQHREACT_Link_List_Add(lnk, port->linkList); +} + + + +void AQHREACT_Port_SendData(const AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) +{ + AQHREACT_LINK_LIST *linkList; + + linkList=AQHREACT_Port_GetLinkList(port); + if (linkList) { + AQHREACT_LINK *lnk; + + lnk=AQHREACT_Link_List_First(linkList); + while(lnk) { + AQHREACT_UNIT *targetUnit; + AQHREACT_PORT *targetPort; + + targetUnit=AQHREACT_Link_GetTargetUnit(lnk); + targetPort=AQHREACT_Link_GetTargetPort(lnk); + if (targetUnit && targetPort) { + DBG_DEBUG(NULL, "%s: Sending data to %s:%s", + AQHREACT_Port_GetName(port), AQHREACT_Unit_GetId(targetUnit), AQHREACT_Port_GetName(targetPort)); + AQHREACT_Unit_InputData(targetUnit, targetPort, dataObject); + } + lnk=AQHREACT_Link_List_Next(lnk); + } /* while */ + } /* if linkList */ +} + + + +AQHREACT_PORT *AQHREACT_Port_List_GetByName(const AQHREACT_PORT_LIST *portList, const char *name) +{ + if (portList && name) { + AQHREACT_PORT *port; + + port=AQHREACT_Port_List_First(portList); + while(port) { + const char *s; + + s=AQHREACT_Port_GetName(port); + if (s && strcasecmp(s, name)==0) + return port; + port=AQHREACT_Port_List_Next(port); + } + } + return NULL; +} + + + +AQHREACT_PORT *AQHREACT_Port_List_GetByIdForUnit(const AQHREACT_PORT_LIST *portList, int id) +{ + if (portList) { + AQHREACT_PORT *port; + + port=AQHREACT_Port_List_First(portList); + while(port) { + if (id==AQHREACT_Port_GetIdForUnit(port)) + return port; + port=AQHREACT_Port_List_Next(port); + } + } + return NULL; +} + + + +void AQHREACT_Port_Dump(const AQHREACT_PORT *port, GWEN_BUFFER *buf, int indent) +{ + if (port && buf) { + if (indent) + GWEN_Buffer_FillWithBytes(buf, ' ', indent); + GWEN_Buffer_AppendArgs(buf, "name........: %s\n", (port->name)?(port->name):""); + + if (indent) + GWEN_Buffer_FillWithBytes(buf, ' ', indent); + GWEN_Buffer_AppendArgs(buf, "description.: %s\n", (port->description)?(port->description):""); + + if (indent) + GWEN_Buffer_FillWithBytes(buf, ' ', indent); + GWEN_Buffer_AppendArgs(buf, "data type...: %s\n", AQHREACT_DataObjectType_toString(port->dataType)); + + if (indent) + GWEN_Buffer_FillWithBytes(buf, ' ', indent); + GWEN_Buffer_AppendArgs(buf, "flags.......: %08x\n", port->flags); + + AQHREACT_Link_List_Dump(port->linkList, buf, indent, "Link List:"); + } +} + + + +void AQHREACT_Port_List_Dump(const AQHREACT_PORT_LIST *portList, GWEN_BUFFER *buf, int indent, const char *title) +{ + if (portList && buf) { + const AQHREACT_PORT *port; + + if (indent) + GWEN_Buffer_FillWithBytes(buf, ' ', indent); + GWEN_Buffer_AppendArgs(buf, "%s\n", (title && *title)?title:"Port List:\n"); + + port=AQHREACT_Port_List_First(portList); + while(port) { + GWEN_Buffer_FillWithBytes(buf, ' ', indent+2); + GWEN_Buffer_AppendString(buf, "Port:\n"); + AQHREACT_Port_Dump(port, buf, indent+4); + port=AQHREACT_Port_List_Next(port); + } + } +} + + + + + + + + + + diff --git a/apps/aqhome-react/types/port.h b/apps/aqhome-react/types/port.h new file mode 100644 index 0000000..e53754d --- /dev/null +++ b/apps/aqhome-react/types/port.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * 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_PORT_H +#define AQHOME_REACT_PORT_H + +#include + + +typedef struct AQHREACT_PORT AQHREACT_PORT; +GWEN_LIST_FUNCTION_DEFS(AQHREACT_PORT, AQHREACT_Port) + + +#include "aqhome-react/aqhome_react.h" +#include "aqhome-react/types/link.h" +#include "aqhome-react/types/dataobject.h" + + + +AQHREACT_PORT *AQHREACT_Port_new(); +AQHREACT_PORT *AQHREACT_Port_dup(const AQHREACT_PORT *srcPort); +void AQHREACT_Port_free(AQHREACT_PORT *port); + +const char *AQHREACT_Port_GetName(const AQHREACT_PORT *port); +void AQHREACT_Port_SetName(AQHREACT_PORT *port, const char *s); + +int AQHREACT_Port_GetIdForUnit(const AQHREACT_PORT *port); +void AQHREACT_Port_SetIdForUnit(AQHREACT_PORT *port, int i); + +const char *AQHREACT_Port_GetDescription(const AQHREACT_PORT *port); +void AQHREACT_Port_SetDescription(AQHREACT_PORT *port, const char *s); + +uint32_t AQHREACT_Port_GetFlags(const AQHREACT_PORT *port); +void AQHREACT_Port_SetFlags(AQHREACT_PORT *port, uint32_t f); +void AQHREACT_Port_AddFlags(AQHREACT_PORT *port, uint32_t f); +void AQHREACT_Port_SubFlags(AQHREACT_PORT *port, uint32_t f); + +int AQHREACT_Port_GetDataType(const AQHREACT_PORT *port); +void AQHREACT_Port_SetDataType(AQHREACT_PORT *port, int i); + +AQHREACT_DATAOBJECT *AQHREACT_Port_GetCurrentDataObject(const AQHREACT_PORT *port); +void AQHREACT_Port_SetCurrentDataObject(AQHREACT_PORT *port, AQHREACT_DATAOBJECT *dataObject); + +void AQHREACT_Port_SendData(const AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); + + +AQHREACT_LINK_LIST *AQHREACT_Port_GetLinkList(const AQHREACT_PORT *port); +void AQHREACT_Port_AddLink(AQHREACT_PORT *port, AQHREACT_LINK *lnk); + + +AQHREACT_PORT *AQHREACT_Port_List_GetByName(const AQHREACT_PORT_LIST *portList, const char *name); +AQHREACT_PORT *AQHREACT_Port_List_GetByIdForUnit(const AQHREACT_PORT_LIST *portList, int id); + + +void AQHREACT_Port_Dump(const AQHREACT_PORT *port, GWEN_BUFFER *buf, int indent); +void AQHREACT_Port_List_Dump(const AQHREACT_PORT_LIST *portList, GWEN_BUFFER *buf, int indent, const char *title); + + + + +#endif + diff --git a/apps/aqhome-react/types/port_p.h b/apps/aqhome-react/types/port_p.h new file mode 100644 index 0000000..fc43566 --- /dev/null +++ b/apps/aqhome-react/types/port_p.h @@ -0,0 +1,31 @@ +/**************************************************************************** + * 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_PORT_P_H +#define AQHOME_REACT_PORT_P_H + + +#include "aqhome-react/types/port.h" + + +struct AQHREACT_PORT { + GWEN_LIST_ELEMENT(AQHREACT_PORT) + + char *name; + char *description; + int idForUnit; + uint32_t flags; + int dataType; + + AQHREACT_DATAOBJECT *currentDataObject; + AQHREACT_LINK_LIST *linkList; +}; + + +#endif + diff --git a/apps/aqhome-react/types/unit.c b/apps/aqhome-react/types/unit.c index 9b24d52..ba4c921 100644 --- a/apps/aqhome-react/types/unit.c +++ b/apps/aqhome-react/types/unit.c @@ -30,9 +30,9 @@ AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh) GWEN_LIST_INIT(AQHREACT_UNIT, unit); unit->aqHomeReact=aqh; - unit->inputSlotList=AQHREACT_InputSlot_List_new(); - unit->outputSlotList=AQHREACT_OutputSlot_List_new(); unit->paramList=AQHREACT_Param_List_new(); + unit->inputPortList=AQHREACT_Port_List_new(); + unit->outputPortList=AQHREACT_Port_List_new(); return unit; } @@ -46,8 +46,8 @@ void AQHREACT_Unit_free(AQHREACT_UNIT *unit) GWEN_INHERIT_FINI(AQHREACT_UNIT, unit); free(unit->name); free(unit->description); - AQHREACT_InputSlot_List_free(unit->inputSlotList); - AQHREACT_OutputSlot_List_free(unit->outputSlotList); + AQHREACT_Port_List_free(unit->outputPortList); + AQHREACT_Port_List_free(unit->inputPortList); AQHREACT_Param_List_free(unit->paramList); GWEN_FREE_OBJECT(unit); } @@ -113,17 +113,10 @@ void AQHREACT_Unit_SetId(AQHREACT_UNIT *unit, const char *s) -int AQHREACT_Unit_GetNextInputSlotId(const AQHREACT_UNIT *unit) -{ - return unit?unit->nextInputSlotId:-1; -} - - - -void AQHREACT_Unit_SetNextInputSlotId(AQHREACT_UNIT *unit, int i) +void AQHREACT_Unit_SetNextInputPortId(AQHREACT_UNIT *unit, int i) { if (unit) - unit->nextInputSlotId=i; + unit->nextInputPortId=i; } @@ -174,36 +167,102 @@ void AQHREACT_Unit_SetGpTimestamp(AQHREACT_UNIT *unit, uint64_t t) -AQHREACT_INPUT_SLOT_LIST *AQHREACT_Unit_GetInputSlots(const AQHREACT_UNIT *unit) +AQHREACT_PORT_LIST *AQHREACT_Unit_GetInputPortList(const AQHREACT_UNIT *unit) { - return unit?unit->inputSlotList:NULL; + return unit?unit->inputPortList:NULL; } -void AQHREACT_Unit_AddInputSlot(AQHREACT_UNIT *unit, AQHREACT_INPUT_SLOT *inSlot) +void AQHREACT_Unit_AddInputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port) { - if (unit) - AQHREACT_InputSlot_List_Add(inSlot, unit->inputSlotList); + if (unit && port) + AQHREACT_Port_List_Add(port, unit->inputPortList); } -AQHREACT_OUTPUT_SLOT_LIST *AQHREACT_Unit_GetOutputSlots(const AQHREACT_UNIT *unit) +AQHREACT_PORT *AQHREACT_Unit_GetInputPortByName(const AQHREACT_UNIT *unit, const char *name) { - return unit?unit->outputSlotList:NULL; + return (unit && name)?AQHREACT_Port_List_GetByName(unit->inputPortList, name):NULL; } -void AQHREACT_Unit_AddOutputSlot(AQHREACT_UNIT *unit, AQHREACT_OUTPUT_SLOT *outSlot) +AQHREACT_PORT *AQHREACT_Unit_GetInputPortByIdForUnit(const AQHREACT_UNIT *unit, int id) { - if (unit) - AQHREACT_OutputSlot_List_Add(outSlot, unit->outputSlotList); + return unit?AQHREACT_Port_List_GetByIdForUnit(unit->inputPortList, id):NULL; } +AQHREACT_PORT *AQHREACT_Unit_GetOrCreateUnusedInputPortByName(AQHREACT_UNIT *unit, const char *s) +{ + if (unit && unit->inputPortList && s && *s) { + AQHREACT_PORT *port; + + port=AQHREACT_Unit_GetInputPortByName(unit, s); + if (port) { + uint32_t flags; + const char *portName; + + portName=AQHREACT_Port_GetName(port); + flags=AQHREACT_Port_GetFlags(port); + if (!(flags & AQHREACT_UNIT_FLAGS_INUSE)) + return port; + if (flags & AQHREACT_UNIT_FLAGS_MULTI) { /* can we just duplicate existing? */ + AQHREACT_PORT *newPort; + + newPort=AQHREACT_Port_dup(port); + AQHREACT_Unit_AddInputPort(unit, newPort); + return newPort; + } + else { + DBG_INFO(NULL, "Port \"%s\" found but in use, no multi flag", portName); + } + } + } + + return NULL; +} + + + +AQHREACT_PORT_LIST *AQHREACT_Unit_GetOutputPortList(const AQHREACT_UNIT *unit) +{ + return unit?unit->outputPortList:NULL; +} + + + +void AQHREACT_Unit_AddOutputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port) +{ + if (unit && port) + AQHREACT_Port_List_Add(port, unit->outputPortList); +} + + + +AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByName(const AQHREACT_UNIT *unit, const char *name) +{ + return (unit && name)?AQHREACT_Port_List_GetByName(unit->outputPortList, name):NULL; +} + + + +AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByIdForUnit(const AQHREACT_UNIT *unit, int id) +{ + return unit?AQHREACT_Port_List_GetByIdForUnit(unit->outputPortList, id):NULL; +} + + + + + + + + + AQHREACT_PARAM_LIST *AQHREACT_Unit_GetParamList(const AQHREACT_UNIT *unit) { return unit?unit->paramList:NULL; @@ -383,94 +442,62 @@ AQHREACT_UNIT_PROCESS_FN AQHREACT_Unit_SetProcessFn(AQHREACT_UNIT *unit, AQHREAC -void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit) { + if (unit && port) { if (unit->outputDataFn) - (unit->outputDataFn)(unit, slotIdForUnit, dataObject); + (unit->outputDataFn)(unit, port, dataObject); else { - if (unit->outputSlotList) { - AQHREACT_OUTPUT_SLOT *slot; - - slot=AQHREACT_Unit_GetOutputSlotByIdForUnit(unit, slotIdForUnit); - if (slot) { - AQHREACT_LINK_LIST *linkList; - - linkList=AQHREACT_OutputSlot_GetLinkList(slot); - if (linkList) { - AQHREACT_LINK *lnk; - - lnk=AQHREACT_Link_List_First(linkList); - while(lnk) { - AQHREACT_UNIT *targetUnit; - int targetSlotIdForUnit; - - targetUnit=AQHREACT_Link_GetTargetUnit(lnk); - targetSlotIdForUnit=AQHREACT_Link_GetTargetInputSlotIdForUnit(lnk); - if (targetUnit && targetSlotIdForUnit>=0) { - DBG_DEBUG(NULL, "%s: Sending data to %s:%d", - AQHREACT_Unit_GetId(unit), - AQHREACT_Link_GetTargetUnitId(lnk), AQHREACT_Link_GetTargetInputSlotIdForUnit(lnk)); - AQHREACT_Unit_InputData(targetUnit, targetSlotIdForUnit, dataObject); - } - lnk=AQHREACT_Link_List_Next(lnk); - } /* while */ - } /* if linkList */ - } /* if slot */ - } /* if output slot list */ - } /* else */ - } /* if unit */ + AQHREACT_Port_SendData(port, dataObject); + } + } } -void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, int slotIndex, double data) +void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, double data) { - if (unit && unit->outputSlotList) { + if (unit && unit->outputPortList) { AQHREACT_DATAOBJECT *dataObject; dataObject=AQHREACT_DataObject_new(); AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_DataObject_SetDoubleData(dataObject, data); - AQHREACT_Unit_OutputData(unit, slotIndex, dataObject); + AQHREACT_Unit_OutputData(unit, port, dataObject); AQHREACT_DataObject_free(dataObject); } } -void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, int slotIndex, const char *data) +void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const char *data) { - if (unit && unit->outputSlotList) { + if (unit && unit->outputPortList) { AQHREACT_DATAOBJECT *dataObject; dataObject=AQHREACT_DataObject_new(); AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_STRING); AQHREACT_DataObject_SetStringData(dataObject, data); - AQHREACT_Unit_OutputData(unit, slotIndex, dataObject); + AQHREACT_Unit_OutputData(unit, port, dataObject); AQHREACT_DataObject_free(dataObject); } } -void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit) { + if (unit && port) { if (unit->inputDataFn) - (unit->inputDataFn)(unit, slotIdForUnit, dataObject); + (unit->inputDataFn)(unit, port, dataObject); else { if (dataObject) { - AQHREACT_INPUT_SLOT *inSlot; - - inSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, slotIdForUnit); - if (inSlot) { - if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_InputSlot_GetAcceptedDataType(inSlot)) { - AQHREACT_InputSlot_SetCurrentDataObject(inSlot, AQHREACT_DataObject_dup(dataObject)); - AQHREACT_InputSlot_AddFlags(inSlot, AQHREACT_UNIT_FLAGS_CHANGED); - AQHREACT_Unit_AddFlags(unit, AQHREACT_UNIT_FLAGS_CHANGED); - } - } + if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_Port_GetDataType(port)) { + AQHREACT_Port_SetCurrentDataObject(port, AQHREACT_DataObject_dup(dataObject)); + AQHREACT_Port_SendData(port, dataObject); + AQHREACT_Port_AddFlags(port, AQHREACT_UNIT_FLAGS_CHANGED); + AQHREACT_Unit_AddFlags(unit, AQHREACT_UNIT_FLAGS_CHANGED); + } } } } @@ -481,13 +508,14 @@ void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHRE + int AQHREACT_Unit_Process(AQHREACT_UNIT *unit) { if (unit) { if (unit->processFn) return (unit->processFn)(unit); else - AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); + AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit); } return 0; @@ -495,129 +523,16 @@ int AQHREACT_Unit_Process(AQHREACT_UNIT *unit) -AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByIdForUnit(const AQHREACT_UNIT *unit, int id) -{ - if (unit && unit->inputSlotList && id>=0) { - AQHREACT_INPUT_SLOT *slot; - - slot=AQHREACT_InputSlot_List_First(unit->inputSlotList); - while(slot) { - if (AQHREACT_InputSlot_GetIdForUnit(slot)==id) - return slot; - slot=AQHREACT_InputSlot_List_Next(slot); - } - } - - return NULL; -} - - - -AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByName(const AQHREACT_UNIT *unit, const char *s) -{ - if (unit && unit->inputSlotList && s && *s) { - AQHREACT_INPUT_SLOT *slot; - - slot=AQHREACT_InputSlot_List_First(unit->inputSlotList); - while(slot) { - const char *slotName; - - slotName=AQHREACT_InputSlot_GetName(slot); - if (slotName && *slotName && strcasecmp(slotName, s)==0) - return slot; - slot=AQHREACT_InputSlot_List_Next(slot); - } - } - - return NULL; -} - - - -AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(AQHREACT_UNIT *unit, const char *s) -{ - if (unit && unit->inputSlotList && s && *s) { - AQHREACT_INPUT_SLOT *slot; - - slot=AQHREACT_Unit_GetInputSlotByName(unit, s); - if (slot) { - uint32_t flags; - const char *slotName; - - slotName=AQHREACT_InputSlot_GetName(slot); - flags=AQHREACT_InputSlot_GetFlags(slot); - if (!(flags & AQHREACT_UNIT_FLAGS_INUSE)) - return slot; - if (flags & AQHREACT_UNIT_FLAGS_MULTI) { /* can we just duplicate existing? */ - AQHREACT_INPUT_SLOT *newSlot; - - newSlot=AQHREACT_InputSlot_dup(slot); - AQHREACT_InputSlot_SetIdForUnit(newSlot, (unit->nextInputSlotId)++); - AQHREACT_Unit_AddInputSlot(unit, newSlot); - return newSlot; - } - else { - DBG_INFO(NULL, "Slot \"%s\" found but in use, no multi flag", slotName); - } - } - } - - return NULL; -} - - - -AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByIdForUnit(const AQHREACT_UNIT *unit, int id) -{ - if (unit && unit->outputSlotList && id>=0) { - AQHREACT_OUTPUT_SLOT *slot; - - slot=AQHREACT_OutputSlot_List_First(unit->outputSlotList); - while(slot) { - if (AQHREACT_OutputSlot_GetIdForUnit(slot)==id) - return slot; - slot=AQHREACT_OutputSlot_List_Next(slot); - } - } - - return NULL; -} - - - -AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByName(const AQHREACT_UNIT *unit, const char *s) -{ - if (unit && unit->outputSlotList && s && *s) { - AQHREACT_OUTPUT_SLOT *slot; - - slot=AQHREACT_OutputSlot_List_First(unit->outputSlotList); - while(slot) { - const char *slotName; - - slotName=AQHREACT_OutputSlot_GetName(slot); - if (slotName && *slotName && strcasecmp(slotName, s)==0) - return slot; - - slot=AQHREACT_OutputSlot_List_Next(slot); - } - return slot; - } - - return NULL; -} - - - -void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(AQHREACT_UNIT *unit) +void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(AQHREACT_UNIT *unit) { if (unit) { - AQHREACT_INPUT_SLOT *slot; + AQHREACT_PORT *port; unit->flags&=~AQHREACT_UNIT_FLAGS_CHANGED; - slot=AQHREACT_InputSlot_List_First(unit->inputSlotList); - while(slot) { - AQHREACT_InputSlot_SubFlags(slot, AQHREACT_UNIT_FLAGS_CHANGED); - slot=AQHREACT_InputSlot_List_Next(slot); + port=AQHREACT_Port_List_First(unit->inputPortList); + while(port) { + AQHREACT_Port_SubFlags(port, AQHREACT_UNIT_FLAGS_CHANGED); + port=AQHREACT_Port_List_Next(port); } } } @@ -627,16 +542,16 @@ void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(AQHREACT_UNIT *unit) int AQHREACT_Unit_InputHasChanged(const AQHREACT_UNIT *unit) { if (unit) { - AQHREACT_INPUT_SLOT *slot; + AQHREACT_PORT *port; if (unit->flags & AQHREACT_UNIT_FLAGS_CHANGED) return 1; - slot=AQHREACT_InputSlot_List_First(unit->inputSlotList); - while(slot) { - if (AQHREACT_InputSlot_GetFlags(slot) & AQHREACT_UNIT_FLAGS_CHANGED) + port=AQHREACT_Port_List_First(unit->inputPortList); + while(port) { + if (AQHREACT_Port_GetFlags(port) & AQHREACT_UNIT_FLAGS_CHANGED) return 1; - slot=AQHREACT_InputSlot_List_Next(slot); + port=AQHREACT_Port_List_Next(port); } } return 0; @@ -685,8 +600,8 @@ void AQHREACT_Unit_Dump(const AQHREACT_UNIT *unit, GWEN_BUFFER *buf, int indent) GWEN_Buffer_AppendArgs(buf, "flags......: %08x\n", unit->flags); AQHREACT_Param_List_Dump(unit->paramList, buf, indent, "Unit Parameter List:"); - AQHREACT_InputSlot_List_Dump(unit->inputSlotList, buf, indent, "Input Slot List:"); - AQHREACT_OutputSlot_List_Dump(unit->outputSlotList, buf, indent, "Output Slot List:"); + AQHREACT_Port_List_Dump(unit->inputPortList, buf, indent, "Input Port List:"); + AQHREACT_Port_List_Dump(unit->outputPortList, buf, indent, "Output Port List:"); } } diff --git a/apps/aqhome-react/types/unit.h b/apps/aqhome-react/types/unit.h index 0294a0b..b7f6579 100644 --- a/apps/aqhome-react/types/unit.h +++ b/apps/aqhome-react/types/unit.h @@ -25,19 +25,19 @@ GWEN_INHERIT_FUNCTION_DEFS(AQHREACT_UNIT) #include "aqhome-react/aqhome_react.h" -#include "aqhome-react/types/inputslot.h" -#include "aqhome-react/types/outputslot.h" +#include "aqhome-react/types/port.h" #include "aqhome-react/types/param.h" #include "aqhome-react/types/dataobject.h" -typedef void (*AQHREACT_UNIT_INPUTDATA_FN)(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); -typedef void (*AQHREACT_UNIT_OUTPUTDATA_FN)(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +typedef void (*AQHREACT_UNIT_INPUTDATA_FN)(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); +typedef void (*AQHREACT_UNIT_OUTPUTDATA_FN)(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); typedef AQHREACT_PARAM* (*AQHREACT_UNIT_GETPARAMBYNAME_FN)(const AQHREACT_UNIT *unit, const char *paramName); typedef int (*AQHREACT_UNIT_PROCESS_FN)(AQHREACT_UNIT *unit); + AQHREACT_UNIT *AQHREACT_Unit_new(AQHOME_REACT *aqh); void AQHREACT_Unit_free(AQHREACT_UNIT *unit); @@ -52,9 +52,6 @@ void AQHREACT_Unit_SetDescription(AQHREACT_UNIT *unit, const char *s); const char *AQHREACT_Unit_GetId(const AQHREACT_UNIT *unit); void AQHREACT_Unit_SetId(AQHREACT_UNIT *unit, const char *s); -int AQHREACT_Unit_GetNextInputSlotId(const AQHREACT_UNIT *unit); -void AQHREACT_Unit_SetNextInputSlotId(AQHREACT_UNIT *unit, int i); - uint32_t AQHREACT_Unit_GetFlags(const AQHREACT_UNIT *unit); void AQHREACT_Unit_SetFlags(AQHREACT_UNIT *unit, uint32_t i); void AQHREACT_Unit_AddFlags(AQHREACT_UNIT *unit, uint32_t i); @@ -65,19 +62,20 @@ uint64_t AQHREACT_Unit_GetGpTimestamp(const AQHREACT_UNIT *unit); void AQHREACT_Unit_SetGpTimestamp(AQHREACT_UNIT *unit, uint64_t t); -AQHREACT_INPUT_SLOT_LIST *AQHREACT_Unit_GetInputSlots(const AQHREACT_UNIT *unit); -void AQHREACT_Unit_AddInputSlot(AQHREACT_UNIT *unit, AQHREACT_INPUT_SLOT *inSlot); -AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByIdForUnit(const AQHREACT_UNIT *unit, int id); -AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetInputSlotByName(const AQHREACT_UNIT *unit, const char *s); -AQHREACT_INPUT_SLOT *AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(AQHREACT_UNIT *unit, const char *s); +AQHREACT_PORT_LIST *AQHREACT_Unit_GetInputPortList(const AQHREACT_UNIT *unit); +void AQHREACT_Unit_AddInputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port); +AQHREACT_PORT *AQHREACT_Unit_GetInputPortByName(const AQHREACT_UNIT *unit, const char *s); +AQHREACT_PORT *AQHREACT_Unit_GetInputPortByIdForUnit(const AQHREACT_UNIT *unit, int id); +AQHREACT_PORT *AQHREACT_Unit_GetOrCreateUnusedInputPortByName(AQHREACT_UNIT *unit, const char *s); +AQHREACT_PORT_LIST *AQHREACT_Unit_GetOutputPortList(const AQHREACT_UNIT *unit); +void AQHREACT_Unit_AddOutputPort(AQHREACT_UNIT *unit, AQHREACT_PORT *port); +AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByName(const AQHREACT_UNIT *unit, const char *s); +AQHREACT_PORT *AQHREACT_Unit_GetOutputPortByIdForUnit(const AQHREACT_UNIT *unit, int id); -AQHREACT_OUTPUT_SLOT_LIST *AQHREACT_Unit_GetOutputSlots(const AQHREACT_UNIT *unit); -void AQHREACT_Unit_AddOutputSlot(AQHREACT_UNIT *unit, AQHREACT_OUTPUT_SLOT *outSlot); -AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByIdForUnit(const AQHREACT_UNIT *unit, int idx); -AQHREACT_OUTPUT_SLOT *AQHREACT_Unit_GetOutputSlotByName(const AQHREACT_UNIT *unit, const char *s); +void AQHREACT_Unit_SetNextInputPortId(AQHREACT_UNIT *unit, int i); -void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(AQHREACT_UNIT *unit); +void AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(AQHREACT_UNIT *unit); int AQHREACT_Unit_InputHasChanged(const AQHREACT_UNIT *unit); @@ -89,12 +87,12 @@ void AQHREACT_Unit_SetParamValueDouble(AQHREACT_UNIT *unit, const char *paramNam const char *AQHREACT_Unit_GetParamValueString(const AQHREACT_UNIT *unit, const char *paramName, const char *defVal); void AQHREACT_Unit_SetParamValueString(AQHREACT_UNIT *unit, const char *paramName, const char *val); -void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); -void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, int slotIdForUnit, double data); -void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, int slotIdForUnit, const char *data); +void AQHREACT_Unit_OutputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); +void AQHREACT_Unit_OutputDoubleData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, double data); +void AQHREACT_Unit_OutputStringData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const char *data); -void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +void AQHREACT_Unit_InputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); /** * Process inputs and generate output. diff --git a/apps/aqhome-react/types/unit_p.h b/apps/aqhome-react/types/unit_p.h index f10ca07..2bc1079 100644 --- a/apps/aqhome-react/types/unit_p.h +++ b/apps/aqhome-react/types/unit_p.h @@ -25,10 +25,10 @@ struct AQHREACT_UNIT { uint32_t flags; uint64_t gpTimestamp; - int nextInputSlotId; + int nextInputPortId; - AQHREACT_INPUT_SLOT_LIST *inputSlotList; - AQHREACT_OUTPUT_SLOT_LIST *outputSlotList; + AQHREACT_PORT_LIST *inputPortList; + AQHREACT_PORT_LIST *outputPortList; AQHREACT_PARAM_LIST *paramList; diff --git a/apps/aqhome-react/units/u_highpass.c b/apps/aqhome-react/units/u_highpass.c index 9c67770..7cfbdc2 100644 --- a/apps/aqhome-react/units/u_highpass.c +++ b/apps/aqhome-react/units/u_highpass.c @@ -31,7 +31,7 @@ * ------------------------------------------------------------------------------------------------ */ -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); @@ -43,8 +43,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_ AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; AQHREACT_PARAM *param; unit=AQHREACT_Unit_new(aqh); @@ -52,17 +51,17 @@ AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh) AQHREACT_Unit_SetDescription(unit, "Highpass filter for data"); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT); @@ -79,17 +78,22 @@ AQHREACT_UNIT *AqHomeReact_UnitHighPass_new(AQHOME_REACT *aqh) -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT) { - double data; - double limit; - double newValue; + if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_HIGHPASS_INSLOT_INPUT) { + AQHREACT_PORT *outputPort; - data=AQHREACT_DataObject_GetDoubleData(dataObject); - limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT, data); - newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_NEWVALUE, data); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT, (data>=limit)?data:newValue); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_HIGHPASS_OUTSLOT_OUTPUT); + if (outputPort) { + double data; + double limit; + double newValue; + + data=AQHREACT_DataObject_GetDoubleData(dataObject); + limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_LIMIT, data); + newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_HIGHPASS_PARAM_NEWVALUE, data); + AQHREACT_Unit_OutputDoubleData(unit, outputPort, (data>=limit)?data:newValue); + } } } diff --git a/apps/aqhome-react/units/u_logical.c b/apps/aqhome-react/units/u_logical.c index 2f32e7a..caa6cdd 100644 --- a/apps/aqhome-react/units/u_logical.c +++ b/apps/aqhome-react/units/u_logical.c @@ -89,27 +89,26 @@ AQHREACT_UNIT *AqHomeReact_UnitXor_new(AQHOME_REACT *aqh) AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; unit=AQHREACT_Unit_new(aqh); AQHREACT_Unit_SetName(unit, "or"); AQHREACT_Unit_SetDescription(unit, "Logical OR inputs"); - AQHREACT_Unit_SetNextInputSlotId(unit, AQHOMEREACT_UNIT_LOGICAL_INSLOT_AUTOINPUT); /* for auto-gen multi-slots */ + AQHREACT_Unit_SetNextInputPortId(unit, AQHOMEREACT_UNIT_LOGICAL_INSLOT_AUTOINPUT); /* for auto-gen multi-slots */ - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_LOGICAL_INSLOT_INPUT); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_InputSlot_AddFlags(inputSlot, AQHREACT_UNIT_FLAGS_MULTI); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOGICAL_INSLOT_INPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Port_AddFlags(port, AQHREACT_UNIT_FLAGS_MULTI); + AQHREACT_Unit_AddInputPort(unit, port); return unit; } @@ -119,41 +118,46 @@ AQHREACT_UNIT *_unitLogical_new(AQHOME_REACT *aqh) int _cbProcessOr(AQHREACT_UNIT *unit) { if (unit && AQHREACT_Unit_InputHasChanged(unit)) { - AQHREACT_INPUT_SLOT_LIST *inputSlotList; + AQHREACT_PORT *outputPort; - inputSlotList=AQHREACT_Unit_GetInputSlots(unit); - if (inputSlotList) { - const AQHREACT_INPUT_SLOT *inputSlot; - int result=0; - - inputSlot=AQHREACT_InputSlot_List_First(inputSlotList); - while(inputSlot) { - const char *slotName; - const AQHREACT_DATAOBJECT *dataObject; - - slotName=AQHREACT_InputSlot_GetName(inputSlot); - dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); - if (dataObject) { - if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) { - double d; - - d=AQHREACT_DataObject_GetDoubleData(dataObject); - if (d>0.0) - result|=1; - } - else { - DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:""); - } - } - else { - DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:""); - } - inputSlot=AQHREACT_InputSlot_List_Next(inputSlot); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT); + if (outputPort) { + AQHREACT_PORT_LIST *portList; + + portList=AQHREACT_Unit_GetInputPortList(unit); + if (portList) { + const AQHREACT_PORT *port; + int result=0; + + port=AQHREACT_Port_List_First(portList); + while(port) { + const char *portName; + const AQHREACT_DATAOBJECT *dataObject; + + portName=AQHREACT_Port_GetName(port); + dataObject=AQHREACT_Port_GetCurrentDataObject(port); + if (dataObject) { + if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) { + double d; + + d=AQHREACT_DataObject_GetDoubleData(dataObject); + if (d>0.0) + result|=1; + } + else { + DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", portName?portName:""); + } + } + else { + DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", portName?portName:""); + } + port=AQHREACT_Port_List_Next(port); + } + + AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit); + AQHREACT_Unit_OutputDoubleData(unit, outputPort, result?1.0:0.0); + return 1; } - - AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0); - return 1; } } @@ -165,41 +169,46 @@ int _cbProcessOr(AQHREACT_UNIT *unit) int _cbProcessAnd(AQHREACT_UNIT *unit) { if (unit && AQHREACT_Unit_InputHasChanged(unit)) { - AQHREACT_INPUT_SLOT_LIST *inputSlotList; + AQHREACT_PORT *outputPort; - inputSlotList=AQHREACT_Unit_GetInputSlots(unit); - if (inputSlotList) { - const AQHREACT_INPUT_SLOT *inputSlot; - int result=1; - - inputSlot=AQHREACT_InputSlot_List_First(inputSlotList); - while(inputSlot) { - const char *slotName; - const AQHREACT_DATAOBJECT *dataObject; - - slotName=AQHREACT_InputSlot_GetName(inputSlot); - dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); - if (dataObject) { - if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) { - double d; - - d=AQHREACT_DataObject_GetDoubleData(dataObject); - if (!(d>0.0)) - result=0; - } - else { - DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:""); - } - } - else { - DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:""); - } - inputSlot=AQHREACT_InputSlot_List_Next(inputSlot); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT); + if (outputPort) { + AQHREACT_PORT_LIST *portList; + + portList=AQHREACT_Unit_GetInputPortList(unit); + if (portList) { + AQHREACT_PORT *port; + int result=1; + + port=AQHREACT_Port_List_First(portList); + while(port) { + const char *portName; + const AQHREACT_DATAOBJECT *dataObject; + + portName=AQHREACT_Port_GetName(port); + dataObject=AQHREACT_Port_GetCurrentDataObject(port); + if (dataObject) { + if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) { + double d; + + d=AQHREACT_DataObject_GetDoubleData(dataObject); + if (!(d>0.0)) + result=0; + } + else { + DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", portName?portName:""); + } + } + else { + DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", portName?portName:""); + } + port=AQHREACT_Port_List_Next(port); + } + + AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit); + AQHREACT_Unit_OutputDoubleData(unit, port, result?1.0:0.0); + return 1; } - - AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0); - return 1; } } @@ -211,41 +220,46 @@ int _cbProcessAnd(AQHREACT_UNIT *unit) int _cbProcessXor(AQHREACT_UNIT *unit) { if (unit && AQHREACT_Unit_InputHasChanged(unit)) { - AQHREACT_INPUT_SLOT_LIST *inputSlotList; + AQHREACT_PORT *outputPort; - inputSlotList=AQHREACT_Unit_GetInputSlots(unit); - if (inputSlotList) { - const AQHREACT_INPUT_SLOT *inputSlot; - int result=0; - - inputSlot=AQHREACT_InputSlot_List_First(inputSlotList); - while(inputSlot) { - const char *slotName; - const AQHREACT_DATAOBJECT *dataObject; - - slotName=AQHREACT_InputSlot_GetName(inputSlot); - dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); - if (dataObject) { - if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) { - double d; - - d=AQHREACT_DataObject_GetDoubleData(dataObject); - if (d>0.0) - result^=1; /*only xor when >0.0, otherwise no change (x XOR 0 is still x) */ - } - else { - DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", slotName?slotName:""); - } - } - else { - DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", slotName?slotName:""); - } - inputSlot=AQHREACT_InputSlot_List_Next(inputSlot); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT); + if (outputPort) { + AQHREACT_PORT_LIST *portList; + + portList=AQHREACT_Unit_GetInputPortList(unit); + if (portList) { + AQHREACT_PORT *port; + int result=0; + + port=AQHREACT_Port_List_First(portList); + while(port) { + const char *portName; + const AQHREACT_DATAOBJECT *dataObject; + + portName=AQHREACT_Port_GetName(port); + dataObject=AQHREACT_Port_GetCurrentDataObject(port); + if (dataObject) { + if (AQHREACT_DataObject_GetDataType(dataObject)==AQHREACT_DATAOBJECTTYPE_DOUBLE) { + double d; + + d=AQHREACT_DataObject_GetDoubleData(dataObject); + if (d>0.0) + result^=1; /*only xor when >0.0, otherwise no change (x XOR 0 is still x) */ + } + else { + DBG_ERROR(NULL, "Data at input slot \"%s\" isn't DOUBLE, ignoring", portName?portName:""); + } + } + else { + DBG_ERROR(NULL, "Data at input slot \"%s\" has not current data, ignoring", portName?portName:""); + } + port=AQHREACT_Port_List_Next(port); + } + + AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit); + AQHREACT_Unit_OutputDoubleData(unit, port, result?1.0:0.0); + return 1; } - - AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOGICAL_OUTSLOT_RESULT, result?1.0:0.0); - return 1; } } diff --git a/apps/aqhome-react/units/u_lowpass.c b/apps/aqhome-react/units/u_lowpass.c index 6ce67ac..0b5fd3d 100644 --- a/apps/aqhome-react/units/u_lowpass.c +++ b/apps/aqhome-react/units/u_lowpass.c @@ -31,7 +31,7 @@ * ------------------------------------------------------------------------------------------------ */ -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); @@ -43,8 +43,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_ AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; AQHREACT_PARAM *param; unit=AQHREACT_Unit_new(aqh); @@ -52,17 +51,17 @@ AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh) AQHREACT_Unit_SetDescription(unit, "Lowpass filter for data"); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT); @@ -79,17 +78,22 @@ AQHREACT_UNIT *AqHomeReact_UnitLowPass_new(AQHOME_REACT *aqh) -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT) { - double data; - double limit; - double newValue; + if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_LOWPASS_INSLOT_INPUT) { + AQHREACT_PORT *outputPort; - data=AQHREACT_DataObject_GetDoubleData(dataObject); - limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT, data); - newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_NEWVALUE, data); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT, (data<=limit)?data:newValue); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_LOWPASS_OUTSLOT_OUTPUT); + if (outputPort) { + double data; + double limit; + double newValue; + + data=AQHREACT_DataObject_GetDoubleData(dataObject); + limit=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_LIMIT, data); + newValue=AQHREACT_Unit_GetParamValueDouble(unit, AQHOMEREACT_UNIT_LOWPASS_PARAM_NEWVALUE, data); + AQHREACT_Unit_OutputDoubleData(unit, outputPort, (data<=limit)?data:newValue); + } } } diff --git a/apps/aqhome-react/units/u_module.c b/apps/aqhome-react/units/u_module.c index 64478e6..1a25fba 100644 --- a/apps/aqhome-react/units/u_module.c +++ b/apps/aqhome-react/units/u_module.c @@ -16,7 +16,7 @@ #include #include -//TODO: set params +//TODO: read modules /* ------------------------------------------------------------------------------------------------ @@ -36,31 +36,43 @@ GWEN_LIST_FUNCTIONS(MODULE_PROXY_DESCR, ModuleProxyDescr); */ static void GWENHYWFAR_CB _freeData(void *bp, void *p); -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); -static void _cbOutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); static AQHREACT_PARAM *_cbGetParamByName(const AQHREACT_UNIT *unit, const char *paramName); static int _cbProcess(AQHREACT_UNIT *unit); -static void _readProxyFromXml(AQHREACT_UNIT *unit, - GWEN_XMLNODE *xmlNode, +static void _readProxyFromXml(GWEN_XMLNODE *xmlNode, MODULE_PROXY_DESCR_LIST *proxyDescrList, const char *mainGroupName, const char *groupName, const char *nameProperty, const char *targetObjectProperty, const char *targetNameProperty); -static void _readInputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); -static void _readOutputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode); -static int _finishInSlots(AQHREACT_UNIT *unit); -static int _finishOutSlots(AQHREACT_UNIT *unit); +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, AQHREACT_UNIT *parentUnit, GWEN_XMLNODE *xmlNode); +static AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *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, + AQHREACT_UNIT *unit, + const char *emittingPortName, + const char *receivingUnitName, + const char *receivingPortName); +static int _linkToModulesOutput(AQHOME_REACT *aqh, + AQHREACT_UNIT *unit, + const char *emittingUnitName, + const char *emittingPortName, + const char *receivingPortName); +static int _linkBetweenUnits(AQHOME_REACT *aqh, + AQHREACT_UNIT *unit, + const char *emittingUnitName, + const char *emittingPortName, + const char *receivingUnitName, + const char *receivingPortName); @@ -138,12 +150,9 @@ AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh) GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit, xunit, _freeData); xunit->paramProxyList=ModuleProxyDescr_List_new(); - xunit->inSlotProxyList=ModuleProxyDescr_List_new(); - xunit->outSlotProxyList=ModuleProxyDescr_List_new(); xunit->unitList=AQHREACT_Unit_List_new(); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - AQHREACT_Unit_SetOutputDataFn(unit, _cbOutputData); AQHREACT_Unit_SetGetParamByNameFn(unit, _cbGetParamByName); AQHREACT_Unit_SetProcessFn(unit, _cbProcess); @@ -152,15 +161,13 @@ AQHREACT_UNIT *AqHomeReact_UnitModule_new(AQHOME_REACT *aqh) -void _freeData(void *bp, void *p) +void _freeData(GWEN_UNUSED void *bp, void *p) { AQHREACT_UNIT_MODULE *xunit; xunit=(AQHREACT_UNIT_MODULE*) p; AQHREACT_Unit_List_free(xunit->unitList); - ModuleProxyDescr_List_free(xunit->outSlotProxyList); - ModuleProxyDescr_List_free(xunit->inSlotProxyList); ModuleProxyDescr_List_free(xunit->paramProxyList); GWEN_FREE_OBJECT(xunit); @@ -171,110 +178,67 @@ void _freeData(void *bp, void *p) AQHREACT_UNIT *AqHomeReact_UnitModule_fromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode) { const char *t; + const char *id; + AQHREACT_UNIT *unit; + AQHREACT_UNIT_MODULE *xunit; + int rv; t=GWEN_XMLNode_GetProperty(xmlNode, "type", NULL); - if (t && *t) { - AQHREACT_UNIT *unit; - AQHREACT_UNIT_MODULE *xunit; - int rv; + id=GWEN_XMLNode_GetProperty(xmlNode, "id", NULL); - unit=AqHomeReact_UnitModule_new(aqh); - xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - AQHREACT_Unit_SetName(unit, t); + unit=AqHomeReact_UnitModule_new(aqh); + xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); + AQHREACT_Unit_SetName(unit, t); + AQHREACT_Unit_SetId(unit, id); - _readProxyFromXml(unit, xmlNode, xunit->paramProxyList, "paramdefs", "param", "name", "targetModule", "targetParam"); + _readProxyFromXml(xmlNode, xunit->paramProxyList, "paramdefs", "param", "name", "targetModule", "targetParam"); - _readInputSlotsFromXml(aqh, unit, xmlNode); - _readOutputSlotsFromXml(aqh, unit, xmlNode); - - _readUnitsFromXml(aqh, unit, xmlNode); - - rv=_finishInSlots(unit); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - rv=_finishOutSlots(unit); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - - rv=_finishParams(unit); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - - rv=_readParamsFromXml(unit, xmlNode, "paramDefs"); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - - rv=_readLinksFromXml(aqh, unit, xmlNode); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - - return unit; - } - else { - DBG_ERROR(NULL, "No \"type\" property in xml node for module"); + rv=_readInputPortsFromXml(unit, xmlNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_Unit_free(unit); return NULL; } + + rv=_readOutputPortsFromXml(unit, xmlNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_Unit_free(unit); + return NULL; + } + + _readUnitsFromXml(aqh, unit, xmlNode); + + rv=_finishParams(unit); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_Unit_free(unit); + return NULL; + } + + rv=_readParamsFromXml(unit, xmlNode, "paramDefs"); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_Unit_free(unit); + return NULL; + } + + rv=_readLinksFromXml(aqh, unit, xmlNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_Unit_free(unit); + return NULL; + } + + return unit; } -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(GWEN_UNUSED AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - AQHREACT_UNIT_MODULE *xunit; - - xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - if (xunit) { - AQHREACT_INPUT_SLOT *slot; - - slot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, slotIdForUnit); - if (slot) { - const char *slotName; - const MODULE_PROXY_DESCR *pd; - - slotName=AQHREACT_InputSlot_GetName(slot); - pd=ModuleProxyDescr_List_FindByName(xunit->inSlotProxyList, slotName); - if (pd) - AQHREACT_Unit_InputData(pd->targetObjectPtr, pd->targetIdForModule, dataObject); - } - } -} - - - -void _cbOutputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) -{ - AQHREACT_UNIT_MODULE *xunit; - - xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - if (xunit) { - AQHREACT_OUTPUT_SLOT *slot; - - slot=AQHREACT_Unit_GetOutputSlotByIdForUnit(unit, slotIdForUnit); - if (slot) { - const char *slotName; - const MODULE_PROXY_DESCR *pd; - - slotName=AQHREACT_OutputSlot_GetName(slot); - pd=ModuleProxyDescr_List_FindByName(xunit->outSlotProxyList, slotName); - if (pd) - AQHREACT_Unit_OutputData(pd->targetObjectPtr, pd->targetIdForModule, dataObject); - } - } + if (port) + AQHREACT_Port_SendData(port, dataObject); } @@ -322,8 +286,7 @@ int _cbProcess(AQHREACT_UNIT *unit) -void _readProxyFromXml(AQHREACT_UNIT *unit, - GWEN_XMLNODE *xmlNode, +void _readProxyFromXml(GWEN_XMLNODE *xmlNode, MODULE_PROXY_DESCR_LIST *proxyDescrList, const char *mainGroupName, const char *groupName, @@ -363,136 +326,42 @@ void _readProxyFromXml(AQHREACT_UNIT *unit, -void _readInputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) +int _readInputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) { AQHREACT_UNIT_MODULE *xunit; GWEN_XMLNODE *nGroup; xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "inputSlots", NULL, NULL); + nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "inputPorts", NULL, NULL); if (nGroup) { GWEN_XMLNODE *n; - n=GWEN_XMLNode_FindFirstTag(nGroup, "inputSlot", NULL, NULL); + n=GWEN_XMLNode_FindFirstTag(nGroup, "inputPort", NULL, NULL); while(n) { const char *name; - const char *targetUnit; - const char *targetSlot; - int slotIdForUnit; + int dataType; + AQHREACT_PORT *port; name=GWEN_XMLNode_GetProperty(n, "name", NULL); - targetUnit=GWEN_XMLNode_GetProperty(n, "targetUnit", NULL); - targetSlot=GWEN_XMLNode_GetProperty(n, "targetSlot", NULL); - slotIdForUnit=GWEN_XMLNode_GetIntProperty(n, "idForUnit", 0); - - if (name && targetUnit && targetSlot) { - MODULE_PROXY_DESCR *pd; - AQHREACT_INPUT_SLOT *slot; - - pd=ModuleProxyDescr_new(name, targetUnit, targetSlot); /* set pd->targetObjectPtr later */ - ModuleProxyDescr_List_Add(pd, xunit->inSlotProxyList); - - slot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(slot, name); - AQHREACT_InputSlot_SetIdForUnit(slot, slotIdForUnit); - AQHREACT_Unit_AddInputSlot(unit, slot); + dataType=AQHREACT_DataObjectType_fromString(GWEN_XMLNode_GetProperty(n, "dataType", "double")); + if (dataType==AQHREACT_DATAOBJECTTYPE_UNKNOWN) { + DBG_ERROR(NULL, "Unknown dataType: %s", GWEN_XMLNode_GetProperty(n, "dataType", "double")); + return GWEN_ERROR_BAD_DATA; } - else { - DBG_ERROR(NULL, "Incomplete input slot, ignoring"); + if (name==NULL) { + DBG_ERROR(NULL, "Missing name in input port"); + return GWEN_ERROR_BAD_DATA; } - n=GWEN_XMLNode_FindNextTag(n, "inputSlot", NULL, NULL); - } - } -} - - -void _readOutputSlotsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) -{ - AQHREACT_UNIT_MODULE *xunit; - GWEN_XMLNODE *nGroup; - - xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - - nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "outputSlots", NULL, NULL); - if (nGroup) { - GWEN_XMLNODE *n; - - n=GWEN_XMLNode_FindFirstTag(nGroup, "outputSlot", NULL, NULL); - while(n) { - const char *name; - const char *targetUnit; - const char *targetSlot; - int slotIdForUnit; - - name=GWEN_XMLNode_GetProperty(n, "name", NULL); - targetUnit=GWEN_XMLNode_GetProperty(n, "targetUnit", NULL); - targetSlot=GWEN_XMLNode_GetProperty(n, "targetSlot", NULL); - slotIdForUnit=GWEN_XMLNode_GetIntProperty(n, "idForUnit", 0); - - if (name && targetUnit && targetSlot) { - MODULE_PROXY_DESCR *pd; - AQHREACT_OUTPUT_SLOT *slot; - - pd=ModuleProxyDescr_new(name, targetUnit, targetSlot); /* set pd->targetObjectPtr later */ - ModuleProxyDescr_List_Add(pd, xunit->outSlotProxyList); - - slot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(slot, name); - AQHREACT_OutputSlot_SetIdForUnit(slot, slotIdForUnit); - AQHREACT_Unit_AddOutputSlot(unit, slot); - } - else { - DBG_ERROR(NULL, "Incomplete output slot, ignoring"); - } - n=GWEN_XMLNode_FindNextTag(n, "outputSlot", NULL, NULL); - } - } -} - - - -int _finishInSlots(AQHREACT_UNIT *unit) -{ - AQHREACT_UNIT_MODULE *xunit; - MODULE_PROXY_DESCR *pd; - const char *unitName; - - xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - unitName=AQHREACT_Unit_GetName(unit); - pd=ModuleProxyDescr_List_First(xunit->inSlotProxyList); - while(pd) { - AQHREACT_UNIT *subUnit; - const AQHREACT_INPUT_SLOT *subUnitSlot; - AQHREACT_INPUT_SLOT *moduleSlot; - - subUnit=AQHREACT_Unit_List_GetById(xunit->unitList, pd->targetObject); - if (subUnit==NULL) { - DBG_ERROR(NULL, "Subunit \"%s\" not found for input slot", pd->targetObject); - return GWEN_ERROR_BAD_DATA; - } - pd->targetObjectPtr=subUnit; - - moduleSlot=AQHREACT_Unit_GetInputSlotByName(subUnit, pd->name); - if (moduleSlot==NULL) { - DBG_ERROR(NULL, "Unit %s: Input slot \"%s\" not defined", unitName, pd->targetName); - return GWEN_ERROR_BAD_DATA; - } - - subUnitSlot=AQHREACT_Unit_GetInputSlotByName(subUnit, pd->targetName); - if (subUnitSlot==NULL) { - DBG_ERROR(NULL, "Unit %s: Input slot \"%s\" not found for subunit \"%s\"", unitName, pd->targetName, pd->targetObject); - return GWEN_ERROR_BAD_DATA; - } - - AQHREACT_InputSlot_SetDescription(moduleSlot, AQHREACT_InputSlot_GetDescription(subUnitSlot)); - AQHREACT_InputSlot_SetFlags(moduleSlot, AQHREACT_InputSlot_GetFlags(subUnitSlot)); - AQHREACT_InputSlot_SetAcceptedDataType(moduleSlot, AQHREACT_InputSlot_GetAcceptedDataType(subUnitSlot)); - - pd->targetIdForModule=AQHREACT_InputSlot_GetIdForUnit(subUnitSlot); - - pd=ModuleProxyDescr_List_Next(pd); + /* create input port */ + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, name); + AQHREACT_Port_SetIdForUnit(port, ++(xunit->lastPortId)); + AQHREACT_Port_SetDataType(port, dataType); + AQHREACT_Unit_AddInputPort(unit, port); + n=GWEN_XMLNode_FindNextTag(n, "inputPort", NULL, NULL); + } /* while */ } return 0; @@ -500,46 +369,42 @@ int _finishInSlots(AQHREACT_UNIT *unit) -int _finishOutSlots(AQHREACT_UNIT *unit) +int _readOutputPortsFromXml(AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlNode) { AQHREACT_UNIT_MODULE *xunit; - MODULE_PROXY_DESCR *pd; - const char *unitName; + GWEN_XMLNODE *nGroup; xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); - unitName=AQHREACT_Unit_GetName(unit); - pd=ModuleProxyDescr_List_First(xunit->outSlotProxyList); - while(pd) { - AQHREACT_UNIT *subUnit; - const AQHREACT_OUTPUT_SLOT *subUnitSlot; - AQHREACT_OUTPUT_SLOT *moduleSlot; - subUnit=AQHREACT_Unit_List_GetById(xunit->unitList, pd->targetObject); - if (subUnit==NULL) { - DBG_ERROR(NULL, "Subunit \"%s\" not found for output slot", pd->targetObject); - return GWEN_ERROR_BAD_DATA; + nGroup=GWEN_XMLNode_FindFirstTag(xmlNode, "outputPorts", NULL, NULL); + if (nGroup) { + GWEN_XMLNODE *n; + + n=GWEN_XMLNode_FindFirstTag(nGroup, "outputPort", NULL, NULL); + while(n) { + const char *name; + int dataType; + AQHREACT_PORT *port; + + name=GWEN_XMLNode_GetProperty(n, "name", NULL); + dataType=AQHREACT_DataObjectType_fromString(GWEN_XMLNode_GetProperty(n, "dataType", "double")); + if (dataType==AQHREACT_DATAOBJECTTYPE_UNKNOWN) { + DBG_ERROR(NULL, "Unknown dataType: %s", GWEN_XMLNode_GetProperty(n, "dataType", "double")); + return GWEN_ERROR_BAD_DATA; + } + if (name==NULL) { + DBG_ERROR(NULL, "Missing name in output port"); + return GWEN_ERROR_BAD_DATA; + } + + /* create input port */ + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, name); + AQHREACT_Port_SetIdForUnit(port, ++(xunit->lastPortId)); + AQHREACT_Port_SetDataType(port, dataType); + AQHREACT_Unit_AddOutputPort(unit, port); + n=GWEN_XMLNode_FindNextTag(n, "outputPort", NULL, NULL); } - pd->targetObjectPtr=subUnit; - - moduleSlot=AQHREACT_Unit_GetOutputSlotByName(subUnit, pd->name); - if (moduleSlot==NULL) { - DBG_ERROR(NULL, "Unit %s: Output slot \"%s\" not defined", unitName, pd->targetName); - return GWEN_ERROR_BAD_DATA; - } - - subUnitSlot=AQHREACT_Unit_GetOutputSlotByName(subUnit, pd->targetName); - if (subUnitSlot==NULL) { - DBG_ERROR(NULL, "Unit %s: Output slot \"%s\" not found for subunit \"%s\"", unitName, pd->targetName, pd->targetObject); - return GWEN_ERROR_BAD_DATA; - } - - AQHREACT_OutputSlot_SetDescription(moduleSlot, AQHREACT_OutputSlot_GetDescription(subUnitSlot)); - AQHREACT_OutputSlot_SetFlags(moduleSlot, AQHREACT_OutputSlot_GetFlags(subUnitSlot)); - AQHREACT_OutputSlot_SetEmittedDataType(moduleSlot, AQHREACT_OutputSlot_GetEmittedDataType(subUnitSlot)); - - pd->targetIdForModule=AQHREACT_OutputSlot_GetIdForUnit(subUnitSlot); - - pd=ModuleProxyDescr_List_Next(pd); } return 0; @@ -589,7 +454,7 @@ void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xml while(n) { AQHREACT_UNIT *subUnit; - subUnit=_readOneUnitFromXml(aqh, unit, n); + subUnit=_readOneUnitFromXml(aqh, n); if (subUnit) AQHREACT_Unit_List_Add(subUnit, xunit->unitList); else { @@ -603,7 +468,7 @@ void _readUnitsFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xml -AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *parentUnit, GWEN_XMLNODE *xmlNode) +AQHREACT_UNIT *_readOneUnitFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *xmlNode) { const char *id; const char *t; @@ -750,63 +615,179 @@ int _readLinksFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *xmlN int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkNode) { - AQHREACT_UNIT_MODULE *xunit; - const char *sourceUnitName; - const char *sourceSlotName; - const char *targetUnitName; - const char *targetSlotName; - AQHREACT_UNIT *sourceUnit; - AQHREACT_UNIT *targetUnit; - AQHREACT_INPUT_SLOT *inputSlot; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_LINK *link; + const char *emittingUnitName; + const char *emittingPortName; + const char *receivingUnitName; + const char *receivingPortName; + int rv; - xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); + emittingUnitName=GWEN_XMLNode_GetProperty(linkNode, "sourceUnit", "."); + emittingPortName=GWEN_XMLNode_GetProperty(linkNode, "sourcePort", NULL); + receivingUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", "."); + receivingPortName=GWEN_XMLNode_GetProperty(linkNode, "targetPort", NULL); - sourceUnitName=GWEN_XMLNode_GetProperty(linkNode, "sourceUnit", NULL); - sourceSlotName=GWEN_XMLNode_GetProperty(linkNode, "sourceSlot", NULL); - targetUnitName=GWEN_XMLNode_GetProperty(linkNode, "targetUnit", NULL); - targetSlotName=GWEN_XMLNode_GetProperty(linkNode, "targetSlot", NULL); - - if (!(sourceUnitName && *sourceUnitName && sourceSlotName && *sourceSlotName && - targetUnitName && *targetUnitName && targetSlotName && *targetSlotName)) { + if (!(emittingUnitName && *emittingUnitName && emittingPortName && *emittingPortName && + receivingUnitName && *receivingUnitName && receivingPortName && *receivingPortName)) { DBG_ERROR(NULL, - "Link in net \"%s\" needs properties sourceUnit, sourceSlot, targetUnit and targetSlot", + "Link in net \"%s\" needs properties sourceUnit, sourcePort, targetUnit and targetPort", AQHREACT_Unit_GetName(unit)); return GWEN_ERROR_BAD_DATA; } - sourceUnit=AQHREACT_Unit_List_GetById(xunit->unitList, sourceUnitName); - if (sourceUnit==NULL) - sourceUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, sourceUnitName); - if (sourceUnit==NULL) { - DBG_ERROR(NULL, "Source unit \"%s\" not found", sourceUnitName); - return GWEN_ERROR_NOT_FOUND; + if (strcasecmp(emittingUnitName, ".")==0) + rv=_linkFromThisModulesInput(aqh, unit, emittingPortName, receivingUnitName, receivingPortName); + else if (strcasecmp(receivingUnitName, ".")==0) + rv=_linkToModulesOutput(aqh, unit, emittingUnitName, emittingPortName, receivingPortName); + else + rv=_linkBetweenUnits(aqh, unit, emittingUnitName, emittingPortName, receivingUnitName, receivingPortName); + if (rv<0) { + DBG_INFO(NULL, "Error creating link: %s:%s -> %s:%s (%d)", + emittingUnitName, emittingPortName, receivingUnitName, receivingPortName, rv); + return rv; } - outputSlot=AQHREACT_Unit_GetOutputSlotByName(sourceUnit, sourceSlotName); - if (outputSlot==NULL) { - DBG_ERROR(NULL, "Output slot \"%s\" not found for source unit \"%s\"", sourceSlotName, sourceUnitName); + + return 0; +} + + + +int _linkFromThisModulesInput(AQHOME_REACT *aqh, + AQHREACT_UNIT *unit, + const char *emittingPortName, + const char *receivingUnitName, + const char *receivingPortName) +{ + AQHREACT_UNIT_MODULE *xunit; + AQHREACT_UNIT *receivingUnit; + AQHREACT_PORT *receivingPort; + AQHREACT_PORT *emittingPort; + AQHREACT_LINK *link; + + xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); + + receivingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, receivingUnitName); + if (receivingUnit==NULL) + receivingUnit=AqHomeReact_FindUnitByUnitId(aqh, receivingUnitName); + if (receivingUnit==NULL) { + DBG_ERROR(NULL, "Target unit \"%s\" not found", receivingUnitName); return GWEN_ERROR_NOT_FOUND; } - targetUnit=AQHREACT_Unit_List_GetById(xunit->unitList, targetUnitName); - if (targetUnit==NULL) - targetUnit=AqHomeReact_FindUnitByNetNameAndUnitId(aqh, NULL, targetUnitName); - if (targetUnit==NULL) { - DBG_ERROR(NULL, "Target unit \"%s\" not found", targetUnitName); + emittingPort=AQHREACT_Unit_GetInputPortByName(unit, emittingPortName); /* find in modules input port list! */ + if (emittingPort==NULL) { + DBG_ERROR(NULL, "Target port \"%s\" not found for source unit \"%s\"", emittingPortName, AQHREACT_Unit_GetName(unit)); return GWEN_ERROR_NOT_FOUND; } - inputSlot=AQHREACT_Unit_GetOrCreateUnusedInputSlotByName(targetUnit, targetSlotName); - if (inputSlot==NULL) { - DBG_ERROR(NULL, "Input slot \"%s\" not found for target unit \"%s\"", targetSlotName, targetUnitName); + + receivingPort=AQHREACT_Unit_GetInputPortByName(receivingUnit, receivingPortName); + if (receivingPort==NULL) { + DBG_ERROR(NULL, "Input port \"%s\" not found for target unit \"%s\"", receivingPortName, receivingUnitName); return GWEN_ERROR_NOT_FOUND; } link=AQHREACT_Link_new(); - AQHREACT_Link_SetTargetUnitId(link, targetUnitName); - AQHREACT_Link_SetTargetUnit(link, targetUnit); - AQHREACT_Link_SetTargetInputSlotIdForUnit(link, AQHREACT_InputSlot_GetIdForUnit(inputSlot)); - AQHREACT_OutputSlot_AddLink(outputSlot, link); + AQHREACT_Link_SetTargetUnit(link, receivingUnit); + AQHREACT_Link_SetTargetPort(link, receivingPort); + AQHREACT_Port_AddLink(emittingPort, link); + return 0; +} + + + +int _linkToModulesOutput(AQHOME_REACT *aqh, + AQHREACT_UNIT *unit, + const char *emittingUnitName, + const char *emittingPortName, + const char *receivingPortName) +{ + AQHREACT_UNIT_MODULE *xunit; + AQHREACT_UNIT *receivingUnit; + AQHREACT_PORT *receivingPort; + AQHREACT_UNIT *emittingUnit; + AQHREACT_PORT *emittingPort; + AQHREACT_LINK *link; + + xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); + + emittingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, emittingUnitName); + if (emittingUnit==NULL) + emittingUnit=AqHomeReact_FindUnitByUnitId(aqh, emittingUnitName); + if (emittingUnit==NULL) { + DBG_ERROR(NULL, "Source unit \"%s\" not found", emittingUnitName); + return GWEN_ERROR_NOT_FOUND; + } + + receivingUnit=unit; + + emittingPort=AQHREACT_Unit_GetOutputPortByName(emittingUnit, emittingPortName); + if (emittingPort==NULL) { + DBG_ERROR(NULL, "Output port \"%s\" not found", emittingPortName); + return GWEN_ERROR_NOT_FOUND; + } + + receivingPort=AQHREACT_Unit_GetOutputPortByName(unit, receivingPortName); /* find in modules output port list! */ + if (receivingPort==NULL) { + DBG_ERROR(NULL, "Target port \"%s\" not found", receivingPortName); + return GWEN_ERROR_NOT_FOUND; + } + + link=AQHREACT_Link_new(); + AQHREACT_Link_SetTargetUnit(link, receivingUnit); + AQHREACT_Link_SetTargetPort(link, receivingPort); + AQHREACT_Port_AddLink(emittingPort, link); + return 0; +} + + + +int _linkBetweenUnits(AQHOME_REACT *aqh, + AQHREACT_UNIT *unit, + const char *emittingUnitName, + const char *emittingPortName, + const char *receivingUnitName, + const char *receivingPortName) +{ + AQHREACT_UNIT_MODULE *xunit; + AQHREACT_UNIT *receivingUnit; + AQHREACT_PORT *receivingPort; + AQHREACT_UNIT *emittingUnit; + AQHREACT_PORT *emittingPort; + AQHREACT_LINK *link; + + xunit=(AQHREACT_UNIT_MODULE*)GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_MODULE, unit); + + emittingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, emittingUnitName); + if (emittingUnit==NULL) + emittingUnit=AqHomeReact_FindUnitByUnitId(aqh, emittingUnitName); + if (emittingUnit==NULL) { + DBG_ERROR(NULL, "Source unit \"%s\" not found", emittingUnitName); + return GWEN_ERROR_NOT_FOUND; + } + + receivingUnit=AQHREACT_Unit_List_GetById(xunit->unitList, receivingUnitName); + if (receivingUnit==NULL) + receivingUnit=AqHomeReact_FindUnitByUnitId(aqh, receivingUnitName); + if (receivingUnit==NULL) { + DBG_ERROR(NULL, "Target unit \"%s\" not found", receivingUnitName); + return GWEN_ERROR_NOT_FOUND; + } + + emittingPort=AQHREACT_Unit_GetOutputPortByName(emittingUnit, emittingPortName); + if (emittingPort==NULL) { + DBG_ERROR(NULL, "Output port \"%s\" not found for source unit \"%s\"", emittingPortName, emittingUnitName); + return GWEN_ERROR_NOT_FOUND; + } + + receivingPort=AQHREACT_Unit_GetOrCreateUnusedInputPortByName(receivingUnit, receivingPortName); + if (receivingPort==NULL) { + DBG_ERROR(NULL, "Input port \"%s\" not found for target unit \"%s\"", receivingPortName, receivingUnitName); + return GWEN_ERROR_NOT_FOUND; + } + + link=AQHREACT_Link_new(); + AQHREACT_Link_SetTargetUnit(link, receivingUnit); + AQHREACT_Link_SetTargetPort(link, receivingPort); + AQHREACT_Port_AddLink(emittingPort, link); return 0; } @@ -814,4 +795,3 @@ int _readLinkFromXml(AQHOME_REACT *aqh, AQHREACT_UNIT *unit, GWEN_XMLNODE *linkN - diff --git a/apps/aqhome-react/units/u_module_p.h b/apps/aqhome-react/units/u_module_p.h index ad0a477..9c46f50 100644 --- a/apps/aqhome-react/units/u_module_p.h +++ b/apps/aqhome-react/units/u_module_p.h @@ -43,10 +43,8 @@ static MODULE_PROXY_DESCR *ModuleProxyDescr_List_FindByName(const MODULE_PROXY_D struct AQHREACT_UNIT_MODULE { MODULE_PROXY_DESCR_LIST *paramProxyList; - MODULE_PROXY_DESCR_LIST *inSlotProxyList; - MODULE_PROXY_DESCR_LIST *outSlotProxyList; - AQHREACT_UNIT_LIST *unitList; + int lastPortId; }; diff --git a/apps/aqhome-react/units/u_passthrough.c b/apps/aqhome-react/units/u_passthrough.c index d81b563..048440b 100644 --- a/apps/aqhome-react/units/u_passthrough.c +++ b/apps/aqhome-react/units/u_passthrough.c @@ -28,7 +28,7 @@ * ------------------------------------------------------------------------------------------------ */ -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); @@ -40,25 +40,24 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_ AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; unit=AQHREACT_Unit_new(aqh); AQHREACT_Unit_SetName(unit, "passthrough"); AQHREACT_Unit_SetDescription(unit, "Generic passthrough unit"); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); return unit; } @@ -66,10 +65,15 @@ AQHREACT_UNIT *AqHomeReact_UnitPassthrough_new(AQHOME_REACT *aqh) -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_PASSTHROUGH_INSLOT_INPUT) - AQHREACT_Unit_OutputData(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT, dataObject); + if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_PASSTHROUGH_INSLOT_INPUT) { + AQHREACT_PORT *outputPort; + + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); + if (outputPort) + AQHREACT_Unit_OutputData(unit, outputPort, dataObject); + } } diff --git a/apps/aqhome-react/units/u_stabilize.c b/apps/aqhome-react/units/u_stabilize.c index ff48ebe..ecd1e99 100644 --- a/apps/aqhome-react/units/u_stabilize.c +++ b/apps/aqhome-react/units/u_stabilize.c @@ -66,8 +66,7 @@ AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh) { AQHREACT_UNIT_STABILIZE *xunit; AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; AQHREACT_PARAM *param; unit=AQHREACT_Unit_new(aqh); @@ -78,23 +77,23 @@ AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh) AQHREACT_Unit_SetDescription(unit, "Stabilize signal changes (only propagate changes stable for some time)"); AQHREACT_Unit_SetProcessFn(unit, _cbProcessFn); - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "timer"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_STABILIZE_INSLOT_TIMER); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "timer"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_STABILIZE_INSLOT_TIMER); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_STABILIZE_PARAM_HOLDTIME_HIGH); @@ -111,7 +110,7 @@ AQHREACT_UNIT *AqHomeReact_UnitStabilize_new(AQHOME_REACT *aqh) -void _freeData(void *bp, void *p) +void _freeData(GWEN_UNUSED void *bp, void *p) { AQHREACT_UNIT_STABILIZE *xunit; @@ -127,7 +126,7 @@ int _cbProcessFn(AQHREACT_UNIT *unit) int rv; rv=_checkState(unit); - AQHREACT_Unit_ClearChangeFlagsInUnitAndInputSlots(unit); + AQHREACT_Unit_ClearChangeFlagsInUnitAndInputPorts(unit); return rv; } return 0; @@ -142,13 +141,13 @@ int _checkState(AQHREACT_UNIT *unit) xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_STABILIZE, unit); if (xunit) { - AQHREACT_INPUT_SLOT *dataSlot; + AQHREACT_PORT *port; - dataSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); - if (dataSlot) { + port=AQHREACT_Unit_GetInputPortByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_INSLOT_INPUT); + if (port) { AQHREACT_DATAOBJECT *dataObject; - dataObject=AQHREACT_InputSlot_GetCurrentDataObject(dataSlot); + dataObject=AQHREACT_Port_GetCurrentDataObject(port); if (dataObject) { double doubleData; int newState; @@ -216,11 +215,16 @@ void _startTimer(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newSta void _setOutput(AQHREACT_UNIT *unit, AQHREACT_UNIT_STABILIZE *xunit, int newState) { - /* timeout, switch output */ - DBG_INFO(NULL, "Switch output to %s", newState?"ON":"OFF"); - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT, newState?1.0:0.0); - xunit->currentOutState=newState; - xunit->tsHoldUntil=0; + AQHREACT_PORT *outputPort; + + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_STABILIZE_OUTSLOT_OUTPUT); + if (outputPort) { + /* timeout, switch output */ + DBG_INFO(NULL, "Switch output to %s", newState?"ON":"OFF"); + AQHREACT_Unit_OutputDoubleData(unit, outputPort, newState?1.0:0.0); + xunit->currentOutState=newState; + xunit->tsHoldUntil=0; + } } diff --git a/apps/aqhome-react/units/u_timer.c b/apps/aqhome-react/units/u_timer.c index 2c8745f..944126d 100644 --- a/apps/aqhome-react/units/u_timer.c +++ b/apps/aqhome-react/units/u_timer.c @@ -32,7 +32,11 @@ AQHREACT_UNIT *AqHomeReact_UnitTimer_new(AQHOME_REACT *aqh) void AqHomeReact_UnitTimer_GenerateTick(AQHREACT_UNIT *unit) { - AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT, 1.0); + AQHREACT_PORT *outputPort; + + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); + if (outputPort) + AQHREACT_Unit_OutputDoubleData(unit, outputPort, 1.0); } diff --git a/apps/aqhome-react/units/u_valuefilter.c b/apps/aqhome-react/units/u_valuefilter.c index 5f1d7cc..bcf7877 100644 --- a/apps/aqhome-react/units/u_valuefilter.c +++ b/apps/aqhome-react/units/u_valuefilter.c @@ -32,7 +32,7 @@ * ------------------------------------------------------------------------------------------------ */ -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); @@ -44,8 +44,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_ AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; AQHREACT_PARAM *param; unit=AQHREACT_Unit_new(aqh); @@ -53,17 +52,17 @@ AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh) AQHREACT_Unit_SetDescription(unit, "Filter values received from unit VarChanges by value path"); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME); @@ -75,22 +74,27 @@ AQHREACT_UNIT *AqHomeReact_UnitValueFilter_new(AQHOME_REACT *aqh) -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE) { - const char *sSystemValueId; + if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_VALUEFILTER_INSLOT_VALUE) { + AQHREACT_PORT *outputPort; - sSystemValueId=AQHREACT_DataObject_GetSystemValueId(dataObject); - if (sSystemValueId && *sSystemValueId) { - const char *sFilter; + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT); + if (outputPort) { + const char *sSystemValueId; - sFilter=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME, NULL); - if (sFilter && *sFilter && strcasecmp(sSystemValueId, sFilter)==0) { - DBG_INFO(NULL, "Value \"%s\" matches", sSystemValueId); - AQHREACT_Unit_OutputData(unit, AQHOMEREACT_UNIT_VALUEFILTER_OUTSLOT_RESULT, dataObject); - } - else { - DBG_DEBUG(NULL, "Value \"%s\" does not match", sSystemValueId); + sSystemValueId=AQHREACT_DataObject_GetSystemValueId(dataObject); + if (sSystemValueId && *sSystemValueId) { + const char *sFilter; + + sFilter=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUEFILTER_PARAM_VALUENAME, NULL); + if (sFilter && *sFilter && strcasecmp(sSystemValueId, sFilter)==0) { + DBG_INFO(NULL, "Value \"%s\" matches", sSystemValueId); + AQHREACT_Unit_OutputData(unit, outputPort, dataObject); + } + else { + DBG_DEBUG(NULL, "Value \"%s\" does not match", sSystemValueId); + } } } } diff --git a/apps/aqhome-react/units/u_valueset.c b/apps/aqhome-react/units/u_valueset.c index 8d64408..fff15f1 100644 --- a/apps/aqhome-react/units/u_valueset.c +++ b/apps/aqhome-react/units/u_valueset.c @@ -34,9 +34,9 @@ * ------------------------------------------------------------------------------------------------ */ -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); -static GWEN_MSG *_mkSetDataMsgString(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); -static GWEN_MSG *_mkSetDataMsgDouble(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); +static GWEN_MSG *_mkSetDataMsgString(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); +static GWEN_MSG *_mkSetDataMsgDouble(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); @@ -48,7 +48,7 @@ static GWEN_MSG *_mkSetDataMsgDouble(AQHREACT_UNIT *unit, const char *sValueName AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; AQHREACT_PARAM *param; unit=AQHREACT_Unit_new(aqh); @@ -56,11 +56,11 @@ AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh) AQHREACT_Unit_SetDescription(unit, "Set value by value path"); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_STRING); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME); @@ -72,9 +72,9 @@ AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh) -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { - if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE) { + if (unit && port && dataObject && AQHREACT_Port_GetIdForUnit(port)==AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE) { const char *sValueName; sValueName=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME, NULL); @@ -87,10 +87,10 @@ void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJ switch(AQHREACT_DataObject_GetDataType(dataObject)) { case AQHREACT_DATAOBJECTTYPE_DOUBLE: - msgOut=_mkSetDataMsgDouble(unit, sValueName, dataObject); + msgOut=_mkSetDataMsgDouble(sValueName, dataObject); break; case AQHREACT_DATAOBJECTTYPE_STRING: - msgOut=_mkSetDataMsgString(unit, sValueName, dataObject); + msgOut=_mkSetDataMsgString(sValueName, dataObject); break; default: DBG_INFO(NULL, "Unhandled data type (%d)", AQHREACT_DataObject_GetDataType(dataObject)); @@ -107,7 +107,7 @@ void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJ } -GWEN_MSG *_mkSetDataMsgString(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) +GWEN_MSG *_mkSetDataMsgString(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { GWEN_MSG *msgOut; AQH_VALUE *v; @@ -122,7 +122,7 @@ GWEN_MSG *_mkSetDataMsgString(AQHREACT_UNIT *unit, const char *sValueName, const -GWEN_MSG *_mkSetDataMsgDouble(AQHREACT_UNIT *unit, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) +GWEN_MSG *_mkSetDataMsgDouble(const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { GWEN_MSG *msgOut; AQH_VALUE *v; diff --git a/apps/aqhome-react/units/u_varchanges.c b/apps/aqhome-react/units/u_varchanges.c index 35ee073..3822c34 100644 --- a/apps/aqhome-react/units/u_varchanges.c +++ b/apps/aqhome-react/units/u_varchanges.c @@ -32,17 +32,22 @@ AQHREACT_UNIT *AqHomeReact_UnitVarChanges_new(AQHOME_REACT *aqh) void AqHomeReact_UnitVarChanges_ValueUpdated(AQHREACT_UNIT *unit, const AQH_VALUE *value, uint64_t timestamp, double data) { - AQHREACT_DATAOBJECT *dataObject; + AQHREACT_PORT *outputPort; - DBG_DEBUG(NULL, "Value \"%s\" changed", AQH_Value_GetNameForSystem(value)); - dataObject=AQHREACT_DataObject_new(); - AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_DataObject_SetTimestamp(dataObject, timestamp); - AQHREACT_DataObject_SetDoubleData(dataObject, data); - AQHREACT_DataObject_SetSystemValueId(dataObject, AQH_Value_GetNameForSystem(value)); - AQHREACT_DataObject_SetValueId(dataObject, AQH_Value_GetId(value)); - AQHREACT_Unit_OutputData(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT, dataObject); - AQHREACT_DataObject_free(dataObject); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_PASSTHROUGH_OUTSLOT_OUTPUT); + if (outputPort) { + AQHREACT_DATAOBJECT *dataObject; + + DBG_DEBUG(NULL, "Value \"%s\" changed", AQH_Value_GetNameForSystem(value)); + dataObject=AQHREACT_DataObject_new(); + AQHREACT_DataObject_SetDataType(dataObject, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_DataObject_SetTimestamp(dataObject, timestamp); + AQHREACT_DataObject_SetDoubleData(dataObject, data); + AQHREACT_DataObject_SetSystemValueId(dataObject, AQH_Value_GetNameForSystem(value)); + AQHREACT_DataObject_SetValueId(dataObject, AQH_Value_GetId(value)); + AQHREACT_Unit_OutputData(unit, outputPort, dataObject); + AQHREACT_DataObject_free(dataObject); + } } diff --git a/apps/aqhome-react/units/u_zeroposnegstring.c b/apps/aqhome-react/units/u_zeroposnegstring.c index 2a77867..429e6a6 100644 --- a/apps/aqhome-react/units/u_zeroposnegstring.c +++ b/apps/aqhome-react/units/u_zeroposnegstring.c @@ -32,7 +32,7 @@ * ------------------------------------------------------------------------------------------------ */ -static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); +static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); @@ -44,8 +44,7 @@ static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_ AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh) { AQHREACT_UNIT *unit; - AQHREACT_OUTPUT_SLOT *outputSlot; - AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PORT *port; AQHREACT_PARAM *param; unit=AQHREACT_Unit_new(aqh); @@ -53,17 +52,17 @@ AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh) AQHREACT_Unit_SetDescription(unit, "Translate double value into strings for zero, positive, negative values"); AQHREACT_Unit_SetInputDataFn(unit, _cbInputData); - outputSlot=AQHREACT_OutputSlot_new(); - AQHREACT_OutputSlot_SetName(outputSlot, "output"); - AQHREACT_OutputSlot_SetIdForUnit(outputSlot, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT); - AQHREACT_OutputSlot_SetEmittedDataType(outputSlot, AQHREACT_DATAOBJECTTYPE_STRING); - AQHREACT_Unit_AddOutputSlot(unit, outputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "output"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Unit_AddOutputPort(unit, port); - inputSlot=AQHREACT_InputSlot_new(); - AQHREACT_InputSlot_SetName(inputSlot, "input"); - AQHREACT_InputSlot_SetIdForUnit(inputSlot, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_INSLOT_VALUE); - AQHREACT_InputSlot_SetAcceptedDataType(inputSlot, AQHREACT_DATAOBJECTTYPE_DOUBLE); - AQHREACT_Unit_AddInputSlot(unit, inputSlot); + port=AQHREACT_Port_new(); + AQHREACT_Port_SetName(port, "input"); + AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_INSLOT_VALUE); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); + AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG); @@ -85,23 +84,28 @@ AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh) -void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +void _cbInputData(AQHREACT_UNIT *unit, GWEN_UNUSED AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject) { if (unit && dataObject) { - const char *result=NULL; - double data; + AQHREACT_PORT *outputPort; - data=AQHREACT_DataObject_GetDoubleData(dataObject); - if (data>0.0) - result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_POS, NULL); - else if (data<0.0) - result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG, NULL); - else - result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO, NULL); + outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT); + if (outputPort) { + const char *result=NULL; + double data; - if (result && *result) { - DBG_DEBUG(NULL, "Sending \"%s\" to output", result); - AQHREACT_Unit_OutputStringData(unit, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT, result); + data=AQHREACT_DataObject_GetDoubleData(dataObject); + if (data>0.0) + result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_POS, NULL); + else if (data<0.0) + result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG, NULL); + else + result=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO, NULL); + + if (result && *result) { + DBG_DEBUG(NULL, "Sending \"%s\" to output", result); + AQHREACT_Unit_OutputStringData(unit, outputPort, result); + } } } }