ZigbeeGeneric: Add support for ZigBee door/window sensors
parent
68ca8605f3
commit
220e307d8d
|
|
@ -37,49 +37,76 @@
|
|||
|
||||
#include <QDebug>
|
||||
|
||||
QHash<ThingClassId, StateTypeId> batteryLevelStateTypeIds = {
|
||||
static QHash<ThingClassId, StateTypeId> batteryLevelStateTypeIds = {
|
||||
{thermostatThingClassId, thermostatBatteryLevelStateTypeId},
|
||||
{doorLockThingClassId, doorLockBatteryLevelStateTypeId}
|
||||
{doorLockThingClassId, doorLockBatteryLevelStateTypeId},
|
||||
{doorSensorThingClassId, doorSensorBatteryLevelStateTypeId}
|
||||
};
|
||||
|
||||
QHash<ThingClassId, StateTypeId> batteryCriticalStateTypeIds = {
|
||||
static QHash<ThingClassId, StateTypeId> batteryCriticalStateTypeIds = {
|
||||
{thermostatThingClassId, thermostatBatteryCriticalStateTypeId},
|
||||
{doorLockThingClassId, doorLockBatteryCriticalStateTypeId}
|
||||
{doorLockThingClassId, doorLockBatteryCriticalStateTypeId},
|
||||
{doorSensorThingClassId, doorSensorBatteryCriticalStateTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> ieeeAddressParamTypeIds = {
|
||||
{thermostatThingClassId, thermostatThingIeeeAddressParamTypeId},
|
||||
{powerSocketThingClassId, powerSocketThingIeeeAddressParamTypeId},
|
||||
{doorLockThingClassId, doorLockThingIeeeAddressParamTypeId},
|
||||
{doorSensorThingClassId, doorSensorThingIeeeAddressParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> networkUuidParamTypeIds = {
|
||||
{thermostatThingClassId, thermostatThingNetworkUuidParamTypeId},
|
||||
{powerSocketThingClassId, powerSocketThingNetworkUuidParamTypeId},
|
||||
{doorLockThingClassId, doorLockThingNetworkUuidParamTypeId},
|
||||
{doorSensorThingClassId, doorSensorThingNetworkUuidParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> endpointIdParamTypeIds = {
|
||||
{thermostatThingClassId, thermostatThingEndpointIdParamTypeId},
|
||||
{powerSocketThingClassId, powerSocketThingEndpointIdParamTypeId},
|
||||
{doorLockThingClassId, doorLockThingEndpointIdParamTypeId},
|
||||
{doorSensorThingClassId, doorSensorThingEndpointIdParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> modelIdParamTypeIds = {
|
||||
{thermostatThingClassId, thermostatThingManufacturerParamTypeId},
|
||||
{powerSocketThingClassId, powerSocketThingManufacturerParamTypeId},
|
||||
{doorLockThingClassId, doorLockThingManufacturerParamTypeId},
|
||||
{doorSensorThingClassId, doorSensorThingManufacturerParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> manufacturerIdParamTypeIds = {
|
||||
{thermostatThingClassId, thermostatThingModelParamTypeId},
|
||||
{powerSocketThingClassId, powerSocketThingModelParamTypeId},
|
||||
{doorLockThingClassId, doorLockThingModelParamTypeId},
|
||||
{doorSensorThingClassId, doorSensorThingModelParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, StateTypeId> connectedStateTypeIds = {
|
||||
{thermostatThingClassId, thermostatConnectedStateTypeId},
|
||||
{powerSocketThingClassId, powerSocketConnectedStateTypeId},
|
||||
{doorLockThingClassId, doorLockConnectedStateTypeId},
|
||||
{doorSensorThingClassId, doorSensorConnectedStateTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, StateTypeId> signalStrengthStateTypeIds = {
|
||||
{thermostatThingClassId, thermostatSignalStrengthStateTypeId},
|
||||
{powerSocketThingClassId, powerSocketSignalStrengthStateTypeId},
|
||||
{doorLockThingClassId, doorLockSignalStrengthStateTypeId},
|
||||
{doorSensorThingClassId, doorSensorSignalStrengthStateTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, StateTypeId> versionStateTypeIds = {
|
||||
{thermostatThingClassId, thermostatVersionStateTypeId},
|
||||
{powerSocketThingClassId, powerSocketVersionStateTypeId},
|
||||
{doorLockThingClassId, doorLockVersionStateTypeId}
|
||||
};
|
||||
|
||||
|
||||
IntegrationPluginZigbeeGeneric::IntegrationPluginZigbeeGeneric()
|
||||
{
|
||||
m_ieeeAddressParamTypeIds[thermostatThingClassId] = thermostatThingIeeeAddressParamTypeId;
|
||||
m_ieeeAddressParamTypeIds[powerSocketThingClassId] = powerSocketThingIeeeAddressParamTypeId;
|
||||
m_ieeeAddressParamTypeIds[doorLockThingClassId] = doorLockThingIeeeAddressParamTypeId;
|
||||
|
||||
m_networkUuidParamTypeIds[thermostatThingClassId] = thermostatThingNetworkUuidParamTypeId;
|
||||
m_networkUuidParamTypeIds[powerSocketThingClassId] = powerSocketThingNetworkUuidParamTypeId;
|
||||
m_networkUuidParamTypeIds[doorLockThingClassId] = doorLockThingNetworkUuidParamTypeId;
|
||||
|
||||
m_endpointIdParamTypeIds[thermostatThingClassId] = thermostatThingEndpointIdParamTypeId;
|
||||
m_endpointIdParamTypeIds[powerSocketThingClassId] = powerSocketThingEndpointIdParamTypeId;
|
||||
m_endpointIdParamTypeIds[doorLockThingClassId] = doorLockThingEndpointIdParamTypeId;
|
||||
|
||||
m_manufacturerIdParamTypeIds[thermostatThingClassId] = thermostatThingManufacturerParamTypeId;
|
||||
m_manufacturerIdParamTypeIds[powerSocketThingClassId] = powerSocketThingManufacturerParamTypeId;
|
||||
m_manufacturerIdParamTypeIds[doorLockThingClassId] = doorLockThingManufacturerParamTypeId;
|
||||
|
||||
m_modelIdParamTypeIds[thermostatThingClassId] = thermostatThingModelParamTypeId;
|
||||
m_modelIdParamTypeIds[powerSocketThingClassId] = powerSocketThingModelParamTypeId;
|
||||
m_modelIdParamTypeIds[doorLockThingClassId] = doorLockThingModelParamTypeId;
|
||||
|
||||
m_connectedStateTypeIds[thermostatThingClassId] = thermostatConnectedStateTypeId;
|
||||
m_connectedStateTypeIds[powerSocketThingClassId] = powerSocketConnectedStateTypeId;
|
||||
m_connectedStateTypeIds[doorLockThingClassId] = doorLockConnectedStateTypeId;
|
||||
|
||||
m_signalStrengthStateTypeIds[thermostatThingClassId] = thermostatSignalStrengthStateTypeId;
|
||||
m_signalStrengthStateTypeIds[powerSocketThingClassId] = powerSocketSignalStrengthStateTypeId;
|
||||
m_signalStrengthStateTypeIds[doorLockThingClassId] = doorLockSignalStrengthStateTypeId;
|
||||
|
||||
m_versionStateTypeIds[thermostatThingClassId] = thermostatVersionStateTypeId;
|
||||
m_versionStateTypeIds[powerSocketThingClassId] = powerSocketVersionStateTypeId;
|
||||
m_versionStateTypeIds[doorLockThingClassId] = doorLockVersionStateTypeId;
|
||||
}
|
||||
|
||||
QString IntegrationPluginZigbeeGeneric::name() const
|
||||
|
|
@ -127,10 +154,50 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n
|
|||
qCDebug(dcZigbeeGeneric()) << "Handling door lock endpoint for" << node << endpoint;
|
||||
createThing(doorLockThingClassId, networkUuid, node, endpoint);
|
||||
// Initialize bindings and cluster attributes
|
||||
initializeDoorLock(node, endpoint);
|
||||
initDoorLock(node, endpoint);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Security sensors
|
||||
if (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceIsaZone) {
|
||||
qCInfo(dcZigbeeGeneric()) << "ISA Zone device found!";
|
||||
// We need to read the Type cluster to determine what this actually is...
|
||||
ZigbeeClusterIasZone *iasZoneCluster = endpoint->inputCluster<ZigbeeClusterIasZone>(ZigbeeClusterLibrary::ClusterIdIasZone);
|
||||
ZigbeeClusterReply *reply = iasZoneCluster->readAttributes({ZigbeeClusterIasZone::AttributeZoneType});
|
||||
connect(reply, &ZigbeeClusterReply::finished, this, [=](){
|
||||
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeGeneric()) << "Reading IAS Zone type attribute finished with error" << reply->error();
|
||||
return;
|
||||
}
|
||||
|
||||
QList<ZigbeeClusterLibrary::ReadAttributeStatusRecord> attributeStatusRecords = ZigbeeClusterLibrary::parseAttributeStatusRecords(reply->responseFrame().payload);
|
||||
if (attributeStatusRecords.count() != 1 || attributeStatusRecords.first().attributeId != ZigbeeClusterIasZone::AttributeZoneType) {
|
||||
qCWarning(dcZigbeeGeneric()) << "Unexpected reply in reading IAS Zone device type:" << attributeStatusRecords;
|
||||
return;
|
||||
}
|
||||
ZigbeeClusterLibrary::ReadAttributeStatusRecord iasZoneTypeRecord = attributeStatusRecords.first();
|
||||
qCDebug(dcZigbeeGeneric()) << "IAS Zone device type:" << iasZoneTypeRecord.dataType.toUInt16();
|
||||
switch (iasZoneTypeRecord.dataType.toUInt16()) {
|
||||
case ZigbeeClusterIasZone::ZoneTypeContactSwitch:
|
||||
qCInfo(dcZigbeeGeneric()) << "Creating contact switch thing";
|
||||
createThing(doorSensorThingClassId, networkUuid, node, endpoint);
|
||||
break;
|
||||
default:
|
||||
qCWarning(dcZigbeeGeneric()) << "Unhandled IAS Zone device type:" << "0x" + QString::number(iasZoneTypeRecord.dataType.toUInt16(), 16);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// createThing(doorSensorThingClassId, networkUuid, node, endpoint);
|
||||
// initDoorSensor(node, endpoint);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
|
@ -157,9 +224,9 @@ void IntegrationPluginZigbeeGeneric::init()
|
|||
void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
QUuid networkUuid = thing->paramValue(networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
qCDebug(dcZigbeeGeneric()) << "Nework uuid:" << networkUuid;
|
||||
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(m_ieeeAddressParamTypeIds.value(thing->thingClassId())).toString());
|
||||
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(ieeeAddressParamTypeIds.value(thing->thingClassId())).toString());
|
||||
ZigbeeNode *node = m_thingNodes.value(thing);
|
||||
if (!node) {
|
||||
node = hardwareManager()->zigbeeResource()->claimNode(this, networkUuid, zigbeeAddress);
|
||||
|
|
@ -180,21 +247,21 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
|
|||
}
|
||||
|
||||
// Update connected state
|
||||
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), node->reachable());
|
||||
thing->setStateValue(connectedStateTypeIds.value(thing->thingClassId()), node->reachable());
|
||||
connect(node, &ZigbeeNode::reachableChanged, thing, [thing, this](bool reachable){
|
||||
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), reachable);
|
||||
thing->setStateValue(connectedStateTypeIds.value(thing->thingClassId()), reachable);
|
||||
});
|
||||
|
||||
// Update signal strength
|
||||
thing->setStateValue(m_signalStrengthStateTypeIds.value(thing->thingClassId()), qRound(node->lqi() * 100.0 / 255.0));
|
||||
thing->setStateValue(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(dcZigbeeGeneric()) << thing << "signal strength changed" << signalStrength << "%";
|
||||
thing->setStateValue(m_signalStrengthStateTypeIds.value(thing->thingClassId()), signalStrength);
|
||||
thing->setStateValue(signalStrengthStateTypeIds.value(thing->thingClassId()), signalStrength);
|
||||
});
|
||||
|
||||
// Set the version
|
||||
thing->setStateValue(m_versionStateTypeIds.value(thing->thingClassId()), endpoint->softwareBuildId());
|
||||
thing->setStateValue(versionStateTypeIds.value(thing->thingClassId()), endpoint->softwareBuildId());
|
||||
|
||||
if (batteryLevelStateTypeIds.contains(thing->thingClassId())) {
|
||||
connectToPowerConfigurationCluster(thing, endpoint);
|
||||
|
|
@ -302,6 +369,23 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
|
|||
}
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == doorSensorThingClassId) {
|
||||
ZigbeeClusterIasZone *iasZoneCluster = endpoint->inputCluster<ZigbeeClusterIasZone>(ZigbeeClusterLibrary::ClusterIdIasZone);
|
||||
if (!iasZoneCluster) {
|
||||
qCWarning(dcZigbeeGeneric()) << "Could not find IAS zone cluster on" << thing << endpoint;
|
||||
} else {
|
||||
if (iasZoneCluster->hasAttribute(ZigbeeClusterIasZone::AttributeZoneStatus)) {
|
||||
qCDebug(dcZigbeeGeneric()) << thing << iasZoneCluster->zoneStatus();
|
||||
ZigbeeClusterIasZone::ZoneStatusFlags zoneStatus = iasZoneCluster->zoneStatus();
|
||||
thing->setStateValue(doorSensorClosedStateTypeId, !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm1) && !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm2));
|
||||
}
|
||||
connect(iasZoneCluster, &ZigbeeClusterIasZone::zoneStatusChanged, thing, [=](ZigbeeClusterIasZone::ZoneStatusFlags zoneStatus, quint8 extendedStatus, quint8 zoneId, quint16 delays) {
|
||||
qCDebug(dcZigbeeGeneric()) << "Zone status changed to:" << zoneStatus << extendedStatus << zoneId << delays;
|
||||
thing->setStateValue(doorSensorClosedStateTypeId, !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm1) && !zoneStatus.testFlag(ZigbeeClusterIasZone::ZoneStatusAlarm2));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
|
||||
|
|
@ -460,7 +544,7 @@ void IntegrationPluginZigbeeGeneric::thingRemoved(Thing *thing)
|
|||
{
|
||||
ZigbeeNode *node = m_thingNodes.take(thing);
|
||||
if (node) {
|
||||
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
QUuid networkUuid = thing->paramValue(networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||
hardwareManager()->zigbeeResource()->removeNodeFromNetwork(networkUuid, node);
|
||||
}
|
||||
}
|
||||
|
|
@ -473,7 +557,7 @@ ZigbeeNodeEndpoint *IntegrationPluginZigbeeGeneric::findEndpoint(Thing *thing)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
quint8 endpointId = thing->paramValue(m_endpointIdParamTypeIds.value(thing->thingClassId())).toUInt();
|
||||
quint8 endpointId = thing->paramValue(endpointIdParamTypeIds.value(thing->thingClassId())).toUInt();
|
||||
return node->getEndpoint(endpointId);
|
||||
}
|
||||
|
||||
|
|
@ -484,11 +568,11 @@ void IntegrationPluginZigbeeGeneric::createThing(const ThingClassId &thingClassI
|
|||
descriptor.setTitle(QString("%1 (%2 - %3)").arg(deviceClassName).arg(endpoint->manufacturerName()).arg(endpoint->modelIdentifier()));
|
||||
|
||||
ParamList params;
|
||||
params.append(Param(m_networkUuidParamTypeIds[thingClassId], networkUuid.toString()));
|
||||
params.append(Param(m_ieeeAddressParamTypeIds[thingClassId], node->extendedAddress().toString()));
|
||||
params.append(Param(m_endpointIdParamTypeIds[thingClassId], endpoint->endpointId()));
|
||||
params.append(Param(m_modelIdParamTypeIds[thingClassId], endpoint->modelIdentifier()));
|
||||
params.append(Param(m_manufacturerIdParamTypeIds[thingClassId], endpoint->manufacturerName()));
|
||||
params.append(Param(networkUuidParamTypeIds[thingClassId], networkUuid.toString()));
|
||||
params.append(Param(ieeeAddressParamTypeIds[thingClassId], node->extendedAddress().toString()));
|
||||
params.append(Param(endpointIdParamTypeIds[thingClassId], endpoint->endpointId()));
|
||||
params.append(Param(modelIdParamTypeIds[thingClassId], endpoint->modelIdentifier()));
|
||||
params.append(Param(manufacturerIdParamTypeIds[thingClassId], endpoint->manufacturerName()));
|
||||
descriptor.setParams(params);
|
||||
emit autoThingsAppeared({descriptor});
|
||||
}
|
||||
|
|
@ -510,7 +594,7 @@ void IntegrationPluginZigbeeGeneric::initSimplePowerSocket(ZigbeeNode *node, Zig
|
|||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGeneric::initializeDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
|
||||
void IntegrationPluginZigbeeGeneric::initDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
|
||||
{
|
||||
bindPowerConfigurationCluster(node, endpoint);
|
||||
|
||||
|
|
@ -564,15 +648,8 @@ void IntegrationPluginZigbeeGeneric::initThermostat(ZigbeeNode *node, ZigbeeNode
|
|||
reportingOccupiedHeatingSetpointConfig.maxReportingInterval = 2700;
|
||||
reportingOccupiedHeatingSetpointConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
|
||||
|
||||
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingBatteryPercentageConfig;
|
||||
reportingBatteryPercentageConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
|
||||
reportingBatteryPercentageConfig.dataType = Zigbee::Uint8;
|
||||
reportingBatteryPercentageConfig.minReportingInterval = 300;
|
||||
reportingBatteryPercentageConfig.maxReportingInterval = 2700;
|
||||
reportingBatteryPercentageConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
|
||||
|
||||
qCDebug(dcZigbeeGeneric()) << "Configuring attribute reporting for thermostat cluster";
|
||||
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)->configureReporting({reportingOccupiedHeatingSetpointConfig, reportingBatteryPercentageConfig});
|
||||
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdThermostat)->configureReporting({reportingOccupiedHeatingSetpointConfig});
|
||||
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
|
||||
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeGeneric()) << "Failed to configure thermostat cluster attribute reporting" << reportingReply->error();
|
||||
|
|
@ -583,6 +660,39 @@ void IntegrationPluginZigbeeGeneric::initThermostat(ZigbeeNode *node, ZigbeeNode
|
|||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGeneric::initDoorSensor(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
|
||||
{
|
||||
bindPowerConfigurationCluster(node, endpoint);
|
||||
|
||||
qCDebug(dcZigbeeGeneric()) << "Binding IAS custer";
|
||||
ZigbeeDeviceObjectReply *bindIasClusterReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdIasZone,
|
||||
hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
|
||||
connect(bindIasClusterReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
|
||||
if (bindIasClusterReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeGeneric()) << "Failed to bind IAS zone cluster" << bindIasClusterReply->error();
|
||||
} else {
|
||||
qCDebug(dcZigbeeGeneric()) << "Binding IAS zone cluster finished successfully";
|
||||
}
|
||||
|
||||
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingStatusConfig;
|
||||
reportingStatusConfig.attributeId = ZigbeeClusterIasZone::AttributeZoneStatus;
|
||||
reportingStatusConfig.dataType = Zigbee::Int16;
|
||||
reportingStatusConfig.minReportingInterval = 300;
|
||||
reportingStatusConfig.maxReportingInterval = 2700;
|
||||
reportingStatusConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
|
||||
|
||||
qCDebug(dcZigbeeGeneric()) << "Configuring attribute reporting for thermostat cluster";
|
||||
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdIasZone)->configureReporting({reportingStatusConfig});
|
||||
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
|
||||
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
|
||||
qCWarning(dcZigbeeGeneric()) << "Failed to configure IAS Zone cluster status attribute reporting" << reportingReply->error();
|
||||
} else {
|
||||
qCDebug(dcZigbeeGeneric()) << "Attribute reporting configuration finished for IAS Zone cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginZigbeeGeneric::bindPowerConfigurationCluster(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
|
||||
{
|
||||
ZigbeeDeviceObjectReply *bindPowerReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdPowerConfiguration,
|
||||
|
|
|
|||
|
|
@ -59,23 +59,14 @@ public:
|
|||
private:
|
||||
QHash<Thing*, ZigbeeNode*> m_thingNodes;
|
||||
|
||||
QHash<ThingClassId, ParamTypeId> m_ieeeAddressParamTypeIds;
|
||||
QHash<ThingClassId, ParamTypeId> m_networkUuidParamTypeIds;
|
||||
QHash<ThingClassId, ParamTypeId> m_endpointIdParamTypeIds;
|
||||
QHash<ThingClassId, ParamTypeId> m_modelIdParamTypeIds;
|
||||
QHash<ThingClassId, ParamTypeId> m_manufacturerIdParamTypeIds;
|
||||
|
||||
QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds;
|
||||
QHash<ThingClassId, StateTypeId> m_signalStrengthStateTypeIds;
|
||||
QHash<ThingClassId, StateTypeId> m_versionStateTypeIds;
|
||||
|
||||
// Get the endpoint for the given thing
|
||||
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);
|
||||
void initDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
|
||||
void initThermostat(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
|
||||
void initDoorSensor(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
|
||||
|
||||
void bindPowerConfigurationCluster(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
|
||||
|
||||
|
|
|
|||
|
|
@ -342,9 +342,99 @@
|
|||
"name": "close",
|
||||
"displayName": "Lock door"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fd43b442-1764-4005-acaf-9075e6d11e3a",
|
||||
"name": "doorSensor",
|
||||
"displayName": "Door sensor",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["closablesensor", "batterylevel", "wirelessconnectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "98d4265d-99b7-4849-97ec-a7eae3b275ff",
|
||||
"name": "ieeeAddress",
|
||||
"displayName": "IEEE adress",
|
||||
"type": "QString",
|
||||
"defaultValue": "00:00:00:00:00:00:00:00"
|
||||
},
|
||||
{
|
||||
"id": "260cb70b-7cb9-46b9-b6f3-0d4810a016b7",
|
||||
"name": "networkUuid",
|
||||
"displayName": "Zigbee network UUID",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "e265b17c-e4f4-4bea-b299-a6a3d94a6e7a",
|
||||
"name": "endpointId",
|
||||
"displayName": "Endpoint ID",
|
||||
"type": "uint",
|
||||
"defaultValue": 1
|
||||
},
|
||||
{
|
||||
"id": "193922e4-2c74-4748-a319-9e5b2f2607b4",
|
||||
"name": "manufacturer",
|
||||
"displayName": "Manufacturer",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "74ddad9e-6849-4b7a-a356-971e77e5195b",
|
||||
"name": "model",
|
||||
"displayName": "Model",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "2fb8e0a0-52f2-4c1d-b1c9-c7a295a83b44",
|
||||
"name": "closed",
|
||||
"displayName": "Closed",
|
||||
"displayNameEvent": "Opened or closed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "3c120c1c-0093-4c5e-8d7e-8892e4ce21b3",
|
||||
"name": "batteryLevel",
|
||||
"displayName": "Battery level",
|
||||
"displayNameEvent": "Battery level changed",
|
||||
"type": "int",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "9628450e-5580-4f30-8af7-f1c3093dcfb7",
|
||||
"name": "batteryCritical",
|
||||
"displayName": "Battery critical",
|
||||
"displayNameEvent": "Battery critical changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "4fae59a7-fe89-4bc7-bc04-fc18e94b5c3e",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected or disconnected",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "a1bf9c90-6e12-4513-a82a-a1d15351f140",
|
||||
"name": "signalStrength",
|
||||
"displayName": "Signal strength",
|
||||
"displayNameEvent": "Signal strength changed",
|
||||
"type": "uint",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue