diff --git a/de_web_plugin.cpp b/de_web_plugin.cpp index b064230f07..99dacaeed3 100644 --- a/de_web_plugin.cpp +++ b/de_web_plugin.cpp @@ -4729,6 +4729,8 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ:: std::vector::iterator i = sensors.begin(); std::vector::iterator end = sensors.end(); + bool pollControlInitialized = false; + for (; i != end; ++i) { if (i->address().ext() == node->address().ext()) @@ -4744,6 +4746,18 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const deCONZ:: DBG_Printf(DBG_INFO, "SensorNode %s set node %s\n", qPrintable(i->id()), qPrintable(node->address().toStringExt())); pushSensorInfoToCore(&*i); + + // If device has Poll Control cluster, configure it via the first Sensor. + if (!pollControlInitialized && PC_GetPollControlEndpoint(node) > 0) + { + auto *itemPending = i->item(RConfigPending); + if (itemPending) + { + DBG_Printf(DBG_INFO, "Init Poll Control for %s\n", qPrintable(node->address().toStringExt())); + pollControlInitialized = true; + itemPending->setValue(itemPending->toNumber() | R_PENDING_WRITE_POLL_CHECKIN_INTERVAL | R_PENDING_SET_LONG_POLL_INTERVAL); + } + } } auto *item = i->item(RStateBattery); @@ -6829,7 +6843,7 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi { sensorNode.setManufacturer("Samjin"); - if (fingerPrint.hasInCluster(IAS_ZONE_CLUSTER_ID)) // POLL_CONTROL_CLUSTER_ID + if (PC_GetPollControlEndpoint(node) > 0) { item = sensorNode.addItem(DataTypeUInt8, RConfigPending); item->setValue(item->toNumber() | R_PENDING_WRITE_POLL_CHECKIN_INTERVAL | R_PENDING_SET_LONG_POLL_INTERVAL); diff --git a/poll_control.cpp b/poll_control.cpp index fc50393701..e61bfe4537 100644 --- a/poll_control.cpp +++ b/poll_control.cpp @@ -113,6 +113,13 @@ bool DeRestPluginPrivate::checkPollControlClusterTask(Sensor *sensor) return false; } + if (sensor->node()->nodeDescriptor().manufacturerCode() == VENDOR_IKEA && (item->toNumber() & R_PENDING_SET_LONG_POLL_INTERVAL) != 0) + { + // for IKEA devices leave long poll interval at factory default settings + // TODO configure in DDF + item->setValue(item->toNumber() & ~(R_PENDING_SET_LONG_POLL_INTERVAL)); + } + if (item->toNumber() & R_PENDING_WRITE_POLL_CHECKIN_INTERVAL) { // write poll control checkin interval @@ -128,12 +135,13 @@ bool DeRestPluginPrivate::checkPollControlClusterTask(Sensor *sensor) item->setValue(item->toNumber() & ~R_PENDING_WRITE_POLL_CHECKIN_INTERVAL); return true; } + + return false; // only send Set Long Poll Interval after writing this attribute } if (item->toNumber() & R_PENDING_SET_LONG_POLL_INTERVAL) { deCONZ::ApsDataRequest apsReq; - deCONZ::ZclFrame zclFrame; // ZDP Header apsReq.dstAddress() = sensor->address(); @@ -146,7 +154,7 @@ bool DeRestPluginPrivate::checkPollControlClusterTask(Sensor *sensor) apsReq.setTxOptions(deCONZ::ApsTxAcknowledgedTransmission); deCONZ::ZclFrame outZclFrame; - outZclFrame.setSequenceNumber(zclFrame.sequenceNumber()); + outZclFrame.setSequenceNumber(static_cast(QDateTime::currentMSecsSinceEpoch())); outZclFrame.setCommandId(0x02); // set long poll interval outZclFrame.setFrameControl(deCONZ::ZclFCClusterCommand | deCONZ::ZclFCDirectionClientToServer); diff --git a/rest_sensors.cpp b/rest_sensors.cpp index 522063de0c..81e785e07b 100644 --- a/rest_sensors.cpp +++ b/rest_sensors.cpp @@ -2721,7 +2721,7 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) if (strncmp(e.what(), "state/", 6) == 0) { ResourceItem *item = sensor->item(e.what()); - if (item) + if (item && item->isPublic()) { if (item->descriptor().suffix == RStatePresence && item->toBool()) { @@ -2779,7 +2779,7 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) { iy = item; } - else if (item->lastSet().isValid() && (gwWebSocketNotifyAll || rid.suffix == RStateButtonEvent || (item->lastChanged().isValid() && item->lastChanged() >= sensor->lastStatePush))) + else if (item->isPublic() && item->lastSet().isValid() && (gwWebSocketNotifyAll || rid.suffix == RStateButtonEvent || (item->lastChanged().isValid() && item->lastChanged() >= sensor->lastStatePush))) { state[key] = item->toVariant(); } @@ -2823,7 +2823,7 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) else if (strncmp(e.what(), "config/", 7) == 0) { ResourceItem *item = sensor->item(e.what()); - if (item) + if (item && item->isPublic()) { if (sensor->lastConfigPush.isValid() && item->lastSet() < sensor->lastConfigPush) @@ -2869,7 +2869,7 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) { ilct = item; } - else if (item->lastSet().isValid() && (gwWebSocketNotifyAll || (item->lastChanged().isValid() && item->lastChanged() >= sensor->lastConfigPush))) + else if (item->isPublic() && item->lastSet().isValid() && (gwWebSocketNotifyAll || (item->lastChanged().isValid() && item->lastChanged() >= sensor->lastConfigPush))) { if (rid.suffix == RConfigSchedule) { @@ -2909,7 +2909,7 @@ void DeRestPluginPrivate::handleSensorEvent(const Event &e) else if (strncmp(e.what(), "attr/", 5) == 0) { ResourceItem *item = sensor->item(e.what()); - if (item) + if (item && item->isPublic()) { QVariantMap map; map["t"] = QLatin1String("event");