diff --git a/src/ebusd/knxhandler.cpp b/src/ebusd/knxhandler.cpp index 8d257408..4a912a56 100644 --- a/src/ebusd/knxhandler.cpp +++ b/src/ebusd/knxhandler.cpp @@ -760,7 +760,7 @@ void KnxHandler::run() { } if (m_con->isConnected()) { deque messages; - m_messages->findAll("", "", m_levels, false, true, true, true, true, true, 0, 0, true, &messages); + m_messages->findAll("", "", m_levels, false, true, true, true, true, true, 0, 0, false, &messages); int addCnt = 0; for (const auto& message : messages) { const auto mit = m_subscribedMessages.find(message->getKey()); @@ -770,10 +770,12 @@ void KnxHandler::run() { if (message->getDstAddress() == SYN) { continue; // not usable in absence of destination address } - bool isWrite = message->isWrite() && !message->isPassive(); // from KNX perspective - if (message->getCreateTime() <= definitionsSince) { // only newer defined + if (message->getCreateTime() <= definitionsSince // only newer defined + && (!message->isConditional() || message->getAvailableSinceTime() <= definitionsSince)) { // unless conditional continue; } + logOtherDebug("knx", "checking association to %s %s", message->getCircuit().c_str(), message->getName().c_str()); + bool isWrite = message->isWrite() && !message->isPassive(); // from KNX perspective ssize_t fieldCount = static_cast(message->getFieldCount()); if (isWrite && fieldCount > 1) { // impossible with more than one field diff --git a/src/ebusd/mqtthandler.cpp b/src/ebusd/mqtthandler.cpp index c734cc5c..20ec1f79 100755 --- a/src/ebusd/mqtthandler.cpp +++ b/src/ebusd/mqtthandler.cpp @@ -816,7 +816,8 @@ void MqttHandler::run() { } } message->setDataHandlerState(1, true); - } else if (message->getCreateTime() <= m_definitionsSince) { // only newer defined + } else if (message->getCreateTime() <= m_definitionsSince // only newer defined + && (!message->isConditional() || message->getAvailableSinceTime() <= m_definitionsSince)) { // unless conditional continue; } if (!FileReader::matches(message->getCircuit(), filterCircuit, true, true) diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index 75b2770f..f7faa051 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -109,7 +109,7 @@ Message::Message(const string& filename, const string& circuit, const string& le m_id(id), m_key(createKey(id, isWrite, isPassive, srcAddress, dstAddress)), m_data(data), m_deleteData(deleteData), m_pollPriority(pollPriority), - m_usedByCondition(false), m_isScanMessage(false), m_condition(condition), + m_usedByCondition(false), m_isScanMessage(false), m_condition(condition), m_availableSinceTime(0), m_dataHandlerState(0), m_lastUpdateTime(0), m_lastChangeTime(0), m_pollOrder(0), m_lastPollTime(0) { if (circuit == "scan") { setScanMessage(); @@ -129,7 +129,7 @@ Message::Message(const string& circuit, const string& level, const string& name, m_id({pb, sb}), m_key(createKey(pb, sb, broadcast)), m_data(data), m_deleteData(deleteData), m_pollPriority(0), - m_usedByCondition(false), m_isScanMessage(true), m_condition(nullptr), + m_usedByCondition(false), m_isScanMessage(true), m_condition(nullptr), m_availableSinceTime(0), m_lastUpdateTime(0), m_lastChangeTime(0), m_pollOrder(0), m_lastPollTime(0) { time(&m_createTime); } @@ -652,6 +652,19 @@ bool Message::isAvailable() { return (m_condition == nullptr) || m_condition->isTrue(); } +time_t Message::getAvailableSinceTime() { + if (m_condition == nullptr) { + return m_createTime; + } + if (!m_condition->isTrue()) { + return 0; + } + if (m_availableSinceTime == 0) { // was not yet available + m_availableSinceTime = m_condition->getLastCheckTime(); + } + return m_availableSinceTime; +} + bool Message::hasField(const char* fieldName, bool numeric) const { return m_data->hasField(fieldName, numeric); } diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 647539f7..21e8118b 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -399,6 +399,12 @@ class Message : public AttributedItem { */ bool isAvailable(); + /** + * Get the time when this (potentially conditional) message first became available. + * @return the time when this message first became available, or 0 if it is not available. + */ + time_t getAvailableSinceTime(); + /** * Return whether the field is available. * @param fieldName the name of the field to find, or nullptr for any. @@ -673,6 +679,9 @@ class Message : public AttributedItem { /** the @a Condition for this message, or nullptr. */ Condition* m_condition; + /** the time when the @a Condition first became available, or 0. */ + time_t m_availableSinceTime; + /** the last seen @a MasterSymbolString. */ MasterSymbolString m_lastMasterData; @@ -927,6 +936,12 @@ class Condition { */ virtual bool isTrue() = 0; + /** + * Get the system time when the condition was last checked. + * @return the system time when the condition was last checked, 0 for never. + */ + time_t getLastCheckTime() const { return m_lastCheckTime; } + protected: /** the system time when the condition was last checked, 0 for never. */