/**************************************************************************** * 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 "./tty_write.h" #include "./aqhomed_p.h" #include "aqhome/msg/msg_value2.h" #include "aqhome/msg/msg_sendstats.h" #include "aqhome/msg/msg_recvstats.h" #include #include #include /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static void _processValue2Message(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 _writeDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v); static void _writeInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v); static void _writeString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v); static void _writeToFile(const char *filename, const char *txt); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ void AqHomed_WriteTtyMsg(AQHOMED *aqh, const GWEN_MSG *msg) { if (aqh && aqh->writeFolder) { switch(AQH_NodeMsg_GetMsgType(msg)) { case AQH_MSG_TYPE_VALUE2: _processValue2Message(aqh, msg); break; case AQH_MSG_TYPE_COMSENDSTATS: _processSendStatsMessage(aqh, msg); break; case AQH_MSG_TYPE_COMRECVSTATS: _processRecvStatsMessage(aqh, msg); break; default: break; } } } void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { const char *sType; sType=AQH_Value2Msg_GetValueTypeName(nodeMsg); if (sType && *sType) { if (AQH_Value2Msg_GetValueType(nodeMsg)==AQH_MSG_VALUE2_TYPE_DOOR) _writeString(aqh, AQH_Value2Msg_GetUid(nodeMsg), AQH_Value2Msg_GetValueId(nodeMsg), sType, AQH_Value2Msg_GetValueAsWindowStateString(nodeMsg)); else _writeDouble(aqh, AQH_Value2Msg_GetUid(nodeMsg), AQH_Value2Msg_GetValueId(nodeMsg), sType, AQH_Value2Msg_GetValue(nodeMsg)); } _writeDouble(aqh, AQH_Value2Msg_GetUid(nodeMsg), AQH_Value2Msg_GetValueId(nodeMsg), "value", AQH_Value2Msg_GetValue(nodeMsg)); } void _processSendStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { uint16_t packetsOutInt; packetsOutInt=AQH_SendStatsMsg_GetPacketsOut(nodeMsg); if (packetsOutInt) { double packetsOut; double collisions; double busy; double collisionsPercentage=0.0; double busyPercentage=0.0; 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; _writeInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/packetsOut", packetsOutInt); _writeInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisions", (int) AQH_SendStatsMsg_GetCollisions(nodeMsg)); _writeDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisionsPercent", collisionsPercentage); _writeDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/busyPercent", busyPercentage); } } void _processRecvStatsMessage(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { uint16_t packetsInInt; packetsInInt=AQH_RecvStatsMsg_GetPacketsIn(nodeMsg); if (packetsInInt) { double packetsIn; double crcErrors; double ioErrors; double crcErrorsPercentage=0.0; double ioErrorsPercentage=0.0; 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; _writeInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/packetsIn", packetsInInt); _writeInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg)); _writeInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrors", (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg)); _writeDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrorsPercent", crcErrorsPercentage); _writeDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrorsPercent", ioErrorsPercentage); } } void _writeDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v) { char numBuf[16]; snprintf(numBuf, sizeof(numBuf)-1, "%f", v); numBuf[sizeof(numBuf)-1]=0; _writeString(aqh, uid, valueId, valuePath, numBuf); } void _writeInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v) { char numBuf[16]; snprintf(numBuf, sizeof(numBuf)-1, "%d", v); numBuf[sizeof(numBuf)-1]=0; _writeString(aqh, uid, valueId, valuePath, numBuf); } void _writeString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v) { GWEN_BUFFER *bufFilename; bufFilename=GWEN_Buffer_new(0, 64, 0, 1); if (valueId>0) GWEN_Buffer_AppendArgs(bufFilename, "%s/%08x/%d/%s", aqh->writeFolder, uid, valueId, valuePath); else GWEN_Buffer_AppendArgs(bufFilename, "%s/%08x/%s", aqh->writeFolder, uid, valuePath); _writeToFile(GWEN_Buffer_GetStart(bufFilename), v); GWEN_Buffer_free(bufFilename); } void _writeToFile(const char *filename, const char *txt) { if (txt && *txt) { GWEN_BUFFER *tmpNameBuf; int rv; tmpNameBuf=GWEN_Buffer_new(0, 256, 0, 1); GWEN_Buffer_AppendString(tmpNameBuf, filename); GWEN_Buffer_AppendString(tmpNameBuf, ".tmp"); rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(tmpNameBuf), GWEN_PATH_FLAGS_VARIABLE); if (rv<0) { DBG_INFO(NULL, "Error getting path for %s (%d)", GWEN_Buffer_GetStart(tmpNameBuf), rv); } else { FILE *f; f=fopen(GWEN_Buffer_GetStart(tmpNameBuf), "w"); if (f) { if (1!=fwrite(txt, strlen(txt), 1, f)) { DBG_ERROR(NULL, "Error writing."); fclose(f); } else { fclose(f); rename(GWEN_Buffer_GetStart(tmpNameBuf), filename); } } } GWEN_Buffer_free(tmpNameBuf); } }