diff --git a/src/vscp/common/vscp-client-mqtt.cpp b/src/vscp/common/vscp-client-mqtt.cpp index c3468a943..65dc57696 100644 --- a/src/vscp/common/vscp-client-mqtt.cpp +++ b/src/vscp/common/vscp-client-mqtt.cpp @@ -631,6 +631,8 @@ vscpClientMqtt::vscpClientMqtt(void) m_keepAlive = 30; // 30 seconds for keepalive // m_bCleanSession = false; // Do not start with a clean session + m_bUseTopicForEventDefaults = false; // Do not use topic for event defaults + // Defaults for timing m_timeoutConnection = 5000; // 5 seconds m_timeoutResponse = 200; @@ -1531,6 +1533,32 @@ vscpClientMqtt::handleMessage(const struct mosquitto_message *pmsg) return false; } + // If standard topic format is used, that is + // vscp////index/zone/subzone + // and instructed to do so we can find the GUID, class and type from the topic + if (m_bUseTopicForEventDefaults) { + std::deque vec; + vscp_split(vec, pmsg->topic, "/"); + if (vec.size() >= 4) { // at least "vscp///" + + // Assigne GUID from topic if all nills from event. + cguid guid(ex.GUID); + if (guid.isNULL()) { + vscp_getGuidFromStringToArray(ex.GUID, vec[1]); + } + + // Assign class from topic if set to zeror in event. + if (!ex.vscp_class) { + ex.vscp_class = vscp_readStringValue(vec[2]); + } + + // Assign type from topic if set to zero in event. + if (!ex.vscp_type) { + ex.vscp_type = vscp_readStringValue(vec[3]); + } + } + } + // If callback is defined send event if (isCallbackEvActive()) { m_callbackev(ev, getCallbackObj()); diff --git a/src/vscp/common/vscp-client-mqtt.h b/src/vscp/common/vscp-client-mqtt.h index ffe50e57c..34afbe0c8 100644 --- a/src/vscp/common/vscp-client-mqtt.h +++ b/src/vscp/common/vscp-client-mqtt.h @@ -591,6 +591,13 @@ class vscpClientMqtt : public CVscpClient { void setKeepAlive(uint16_t keepAlive) { m_keepAlive = keepAlive; }; uint32_t getKeepAlive(void) { return m_keepAlive; }; + /*! + Getter/setter for bUseTopicForEventDefaults + */ + void setUseTopicForEventDefaults(bool b) { m_bUseTopicForEventDefaults = b; }; + bool getUseTopicForEventDefaults(void) { return m_bUseTopicForEventDefaults; }; + bool isUseTopicForEventDefaults(void) { return m_bUseTopicForEventDefaults; }; + /*! Getter for remote port @return remote host port. @@ -658,7 +665,7 @@ class vscpClientMqtt : public CVscpClient { /*! Set parent disconnect callback */ - void setFuncParentCallbackDisconnet(LPFN_PARENT_CALLBACK_DISCONNECT func) { m_parentCallbackDisconnect = func; }; + void setFuncParentCallbackDisconnect(LPFN_PARENT_CALLBACK_DISCONNECT func) { m_parentCallbackDisconnect = func; }; /*! Set parent publish callback @@ -736,6 +743,19 @@ class vscpClientMqtt : public CVscpClient { */ bool m_bJsonMeasurementAdd; + /*! + Use topic for defaults. + + If the standard format for topics is used, that is + vscp/guid/class/type/index/zone/subzone + the by enabling this guid, class and type information that + is absent from the received event can be filled in from the + MQTT topic of the message. This allows for very compact + MQTT messages while still preserving the full VSCP event + information. + */ + bool m_bUseTopicForEventDefaults; + /*! Mutex that protect CANAL interface when callbacks are defined */ diff --git a/src/vscp/common/vscphelper.cpp b/src/vscp/common/vscphelper.cpp index ef3074213..2203904ad 100644 --- a/src/vscp/common/vscphelper.cpp +++ b/src/vscp/common/vscphelper.cpp @@ -4479,6 +4479,9 @@ vscp_convertJSONToEvent(vscpEvent *pEvent, std::string &strJSON) return false; } + // Initialize event + memset(pEvent, 0, sizeof(vscpEvent)); + try { auto j = json::parse(strJSON); @@ -4632,6 +4635,9 @@ vscp_convertJSONToEventEx(vscpEventEx *pEventEx, std::string &strJSON) return false; } + // Initialize event + memset(pEventEx, 0, sizeof(vscpEventEx)); + try { auto j = json::parse(strJSON); diff --git a/src/vscp/common/vscphelper.h b/src/vscp/common/vscphelper.h index 5adf5672c..eb6c53b75 100644 --- a/src/vscp/common/vscphelper.h +++ b/src/vscp/common/vscphelper.h @@ -1621,12 +1621,26 @@ vscp_convertEventExToJSON(std::string &strJSON, vscpEventEx *pEventEx); /*! * Convert JSON string to event + * + * If a value is not found in the JSON string + * it will be set to zero. This means a value + * can be omitted in the JSON string. The only + * values that must be in the JSON string is + * class and type as long as the GUID is known + * beforehand */ bool vscp_convertJSONToEvent(vscpEvent *pEvent, std::string &strJSON); /*! * Convert JSON string to eventex + * + * If a value is not found in the JSON string + * it will be set to zero. This means a value + * can be omitted in the JSON string. The only + * values that must be in the JSON string is + * class and type as long as the GUID is known + * beforehand */ bool vscp_convertJSONToEventEx(vscpEventEx *pEventEx, std::string &strJSONx); diff --git a/third_party/mongoose b/third_party/mongoose index ef8e7419f..2df53c3d2 160000 --- a/third_party/mongoose +++ b/third_party/mongoose @@ -1 +1 @@ -Subproject commit ef8e7419fa704838f8513fd1c6e99363e5dcc182 +Subproject commit 2df53c3d27b9ae54b1c08b6c3c3cc660a49fa4a2 diff --git a/third_party/nlohmann b/third_party/nlohmann index 606b6347e..a97041a98 160000 --- a/third_party/nlohmann +++ b/third_party/nlohmann @@ -1 +1 @@ -Subproject commit 606b6347edf0758c531abb6c36743e09a4c48a84 +Subproject commit a97041a98fc7436cda3b28fb6e353071829d3f02 diff --git a/third_party/spdlog b/third_party/spdlog index f355b3d58..43dcb3982 160000 --- a/third_party/spdlog +++ b/third_party/spdlog @@ -1 +1 @@ -Subproject commit f355b3d58f7067eee1706ff3c801c2361011f3d5 +Subproject commit 43dcb3982d1cffcf34a8b126cd12ee07b8eaa2d9