Add philips hue zigbee plugin with hue dimmer switch support

master
Simon Stürz 2020-11-26 18:22:55 +01:00
parent 3d365d2c57
commit 10cc4ed8db
9 changed files with 540 additions and 6 deletions

18
debian/control vendored
View File

@ -1061,6 +1061,23 @@ Description: nymea.io zigbee plugin for different generic recognizable lights
.
This package will install the nymea.io plugin for generic recognizable lights
Package: nymea-plugin-zigbee-philipshue
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
libnymea-zigbee1,
nymea-plugins-translations,
Description: nymea.io zigbee plugin for Philips Hue devices
The nymea daemon is a plugin based IoT (Internet of Things) server. The
server works like a translator for devices, things and services and
allows them to interact.
With the powerful rule engine you are able to connect any device available
in the system and create individual scenes and behaviors for your environment.
.
This package will install the nymea.io plugin for Philips Hue zigbee devices
Package: nymea-plugin-zigbee-tradfri
Architecture: any
Depends: ${shlibs:Depends},
@ -1149,6 +1166,7 @@ Architecture: all
Depends: nymea-plugin-zigbee-lumi,
nymea-plugin-zigbee-generic,
nymea-plugin-zigbee-generic-lights,
nymea-plugin-zigbee-philipshue,
nymea-plugin-zigbee-tradfri
Description: Zigbee plugins for nymea IoT server - meta package for all zigbee replated plugins
The nymea daemon is a plugin based IoT (Internet of Things) server. The

View File

@ -0,0 +1 @@
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginzigbee-philipshue.so

View File

@ -67,6 +67,7 @@ PLUGIN_DIRS = \
zigbee-generic \
zigbee-generic-lights \
zigbee-lumi \
zigbee-philipshue \
zigbee-tradfri \

View File

@ -0,0 +1,107 @@
{
"name": "ZigbeePhilipsHue",
"displayName": "Zigbee Philips Hue",
"id": "0ca340b7-061a-42e6-ab7d-d7b4fd235d02",
"vendors": [
{
"id": "0ae1e001-2aa6-47ed-b8c0-334c3728a68f",
"name": "philips",
"displayName": "Philips",
"thingClasses": [
{
"name": "dimmerSwitch",
"displayName": "Hue dimmer switch",
"id": "b2711164-a848-4715-8ddf-33ca86f9f4cf",
"setupMethod": "JustAdd",
"createMethods": [ "Auto" ],
"interfaces": [ "multibutton", "batterylevel", "wirelessconnectable" ],
"paramTypes": [
{
"id": "b221cad1-ef2e-4192-8168-11d0205a43da",
"name": "ieeeAddress",
"displayName": "IEEE adress",
"type": "QString",
"defaultValue": "00:00:00:00:00:00:00:00"
},
{
"id": "d2bb97ee-caed-4776-8931-9fc0a04e4e8f",
"name": "networkUuid",
"displayName": "Zigbee network UUID",
"type": "QString",
"defaultValue": ""
}
],
"stateTypes": [
{
"id": "5ac101b2-4bb7-4b5c-8493-08b1ae7ca0c1",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"type": "bool",
"cached": false,
"defaultValue": false
},
{
"id": "5a6e325e-a6ee-4a36-b429-f5d8c8adb80b",
"name": "signalStrength",
"displayName": "Signal strength",
"displayNameEvent": "Signal strength changed",
"defaultValue": 0,
"maxValue": 100,
"minValue": 0,
"type": "uint",
"unit": "Percentage"
},
{
"id": "12139630-668a-4ad8-96fa-781028e9eced",
"name": "version",
"displayName": "Version",
"displayNameEvent": "Version changed",
"type": "QString",
"cached": true,
"defaultValue": ""
},
{
"id": "3e28e0b3-fe23-4293-8876-8384def6c4fb",
"name": "batteryLevel",
"displayName": "Battery",
"displayNameEvent": "Battery changed",
"type": "int",
"unit": "Percentage",
"defaultValue": 0,
"minValue": 0,
"maxValue": 100
},
{
"id": "4223a3bc-9616-4ed2-ae50-704b9df62d0e",
"name": "batteryCritical",
"displayName": "Battery critical",
"displayNameEvent": "Battery critical changed",
"type": "bool",
"defaultValue": false
}
],
"actionTypes": [
],
"eventTypes": [
{
"id": "33bb5816-8479-4995-99e2-cb0443886003",
"name": "pressed",
"displayName": "Button pressed",
"paramTypes": [
{
"id": "c086a247-838f-49c0-b1e4-2ae1ed181b55",
"name": "buttonName",
"displayName": "Button name",
"type": "QString",
"allowedValues": ["ON", "OFF", "DIM UP", "DIM DOWN"]
}
]
}
]
}
]
}
]
}

View File

@ -0,0 +1,321 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "integrationpluginzigbeephilipshue.h"
#include "plugininfo.h"
#include "hardware/zigbee/zigbeehardwareresource.h"
IntegrationPluginZigbeePhilipsHue::IntegrationPluginZigbeePhilipsHue()
{
m_ieeeAddressParamTypeIds[dimmerSwitchThingClassId] = dimmerSwitchThingIeeeAddressParamTypeId;
m_networkUuidParamTypeIds[dimmerSwitchThingClassId] = dimmerSwitchThingNetworkUuidParamTypeId;
m_connectedStateTypeIds[dimmerSwitchThingClassId] = dimmerSwitchConnectedStateTypeId;
m_signalStrengthStateTypeIds[dimmerSwitchThingClassId] = dimmerSwitchSignalStrengthStateTypeId;
m_versionStateTypeIds[dimmerSwitchThingClassId] = dimmerSwitchVersionStateTypeId;
}
QString IntegrationPluginZigbeePhilipsHue::name() const
{
return "Philips Hue";
}
bool IntegrationPluginZigbeePhilipsHue::handleNode(ZigbeeNode *node, const QUuid &networkUuid)
{
// Make sure this is from Philips 0x100b
if (node->nodeDescriptor().manufacturerCode != Zigbee::Philips)
return false;
bool handled = false;
if (node->endpoints().count() == 2 && node->hasEndpoint(0x01) && node->hasEndpoint(0x02)) {
ZigbeeNodeEndpoint *endpointOne = node->getEndpoint(0x01);
ZigbeeNodeEndpoint *endpoinTwo = node->getEndpoint(0x02);
// Dimmer switch
if (endpointOne->profile() == Zigbee::ZigbeeProfileLightLink &&
endpointOne->deviceId() == Zigbee::LightLinkDeviceNonColourSceneController
&& endpoinTwo->profile() == Zigbee::ZigbeeProfileHomeAutomation &&
endpoinTwo->deviceId() == Zigbee::HomeAutomationDeviceSimpleSensor) {
qCDebug(dcZigbeePhilipsHue()) << "Handeling Hue dimmer switch" << node << endpointOne << endpoinTwo;
createThing(dimmerSwitchThingClassId, networkUuid, node);
initDimmerSwitch(node);
return true;
}
}
return handled;
}
void IntegrationPluginZigbeePhilipsHue::handleRemoveNode(ZigbeeNode *node, const QUuid &networkUuid)
{
Q_UNUSED(networkUuid)
if (m_thingNodes.values().contains(node)) {
Thing *thing = m_thingNodes.key(node);
qCDebug(dcZigbeePhilipsHue()) << node << "for" << thing << "has left the network.";
m_thingNodes.remove(thing);
emit autoThingDisappeared(thing->id());
}
}
void IntegrationPluginZigbeePhilipsHue::init()
{
hardwareManager()->zigbeeResource()->registerHandler(this, ZigbeeHardwareResource::HandlerTypeVendor);
}
void IntegrationPluginZigbeePhilipsHue::setupThing(ThingSetupInfo *info)
{
Thing *thing = info->thing();
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(m_ieeeAddressParamTypeIds.value(thing->thingClassId())).toString());
ZigbeeNode *node = hardwareManager()->zigbeeResource()->claimNode(this, networkUuid, zigbeeAddress);
if (!node) {
qCWarning(dcZigbeePhilipsHue()) << "Zigbee node for" << info->thing()->name() << "not found.";
info->finish(Thing::ThingErrorHardwareNotAvailable);
return;
}
m_thingNodes.insert(thing, node);
// Update connected state
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), node->reachable());
connect(node, &ZigbeeNode::reachableChanged, thing, [thing, this](bool reachable){
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), reachable);
});
// Update signal strength
thing->setStateValue(m_signalStrengthStateTypeIds.value(thing->thingClassId()), qRound(node->lqi() * 100.0 / 255.0));
connect(node, &ZigbeeNode::lqiChanged, thing, [this, thing](quint8 lqi){
uint signalStrength = qRound(lqi * 100.0 / 255.0);
qCDebug(dcZigbeePhilipsHue()) << thing << "signal strength changed" << signalStrength << "%";
thing->setStateValue(m_signalStrengthStateTypeIds.value(thing->thingClassId()), signalStrength);
});
// Thing specific setup
if (thing->thingClassId() == dimmerSwitchThingClassId) {
ZigbeeNodeEndpoint *endpointZll = node->getEndpoint(0x01);
ZigbeeNodeEndpoint *endpointHa = node->getEndpoint(0x02);
// Set the version
thing->setStateValue(m_versionStateTypeIds.value(thing->thingClassId()), endpointZll->softwareBuildId());
// Receive on/off commands
ZigbeeClusterOnOff *onOffCluster = endpointZll->outputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
if (!onOffCluster) {
qCWarning(dcZigbeePhilipsHue()) << "Could not find on/off client cluster on" << thing << endpointZll;
} else {
connect(onOffCluster, &ZigbeeClusterOnOff::commandSent, thing, [=](ZigbeeClusterOnOff::Command command){
if (command == ZigbeeClusterOnOff::CommandOn) {
qCDebug(dcZigbeePhilipsHue()) << thing << "pressed ON";
emit emitEvent(Event(dimmerSwitchPressedEventTypeId, thing->id(), ParamList() << Param(dimmerSwitchPressedEventButtonNameParamTypeId, "ON")));
} else {
qCWarning(dcZigbeePhilipsHue()) << thing << "unhandled command received" << command;
}
});
connect(onOffCluster, &ZigbeeClusterOnOff::commandOffWithEffectSent, thing, [=](ZigbeeClusterOnOff::Effect effect, quint8 effectVariant){
qCDebug(dcZigbeePhilipsHue()) << thing << "OFF button pressed" << effect << effectVariant;
emit emitEvent(Event(dimmerSwitchPressedEventTypeId, thing->id(), ParamList() << Param(dimmerSwitchPressedEventButtonNameParamTypeId, "OFF")));
});
}
// Receive level control commands
ZigbeeClusterLevelControl *levelCluster = endpointZll->outputCluster<ZigbeeClusterLevelControl>(ZigbeeClusterLibrary::ClusterIdLevelControl);
if (!levelCluster) {
qCWarning(dcZigbeePhilipsHue()) << "Could not find level client cluster on" << thing << endpointZll;
} else {
connect(levelCluster, &ZigbeeClusterLevelControl::commandStepSent, thing, [=](ZigbeeClusterLevelControl::FadeMode fadeMode, quint8 stepSize, quint16 transitionTime){
qCDebug(dcZigbeePhilipsHue()) << thing << "level button pressed" << fadeMode << stepSize << transitionTime;
switch (fadeMode) {
case ZigbeeClusterLevelControl::FadeModeUp:
qCDebug(dcZigbeePhilipsHue()) << thing << "DIM UP pressed";
emit emitEvent(Event(dimmerSwitchPressedEventTypeId, thing->id(), ParamList() << Param(dimmerSwitchPressedEventButtonNameParamTypeId, "DIM UP")));
break;
case ZigbeeClusterLevelControl::FadeModeDown:
qCDebug(dcZigbeePhilipsHue()) << thing << "DIM DOWN pressed";
emit emitEvent(Event(dimmerSwitchPressedEventTypeId, thing->id(), ParamList() << Param(dimmerSwitchPressedEventButtonNameParamTypeId, "DIM DOWN")));
break;
}
});
}
// Get battery level changes
ZigbeeClusterPowerConfiguration *powerCluster = endpointHa->inputCluster<ZigbeeClusterPowerConfiguration>(ZigbeeClusterLibrary::ClusterIdPowerConfiguration);
if (!powerCluster) {
qCWarning(dcZigbeePhilipsHue()) << "Could not find power configuration cluster on" << thing << endpointHa;
} else {
// Only set the initial state if the attribute already exists
if (powerCluster->hasAttribute(ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining)) {
thing->setStateValue(dimmerSwitchBatteryLevelStateTypeId, powerCluster->batteryPercentage());
thing->setStateValue(dimmerSwitchBatteryCriticalStateTypeId, (powerCluster->batteryPercentage() < 10.0));
}
connect(powerCluster, &ZigbeeClusterPowerConfiguration::batteryPercentageChanged, thing, [=](double percentage){
qCDebug(dcZigbeePhilipsHue()) << "Battery percentage changed" << percentage << "%" << thing;
thing->setStateValue(dimmerSwitchBatteryLevelStateTypeId, percentage);
thing->setStateValue(dimmerSwitchBatteryCriticalStateTypeId, (percentage < 10.0));
});
}
}
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginZigbeePhilipsHue::executeAction(ThingActionInfo *info)
{
info->finish(Thing::ThingErrorUnsupportedFeature);
}
void IntegrationPluginZigbeePhilipsHue::thingRemoved(Thing *thing)
{
ZigbeeNode *node = m_thingNodes.take(thing);
if (node) {
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
hardwareManager()->zigbeeResource()->removeNodeFromNetwork(networkUuid, node);
}
}
void IntegrationPluginZigbeePhilipsHue::createThing(const ThingClassId &thingClassId, const QUuid &networkUuid, ZigbeeNode *node)
{
ThingDescriptor descriptor(thingClassId);
QString deviceClassName = supportedThings().findById(thingClassId).displayName();
descriptor.setTitle(deviceClassName);
ParamList params;
params.append(Param(m_networkUuidParamTypeIds[thingClassId], networkUuid.toString()));
params.append(Param(m_ieeeAddressParamTypeIds[thingClassId], node->extendedAddress().toString()));
descriptor.setParams(params);
emit autoThingsAppeared({descriptor});
}
void IntegrationPluginZigbeePhilipsHue::initDimmerSwitch(ZigbeeNode *node)
{
ZigbeeNodeEndpoint *endpointZll = node->getEndpoint(0x01);
ZigbeeNodeEndpoint *endpointHa = node->getEndpoint(0x02);
// Get the current configured bindings for this node
ZigbeeReply *reply = node->removeAllBindings();
connect(reply, &ZigbeeReply::finished, node, [=](){
if (reply->error() != ZigbeeReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to remove all bindings for initialization of" << node;
}
// Read battery, bind and configure attribute reporting for battery
if (!endpointHa->hasInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to initialize the power configuration cluster because the cluster could not be found" << node << endpointHa;
return;
}
qCDebug(dcZigbeePhilipsHue()) << "Read power configuration cluster attributes" << node;
ZigbeeClusterReply *readAttributeReply = endpointHa->getInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)->readAttributes({ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining});
connect(readAttributeReply, &ZigbeeClusterReply::finished, node, [=](){
if (readAttributeReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to read power cluster attributes" << readAttributeReply->error();
//emit nodeInitialized(node);
return;
}
qCDebug(dcZigbeePhilipsHue()) << "Read power configuration cluster attributes finished successfully";
// Bind the cluster to the coordinator
qCDebug(dcZigbeePhilipsHue()) << "Bind power configuration cluster to coordinator IEEE address";
ZigbeeDeviceObjectReply * zdoReply = node->deviceObject()->requestBindIeeeAddress(endpointHa->endpointId(), ZigbeeClusterLibrary::ClusterIdPowerConfiguration,
hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to bind power cluster to coordinator" << zdoReply->error();
return;
}
qCDebug(dcZigbeePhilipsHue()) << "Bind power configuration cluster to coordinator finished successfully";
// Configure attribute rporting for battery remaining (0.5 % changes = 1)
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
reportingConfig.dataType = Zigbee::Uint8;
reportingConfig.minReportingInterval = 300;
reportingConfig.maxReportingInterval = 2700;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeePhilipsHue()) << "Configure attribute reporting for power configuration cluster to coordinator";
ZigbeeClusterReply *reportingReply = endpointHa->getInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)->configureReporting({reportingConfig});
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to configure power cluster attribute reporting" << reportingReply->error();
return;
}
qCDebug(dcZigbeePhilipsHue()) << "Attribute reporting configuration finished for power cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
qCDebug(dcZigbeePhilipsHue()) << "Bind on/off cluster to coordinator";
ZigbeeDeviceObjectReply * zdoReply = node->deviceObject()->requestBindShortAddress(endpointZll->endpointId(), ZigbeeClusterLibrary::ClusterIdOnOff, 0x0000);
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to bind on/off cluster to coordinator" << zdoReply->error();
return;
}
qCDebug(dcZigbeePhilipsHue()) << "Bind on/off cluster to coordinator finished successfully";
qCDebug(dcZigbeePhilipsHue()) << "Bind power level cluster to coordinator";
ZigbeeDeviceObjectReply * zdoReply = node->deviceObject()->requestBindShortAddress(endpointZll->endpointId(), ZigbeeClusterLibrary::ClusterIdLevelControl, 0x0000);
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to bind level cluster to coordinator" << zdoReply->error();
return;
}
qCDebug(dcZigbeePhilipsHue()) << "Bind level cluster to coordinator finished successfully";
qCDebug(dcZigbeePhilipsHue()) << "Read binding table from node" << node;
ZigbeeReply *reply = node->readBindingTableEntries();
connect(reply, &ZigbeeReply::finished, node, [=](){
if (reply->error() != ZigbeeReply::ErrorNoError) {
qCWarning(dcZigbeePhilipsHue()) << "Failed to read binding table from" << node;
} else {
foreach (const ZigbeeDeviceProfile::BindingTableListRecord &binding, node->bindingTableRecords()) {
qCDebug(dcZigbeePhilipsHue()) << node << binding;
}
}
});
});
});
});
});
});
});
}

View File

@ -0,0 +1,76 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef INTEGRATIONPLUGINZIGBEEPHILIPSHUE_H
#define INTEGRATIONPLUGINZIGBEEPHILIPSHUE_H
#include "integrations/integrationplugin.h"
#include "hardware/zigbee/zigbeehandler.h"
#include "plugintimer.h"
#include <QTimer>
class IntegrationPluginZigbeePhilipsHue: public IntegrationPlugin, public ZigbeeHandler
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginzigbee-philipshue.json")
Q_INTERFACES(IntegrationPlugin)
public:
explicit IntegrationPluginZigbeePhilipsHue();
QString name() const override;
bool handleNode(ZigbeeNode *node, const QUuid &networkUuid) override;
void handleRemoveNode(ZigbeeNode *node, const QUuid &networkUuid) override;
void init() override;
void setupThing(ThingSetupInfo *info) override;
void executeAction(ThingActionInfo *info) override;
void thingRemoved(Thing *thing) override;
private:
PluginTimer *m_presenceTimer = nullptr;
QHash<Thing*, ZigbeeNode*> m_thingNodes;
QHash<ThingClassId, ParamTypeId> m_ieeeAddressParamTypeIds;
QHash<ThingClassId, ParamTypeId> m_networkUuidParamTypeIds;
QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds;
QHash<ThingClassId, StateTypeId> m_signalStrengthStateTypeIds;
QHash<ThingClassId, StateTypeId> m_versionStateTypeIds;
void createThing(const ThingClassId &thingClassId, const QUuid &networkUuid, ZigbeeNode *node);
void initDimmerSwitch(ZigbeeNode *node);
};
#endif // INTEGRATIONPLUGINZIGBEEPHILIPSHUE_H

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE TS><TS version="2.1"></TS>

View File

@ -0,0 +1,9 @@
include(../plugins.pri)
PKGCONFIG += nymea-zigbee
SOURCES += \
integrationpluginzigbeephilipshue.cpp
HEADERS += \
integrationpluginzigbeephilipshue.h

View File

@ -394,8 +394,8 @@ void IntegrationPluginZigbeeTradfri::initOnOffSwitch(ZigbeeNode *node, ZigbeeNod
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
reportingConfig.dataType = Zigbee::Uint8;
reportingConfig.minReportingInterval = 60;//300;
reportingConfig.maxReportingInterval = 120;//2700;
reportingConfig.minReportingInterval = 300;
reportingConfig.maxReportingInterval = 2700;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeTradfri()) << "Configure attribute reporting for power configuration cluster to coordinator";
@ -487,8 +487,8 @@ void IntegrationPluginZigbeeTradfri::initRemote(ZigbeeNode *node, ZigbeeNodeEndp
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
reportingConfig.dataType = Zigbee::Uint8;
reportingConfig.minReportingInterval = 60;//300;
reportingConfig.maxReportingInterval = 120;//2700;
reportingConfig.minReportingInterval = 300;
reportingConfig.maxReportingInterval = 2700;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeTradfri()) << "Configure attribute reporting for power configuration cluster to coordinator";
@ -585,8 +585,8 @@ void IntegrationPluginZigbeeTradfri::initPowerConfigurationCluster(ZigbeeNode *n
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
reportingConfig.dataType = Zigbee::Uint8;
reportingConfig.minReportingInterval = 60;//300;
reportingConfig.maxReportingInterval = 120;//2700;
reportingConfig.minReportingInterval = 300;
reportingConfig.maxReportingInterval = 2700;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeTradfri()) << "Configure attribute reporting for power configuration cluster to coordinator";