/**************************************************************************** * 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_mqtt.h" #include "./aqhomed_p.h" #include "./tty_log.h" #include "./tty_write.h" #include "./db.h" #include "aqhome/msg/endpoint_tty.h" #include "aqhome/msg/msg_node.h" #include "aqhome/msg/msg_value2.h" #include "aqhome/msg/msg_sendstats.h" #include "aqhome/msg/msg_recvstats.h" #include "aqhome/ipc/endpoint_ipc.h" #include "aqhome/ipc/nodes/msg_ipc_forward.h" #include "aqhome/ipc/nodes/msg_ipc_value.h" #include "aqhome/mqtt/endpoint_mqttc.h" #include "aqhome/mqtt/msg_mqtt_publish.h" #include #include #include #include /* ------------------------------------------------------------------------------------------------ * defines * ------------------------------------------------------------------------------------------------ */ #define I18N(msg) msg #define I18S(msg) msg /* ------------------------------------------------------------------------------------------------ * 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 _publishDouble(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, double v); static void _publishInt(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, int v); static void _publishString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ void AqHomed_ForwardTtyMsgToMqttServer(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { if (GWEN_MsgEndpoint_GetState(aqh->mqttEndpoint)==GWEN_MSG_ENDPOINT_STATE_CONNECTED) { DBG_DEBUG(AQH_LOGDOMAIN, "Processing output message"); switch(AQH_NodeMsg_GetMsgType(nodeMsg)) { case AQH_MSG_TYPE_VALUE2: _processValue2Message(aqh, nodeMsg); break; case AQH_MSG_TYPE_COMSENDSTATS: _processSendStatsMessage(aqh, nodeMsg); break; case AQH_MSG_TYPE_COMRECVSTATS: _processRecvStatsMessage(aqh, nodeMsg); break; default: break; } } } void _processValue2Message(AQHOMED *aqh, const GWEN_MSG *nodeMsg) { if (AQH_Value2Msg_GetValueType(nodeMsg)==AQH_MSG_VALUE2_TYPE_DOOR) _publishString(aqh, AQH_Value2Msg_GetUid(nodeMsg), AQH_Value2Msg_GetValueId(nodeMsg), AQH_Value2Msg_GetValueTypeName(nodeMsg), AQH_Value2Msg_GetValueAsWindowStateString(nodeMsg)); else _publishDouble(aqh, AQH_Value2Msg_GetUid(nodeMsg), AQH_Value2Msg_GetValueId(nodeMsg), AQH_Value2Msg_GetValueTypeName(nodeMsg), 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; _publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/packetsOut", packetsOutInt); _publishInt(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisions", (int) AQH_SendStatsMsg_GetCollisions(nodeMsg)); _publishDouble(aqh, AQH_SendStatsMsg_GetUid(nodeMsg), 0, "net/collisionsPercent", collisionsPercentage); _publishDouble(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; _publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/packetsIn", packetsInInt); _publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrors", (int) AQH_RecvStatsMsg_GetCrcErrors(nodeMsg)); _publishInt(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrors", (int) AQH_RecvStatsMsg_GetIoErrors(nodeMsg)); _publishDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/crcerrorsPercent", crcErrorsPercentage); _publishDouble(aqh, AQH_RecvStatsMsg_GetUid(nodeMsg), 0, "net/ioerrorsPercent", ioErrorsPercentage); } } void _publishDouble(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; _publishString(aqh, uid, valueId, valuePath, numBuf); } void _publishInt(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; _publishString(aqh, uid, valueId, valuePath, numBuf); } void _publishString(AQHOMED *aqh, uint32_t uid, int valueId, const char *valuePath, const char *v) { GWEN_BUFFER *bufTopic; GWEN_MSG *pubMsg; bufTopic=GWEN_Buffer_new(0, 64, 0, 1); if (valueId>0) GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%d/%s", aqh->mqttTopicPrefix, uid, valueId, valuePath); else GWEN_Buffer_AppendArgs(bufTopic, "%s/%08x/%s", aqh->mqttTopicPrefix, uid, valuePath); pubMsg=AQH_PublishMqttMsg_new(0, 0, GWEN_Buffer_GetStart(bufTopic), (const uint8_t*) v, strlen(v)); if (pubMsg) { DBG_INFO(AQH_LOGDOMAIN, "MQTT PUBLISH %s: %s", GWEN_Buffer_GetStart(bufTopic), v); GWEN_MsgEndpoint_AddSendMessage(aqh->mqttEndpoint, pubMsg); } GWEN_Buffer_free(bufTopic); }