Add trafri plugin with on/off switch basic structure
parent
6c9276755a
commit
b48e1245ab
|
|
@ -1061,6 +1061,21 @@ 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-tradfri
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libnymea-zigbee1,
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io zigbee plugin for Ikea TRADRFI 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 Ikea TRADFRI zigbee devices
|
||||
|
||||
|
||||
Package: nymea-plugins-translations
|
||||
Section: misc
|
||||
|
|
@ -1133,7 +1148,8 @@ Section: libs
|
|||
Architecture: all
|
||||
Depends: nymea-plugin-zigbee-lumi,
|
||||
nymea-plugin-zigbee-generic,
|
||||
nymea-plugin-zigbee-generic-lights
|
||||
nymea-plugin-zigbee-generic-lights,
|
||||
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
|
||||
server works like a translator for devices, things and services and
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ PLUGIN_DIRS = \
|
|||
zigbee-generic \
|
||||
zigbee-generic-lights \
|
||||
zigbee-lumi \
|
||||
zigbee-tradfri \
|
||||
|
||||
|
||||
message(============================================)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
{
|
||||
"name": "ZigbeeTradfri",
|
||||
"displayName": "Zigbee TRÅDFRI",
|
||||
"id": "6a4343be-9fd6-4015-9ff5-38542651c534",
|
||||
"vendors": [
|
||||
{
|
||||
"name": "ikeaTradfri",
|
||||
"displayName": "IKEA TRÅDFRI",
|
||||
"id": "1a4fdeb3-2eab-47f2-9775-569552988a88",
|
||||
"thingClasses": [
|
||||
{
|
||||
"name": "onOffSwitch",
|
||||
"displayName": "TRÅDFRI On/Off switch",
|
||||
"id": "2007e8ae-4849-47f6-98d6-ea6769c8ebd9",
|
||||
"setupMethod": "JustAdd",
|
||||
"createMethods": [ "Auto" ],
|
||||
"interfaces": [ "longpressmultibutton", "batterylevel", "wirelessconnectable" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "8b33f5cb-d1a3-4ae6-837a-d88e77252185",
|
||||
"name": "ieeeAddress",
|
||||
"displayName": "IEEE adress",
|
||||
"type": "QString",
|
||||
"defaultValue": "00:00:00:00:00:00:00:00"
|
||||
},
|
||||
{
|
||||
"id": "37fae6ef-bbbe-4eb8-a199-9ed718224b70",
|
||||
"name": "networkUuid",
|
||||
"displayName": "Zigbee network UUID",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "4dafffae-af3b-40c0-8a61-8a15b9d24f64",
|
||||
"name": "endpointId",
|
||||
"displayName": "Endpoint ID",
|
||||
"type": "uint",
|
||||
"defaultValue": 1
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "b5abd47e-95f1-4e35-94fa-be87c396073a",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"cached": false,
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "21889797-32c0-4f1b-903d-8af71981882b",
|
||||
"name": "signalStrength",
|
||||
"displayName": "Signal strength",
|
||||
"displayNameEvent": "Signal strength changed",
|
||||
"defaultValue": 0,
|
||||
"maxValue": 100,
|
||||
"minValue": 0,
|
||||
"type": "uint",
|
||||
"unit": "Percentage"
|
||||
},
|
||||
{
|
||||
"id": "41c74445-4d2d-46dc-8a63-c98f1df8e742",
|
||||
"name": "version",
|
||||
"displayName": "Version",
|
||||
"displayNameEvent": "Version changed",
|
||||
"type": "QString",
|
||||
"cached": true,
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "103fba1d-79a6-4b48-b7a1-f91090f1c699",
|
||||
"name": "batteryLevel",
|
||||
"displayName": "Battery",
|
||||
"displayNameEvent": "Battery changed",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
},
|
||||
{
|
||||
"id": "a47e27ce-f443-4c9a-96fc-d59ec4989b49",
|
||||
"name": "batteryCritical",
|
||||
"displayName": "Battery critical",
|
||||
"displayNameEvent": "Battery critical changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
||||
],
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "20a75127-21ec-43b5-adb0-4f33e03303f7",
|
||||
"name": "pressed",
|
||||
"displayName": "Button pressed",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "1b2abb21-f60e-410b-9cfc-57ca991fb5af",
|
||||
"name": "buttonName",
|
||||
"displayName": "Button name",
|
||||
"type": "QString",
|
||||
"allowedValues": ["ON", "OFF"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "496c4d7f-ad90-427b-8363-56add5d64304",
|
||||
"name": "longPressed",
|
||||
"displayName": "Button longpressed",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "c6bde301-634e-404f-baed-80c5a50a3d46",
|
||||
"name": "buttonName",
|
||||
"displayName": "Button name",
|
||||
"type": "QString",
|
||||
"allowedValues": ["ON", "OFF"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
*
|
||||
* 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 "integrationpluginzigbeetradfri.h"
|
||||
#include "plugininfo.h"
|
||||
#include "hardware/zigbee/zigbeehardwareresource.h"
|
||||
|
||||
|
||||
IntegrationPluginZigbeeTradfri::IntegrationPluginZigbeeTradfri()
|
||||
{
|
||||
m_ieeeAddressParamTypeIds[onOffSwitchThingClassId] = onOffSwitchThingIeeeAddressParamTypeId;
|
||||
|
||||
m_networkUuidParamTypeIds[onOffSwitchThingClassId] = onOffSwitchThingNetworkUuidParamTypeId;
|
||||
|
||||
m_endpointIdParamTypeIds[onOffSwitchThingClassId] = onOffSwitchThingEndpointIdParamTypeId;
|
||||
|
||||
m_connectedStateTypeIds[onOffSwitchThingClassId] = onOffSwitchConnectedStateTypeId;
|
||||
|
||||
m_signalStrengthStateTypeIds[onOffSwitchThingClassId] = onOffSwitchSignalStrengthStateTypeId;
|
||||
|
||||
m_versionStateTypeIds[onOffSwitchThingClassId] = onOffSwitchVersionStateTypeId;
|
||||
}
|
||||
|
||||
QString IntegrationPluginZigbeeTradfri::name() const
|
||||
{
|
||||
return "Ikea TRADFRI";
|
||||
}
|
||||
|
||||
bool IntegrationPluginZigbeeTradfri::handleNode(ZigbeeNode *node, const QUuid &networkUuid)
|
||||
{
|
||||
// Make sure this is from ikea 0x117C
|
||||
if (node->nodeDescriptor().manufacturerCode != Zigbee::Ikea)
|
||||
return false;
|
||||
|
||||
bool handled = false;
|
||||
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
|
||||
if (endpoint->profile() == Zigbee::ZigbeeProfileHomeAutomation &&
|
||||
endpoint->deviceId() == Zigbee::HomeAutomationDeviceNonColourController) {
|
||||
qCDebug(dcZigbeeTradfri()) << "Handeling TRADFRI on/off switch" << node << endpoint;
|
||||
ThingDescriptor descriptor(onOffSwitchThingClassId);
|
||||
QString deviceClassName = supportedThings().findById(onOffSwitchThingClassId).displayName();
|
||||
descriptor.setTitle(deviceClassName);
|
||||
|
||||
ParamList params;
|
||||
params.append(Param(onOffSwitchThingNetworkUuidParamTypeId, networkUuid.toString()));
|
||||
params.append(Param(onOffSwitchThingIeeeAddressParamTypeId, node->extendedAddress().toString()));
|
||||
descriptor.setParams(params);
|
||||
emit autoThingsAppeared({descriptor});
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeTradfri::handleRemoveNode(ZigbeeNode *node, const QUuid &networkUuid)
|
||||
{
|
||||
Q_UNUSED(networkUuid)
|
||||
Thing *thing = m_thingNodes.key(node);
|
||||
if (thing) {
|
||||
qCDebug(dcZigbeeTradfri()) << node << "for" << thing << "has left the network.";
|
||||
emit autoThingDisappeared(thing->id());
|
||||
|
||||
// Removing it from our map to prevent a loop that would ask the zigbee network to remove this node (see thingRemoved())
|
||||
m_thingNodes.remove(thing);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeTradfri::init()
|
||||
{
|
||||
hardwareManager()->zigbeeResource()->registerHandler(this, ZigbeeHardwareResource::HandlerTypeVendor);
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeTradfri::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(dcZigbeeTradfri()) << "Zigbee node for" << info->thing()->name() << "not found.";
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
m_thingNodes.insert(thing, node);
|
||||
|
||||
ZigbeeNodeEndpoint *endpoint = findEndpoint(thing);
|
||||
if (!endpoint) {
|
||||
qCWarning(dcZigbeeTradfri()) << "Could not find endpoint for" << thing;
|
||||
info->finish(Thing::ThingErrorSetupFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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(dcZigbeeTradfri()) << 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());
|
||||
|
||||
if (thing->thingClassId() == onOffSwitchThingClassId) {
|
||||
|
||||
// Receive on/off commands
|
||||
ZigbeeClusterOnOff *onOffCluster = endpoint->outputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
|
||||
if (!onOffCluster) {
|
||||
qCWarning(dcZigbeeTradfri()) << "Could not find on/off client cluster on" << thing << endpoint;
|
||||
} else {
|
||||
connect(onOffCluster, &ZigbeeClusterOnOff::commandSent, thing, [=](ZigbeeClusterOnOff::Command command){
|
||||
qCDebug(dcZigbeeTradfri()) << thing << "button pressed" << command;
|
||||
if (command == ZigbeeClusterOnOff::CommandOn) {
|
||||
qCDebug(dcZigbeeTradfri()) << thing << "pressed ON";
|
||||
emit emitEvent(Event(onOffSwitchPressedEventTypeId, thing->id(), ParamList() << Param(onOffSwitchLongPressedEventButtonNameParamTypeId, "ON")));
|
||||
} else if (command == ZigbeeClusterOnOff::CommandOff) {
|
||||
qCDebug(dcZigbeeTradfri()) << thing << "pressed OFF";
|
||||
emit emitEvent(Event(onOffSwitchPressedEventTypeId, thing->id(), ParamList() << Param(onOffSwitchLongPressedEventButtonNameParamTypeId, "OFF")));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Receive level cntrol commands
|
||||
ZigbeeClusterLevelControl *levelCluster = endpoint->outputCluster<ZigbeeClusterLevelControl>(ZigbeeClusterLibrary::ClusterIdLevelControl);
|
||||
if (!levelCluster) {
|
||||
qCWarning(dcZigbeeTradfri()) << "Could not find level client cluster on" << thing << endpoint;
|
||||
} else {
|
||||
connect(levelCluster, &ZigbeeClusterLevelControl::commandSent, thing, [=](ZigbeeClusterLevelControl::Command command, const QByteArray &payload){
|
||||
qCDebug(dcZigbeeTradfri()) << thing << "button pressed" << command << payload.toHex();
|
||||
switch (command) {
|
||||
case ZigbeeClusterLevelControl::CommandMoveWithOnOff:
|
||||
qCDebug(dcZigbeeTradfri()) << thing << "long pressed ON";
|
||||
emit emitEvent(Event(onOffSwitchLongPressedEventTypeId, thing->id(), ParamList() << Param(onOffSwitchLongPressedEventButtonNameParamTypeId, "ON")));
|
||||
break;
|
||||
case ZigbeeClusterLevelControl::CommandMove:
|
||||
qCDebug(dcZigbeeTradfri()) << thing << "long pressed OFF";
|
||||
emit emitEvent(Event(onOffSwitchLongPressedEventTypeId, thing->id(), ParamList() << Param(onOffSwitchLongPressedEventButtonNameParamTypeId, "OFF")));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ZigbeeClusterPowerConfiguration *powerCluster = endpoint->inputCluster<ZigbeeClusterPowerConfiguration>(ZigbeeClusterLibrary::ClusterIdPowerConfiguration);
|
||||
if (!powerCluster) {
|
||||
qCWarning(dcZigbeeTradfri()) << "Could not find power configuration cluster on" << thing << endpoint;
|
||||
} else {
|
||||
// Only set the initial state if the attribute already exists
|
||||
if (powerCluster->hasAttribute(ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining)) {
|
||||
thing->setStateValue(onOffSwitchBatteryLevelStateTypeId, powerCluster->batteryPercentage());
|
||||
thing->setStateValue(onOffSwitchBatteryCriticalStateTypeId, (powerCluster->batteryPercentage() < 10.0));
|
||||
}
|
||||
|
||||
connect(powerCluster, &ZigbeeClusterPowerConfiguration::batteryPercentageChanged, thing, [=](double percentage){
|
||||
qCDebug(dcZigbeeTradfri()) << "Battery percentage changed" << percentage << "%" << thing;
|
||||
thing->setStateValue(onOffSwitchBatteryLevelStateTypeId, percentage);
|
||||
thing->setStateValue(onOffSwitchBatteryCriticalStateTypeId, (percentage < 10.0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeTradfri::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
info->finish(Thing::ThingErrorUnsupportedFeature);
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeTradfri::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 *IntegrationPluginZigbeeTradfri::findEndpoint(Thing *thing)
|
||||
{
|
||||
ZigbeeNode *node = m_thingNodes.value(thing);
|
||||
if (!node) {
|
||||
qCWarning(dcZigbeeTradfri()) << "Could not find the node for" << thing;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
quint8 endpointId = thing->paramValue(m_endpointIdParamTypeIds.value(thing->thingClassId())).toUInt();
|
||||
return node->getEndpoint(endpointId);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 INTEGRATIONPLUGINZIGBEETRADFRI_H
|
||||
#define INTEGRATIONPLUGINZIGBEETRADFRI_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "hardware/zigbee/zigbeehandler.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
class IntegrationPluginZigbeeTradfri: public IntegrationPlugin, public ZigbeeHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginzigbee-tradfri.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
explicit IntegrationPluginZigbeeTradfri();
|
||||
|
||||
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<Thing*, ZigbeeNode*> m_thingNodes;
|
||||
|
||||
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;
|
||||
|
||||
ZigbeeNodeEndpoint *findEndpoint(Thing *thing);
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINZIGBEETRADFRI_H
|
||||
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE TS><TS version="2.1"></TS>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
include(../plugins.pri)
|
||||
|
||||
PKGCONFIG += nymea-zigbee
|
||||
|
||||
SOURCES += \
|
||||
integrationpluginzigbeetradfri.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationpluginzigbeetradfri.h
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue