diff --git a/apps/aqhome-react/0BUILD b/apps/aqhome-react/0BUILD index 0d3de92..4946776 100644 --- a/apps/aqhome-react/0BUILD +++ b/apps/aqhome-react/0BUILD @@ -68,6 +68,7 @@ types units + networks diff --git a/apps/aqhome-react/net_read.c b/apps/aqhome-react/net_read.c index a5f201b..dadd6f7 100644 --- a/apps/aqhome-react/net_read.c +++ b/apps/aqhome-react/net_read.c @@ -32,12 +32,20 @@ * ------------------------------------------------------------------------------------------------ */ -AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl); -static int _readUnitNetFileToList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList); +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 *_readNetworkFromSysconfIntoXml(AQHOME_REACT *aqh, const char *networkName); static AQHREACT_UNIT_NET *_readUnitNetFromXml(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); +static int _readLinks(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode); static AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode); -static int _readParam(AQHREACT_UNIT *unit, GWEN_XMLNODE *n); +static int _readParamValuesForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *parentNode); +static int _readParamValueForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *paramNode); +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); @@ -111,6 +119,37 @@ AQHREACT_UNIT_NET_LIST *AQHREACT_ReadUnitNetFiles(AQHOME_REACT *aqh) +GWEN_XMLNODE *_readNetworkFromSysconfIntoXml(AQHOME_REACT *aqh, const char *networkName) +{ + GWEN_XMLNODE *n; + GWEN_BUFFER *bufFilename; + GWEN_BUFFER *bufPath; + + 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_FindPathOfSysconfFile(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)); + if (n==NULL) { + DBG_ERROR(NULL, "Error reading network file \"%s\" from sysconf dir", GWEN_Buffer_GetStart(bufPath)); + GWEN_Buffer_free(bufPath); + return NULL; + } + GWEN_Buffer_free(bufPath); + return n; +} + + + AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLIST *sl) { GWEN_STRINGLISTENTRY *se; @@ -126,7 +165,7 @@ AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLI int rv; DBG_INFO(NULL, "Reading unit network file \"%s\"", s); - rv=_readUnitNetFileToList(aqh, s, unitNetList); + 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); } @@ -144,7 +183,7 @@ AQHREACT_UNIT_NET_LIST *_readUnitNetFiles(AQHOME_REACT *aqh, const GWEN_STRINGLI -int _readUnitNetFileToList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList) +int _readAllNetworksFromFileIntoList(AQHOME_REACT *aqh, const char *sFilename, AQHREACT_UNIT_NET_LIST *unitNetList) { GWEN_XMLNODE *rootNode; GWEN_XMLNODE *netListNode; @@ -185,12 +224,108 @@ AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetN { AQHREACT_UNIT_NET *unitNet; const char *s; - GWEN_XMLNODE *nGroup; + int rv; unitNet=AQHREACT_UnitNet_new(); s=GWEN_XMLNode_GetProperty(unitNetNode, "id", NULL); AQHREACT_UnitNet_SetName(unitNet, s); + s=GWEN_XMLNode_GetProperty(unitNetNode, "type", NULL); + if (s && *s) { + GWEN_XMLNODE *baseNetXml; + + /* uses a template file, load that and only set params from non-template file */ + DBG_INFO(NULL, "Loading base network \"%s\"", s); + baseNetXml=_readNetworkFromSysconfIntoXml(aqh, s); + if (baseNetXml==NULL) { + DBG_ERROR(NULL, "Base network \"%s\" not available (error or missing)", s); + AQHREACT_UnitNet_free(unitNet); + return NULL; + } + _readNetParamDefsWithList(AQHREACT_UnitNet_GetParamList(unitNet), baseNetXml); + + /* also read netParams from this file (after reading from template) */ + rv=_readParamValuesForList(AQHREACT_UnitNet_GetParamList(unitNet), unitNetNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_UnitNet_free(unitNet); + GWEN_XMLNode_free(baseNetXml); + return NULL; + } + + rv=_readUnits(aqh, unitNet, baseNetXml); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_UnitNet_free(unitNet); + GWEN_XMLNode_free(baseNetXml); + return NULL; + } + + rv=_readLinks(aqh, unitNet, baseNetXml); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_UnitNet_free(unitNet); + GWEN_XMLNode_free(baseNetXml); + return NULL; + } + GWEN_XMLNode_free(baseNetXml); + } + else { + /* just directly read network from given XML node (no need to load a template file) */ + _readNetParamDefsWithList(AQHREACT_UnitNet_GetParamList(unitNet), unitNetNode); + + rv=_readUnits(aqh, unitNet, unitNetNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_UnitNet_free(unitNet); + return NULL; + } + + rv=_readLinks(aqh, unitNet, unitNetNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_UnitNet_free(unitNet); + return NULL; + } + } + + return unitNet; +} + + + +GWEN_XMLNODE *_readUnitNetFileToXml(AQHOME_REACT *aqh, const char *sFilename) +{ + GWEN_XMLNODE *rootNode; + 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 NULL; + } + + netNode=GWEN_XMLNode_FindFirstTag(rootNode, "network", NULL, NULL); + if (netNode) { + GWEN_XMLNode_UnlinkChild(rootNode, netNode); + GWEN_XMLNode_free(rootNode); + return netNode; + } + else { + DBG_ERROR(NULL, "No \"network\" element in network file \"%s\"", sFilename); + return NULL; + } +} + + + +int _readUnits(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode) +{ + GWEN_XMLNODE *nGroup; + nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "units", NULL, NULL); if (nGroup) { GWEN_XMLNODE *n; @@ -204,13 +339,21 @@ AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetN AQHREACT_UnitNet_AddUnit(unitNet, unit); else { DBG_ERROR(NULL, "Error reading unit in net \"%s\"", AQHREACT_UnitNet_GetName(unitNet)); - AQHREACT_UnitNet_free(unitNet); - return NULL; + return GWEN_ERROR_BAD_DATA; } n=GWEN_XMLNode_FindNextTag(n, "unit", NULL, NULL); } } + return 0; +} + + + +int _readLinks(AQHOME_REACT *aqh, AQHREACT_UNIT_NET *unitNet, GWEN_XMLNODE *unitNetNode) +{ + GWEN_XMLNODE *nGroup; + nGroup=GWEN_XMLNode_FindFirstTag(unitNetNode, "links", NULL, NULL); if (nGroup) { GWEN_XMLNODE *n; @@ -222,25 +365,22 @@ AQHREACT_UNIT_NET *_readUnitNetFromXml(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNetN rv=_readLink(aqh, unitNet, n); if (rv<0) { DBG_ERROR(NULL, "Error reading link in net \"%s\" (%d)", AQHREACT_UnitNet_GetName(unitNet), rv); - AQHREACT_UnitNet_free(unitNet); - return NULL; + return GWEN_ERROR_BAD_DATA; } n=GWEN_XMLNode_FindNextTag(n, "link", NULL, NULL); } } - - return unitNet; + return 0; } - AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode) { AQHREACT_UNIT *unit; const char *unitType; const char *unitId; - GWEN_XMLNODE *nGroup; + int rv; unitType=GWEN_XMLNode_GetProperty(unitNode, "type", NULL); if (!(unitType && *unitType)) { @@ -252,22 +392,11 @@ AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode) unitId=GWEN_XMLNode_GetProperty(unitNode, "id", NULL); AQHREACT_Unit_SetId(unit, unitId); - nGroup=GWEN_XMLNode_FindFirstTag(unitNode, "params", NULL, NULL); - if (nGroup) { - GWEN_XMLNODE *n; - - n=GWEN_XMLNode_FindFirstTag(nGroup, "param", NULL, NULL); - while(n) { - int rv; - - rv=_readParam(unit, n); - if (rv<0) { - DBG_INFO(NULL, "here (%d)", rv); - AQHREACT_Unit_free(unit); - return NULL; - } - n=GWEN_XMLNode_FindNextTag(n, "param", NULL, NULL); - } + rv=_readParamValuesForList(AQHREACT_Unit_GetParamList(unit), unitNode); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQHREACT_Unit_free(unit); + return NULL; } return unit; @@ -275,7 +404,32 @@ AQHREACT_UNIT *_readUnit(AQHOME_REACT *aqh, GWEN_XMLNODE *unitNode) -int _readParam(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode) +int _readParamValuesForList(const AQHREACT_PARAM_LIST *paramList, GWEN_XMLNODE *parentNode) +{ + 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); + 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) { const char *paramName; @@ -283,7 +437,7 @@ int _readParam(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode) if (paramName && *paramName) { AQHREACT_PARAM *param; - param=AQHREACT_Unit_GetParamByName(unit, paramName); + param=AQHREACT_Param_List_GetParamByName(paramList, paramName); if (param) { const char *value; @@ -300,7 +454,7 @@ int _readParam(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode) rv=GWEN_Text_StringToDouble(value, &valueAsDouble); if (rv<0) { - DBG_ERROR(NULL, "Not a DOUBLE value for param %s in unit %s [%s]", paramName, AQHREACT_Unit_GetId(unit), value); + DBG_ERROR(NULL, "Not a DOUBLE value for param %s in list [%s]", paramName, value); return rv; } AQHREACT_Param_SetDoubleValue(param, valueAsDouble); @@ -314,7 +468,7 @@ int _readParam(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode) } } else { - DBG_ERROR(NULL, "No param name \"%s\" in unit %s", paramName, AQHREACT_Unit_GetId(unit)); + DBG_ERROR(NULL, "No param name \"%s\" in list", paramName); return GWEN_ERROR_BAD_DATA; } } @@ -324,6 +478,100 @@ int _readParam(AQHREACT_UNIT *unit, GWEN_XMLNODE *paramNode) +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 *sourceUnitName; diff --git a/apps/aqhome-react/networks/0BUILD b/apps/aqhome-react/networks/0BUILD new file mode 100644 index 0000000..f5f1467 --- /dev/null +++ b/apps/aqhome-react/networks/0BUILD @@ -0,0 +1,8 @@ + + + + + tvlight.xml + + + diff --git a/apps/aqhome-react/networks/tvlight.xml b/apps/aqhome-react/networks/tvlight.xml new file mode 100644 index 0000000..05522aa --- /dev/null +++ b/apps/aqhome-react/networks/tvlight.xml @@ -0,0 +1,63 @@ + + + + + + + + 30 + 70 + + + + + + + $(inPlugValue) + + + + + + + $(threshold) + + + + + + + $(outPlugValue) + + + + + + + OFF + OFF + ON + + + + + + + $(delayTime) + 0.0 + + + + + + + + + + + + + + + + diff --git a/apps/aqhome-react/types/param.c b/apps/aqhome-react/types/param.c index e9e2815..2b7f84a 100644 --- a/apps/aqhome-react/types/param.c +++ b/apps/aqhome-react/types/param.c @@ -157,6 +157,26 @@ void AQHREACT_Param_SubFlags(AQHREACT_PARAM *param, uint32_t f) +AQHREACT_PARAM *AQHREACT_Param_List_GetParamByName(const AQHREACT_PARAM_LIST *paramList, const char *paramName) +{ + if (paramList && paramName && *paramName) { + AQHREACT_PARAM *param; + + param=AQHREACT_Param_List_First(paramList); + while(param) { + const char *s; + + s=AQHREACT_Param_GetName(param); + if (s && *s && strcasecmp(paramName, s)==0) + return param; + param=AQHREACT_Param_List_Next(param); + } + } + return NULL; +} + + + diff --git a/apps/aqhome-react/types/param.h b/apps/aqhome-react/types/param.h index a0dc30a..0a04714 100644 --- a/apps/aqhome-react/types/param.h +++ b/apps/aqhome-react/types/param.h @@ -42,6 +42,7 @@ void AQHREACT_Param_SetFlags(AQHREACT_PARAM *param, uint32_t f); void AQHREACT_Param_AddFlags(AQHREACT_PARAM *param, uint32_t f); void AQHREACT_Param_SubFlags(AQHREACT_PARAM *param, uint32_t f); +AQHREACT_PARAM *AQHREACT_Param_List_GetParamByName(const AQHREACT_PARAM_LIST *paramList, const char *paramName); #endif diff --git a/apps/aqhome-react/types/unitnet.c b/apps/aqhome-react/types/unitnet.c index 4e5c0ca..40131d9 100644 --- a/apps/aqhome-react/types/unitnet.c +++ b/apps/aqhome-react/types/unitnet.c @@ -28,6 +28,7 @@ AQHREACT_UNIT_NET *AQHREACT_UnitNet_new(void) GWEN_LIST_INIT(AQHREACT_UNIT_NET, unitNet); unitNet->unitList=AQHREACT_Unit_List_new(); + unitNet->paramList=AQHREACT_Param_List_new(); return unitNet; } @@ -38,6 +39,7 @@ void AQHREACT_UnitNet_free(AQHREACT_UNIT_NET *unitNet) { if (unitNet) { GWEN_LIST_FINI(AQHREACT_UNIT_NET, unitNet); + AQHREACT_Param_List_free(unitNet->paramList); AQHREACT_Unit_List_free(unitNet->unitList); GWEN_FREE_OBJECT(unitNet); } @@ -84,6 +86,41 @@ void AQHREACT_UnitNet_AddUnit(AQHREACT_UNIT_NET *unitNet, AQHREACT_UNIT *unit) +AQHREACT_PARAM_LIST *AQHREACT_UnitNet_GetParamList(const AQHREACT_UNIT_NET *unitNet) +{ + return unitNet?unitNet->paramList:NULL; +} + + + +void AQHREACT_UnitNet_AddParam(AQHREACT_UNIT_NET *unitNet, AQHREACT_PARAM *param) +{ + if (unitNet) + AQHREACT_Param_List_Add(param, unitNet->paramList); +} + + + +AQHREACT_PARAM *AQHREACT_UnitNet_GetParamByName(const AQHREACT_UNIT_NET *unitNet, const char *paramName) +{ + if (unitNet && unitNet->paramList && paramName && *paramName) { + AQHREACT_PARAM *param; + + param=AQHREACT_Param_List_First(unitNet->paramList); + while(param) { + const char *s; + + s=AQHREACT_Param_GetName(param); + if (s && *s && strcasecmp(paramName, s)==0) + return param; + param=AQHREACT_Param_List_Next(param); + } + } + return NULL; +} + + + AQHREACT_UNIT_NET *AQHREACT_UnitNet_List_GetByName(const AQHREACT_UNIT_NET_LIST *unitNetList, const char *name) { if (unitNetList && name && *name) { diff --git a/apps/aqhome-react/types/unitnet.h b/apps/aqhome-react/types/unitnet.h index 8657912..13d8105 100644 --- a/apps/aqhome-react/types/unitnet.h +++ b/apps/aqhome-react/types/unitnet.h @@ -18,6 +18,7 @@ GWEN_LIST_FUNCTION_DEFS(AQHREACT_UNIT_NET, AQHREACT_UnitNet) #include "aqhome-react/aqhome_react.h" +#include "aqhome-react/types/param.h" AQHREACT_UNIT_NET *AQHREACT_UnitNet_new(void); @@ -30,6 +31,11 @@ AQHREACT_UNIT_LIST *AQHREACT_UnitNet_GetUnitList(const AQHREACT_UNIT_NET *unitNe AQHREACT_UNIT *AQHREACT_UnitNet_GetUnitById(const AQHREACT_UNIT_NET *unitNet, const char *s); void AQHREACT_UnitNet_AddUnit(AQHREACT_UNIT_NET *unitNet, AQHREACT_UNIT *unit); +AQHREACT_PARAM_LIST *AQHREACT_UnitNet_GetParamList(const AQHREACT_UNIT_NET *unitNet); +void AQHREACT_UnitNet_AddParam(AQHREACT_UNIT_NET *unitNet, AQHREACT_PARAM *param); +AQHREACT_PARAM *AQHREACT_UnitNet_GetParamByName(const AQHREACT_UNIT_NET *unitNet, const char *paramName); + + AQHREACT_UNIT_NET *AQHREACT_UnitNet_List_GetByName(const AQHREACT_UNIT_NET_LIST *unitNetList, const char *name); diff --git a/apps/aqhome-react/types/unitnet_p.h b/apps/aqhome-react/types/unitnet_p.h index 57d7d8b..5cfe3cd 100644 --- a/apps/aqhome-react/types/unitnet_p.h +++ b/apps/aqhome-react/types/unitnet_p.h @@ -18,6 +18,7 @@ struct AQHREACT_UNIT_NET { char *name; AQHREACT_UNIT_LIST *unitList; + AQHREACT_PARAM_LIST *paramList; }; diff --git a/apps/aqhome-react/units/0BUILD b/apps/aqhome-react/units/0BUILD index a5e3813..5c9148c 100644 --- a/apps/aqhome-react/units/0BUILD +++ b/apps/aqhome-react/units/0BUILD @@ -45,6 +45,8 @@ u_lowpass.h u_highpass.h u_stabilize.h + u_valueset.h + u_zeroposnegstring.h @@ -57,6 +59,8 @@ u_lowpass.c u_highpass.c u_stabilize.c + u_valueset.c + u_zeroposnegstring.c diff --git a/apps/aqhome-react/units/u_valueset.c b/apps/aqhome-react/units/u_valueset.c new file mode 100644 index 0000000..0d7169f --- /dev/null +++ b/apps/aqhome-react/units/u_valueset.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * 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 "./u_valueset.h" + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE 0 + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + +AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh) +{ + AQHREACT_UNIT *unit; + AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PARAM *param; + + unit=AQHREACT_Unit_new(aqh); + AQHREACT_Unit_SetName(unit, "valueset"); + 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); + + param=AQHREACT_Param_new(); + AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME); + AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Unit_AddParam(unit, param); + + return unit; +} + + + +void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +{ + if (unit && dataObject && slotIdForUnit==AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE) { + const char *sSystemValueId; + + sSystemValueId=AQHREACT_DataObject_GetSystemValueId(dataObject); + if (sSystemValueId && *sSystemValueId) { + const char *sValueName; + + sValueName=AQHREACT_Unit_GetParamValueString(unit, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME, NULL); + if (sValueName && *sValueName) { + // TODO: set value + } + } + } +} + + + + diff --git a/apps/aqhome-react/units/u_valueset.h b/apps/aqhome-react/units/u_valueset.h new file mode 100644 index 0000000..3cef416 --- /dev/null +++ b/apps/aqhome-react/units/u_valueset.h @@ -0,0 +1,26 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2024 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOMEREACT_U_VALUESET_H +#define AQHOMEREACT_U_VALUESET_H + + +#include "aqhome-react/aqhome_react.h" +#include "aqhome-react/types/unit.h" + + +#define AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME "valueName" + + +AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQHOME_REACT *aqh); + + + +#endif + + diff --git a/apps/aqhome-react/units/u_zeroposnegstring.c b/apps/aqhome-react/units/u_zeroposnegstring.c new file mode 100644 index 0000000..f41dd6c --- /dev/null +++ b/apps/aqhome-react/units/u_zeroposnegstring.c @@ -0,0 +1,119 @@ +/**************************************************************************** + * 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 "./u_zeroposnegstring.h" + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defines + * ------------------------------------------------------------------------------------------------ + */ + +#define AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_INSLOT_VALUE 0 + +#define AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT 0 + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject); + + + +/* ------------------------------------------------------------------------------------------------ + * implementations + * ------------------------------------------------------------------------------------------------ + */ + +AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh) +{ + AQHREACT_UNIT *unit; + AQHREACT_OUTPUT_SLOT *outputSlot; + AQHREACT_INPUT_SLOT *inputSlot; + AQHREACT_PARAM *param; + + unit=AQHREACT_Unit_new(aqh); + AQHREACT_Unit_SetName(unit, "zeroPosNegString"); + 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); + + 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); + + param=AQHREACT_Param_new(); + AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG); + AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Unit_AddParam(unit, param); + + param=AQHREACT_Param_new(); + AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_POS); + AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Unit_AddParam(unit, param); + + param=AQHREACT_Param_new(); + AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO); + AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Unit_AddParam(unit, param); + + return unit; +} + + + +void _cbInputData(AQHREACT_UNIT *unit, int slotIdForUnit, const AQHREACT_DATAOBJECT *dataObject) +{ + if (unit && dataObject) { + const char *result=NULL; + const AQHREACT_INPUT_SLOT *inputSlot; + + inputSlot=AQHREACT_Unit_GetInputSlotByIdForUnit(unit, slotIdForUnit); + if (inputSlot) { + AQHREACT_DATAOBJECT *dataObject; + + dataObject=AQHREACT_InputSlot_GetCurrentDataObject(inputSlot); + if (dataObject) { + double data; + + 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) + AQHREACT_Unit_OutputStringData(unit, AQHOMEREACT_UNIT_ZEROPOSNEGSTRING_OUTSLOT_RESULT, result); + } +} + + + + diff --git a/apps/aqhome-react/units/u_zeroposnegstring.h b/apps/aqhome-react/units/u_zeroposnegstring.h new file mode 100644 index 0000000..d635cfa --- /dev/null +++ b/apps/aqhome-react/units/u_zeroposnegstring.h @@ -0,0 +1,28 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2024 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOMEREACT_U_ZEROPOSNEGSTRING_H +#define AQHOMEREACT_U_ZEROPOSNEGSTRING_H + + +#include "aqhome-react/aqhome_react.h" +#include "aqhome-react/types/unit.h" + + +#define AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_NEG "valueIfNegative" +#define AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_POS "valueIfPositive" +#define AQHOMEREACT_UNIT_VALUESET_PARAM_VALUE_ZERO "valueIfZero" + + +AQHREACT_UNIT *AqHomeReact_UnitZeroPosNegString_new(AQHOME_REACT *aqh); + + + +#endif + + diff --git a/aqhome/aqhome.c b/aqhome/aqhome.c index bba13cd..ff1814f 100644 --- a/aqhome/aqhome.c +++ b/aqhome/aqhome.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -41,6 +42,7 @@ static void _initI18n(void); static void _definePath(const char *pathName, const char *pathValue); static GWEN_STRINGLIST *_getListOfMatchingFiles(const char *pathName, const char *subFolder, const char *mask); static GWEN_BUFFER *_getRuntimeFilePath(const char *pathName, const char *sFilename); +static GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename); @@ -115,6 +117,20 @@ GWEN_BUFFER *AQH_GetRuntimeFilePath(const char *sFilename) +GWEN_BUFFER *AQH_FindPathOfRuntimeFile(const char *sFilename) +{ + return _findFileinPath(AQHOME_PM_RTDATADIR, sFilename); +} + + + +GWEN_BUFFER *AQH_FindPathOfSysconfFile(const char *sFilename) +{ + return _findFileinPath(AQHOME_PM_SYSCONFDIR, sFilename); +} + + + GWEN_DB_NODE *AQH_LoadConfigFile(void) { @@ -306,3 +322,24 @@ GWEN_BUFFER *_getRuntimeFilePath(const char *pathName, const char *sFilename) +GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename) +{ + GWEN_STRINGLIST *sl; + + sl=GWEN_PathManager_GetPaths(AQHOME_PM_LIBNAME, pathName); + if (sl) { + int rv; + GWEN_BUFFER *buf; + + buf=GWEN_Buffer_new(0, 256, 0, 1); + rv=GWEN_Directory_FindFileInPaths(sl, sFilename, buf); + GWEN_StringList_free(sl); + if (rv==0) + return buf; + GWEN_Buffer_free(buf); + } + return NULL; +} + + + diff --git a/aqhome/aqhome.h b/aqhome/aqhome.h index 99f9c60..dbeb4b1 100644 --- a/aqhome/aqhome.h +++ b/aqhome/aqhome.h @@ -30,6 +30,10 @@ AQHOME_API GWEN_STRINGLIST *AQH_GetListOfMatchingSysconfFiles(const char *subFol AQHOME_API GWEN_BUFFER *AQH_GetRuntimeFilePath(const char *sFilename); +AQHOME_API GWEN_BUFFER *AQH_FindPathOfRuntimeFile(const char *sFilename); +AQHOME_API GWEN_BUFFER *AQH_FindPathOfSysconfFile(const char *sFilename); + + AQHOME_API GWEN_STRINGLIST *AQH_GetGlobalDataDirs(void); AQHOME_API GWEN_STRINGLIST *AQH_GetGlobalSysconfDirs(void);