mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-07-14 00:12:27 +02:00
Add zigbee debian packages and introduce nymea-plugins-zigbee metapackage
This commit is contained in:
parent
07b27c2272
commit
694f7c8c99
65
debian/control
vendored
65
debian/control
vendored
@ -6,6 +6,7 @@ Build-depends: libboblight-dev,
|
||||
debhelper (>= 0.0.0),
|
||||
libnymea1-dev (>= 0.17),
|
||||
libnymea-mqtt-dev,
|
||||
libnymea-zigbee-dev,
|
||||
libqt5serialport5-dev,
|
||||
libqt5websockets5-dev,
|
||||
nymea-dev-tools:native,
|
||||
@ -1013,6 +1014,54 @@ Description: nymea.io plugin to connect to your Tado account
|
||||
This package will install the nymea.io plugin for Tado
|
||||
|
||||
|
||||
Package: nymea-plugin-zigbee-lumi
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libnymea-zigbee1,
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io zigbee plugin for lumi/aquara/xiaomi things
|
||||
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 Lumi
|
||||
|
||||
|
||||
Package: nymea-plugin-zigbee-generic
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libnymea-zigbee1,
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io zigbee plugin for different generic recognizable 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 generic recognizable zigbee devices
|
||||
|
||||
|
||||
Package: nymea-plugin-zigbee-generic-lights
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libnymea-zigbee1,
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io zigbee plugin for different generic recognizable lights
|
||||
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 generic recognizable lights
|
||||
|
||||
|
||||
Package: nymea-plugins-translations
|
||||
Section: misc
|
||||
Architecture: all
|
||||
@ -1079,6 +1128,21 @@ Description: Plugins for nymea IoT server - the default plugin collection
|
||||
.
|
||||
This package will install the default nymea plugins.
|
||||
|
||||
Package: nymea-plugins-zigbee
|
||||
Section: libs
|
||||
Architecture: all
|
||||
Depends: nymea-plugin-zigbee-lumi,
|
||||
nymea-plugin-zigbee-generic,
|
||||
nymea-plugin-zigbee-generic-lights
|
||||
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
|
||||
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 all nymea zigbee related plugins.
|
||||
|
||||
|
||||
Package: nymea-plugins-maker
|
||||
Section: libs
|
||||
@ -1125,6 +1189,7 @@ Package: nymea-plugins-all
|
||||
Section: libs
|
||||
Architecture: all
|
||||
Depends: nymea-plugins,
|
||||
nymea-plugins-zigbee,
|
||||
nymea-plugin-simulation,
|
||||
nymea-plugin-snapd,
|
||||
nymea-plugins-maker,
|
||||
|
||||
1
debian/nymea-plugin-zigbee-generic-lights.install.in
vendored
Normal file
1
debian/nymea-plugin-zigbee-generic-lights.install.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginzigbee-generic-lights.so
|
||||
1
debian/nymea-plugin-zigbee-generic.install.in
vendored
Normal file
1
debian/nymea-plugin-zigbee-generic.install.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginzigbee-generic.so
|
||||
1
debian/nymea-plugin-zigbee-lumi.install.in
vendored
Normal file
1
debian/nymea-plugin-zigbee-lumi.install.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginzigbee-lumi.so
|
||||
@ -65,6 +65,7 @@ PLUGIN_DIRS = \
|
||||
wemo \
|
||||
ws2812fx \
|
||||
zigbee-generic \
|
||||
zigbee-generic-lights \
|
||||
zigbee-lumi \
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
{
|
||||
"name": "ZigbeeGenericLights",
|
||||
"displayName": "Zigbee Generic Lights",
|
||||
"id": "ee67f87d-d4cc-4223-a9f3-79e47c0267e0",
|
||||
"vendors": [
|
||||
{
|
||||
"name": "nymea",
|
||||
"displayName": "nymea",
|
||||
"id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6",
|
||||
"thingClasses": [
|
||||
{
|
||||
"name": "onOffLight",
|
||||
"displayName": "On/Off Light",
|
||||
"id": "7fbc3165-e618-4dc0-8255-8dac2cc08dfa",
|
||||
"setupMethod": "JustAdd",
|
||||
"createMethods": [ "Auto" ],
|
||||
"interfaces": [ "light", "alert", "wirelessconnectable" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "1b434d5d-4fe4-439c-b842-3483e8e24820",
|
||||
"name": "ieeeAddress",
|
||||
"displayName": "IEEE address",
|
||||
"type": "QString",
|
||||
"defaultValue": "00:00:00:00:00:00:00:00"
|
||||
},
|
||||
{
|
||||
"id": "b3e298de-140c-4d3d-be81-0a9792359275",
|
||||
"name": "networkUuid",
|
||||
"displayName": "Zigbee network UUID",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "fd8a6ae6-202b-4634-824f-8d4b187430fa",
|
||||
"name": "endpointId",
|
||||
"displayName": "Endpoint ID",
|
||||
"type": "uint",
|
||||
"defaultValue": 1
|
||||
},
|
||||
{
|
||||
"id": "acb5e910-ed8b-4968-972e-5fc57f466b8a",
|
||||
"name": "manufacturer",
|
||||
"displayName": "Manufacturer",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "3d942b2d-302a-4c42-8cf5-be2865736736",
|
||||
"name": "model",
|
||||
"displayName": "Model",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "7548ac08-4ea1-4dcd-98b9-9d58bbc06ab7",
|
||||
"name": "connected",
|
||||
"displayName": "Available",
|
||||
"displayNameEvent": "Available changed",
|
||||
"type": "bool",
|
||||
"cached": false,
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "5857943e-ed90-4321-966e-b56eddaf2441",
|
||||
"name": "signalStrength",
|
||||
"displayName": "Signal strength",
|
||||
"displayNameEvent": "Signal strength changed",
|
||||
"defaultValue": 0,
|
||||
"maxValue": 100,
|
||||
"minValue": 0,
|
||||
"type": "uint",
|
||||
"unit": "Percentage"
|
||||
},
|
||||
{
|
||||
"id": "f5b5e0b3-2c34-4ccc-baef-8e29b84e7a2b",
|
||||
"name": "version",
|
||||
"displayName": "Version",
|
||||
"displayNameEvent": "Version changed",
|
||||
"type": "QString",
|
||||
"cached": true,
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "ae03155c-f17f-4d9f-bb40-157a8cb1f83c",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "9388290d-5db2-484a-a702-53a0d842d412",
|
||||
"name": "alert",
|
||||
"displayName": "Identify"
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
261
zigbee-generic-lights/integrationpluginzigbeegenericlights.cpp
Normal file
261
zigbee-generic-lights/integrationpluginzigbeegenericlights.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
*
|
||||
* 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 "integrationpluginzigbeegenericlights.h"
|
||||
#include "plugininfo.h"
|
||||
#include "hardware/zigbee/zigbeehardwareresource.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
IntegrationPluginZigbeeGenericLights::IntegrationPluginZigbeeGenericLights()
|
||||
{
|
||||
m_ieeeAddressParamTypeIds[onOffLightThingClassId] = onOffLightThingIeeeAddressParamTypeId;
|
||||
|
||||
m_networkUuidParamTypeIds[onOffLightThingClassId] = onOffLightThingNetworkUuidParamTypeId;
|
||||
|
||||
m_endpointIdParamTypeIds[onOffLightThingClassId] = onOffLightThingEndpointIdParamTypeId;
|
||||
|
||||
m_connectedStateTypeIds[onOffLightThingClassId] = onOffLightConnectedStateTypeId;
|
||||
|
||||
m_signalStrengthStateTypeIds[onOffLightThingClassId] = onOffLightSignalStrengthStateTypeId;
|
||||
|
||||
m_versionStateTypeIds[onOffLightThingClassId] = onOffLightVersionStateTypeId;
|
||||
}
|
||||
|
||||
QString IntegrationPluginZigbeeGenericLights::name() const
|
||||
{
|
||||
return "Generic lights";
|
||||
}
|
||||
|
||||
bool IntegrationPluginZigbeeGenericLights::handleNode(ZigbeeNode *node, const QUuid &networkUuid)
|
||||
{
|
||||
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
|
||||
if ((endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileLightLink &&
|
||||
endpoint->deviceId() == Zigbee::LightLinkDevice::LightLinkDeviceOnOffLight) ||
|
||||
(endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation &&
|
||||
endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffLight)) {
|
||||
|
||||
ThingDescriptor descriptor(onOffLightThingClassId);
|
||||
QString deviceClassName = supportedThings().findById(onOffLightThingClassId).displayName();
|
||||
descriptor.setTitle(QString("%1 (%2 - %3)").arg(deviceClassName).arg(endpoint->manufacturerName()).arg(endpoint->modelIdentifier()));
|
||||
qCDebug(dcZigbeeGenericLights()) << "Handeling generic on/off light" << descriptor.title();
|
||||
|
||||
ParamList params;
|
||||
params.append(Param(onOffLightThingNetworkUuidParamTypeId, networkUuid.toString()));
|
||||
params.append(Param(onOffLightThingIeeeAddressParamTypeId, node->extendedAddress().toString()));
|
||||
params.append(Param(onOffLightThingEndpointIdParamTypeId, endpoint->endpointId()));
|
||||
params.append(Param(onOffLightThingModelParamTypeId, endpoint->modelIdentifier()));
|
||||
params.append(Param(onOffLightThingManufacturerParamTypeId, endpoint->manufacturerName()));
|
||||
descriptor.setParams(params);
|
||||
emit autoThingsAppeared({descriptor});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGenericLights::handleRemoveNode(ZigbeeNode *node, const QUuid &networkUuid)
|
||||
{
|
||||
Q_UNUSED(networkUuid)
|
||||
|
||||
if (m_thingNodes.values().contains(node)) {
|
||||
Thing *thing = m_thingNodes.key(node);
|
||||
qCDebug(dcZigbeeGenericLights()) << node << "for" << thing << "has left the network.";
|
||||
m_thingNodes.remove(thing);
|
||||
emit autoThingDisappeared(thing->id());
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGenericLights::init()
|
||||
{
|
||||
hardwareManager()->zigbeeResource()->registerHandler(this, ZigbeeHardwareResource::HandlerTypeCatchAll);
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGenericLights::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
|
||||
// Get the node for this 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()->getNode(networkUuid, zigbeeAddress);
|
||||
if (!node) {
|
||||
qCWarning(dcZigbeeGenericLights()) << "Zigbee node for" << info->thing()->name() << "not found.´";
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the node thing association for removing
|
||||
m_thingNodes.insert(thing, node);
|
||||
|
||||
// Get the endpoint for this thing
|
||||
ZigbeeNodeEndpoint *endpoint = findEndpoint(thing);
|
||||
if (!endpoint) {
|
||||
qCWarning(dcZigbeeGenericLights()) << "Unable to get the endpoint from node" << node << "for" << thing;
|
||||
info->finish(Thing::ThingErrorSetupFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
// General thing setup
|
||||
|
||||
// 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(dcZigbeeGenericLights()) << thing << "signal strength changed" << signalStrength << "%";
|
||||
thing->setStateValue(m_signalStrengthStateTypeIds.value(thing->thingClassId()), signalStrength);
|
||||
});
|
||||
|
||||
// Set the version
|
||||
thing->setStateValue(m_versionStateTypeIds.value(thing->thingClassId()), endpoint->softwareBuildId());
|
||||
|
||||
// Thing specific setup
|
||||
if (thing->thingClassId() == onOffLightThingClassId) {
|
||||
|
||||
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
|
||||
if (!onOffCluster) {
|
||||
qCWarning(dcZigbeeGenericLights()) << "Could not find on/off cluster for" << thing << "in" << node;
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
connect(onOffCluster, &ZigbeeClusterOnOff::powerChanged, thing, [thing](bool power){
|
||||
qCDebug(dcZigbeeGenericLights()) << thing << "power state changed" << power;
|
||||
thing->setStateValue(onOffLightPowerStateTypeId, power);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGenericLights::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
if (!hardwareManager()->zigbeeResource()->available()) {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the node
|
||||
Thing *thing = info->thing();
|
||||
ZigbeeNode *node = m_thingNodes.value(thing);
|
||||
if (!node->reachable()) {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the endpoint
|
||||
ZigbeeNodeEndpoint *endpoint = findEndpoint(thing);
|
||||
if (!endpoint) {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == onOffLightThingClassId) {
|
||||
|
||||
if (info->action().actionTypeId() == onOffLightAlertActionTypeId) {
|
||||
// Get the identify server cluster from the endpoint
|
||||
ZigbeeClusterIdentify *identifyCluster = endpoint->inputCluster<ZigbeeClusterIdentify>(ZigbeeClusterLibrary::ClusterIdIdentify);
|
||||
if (!identifyCluster) {
|
||||
qCWarning(dcZigbeeGenericLights()) << "Could not find identify cluster for" << thing << "in" << node;
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the command trough the network
|
||||
ZigbeeClusterReply *reply = identifyCluster->identify(2);
|
||||
connect(reply, &ZigbeeClusterReply::finished, this, [reply, info](){
|
||||
// Note: reply will be deleted automatically
|
||||
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->action().actionTypeId() == onOffLightPowerActionTypeId) {
|
||||
// Get the identify server cluster from the endpoint
|
||||
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
|
||||
if (!onOffCluster) {
|
||||
qCWarning(dcZigbeeGenericLights()) << "Could not find on/off cluster for" << thing << "in" << node;
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the command trough the network
|
||||
bool power = info->action().param(onOffLightPowerActionPowerParamTypeId).value().toBool();
|
||||
ZigbeeClusterReply *reply = (power ? onOffCluster->commandOn() : onOffCluster->commandOff());
|
||||
connect(reply, &ZigbeeClusterReply::finished, thing, [reply, info, power, thing](){
|
||||
// Note: reply will be deleted automatically
|
||||
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
thing->setStateValue(onOffLightPowerStateTypeId, power);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info->finish(Thing::ThingErrorUnsupportedFeature);
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGenericLights::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);
|
||||
}
|
||||
}
|
||||
|
||||
ZigbeeNodeEndpoint *IntegrationPluginZigbeeGenericLights::findEndpoint(Thing *thing)
|
||||
{
|
||||
ZigbeeNode *node = m_thingNodes.value(thing);
|
||||
if (!node) {
|
||||
qCWarning(dcZigbeeGenericLights()) << "Could not find the node for" << thing;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
quint8 endpointId = thing->paramValue(m_endpointIdParamTypeIds.value(thing->thingClassId())).toUInt();
|
||||
return node->getEndpoint(endpointId);
|
||||
}
|
||||
71
zigbee-generic-lights/integrationpluginzigbeegenericlights.h
Normal file
71
zigbee-generic-lights/integrationpluginzigbeegenericlights.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 INTEGRATIONPLUGINZIGBEEGENERICLIGHTS_H
|
||||
#define INTEGRATIONPLUGINZIGBEEGENERICLIGHTS_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "hardware/zigbee/zigbeehandler.h"
|
||||
|
||||
class IntegrationPluginZigbeeGenericLights: public IntegrationPlugin, public ZigbeeHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginzigbee-generic-lights.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
explicit IntegrationPluginZigbeeGenericLights();
|
||||
|
||||
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:
|
||||
QHash<ThingClassId, ParamTypeId> m_ieeeAddressParamTypeIds;
|
||||
QHash<ThingClassId, ParamTypeId> m_networkUuidParamTypeIds;
|
||||
QHash<ThingClassId, ParamTypeId> m_endpointIdParamTypeIds;
|
||||
|
||||
QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds;
|
||||
QHash<ThingClassId, StateTypeId> m_signalStrengthStateTypeIds;
|
||||
QHash<ThingClassId, StateTypeId> m_versionStateTypeIds;
|
||||
|
||||
QHash<Thing *, ZigbeeNode *> m_thingNodes;
|
||||
|
||||
ZigbeeNodeEndpoint *findEndpoint(Thing *thing);
|
||||
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINZIGBEEGENERICLIGHTS_H
|
||||
9
zigbee-generic-lights/zigbee-generic-lights.pro
Normal file
9
zigbee-generic-lights/zigbee-generic-lights.pro
Normal file
@ -0,0 +1,9 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
PKGCONFIG += nymea-zigbee
|
||||
|
||||
SOURCES += \
|
||||
integrationpluginzigbeegenericlights.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationpluginzigbeegenericlights.h
|
||||
@ -141,10 +141,10 @@ void IntegrationPluginZigbeeLumi::handleRemoveNode(ZigbeeNode *node, const QUuid
|
||||
{
|
||||
Q_UNUSED(networkUuid)
|
||||
|
||||
if (m_nodeThings.values().contains(node)) {
|
||||
Thing *thing = m_nodeThings.key(node);
|
||||
qCDebug(dcZigbeeLumi()) << "Node for" << thing << node << "has left the network. Removing thing";
|
||||
m_nodeThings.remove(thing);
|
||||
if (m_thingNodes.values().contains(node)) {
|
||||
Thing *thing = m_thingNodes.key(node);
|
||||
qCDebug(dcZigbeeLumi()) << node << "for" << thing << "has left the network.";
|
||||
m_thingNodes.remove(thing);
|
||||
emit autoThingDisappeared(thing->id());
|
||||
}
|
||||
}
|
||||
@ -157,10 +157,10 @@ void IntegrationPluginZigbeeLumi::init()
|
||||
void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
qCDebug(dcZigbeeLumi()) << "Nework uuid:" << networkUuid;
|
||||
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(m_zigbeeAddressParamTypeIds.value(thing->thingClassId())).toString());
|
||||
|
||||
// Get the node for this thing
|
||||
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(m_zigbeeAddressParamTypeIds.value(thing->thingClassId())).toString());
|
||||
ZigbeeNode *node = hardwareManager()->zigbeeResource()->getNode(networkUuid, zigbeeAddress);
|
||||
if (!node) {
|
||||
qCWarning(dcZigbeeLumi()) << "Zigbee node for" << info->thing()->name() << "not found.´";
|
||||
@ -175,16 +175,14 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
||||
info->finish(Thing::ThingErrorSetupFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
m_nodeThings.insert(thing, node);
|
||||
|
||||
// General signals and states
|
||||
// Store the node thing association for removing
|
||||
m_thingNodes.insert(thing, node);
|
||||
|
||||
// Update connected state
|
||||
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), hardwareManager()->zigbeeResource()->networkState(networkUuid) == ZigbeeNetwork::StateRunning);
|
||||
connect(hardwareManager()->zigbeeResource(), &ZigbeeHardwareResource::networkStateChanged, thing, [thing, this](const QUuid &networkUuid, ZigbeeNetwork::State state){
|
||||
if (thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid() == networkUuid) {
|
||||
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), state == ZigbeeNetwork::StateRunning);
|
||||
}
|
||||
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
|
||||
@ -198,7 +196,7 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
||||
// Set the version
|
||||
thing->setStateValue(m_versionStateTypeIds.value(thing->thingClassId()), endpoint->softwareBuildId());
|
||||
|
||||
|
||||
// Thing specific setup
|
||||
if (thing->thingClassId() == lumiMagnetSensorThingClassId) {
|
||||
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
|
||||
if (onOffCluster) {
|
||||
@ -461,7 +459,7 @@ void IntegrationPluginZigbeeLumi::executeAction(ThingActionInfo *info)
|
||||
|
||||
void IntegrationPluginZigbeeLumi::thingRemoved(Thing *thing)
|
||||
{
|
||||
ZigbeeNode *node = m_nodeThings.take(thing);
|
||||
ZigbeeNode *node = m_thingNodes.take(thing);
|
||||
if (node) {
|
||||
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
hardwareManager()->zigbeeResource()->removeNodeFromNetwork(networkUuid, node);
|
||||
|
||||
@ -66,7 +66,7 @@ private:
|
||||
|
||||
QHash<QString, ThingClassId> m_knownLumiDevices;
|
||||
|
||||
QHash<Thing *, ZigbeeNode *> m_nodeThings;
|
||||
QHash<Thing *, ZigbeeNode *> m_thingNodes;
|
||||
|
||||
PluginTimer *m_presenceTimer = nullptr;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user