/**************************************************************************** * This file is part of the project AqHome. * AqHome (c) by 2023 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 "./c_setdata.h" #include "./aqhome_data_p.h" #include "./loop.h" #include "aqhome/ipc/data/ipc_data.h" #include "aqhome/ipc/data/msg_data_singledata.h" #include "aqhome/ipc/endpoint_ipc.h" #include "aqhome/ipc/msg_ipc_result.h" #include "aqhome/ipc/msg_ipc_tag16.h" #include /* ------------------------------------------------------------------------------------------------ * defines * ------------------------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static int _forwardDataToDriver(AQHOME_DATA *aqh, const AQH_VALUE *v, uint64_t timestamp, double datapoint); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ void AqHomeData_HandleSetData(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *epSrc, const GWEN_MSG *recvdMsg) { GWEN_MSG *outMsg; int resultCode=AQH_MSG_IPC_SUCCESS; GWEN_TAG16_LIST *tagList; AQH_VALUE *value; char *valueName=NULL; uint64_t timestamp=0; union {double f; uint64_t i;} u; tagList=AQH_Tag16IpcMsg_ParseTags(recvdMsg, 0); if (tagList) { const GWEN_TAG16 *tag; tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_SINGLEDATA_TAGS_NAME); valueName=tag?GWEN_Tag16_GetTagDataAsNewString(tag, NULL):NULL; tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_SINGLEDATA_TAGS_TIME); timestamp=tag?GWEN_Tag16_GetTagDataAsUint64(tag, 0):0; tag=GWEN_Tag16_List_FindFirstByTagType(tagList, AQH_MSGDATA_SINGLEDATA_TAGS_DATA); u.i=tag?GWEN_Tag16_GetTagDataAsUint64(tag, 0):0; } value=AQH_Storage_GetValueByNameForSystem(aqh->storage, valueName); if (value) { if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) { resultCode=_forwardDataToDriver(aqh, value, timestamp, u.f); } else { DBG_INFO(NULL, "Value \"%s\" is not an actor", valueName); resultCode=AQH_MSG_IPC_ERROR_INVALID; } } else { DBG_INFO(NULL, "Actor value \"%s\" does not exist", valueName); resultCode=AQH_MSG_IPC_ERROR_NOTFOUND; } free(valueName); outMsg=AQH_ResultIpcMsg_new(AQH_MSGTYPE_IPC_DATA_RESULT, resultCode); GWEN_MsgEndpoint_AddSendMessage(epSrc, outMsg); } int _forwardDataToDriver(AQHOME_DATA *aqh, const AQH_VALUE *v, uint64_t timestamp, double datapoint) { const char *driverName; driverName=AQH_Value_GetDriver(v); if (driverName && *driverName) { GWEN_MSG_ENDPOINT *ep; ep=AqHomeData_GetIpcEndpointByServiceName(aqh, driverName); if (ep) { GWEN_MSG *driverMsg; DBG_INFO(AQH_LOGDOMAIN, "Sending SETDATA msg to driver endpoint (%s)", GWEN_MsgEndpoint_GetName(ep)); driverMsg=AQH_SingleDataDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_SETDATA, AQH_Value_GetNameForDriver(v), AQH_Value_GetValueUnits(v), AQH_Value_GetValueType(v), NULL, timestamp, datapoint); GWEN_MsgEndpoint_AddSendMessage(ep, driverMsg); return AQH_MSG_IPC_SUCCESS; } else { DBG_INFO(NULL, "Driver \"%s\" not available", driverName); return AQH_MSG_IPC_ERROR_GENERIC; } } else { DBG_INFO(NULL, "No driver name"); return AQH_MSG_IPC_ERROR_GENERIC; } }