also send MQTT definition topic and handle knx subscription for conditional messages evaluated later

This commit is contained in:
John
2024-01-14 11:04:10 +01:00
parent 3232f4ff95
commit 1316291740
4 changed files with 37 additions and 6 deletions
+5 -3
View File
@@ -760,7 +760,7 @@ void KnxHandler::run() {
}
if (m_con->isConnected()) {
deque<Message*> 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<signed>(message->getFieldCount());
if (isWrite && fieldCount > 1) {
// impossible with more than one field
+2 -1
View File
@@ -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)
+15 -2
View File
@@ -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);
}
+15
View File
@@ -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. */