also send MQTT definition topic and handle knx subscription for conditional messages evaluated later
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user