From 99c10bb1911e799a54809571afc5f2ebc5617308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 29 Dec 2020 23:15:41 +0100 Subject: [PATCH 1/3] Add MainPowerOutlet to power socket generic class --- .../integrationpluginzigbeegeneric.cpp | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/zigbeegeneric/integrationpluginzigbeegeneric.cpp b/zigbeegeneric/integrationpluginzigbeegeneric.cpp index c2fac542..b2e22320 100644 --- a/zigbeegeneric/integrationpluginzigbeegeneric.cpp +++ b/zigbeegeneric/integrationpluginzigbeegeneric.cpp @@ -95,7 +95,9 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n if ((endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileLightLink && endpoint->deviceId() == Zigbee::LightLinkDevice::LightLinkDeviceOnOffPlugin) || (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && - endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffPlugin)) { + endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffPlugin) || + (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && + endpoint->deviceId() == Zigbee::HomeAutomationDeviceMainPowerOutlet)) { qCDebug(dcZigbeeGeneric()) << "Handeling power socket endpoint for" << node << endpoint; createThing(powerSocketThingClassId, networkUuid, node, endpoint); @@ -187,7 +189,7 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info) qCWarning(dcZigbeeGeneric()) << "Failed to read thermostat cluster"; return; } -// thermostatCluster->attribute(ZigbeeClusterLibrary::ClusterIdThermostat); + // thermostatCluster->attribute(ZigbeeClusterLibrary::ClusterIdThermostat); // We need to read them from the lamp ZigbeeClusterReply *reply = thermostatCluster->readAttributes({ZigbeeClusterThermostat::AttributeLocalTemperature, ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint}); @@ -239,15 +241,15 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info) }); connect(node, &ZigbeeNode::reachableChanged, thing, [=](bool reachable){ - if (reachable) { - ZigbeeClusterReply *reply = onOffCluster->readAttributes({ZigbeeClusterOnOff::AttributeOnOff}); - connect(reply, &ZigbeeClusterReply::finished, thing, [=](){ - if (reply->error() != ZigbeeClusterReply::ErrorNoError) { - qCWarning(dcZigbeeGeneric()) << "Reading attribute from" << thing << "finished with error" << reply->error(); - } - // Note: the state will be updated using the power changed signal from the cluster - }); - } + if (reachable) { + ZigbeeClusterReply *reply = onOffCluster->readAttributes({ZigbeeClusterOnOff::AttributeOnOff}); + connect(reply, &ZigbeeClusterReply::finished, thing, [=](){ + if (reply->error() != ZigbeeClusterReply::ErrorNoError) { + qCWarning(dcZigbeeGeneric()) << "Reading attribute from" << thing << "finished with error" << reply->error(); + } + // Note: the state will be updated using the power changed signal from the cluster + }); + } }); } else { qCWarning(dcZigbeeGeneric()) << "Could not find the OnOff input cluster on" << thing << endpoint; From 26f2be502981fe51abf7b68dcbcc0a52f6f1138f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 29 Dec 2020 23:18:30 +0100 Subject: [PATCH 2/3] Add smart plug and FIXME warning once smart metering is suppoerted --- zigbeegeneric/integrationpluginzigbeegeneric.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zigbeegeneric/integrationpluginzigbeegeneric.cpp b/zigbeegeneric/integrationpluginzigbeegeneric.cpp index b2e22320..43dc001c 100644 --- a/zigbeegeneric/integrationpluginzigbeegeneric.cpp +++ b/zigbeegeneric/integrationpluginzigbeegeneric.cpp @@ -97,8 +97,11 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffPlugin) || (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && - endpoint->deviceId() == Zigbee::HomeAutomationDeviceMainPowerOutlet)) { + endpoint->deviceId() == Zigbee::HomeAutomationDeviceMainPowerOutlet) || + (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && + endpoint->deviceId() == Zigbee::HomeAutomationDeviceSmartPlug)) { + // FIXME: create powersocket with metering for SmartPlug device ID qCDebug(dcZigbeeGeneric()) << "Handeling power socket endpoint for" << node << endpoint; createThing(powerSocketThingClassId, networkUuid, node, endpoint); handled = true; From b97b7c3ee34986a83cb40f6d9e5eccba5fa1d8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 30 Dec 2020 12:34:41 +0100 Subject: [PATCH 3/3] Improve generic power socket device creation and init power state reading --- .../integrationpluginzigbeegeneric.cpp | 43 +++++++++++++------ .../integrationpluginzigbeegeneric.h | 1 + 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/zigbeegeneric/integrationpluginzigbeegeneric.cpp b/zigbeegeneric/integrationpluginzigbeegeneric.cpp index 43dc001c..740ec69a 100644 --- a/zigbeegeneric/integrationpluginzigbeegeneric.cpp +++ b/zigbeegeneric/integrationpluginzigbeegeneric.cpp @@ -91,20 +91,20 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n handled = true; } - // Check on/off plug - if ((endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileLightLink && - endpoint->deviceId() == Zigbee::LightLinkDevice::LightLinkDeviceOnOffPlugin) || - (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && - endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffPlugin) || - (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && - endpoint->deviceId() == Zigbee::HomeAutomationDeviceMainPowerOutlet) || - (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && - endpoint->deviceId() == Zigbee::HomeAutomationDeviceSmartPlug)) { + // Check on/off thing + if ((endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileLightLink && endpoint->deviceId() == Zigbee::LightLinkDevice::LightLinkDeviceOnOffPlugin) || + (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffPlugin) || + (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceMainPowerOutlet) || + (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceSmartPlug)) { - // FIXME: create powersocket with metering for SmartPlug device ID - qCDebug(dcZigbeeGeneric()) << "Handeling power socket endpoint for" << node << endpoint; - createThing(powerSocketThingClassId, networkUuid, node, endpoint); - handled = true; + // Simple on/off device + if (endpoint->hasInputCluster(ZigbeeClusterLibrary::ClusterIdOnOff)) { + // FIXME: create powersocket with metering for SmartPlug device ID + qCDebug(dcZigbeeGeneric()) << "Handeling power socket endpoint for" << node << endpoint; + createThing(powerSocketThingClassId, networkUuid, node, endpoint); + initSimplePowerSocket(node, endpoint); + handled = true; + } } // Check door lock @@ -455,6 +455,23 @@ void IntegrationPluginZigbeeGeneric::createThing(const ThingClassId &thingClassI emit autoThingsAppeared({descriptor}); } +void IntegrationPluginZigbeeGeneric::initSimplePowerSocket(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint) +{ + // Get the on/off server cluster from the endpoint + ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster(ZigbeeClusterLibrary::ClusterIdOnOff); + if (!onOffCluster) + return; + + qCDebug(dcZigbeeGeneric()) << "Reading on/off power value for" << node << endpoint; + ZigbeeClusterReply *reply = onOffCluster->readAttributes({ZigbeeClusterOnOff::AttributeOnOff}); + connect(reply, &ZigbeeClusterReply::finished, node, [=](){ + if (reply->error() != ZigbeeClusterReply::ErrorNoError) { + qCWarning(dcZigbeeGeneric()) << "Failed to read on/off cluster attribute from" << node << endpoint << reply->error(); + return; + } + }); +} + void IntegrationPluginZigbeeGeneric::initializeDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint) { qCDebug(dcZigbeeGeneric()) << "Read power configuration cluster attributes" << node; diff --git a/zigbeegeneric/integrationpluginzigbeegeneric.h b/zigbeegeneric/integrationpluginzigbeegeneric.h index 788c7d26..cf90c3f6 100644 --- a/zigbeegeneric/integrationpluginzigbeegeneric.h +++ b/zigbeegeneric/integrationpluginzigbeegeneric.h @@ -73,6 +73,7 @@ private: ZigbeeNodeEndpoint *findEndpoint(Thing *thing); void createThing(const ThingClassId &thingClassId, const QUuid &networkUuid, ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint); + void initSimplePowerSocket(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint); void initializeDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint); };