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()) {
|
if (m_con->isConnected()) {
|
||||||
deque<Message*> messages;
|
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;
|
int addCnt = 0;
|
||||||
for (const auto& message : messages) {
|
for (const auto& message : messages) {
|
||||||
const auto mit = m_subscribedMessages.find(message->getKey());
|
const auto mit = m_subscribedMessages.find(message->getKey());
|
||||||
@@ -770,10 +770,12 @@ void KnxHandler::run() {
|
|||||||
if (message->getDstAddress() == SYN) {
|
if (message->getDstAddress() == SYN) {
|
||||||
continue; // not usable in absence of destination address
|
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;
|
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());
|
ssize_t fieldCount = static_cast<signed>(message->getFieldCount());
|
||||||
if (isWrite && fieldCount > 1) {
|
if (isWrite && fieldCount > 1) {
|
||||||
// impossible with more than one field
|
// impossible with more than one field
|
||||||
|
|||||||
@@ -816,7 +816,8 @@ void MqttHandler::run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
message->setDataHandlerState(1, true);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if (!FileReader::matches(message->getCircuit(), filterCircuit, true, true)
|
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_id(id), m_key(createKey(id, isWrite, isPassive, srcAddress, dstAddress)),
|
||||||
m_data(data), m_deleteData(deleteData),
|
m_data(data), m_deleteData(deleteData),
|
||||||
m_pollPriority(pollPriority),
|
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) {
|
m_dataHandlerState(0), m_lastUpdateTime(0), m_lastChangeTime(0), m_pollOrder(0), m_lastPollTime(0) {
|
||||||
if (circuit == "scan") {
|
if (circuit == "scan") {
|
||||||
setScanMessage();
|
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_id({pb, sb}), m_key(createKey(pb, sb, broadcast)),
|
||||||
m_data(data), m_deleteData(deleteData),
|
m_data(data), m_deleteData(deleteData),
|
||||||
m_pollPriority(0),
|
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) {
|
m_lastUpdateTime(0), m_lastChangeTime(0), m_pollOrder(0), m_lastPollTime(0) {
|
||||||
time(&m_createTime);
|
time(&m_createTime);
|
||||||
}
|
}
|
||||||
@@ -652,6 +652,19 @@ bool Message::isAvailable() {
|
|||||||
return (m_condition == nullptr) || m_condition->isTrue();
|
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 {
|
bool Message::hasField(const char* fieldName, bool numeric) const {
|
||||||
return m_data->hasField(fieldName, numeric);
|
return m_data->hasField(fieldName, numeric);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,6 +399,12 @@ class Message : public AttributedItem {
|
|||||||
*/
|
*/
|
||||||
bool isAvailable();
|
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.
|
* Return whether the field is available.
|
||||||
* @param fieldName the name of the field to find, or nullptr for any.
|
* @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. */
|
/** the @a Condition for this message, or nullptr. */
|
||||||
Condition* m_condition;
|
Condition* m_condition;
|
||||||
|
|
||||||
|
/** the time when the @a Condition first became available, or 0. */
|
||||||
|
time_t m_availableSinceTime;
|
||||||
|
|
||||||
/** the last seen @a MasterSymbolString. */
|
/** the last seen @a MasterSymbolString. */
|
||||||
MasterSymbolString m_lastMasterData;
|
MasterSymbolString m_lastMasterData;
|
||||||
|
|
||||||
@@ -927,6 +936,12 @@ class Condition {
|
|||||||
*/
|
*/
|
||||||
virtual bool isTrue() = 0;
|
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:
|
protected:
|
||||||
/** the system time when the condition was last checked, 0 for never. */
|
/** the system time when the condition was last checked, 0 for never. */
|
||||||
|
|||||||
Reference in New Issue
Block a user