/**************************************************************************** * 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 "./loop_tty_broker.h" #include "./aqhomed_p.h" #include "./tty_log.h" #include "./db.h" #include "aqhome/aqhome.h" #include "aqhome/msg/endpoint_tty.h" #include "aqhome/msg/msg_node.h" #include "aqhome/msg/msg_value2.h" #include "aqhome/msg/msg_value3.h" #include "aqhome/msg/msg_sendstats.h" #include "aqhome/msg/msg_recvstats.h" #include "aqhome/ipc/endpoint_ipc.h" #include "aqhome/ipc/data/msg_data_multidata.h" #include "aqhome/ipc/data/ipc_data.h" #include #include #include #include /* ------------------------------------------------------------------------------------------------ * defines * ------------------------------------------------------------------------------------------------ */ #define I18N(msg) msg #define I18S(msg) msg /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static void _processValue3Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg); static void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg); static void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg); static void _publishInt(AQHOMED *aqh, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v); static void _publishDouble(AQHOMED *aqh, uint32_t uid, const char *vPath, int vType, const char *vUnits, double v); static void _setDeviceName(AQH_VALUE *value, uint32_t uid); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ void AqHomed_ForwardTtyMsgToBroker(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { if (GWEN_MsgEndpoint_GetState(aqh->brokerEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) { DBG_DEBUG(AQH_LOGDOMAIN, "Processing output message"); switch(AQH_NodeMsg_GetMsgType(nodeMsg)) { case AQH_MSG_TYPE_VALUE_REPORT: _processValue3Message(aqh, nodeMsg); break; case AQH_MSG_TYPE_COMSENDSTATS: _processSendStatsMessage(aqh, nodeMsg); break; case AQH_MSG_TYPE_COMRECVSTATS: _processRecvStatsMessage(aqh, nodeMsg); break; default: break; } } } void _processValue3Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { uint32_t uid; uint8_t valueId; AQH_NODE_INFO *ni; double v; uid=AQH_Value3Msg_GetUid(nodeMsg); valueId=AQH_Value3Msg_GetValueId(nodeMsg); v=AQH_Value3Msg_GetValue(nodeMsg); ni=AQH_NodeDb_GetNodeInfoByUid(aqh->nodeDb, uid); if (ni) { const char *devName; devName=AQH_NodeInfo_GetDeviceId(ni); if (devName) { const AQHNODE_DEVICE *devInfo; devInfo=AqHomed_GetDeviceDefByName(aqh, devName); if (devInfo) { const AQHNODE_VALUE *value; value=AQHNODE_Value_List_GetById(AQHNODE_Device_GetValueList(devInfo), valueId); if (value) { const char *vname; vname=AQHNODE_Value_GetName(value); if (vname && *vname) _publishDouble(aqh, uid, vname, AQHNODE_Value_GetModality(value), AQHNODE_Value_GetValueUnits(value), v); } } } } } void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { uint16_t packetsOutInt; packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg); if (packetsOutInt) { uint32_t uid; double packetsOut; double collisions; double busy; double collisionsPercentage=0.0; double busyPercentage=0.0; uid=AQH_SendStatsMsg_GetUid(nodeMsg); packetsOut=/*(double)*/ packetsOutInt; collisions=/*(double)*/ AQH_SendStatsMsg_GetCollisions(nodeMsg); busy=/*(double)*/ AQH_SendStatsMsg_GetBusyErrors(nodeMsg); collisionsPercentage=collisions*100.0/packetsOut; busyPercentage=busy*100.0/packetsOut; _publishInt( aqh, uid, "net/packetsOut", 0, NULL, packetsOutInt); _publishInt( aqh, uid, "net/collisions", 0, NULL, (int) AQH_SendStatsMsg_GetCollisions(nodeMsg)); _publishDouble(aqh, uid, "net/collisionsPercent", 0, "%", collisionsPercentage); _publishDouble(aqh, uid, "net/busyPercent", 0, "%", busyPercentage); } } void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { uint16_t packetsInInt; packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg); if (packetsInInt) { uint32_t uid; double packetsIn; double crcErrors; double ioErrors; double crcErrorsPercentage=0.0; double ioErrorsPercentage=0.0; uid=AQH_SendStatsMsg_GetUid(nodeMsg); packetsIn=/*(double)*/ packetsInInt; crcErrors=/*(double)*/AQH_RecvStatsMsg_GetCrcErrors(nodeMsg); ioErrors=/*(double)*/AQH_RecvStatsMsg_GetIoErrors(nodeMsg); crcErrorsPercentage=crcErrors*100.0/packetsIn; ioErrorsPercentage=ioErrors*100.0/packetsIn; _publishInt( aqh, uid, "net/packetsIn", 0, NULL, packetsInInt); _publishInt( aqh, uid, "net/crcerrors", 0, NULL, (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg)); _publishInt( aqh, uid, "net/ioerrors", 0, NULL, (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg)); _publishDouble(aqh, uid, "net/crcerrorsPercent", 0, "%", crcErrorsPercentage); _publishDouble(aqh, uid, "net/ioerrorsPercent", 0, "%", ioErrorsPercentage); } } void _publishInt(AQHOMED *aqh, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v) { _publishDouble(aqh, uid, vPath, vModality, vUnits, /*(double)*/ v); } void _publishDouble(AQHOMED *aqh, uint32_t uid, const char *vPath, int vModality, const char *vUnits, double v) { GWEN_MSG *pubMsg; union {double f; uint64_t i;} u; uint64_t arrayToSend[2]; AQH_VALUE *value; u.f=v; arrayToSend[0]=(uint64_t) time(NULL); arrayToSend[1]=u.i; value=AQH_Value_new(); _setDeviceName(value, uid); AQH_Value_SetName(value, vPath); AQH_Value_SetValueUnits(value, vUnits); AQH_Value_SetValueType(value, AQH_ValueType_Sensor); AQH_Value_SetModality(value, vModality); pubMsg=AQH_MultiDataDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_UPDATEDATA, GWEN_MsgEndpoint_GetNextMessageId(aqh->brokerEndpoint), 0, value, arrayToSend, 1); if (pubMsg) { DBG_INFO(AQH_LOGDOMAIN, "BROKER PUBLISH %s: %f", AQH_Value_GetName(value), v); GWEN_MsgEndpoint_AddSendMessage(aqh->brokerEndpoint, pubMsg); } AQH_Value_free(value); } void _setDeviceName(AQH_VALUE *value, uint32_t uid) { GWEN_BUFFER *buf; buf=GWEN_Buffer_new(0, 64, 0, 1); GWEN_Buffer_AppendArgs(buf, "%08x", uid); AQH_Value_SetDeviceName(value, GWEN_Buffer_GetStart(buf)); GWEN_Buffer_free(buf); }