Merge PR #393: Zigbee: Complete support for ZigBee Thermostats (generic)

This commit is contained in:
Jenkins nymea 2021-02-26 10:28:08 +01:00
commit 40b132afe9
6 changed files with 382 additions and 193 deletions

View File

@ -18,6 +18,9 @@ Simple on/off power sockets.
> Most power sockets have a pairing button. Once the device is powered, it can be resetted / paired by clicking the button multiple times of keeping it pressed for several seconds.
### Radiator thermostats
Radiator thermostats that follow the ZigBee specification.
## Requirements

View File

@ -37,6 +37,16 @@
#include <QDebug>
QHash<ThingClassId, StateTypeId> batteryLevelStateTypeIds = {
{thermostatThingClassId, thermostatBatteryLevelStateTypeId},
{doorLockThingClassId, doorLockBatteryLevelStateTypeId}
};
QHash<ThingClassId, StateTypeId> batteryCriticalStateTypeIds = {
{thermostatThingClassId, thermostatBatteryCriticalStateTypeId},
{doorLockThingClassId, doorLockBatteryCriticalStateTypeId}
};
IntegrationPluginZigbeeGeneric::IntegrationPluginZigbeeGeneric()
{
m_ieeeAddressParamTypeIds[thermostatThingClassId] = thermostatThingIeeeAddressParamTypeId;
@ -86,8 +96,9 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n
// Check thermostat
if (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation &&
endpoint->deviceId() == Zigbee::HomeAutomationDeviceThermostat) {
qCDebug(dcZigbeeGeneric()) << "Handeling thermostat endpoint for" << node << endpoint;
qCDebug(dcZigbeeGeneric()) << "Handling thermostat endpoint for" << node << endpoint;
createThing(thermostatThingClassId, networkUuid, node, endpoint);
initThermostat(node, endpoint);
handled = true;
}
@ -100,7 +111,7 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n
// Simple on/off device
if (endpoint->hasInputCluster(ZigbeeClusterLibrary::ClusterIdOnOff)) {
// FIXME: create powersocket with metering for SmartPlug device ID
qCDebug(dcZigbeeGeneric()) << "Handeling power socket endpoint for" << node << endpoint;
qCDebug(dcZigbeeGeneric()) << "Handling power socket endpoint for" << node << endpoint;
createThing(powerSocketThingClassId, networkUuid, node, endpoint);
initSimplePowerSocket(node, endpoint);
handled = true;
@ -113,7 +124,7 @@ bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &n
!endpoint->hasInputCluster(ZigbeeClusterLibrary::ClusterIdDoorLock)) {
qCWarning(dcZigbeeGeneric()) << "Endpoint claims to be a door lock, but the appropriate input clusters could not be found" << node << endpoint;
} else {
qCDebug(dcZigbeeGeneric()) << "Handeling door lock endpoint for" << node << endpoint;
qCDebug(dcZigbeeGeneric()) << "Handling door lock endpoint for" << node << endpoint;
createThing(doorLockThingClassId, networkUuid, node, endpoint);
// Initialize bindings and cluster attributes
initializeDoorLock(node, endpoint);
@ -185,49 +196,62 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
// Set the version
thing->setStateValue(m_versionStateTypeIds.value(thing->thingClassId()), endpoint->softwareBuildId());
if (batteryLevelStateTypeIds.contains(thing->thingClassId())) {
connectToPowerConfigurationCluster(thing, endpoint);
}
// Type specific setup
if (thing->thingClassId() == thermostatThingClassId) {
ZigbeeClusterThermostat *thermostatCluster = endpoint->inputCluster<ZigbeeClusterThermostat>(ZigbeeClusterLibrary::ClusterIdThermostat);
if (!thermostatCluster) {
qCWarning(dcZigbeeGeneric()) << "Failed to read thermostat cluster";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
// thermostatCluster->attribute(ZigbeeClusterLibrary::ClusterIdThermostat);
// We need to read them from the lamp
ZigbeeClusterReply *reply = thermostatCluster->readAttributes({ZigbeeClusterThermostat::AttributeLocalTemperature, ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint});
// Read initial attribute values
ZigbeeClusterReply *reply = thermostatCluster->readAttributes({ZigbeeClusterThermostat::AttributeLocalTemperature,
ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint,
ZigbeeClusterThermostat::AttributePIHeatingDemand,
ZigbeeClusterThermostat::AttributePICoolingDemand});
connect(reply, &ZigbeeClusterReply::finished, thing, [=](){
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Reading loacal temperature attribute finished with error" << reply->error();
qCWarning(dcZigbeeGeneric()) << "Reading thermostat attributes finished with error" << reply->error();
return;
}
QList<ZigbeeClusterLibrary::ReadAttributeStatusRecord> attributeStatusRecords = ZigbeeClusterLibrary::parseAttributeStatusRecords(reply->responseFrame().payload);
foreach (const ZigbeeClusterLibrary::ReadAttributeStatusRecord &record, attributeStatusRecords) {
if (record.attributeId == ZigbeeClusterThermostat::AttributeLocalTemperature) {
bool valueOk = false;
quint16 localTemperature = record.dataType.toUInt16(&valueOk);
if (!valueOk) {
qCWarning(dcZigbeeGeneric()) << "Failed to read local temperature" << attributeStatusRecords;
return;
}
thing->setStateValue(thermostatTemperatureStateTypeId, localTemperature * 0.01);
thing->setStateValue(thermostatTemperatureStateTypeId, record.dataType.toInt16() * 0.01);
}
if (record.attributeId == ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint) {
bool valueOk = false;
quint16 targetTemperature = record.dataType.toUInt16(&valueOk);
if (!valueOk) {
qCWarning(dcZigbeeGeneric()) << "Failed to read local temperature" << attributeStatusRecords;
return;
}
thing->setStateValue(thermostatTargetTemperatureStateTypeId, targetTemperature * 0.01);
thing->setStateValue(thermostatTargetTemperatureStateTypeId, record.dataType.toInt16() * 0.01);
}
if (record.attributeId == ZigbeeClusterThermostat::AttributePIHeatingDemand) {
thing->setStateValue(thermostatHeatingOnStateTypeId, record.dataType.toUInt8() > 0);
}
if (record.attributeId == ZigbeeClusterThermostat::AttributePICoolingDemand) {
thing->setStateValue(thermostatCoolingOnStateTypeId, record.dataType.toUInt8() > 0);
}
}
});
// Connect to attribute changes
connect(thermostatCluster, &ZigbeeClusterThermostat::attributeChanged, thing, [thing](const ZigbeeClusterAttribute &attribute){
qCDebug(dcZigbeeGeneric()) << "Thermostat attribute changed" << thing->name() << attribute.id() << attribute.dataType();
if (attribute.id() == ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint) {
thing->setStateValue(thermostatTargetTemperatureStateTypeId, attribute.dataType().toUInt16() * 0.01);
}
if (attribute.id() == ZigbeeClusterThermostat::AttributeLocalTemperature) {
thing->setStateValue(thermostatTemperatureStateTypeId, attribute.dataType().toUInt16() * 0.01);
}
if (attribute.id() == ZigbeeClusterThermostat::AttributePIHeatingDemand) {
thing->setStateValue(thermostatHeatingOnStateTypeId, attribute.dataType().toUInt8() > 0);
}
if (attribute.id() == ZigbeeClusterThermostat::AttributePICoolingDemand) {
thing->setStateValue(thermostatCoolingOnStateTypeId, attribute.dataType().toUInt8() > 0);
}
});
}
@ -237,7 +261,6 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
if (onOffCluster->hasAttribute(ZigbeeClusterOnOff::AttributeOnOff)) {
thing->setStateValue(powerSocketPowerStateTypeId, onOffCluster->power());
}
connect(onOffCluster, &ZigbeeClusterOnOff::powerChanged, thing, [thing](bool power){
qCDebug(dcZigbeeGeneric()) << thing << "power changed" << power;
thing->setStateValue(powerSocketPowerStateTypeId, power);
@ -261,24 +284,6 @@ void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
if (thing->thingClassId() == doorLockThingClassId) {
// Get battery level changes
ZigbeeClusterPowerConfiguration *powerCluster = endpoint->inputCluster<ZigbeeClusterPowerConfiguration>(ZigbeeClusterLibrary::ClusterIdPowerConfiguration);
if (!powerCluster) {
qCWarning(dcZigbeeGeneric()) << "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(doorLockBatteryLevelStateTypeId, powerCluster->batteryPercentage());
thing->setStateValue(doorLockBatteryCriticalStateTypeId, (powerCluster->batteryPercentage() < 10.0));
}
connect(powerCluster, &ZigbeeClusterPowerConfiguration::batteryPercentageChanged, thing, [=](double percentage){
qCDebug(dcZigbeeGeneric()) << "Battery percentage changed" << percentage << "%" << thing;
thing->setStateValue(doorLockBatteryLevelStateTypeId, percentage);
thing->setStateValue(doorLockBatteryCriticalStateTypeId, (percentage < 10.0));
});
}
// Get door state changes
ZigbeeClusterDoorLock *doorLockCluster = endpoint->inputCluster<ZigbeeClusterDoorLock>(ZigbeeClusterLibrary::ClusterIdDoorLock);
if (!doorLockCluster) {
@ -322,6 +327,39 @@ void IntegrationPluginZigbeeGeneric::executeAction(ThingActionInfo *info)
return;
}
if (thing->thingClassId() == thermostatThingClassId) {
if (info->action().actionTypeId() == thermostatTargetTemperatureActionTypeId) {
ZigbeeClusterThermostat *thermostatCluster = endpoint->inputCluster<ZigbeeClusterThermostat>(ZigbeeClusterLibrary::ClusterIdThermostat);
if (!thermostatCluster) {
qCWarning(dcZigbeeGeneric()) << "Thermostat cluster not found on thing" << thing->name();
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
qint16 targetTemp = qRound(info->action().paramValue(thermostatTargetTemperatureStateTypeId).toDouble() * 10) * 10;
// TODO: The following should probably move into libnymea-zibee prividing a
// thermostatCluster->writeOccupiedHeatingSetpoint(targetTemp);
ZigbeeDataType dataType(targetTemp);
QList<ZigbeeClusterLibrary::WriteAttributeRecord> attributes;
ZigbeeClusterLibrary::WriteAttributeRecord occupiedHeatingSetpointAttribute;
occupiedHeatingSetpointAttribute.attributeId = ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint;
occupiedHeatingSetpointAttribute.dataType = dataType.dataType();
occupiedHeatingSetpointAttribute.data = dataType.data();
attributes.append(occupiedHeatingSetpointAttribute);
qCDebug(dcZigbeeGeneric()) << "Writing target temp" << targetTemp << occupiedHeatingSetpointAttribute.data;
ZigbeeClusterReply *reply = thermostatCluster->writeAttributes(attributes);
connect(reply, &ZigbeeClusterReply::finished, info, [info, reply](){
qCDebug(dcZigbeeGeneric()) << "Writing attributes finished:" << reply->error();
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
info->thing()->setStateValue(thermostatTargetTemperatureStateTypeId, info->action().paramValue(thermostatTargetTemperatureActionTargetTemperatureParamTypeId));
info->finish(Thing::ThingErrorNoError);
});
return;
}
}
if (thing->thingClassId() == powerSocketThingClassId) {
if (info->action().actionTypeId() == powerSocketAlertActionTypeId) {
ZigbeeClusterIdentify *identifyCluster = endpoint->inputCluster<ZigbeeClusterIdentify>(ZigbeeClusterLibrary::ClusterIdIdentify);
@ -474,82 +512,132 @@ void IntegrationPluginZigbeeGeneric::initSimplePowerSocket(ZigbeeNode *node, Zig
void IntegrationPluginZigbeeGeneric::initializeDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
{
qCDebug(dcZigbeeGeneric()) << "Read power configuration cluster attributes" << node;
ZigbeeClusterReply *readAttributeReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)->readAttributes({ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining});
connect(readAttributeReply, &ZigbeeClusterReply::finished, node, [=](){
if (readAttributeReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to read power configuration cluster attributes" << readAttributeReply->error();
bindPowerConfigurationCluster(node, endpoint);
qCDebug(dcZigbeeGeneric()) << "Binding door lock cluster ";
ZigbeeDeviceObjectReply * zdoReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdDoorLock, hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to door lock cluster to coordinator" << zdoReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Read power configuration cluster attributes finished successfully";
qCDebug(dcZigbeeGeneric()) << "Bind door lock cluster to coordinator finished successfully";
}
// Bind the cluster to the coordinator
qCDebug(dcZigbeeGeneric()) << "Bind power configuration cluster to coordinator IEEE address";
ZigbeeDeviceObjectReply * zdoReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdPowerConfiguration, hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to bind power cluster to coordinator" << zdoReply->error();
// Configure attribute reporting for lock state
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterDoorLock::AttributeLockState;
reportingConfig.dataType = Zigbee::Enum8;
reportingConfig.minReportingInterval = 60;
reportingConfig.maxReportingInterval = 120;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeGeneric()) << "Configure attribute reporting for door lock cluster to coordinator";
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdDoorLock)->configureReporting({reportingConfig});
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to door lock cluster attribute reporting" << reportingReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Bind power configuration cluster to coordinator finished successfully";
qCDebug(dcZigbeeGeneric()) << "Attribute reporting configuration finished for door lock cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
}
// Configure attribute rporting for battery remaining (0.5 % changes = 1)
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
reportingConfig.dataType = Zigbee::Uint8;
reportingConfig.minReportingInterval = 60; // for production use 300;
reportingConfig.maxReportingInterval = 120; // for production use 2700;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeGeneric()) << "Configure attribute reporting for power configuration cluster to coordinator";
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)->configureReporting({reportingConfig});
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to configure power cluster attribute reporting" << reportingReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Attribute reporting configuration finished for power cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
}
// Configure door lock attribute reporting and read initial values
qCDebug(dcZigbeeGeneric()) << "Read door lock cluster attributes" << node;
ZigbeeClusterReply *readAttributeReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdDoorLock)->readAttributes({ZigbeeClusterDoorLock::AttributeDoorState, ZigbeeClusterDoorLock::AttributeLockType});
connect(readAttributeReply, &ZigbeeClusterReply::finished, node, [=](){
if (readAttributeReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to read door lock attributes" << readAttributeReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Read door lock cluster attributes finished successfully";
}
// Bind the cluster to the coordinator
qCDebug(dcZigbeeGeneric()) << "Bind door lock cluster to coordinator IEEE address";
ZigbeeDeviceObjectReply * zdoReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdDoorLock, hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
connect(zdoReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (zdoReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to door lock cluster to coordinator" << zdoReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Bind door lock cluster to coordinator finished successfully";
}
// Configure attribute reporting for lock state
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingConfig;
reportingConfig.attributeId = ZigbeeClusterDoorLock::AttributeLockState;
reportingConfig.dataType = Zigbee::Enum8;
reportingConfig.minReportingInterval = 60;
reportingConfig.maxReportingInterval = 120;
reportingConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeGeneric()) << "Configure attribute reporting for door lock cluster to coordinator";
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdDoorLock)->configureReporting({reportingConfig});
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to door lock cluster attribute reporting" << reportingReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Attribute reporting configuration finished for door lock cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
}
});
});
});
});
});
});
}
void IntegrationPluginZigbeeGeneric::initThermostat(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
{
bindPowerConfigurationCluster(node, endpoint);
qCDebug(dcZigbeeGeneric()) << "Binding thermostat custer";
ZigbeeDeviceObjectReply *bindThermostatReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdThermostat,
hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
connect(bindThermostatReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (bindThermostatReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to bind thermostat cluster" << bindThermostatReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Binding thermostat cluster finished successfully";
}
ZigbeeClusterLibrary::AttributeReportingConfiguration reportingOccupiedHeatingSetpointConfig;
reportingOccupiedHeatingSetpointConfig.attributeId = ZigbeeClusterThermostat::AttributeOccupiedHeatingSetpoint;
reportingOccupiedHeatingSetpointConfig.dataType = Zigbee::Int16;
reportingOccupiedHeatingSetpointConfig.minReportingInterval = 300;
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});
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to configure thermostat cluster attribute reporting" << reportingReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Attribute reporting configuration finished for thermostat cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
}
});
});
}
void IntegrationPluginZigbeeGeneric::bindPowerConfigurationCluster(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint)
{
ZigbeeDeviceObjectReply *bindPowerReply = node->deviceObject()->requestBindIeeeAddress(endpoint->endpointId(), ZigbeeClusterLibrary::ClusterIdPowerConfiguration,
hardwareManager()->zigbeeResource()->coordinatorAddress(node->networkUuid()), 0x01);
connect(bindPowerReply, &ZigbeeDeviceObjectReply::finished, node, [=](){
if (bindPowerReply->error() != ZigbeeDeviceObjectReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to bind power configuration cluster" << bindPowerReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Binding power configuration cluster finished successfully";
}
ZigbeeClusterLibrary::AttributeReportingConfiguration batteryPercentageConfig;
batteryPercentageConfig.attributeId = ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining;
batteryPercentageConfig.dataType = Zigbee::Uint8;
batteryPercentageConfig.minReportingInterval = 60; // for production use 300;
batteryPercentageConfig.maxReportingInterval = 120; // for production use 2700;
batteryPercentageConfig.reportableChange = ZigbeeDataType(static_cast<quint8>(1)).data();
qCDebug(dcZigbeeGeneric()) << "Configuring attribute reporting for power configuration cluster";
ZigbeeClusterReply *reportingReply = endpoint->getInputCluster(ZigbeeClusterLibrary::ClusterIdPowerConfiguration)->configureReporting({batteryPercentageConfig});
connect(reportingReply, &ZigbeeClusterReply::finished, this, [=](){
if (reportingReply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Failed to configure power configuration cluster attribute reporting" << reportingReply->error();
} else {
qCDebug(dcZigbeeGeneric()) << "Attribute reporting configuration finished for power configuration cluster" << ZigbeeClusterLibrary::parseAttributeReportingStatusRecords(reportingReply->responseFrame().payload);
}
});
});
}
void IntegrationPluginZigbeeGeneric::connectToPowerConfigurationCluster(Thing *thing, ZigbeeNodeEndpoint *endpoint)
{
// Get battery level changes
ZigbeeClusterPowerConfiguration *powerCluster = endpoint->inputCluster<ZigbeeClusterPowerConfiguration>(ZigbeeClusterLibrary::ClusterIdPowerConfiguration);
if (powerCluster) {
// If the power cluster attributes are already available, read values now
if (powerCluster->hasAttribute(ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining)) {
thing->setStateValue(batteryLevelStateTypeIds.value(thing->thingClassId()), powerCluster->batteryPercentage());
thing->setStateValue(batteryCriticalStateTypeIds.value(thing->thingClassId()), (powerCluster->batteryPercentage() < 10.0));
}
// Refresh power cluster attributes in any case
ZigbeeClusterReply *reply = powerCluster->readAttributes({ZigbeeClusterPowerConfiguration::AttributeBatteryPercentageRemaining});
connect(reply, &ZigbeeClusterReply::finished, thing, [=](){
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeGeneric()) << "Reading power configuration cluster attributes finished with error" << reply->error();
return;
}
thing->setStateValue(batteryLevelStateTypeIds.value(thing->thingClassId()), powerCluster->batteryPercentage());
thing->setStateValue(batteryCriticalStateTypeIds.value(thing->thingClassId()), (powerCluster->batteryPercentage() < 10.0));
});
// Connect to battery level changes
connect(powerCluster, &ZigbeeClusterPowerConfiguration::batteryPercentageChanged, thing, [=](double percentage){
thing->setStateValue(batteryLevelStateTypeIds.value(thing->thingClassId()), percentage);
thing->setStateValue(batteryCriticalStateTypeIds.value(thing->thingClassId()), (percentage < 10.0));
});
}
}

View File

@ -75,7 +75,11 @@ private:
void initSimplePowerSocket(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
void initializeDoorLock(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
void initThermostat(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
void bindPowerConfigurationCluster(ZigbeeNode *node, ZigbeeNodeEndpoint *endpoint);
void connectToPowerConfigurationCluster(Thing *thing, ZigbeeNodeEndpoint *endpoint);
};
#endif // INTEGRATIONPLUGINZIGBEEGENERIC_H

View File

@ -13,7 +13,7 @@
"name": "thermostat",
"displayName": "Zigbee Thermostat",
"createMethods": ["auto"],
"interfaces": ["thermostat", "temperaturesensor", "wirelessconnectable"],
"interfaces": ["thermostat", "temperaturesensor", "batterylevel", "wirelessconnectable"],
"paramTypes": [
{
"id": "f38746d8-0084-43a3-b645-3ec743ea5fbc",
@ -57,11 +57,13 @@
"name": "targetTemperature",
"displayName": "Target temperature",
"displayNameEvent": "Target temperature changed",
"displayNameAction": "Set target temperature",
"type": "double",
"unit": "DegreeCelsius",
"minValue": 0,
"maxValue": 50,
"defaultValue": 0
"defaultValue": 0,
"writable": true
},
{
"id": "497af03a-a893-438c-aba2-1bf3ecfc66c5",
@ -72,6 +74,22 @@
"unit": "DegreeCelsius",
"defaultValue": 0
},
{
"id": "88d5dda1-b8f6-49f1-a55a-20415f9157b3",
"name": "heatingOn",
"displayName": "Heating on",
"displayNameEvent": "Heating turned on",
"type": "bool",
"defaultValue": false
},
{
"id": "c77a3d3f-46c7-4026-b9ab-02ab88077cc4",
"name": "coolingOn",
"displayName": "Cooling on",
"displayNameEvent": "Cooling turned on",
"type": "bool",
"defaultValue": false
},
{
"id": "e9fb2b10-96da-4b70-afda-46e948399af8",
"name": "connected",
@ -100,6 +118,25 @@
"type": "QString",
"cached": true,
"defaultValue": ""
},
{
"id": "3a733e99-850b-4c56-b058-d39850ef2fee",
"name": "batteryLevel",
"displayName": "Battery",
"displayNameEvent": "Battery changed",
"type": "int",
"unit": "Percentage",
"defaultValue": 0,
"minValue": 0,
"maxValue": 100
},
{
"id": "5cec4399-ba7c-4c78-8c30-c91040ad99cf",
"name": "batteryCritical",
"displayName": "Battery critical",
"displayNameEvent": "Battery critical changed",
"type": "bool",
"defaultValue": false
}
]
},

View File

@ -4,42 +4,60 @@
<context>
<name>ZigbeeGeneric</name>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="87"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="90"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="106"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="109"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="112"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="115"/>
<source>Battery</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, EventType: batteryLevel, ID: {568e5bdd-47f3-4ccb-a1d8-ff3a5ea87ad8})
----------
The name of the StateType ({568e5bdd-47f3-4ccb-a1d8-ff3a5ea87ad8}) of ThingClass doorLock</extracomment>
The name of the StateType ({568e5bdd-47f3-4ccb-a1d8-ff3a5ea87ad8}) of ThingClass doorLock
----------
The name of the ParamType (ThingClass: thermostat, EventType: batteryLevel, ID: {3a733e99-850b-4c56-b058-d39850ef2fee})
----------
The name of the StateType ({3a733e99-850b-4c56-b058-d39850ef2fee}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="93"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="118"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="121"/>
<source>Battery changed</source>
<extracomment>The name of the EventType ({568e5bdd-47f3-4ccb-a1d8-ff3a5ea87ad8}) of ThingClass doorLock</extracomment>
<extracomment>The name of the EventType ({568e5bdd-47f3-4ccb-a1d8-ff3a5ea87ad8}) of ThingClass doorLock
----------
The name of the EventType ({3a733e99-850b-4c56-b058-d39850ef2fee}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="96"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="99"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="124"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="127"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="130"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="133"/>
<source>Battery critical</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, EventType: batteryCritical, ID: {89abea26-b772-4258-9b56-e026b80c2028})
----------
The name of the StateType ({89abea26-b772-4258-9b56-e026b80c2028}) of ThingClass doorLock</extracomment>
The name of the StateType ({89abea26-b772-4258-9b56-e026b80c2028}) of ThingClass doorLock
----------
The name of the ParamType (ThingClass: thermostat, EventType: batteryCritical, ID: {5cec4399-ba7c-4c78-8c30-c91040ad99cf})
----------
The name of the StateType ({5cec4399-ba7c-4c78-8c30-c91040ad99cf}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="102"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="136"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="139"/>
<source>Battery critical changed</source>
<extracomment>The name of the EventType ({89abea26-b772-4258-9b56-e026b80c2028}) of ThingClass doorLock</extracomment>
<extracomment>The name of the EventType ({89abea26-b772-4258-9b56-e026b80c2028}) of ThingClass doorLock
----------
The name of the EventType ({5cec4399-ba7c-4c78-8c30-c91040ad99cf}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="105"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="108"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="111"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="114"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="117"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="120"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="142"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="145"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="148"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="151"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="154"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="157"/>
<source>Connected</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, EventType: connected, ID: {206b0508-b477-4aa2-b420-aba2259fb6e6})
----------
@ -55,8 +73,8 @@ The name of the StateType ({e9fb2b10-96da-4b70-afda-46e948399af8}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="123"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="126"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="160"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="163"/>
<source>Connected changed</source>
<extracomment>The name of the EventType ({206b0508-b477-4aa2-b420-aba2259fb6e6}) of ThingClass doorLock
----------
@ -64,14 +82,29 @@ The name of the EventType ({b5abd47e-95f1-4e35-94fa-be87c396073a}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="129"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="166"/>
<source>Connected/disconnected</source>
<extracomment>The name of the EventType ({e9fb2b10-96da-4b70-afda-46e948399af8}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="132"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="135"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="169"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="172"/>
<source>Cooling on</source>
<extracomment>The name of the ParamType (ThingClass: thermostat, EventType: coolingOn, ID: {c77a3d3f-46c7-4026-b9ab-02ab88077cc4})
----------
The name of the StateType ({c77a3d3f-46c7-4026-b9ab-02ab88077cc4}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="175"/>
<source>Cooling turned on</source>
<extracomment>The name of the EventType ({c77a3d3f-46c7-4026-b9ab-02ab88077cc4}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="178"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="181"/>
<source>Current temperature</source>
<extracomment>The name of the ParamType (ThingClass: thermostat, EventType: temperature, ID: {497af03a-a893-438c-aba2-1bf3ecfc66c5})
----------
@ -79,21 +112,21 @@ The name of the StateType ({497af03a-a893-438c-aba2-1bf3ecfc66c5}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="138"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="184"/>
<source>Current temperature changed</source>
<extracomment>The name of the EventType ({497af03a-a893-438c-aba2-1bf3ecfc66c5}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="141"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="187"/>
<source>Door lock</source>
<extracomment>The name of the ThingClass ({34cb3d09-dd9f-4b95-95d0-30a1cd94adac})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="144"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="147"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="150"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="190"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="193"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="196"/>
<source>Endpoint ID</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, Type: thing, ID: {ebf17460-4a37-461f-aa24-e0a9a4238c63})
----------
@ -103,9 +136,24 @@ The name of the ParamType (ThingClass: thermostat, Type: thing, ID: {138a529d-1d
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="153"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="156"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="159"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="199"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="202"/>
<source>Heating on</source>
<extracomment>The name of the ParamType (ThingClass: thermostat, EventType: heatingOn, ID: {88d5dda1-b8f6-49f1-a55a-20415f9157b3})
----------
The name of the StateType ({88d5dda1-b8f6-49f1-a55a-20415f9157b3}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="205"/>
<source>Heating turned on</source>
<extracomment>The name of the EventType ({88d5dda1-b8f6-49f1-a55a-20415f9157b3}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="208"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="211"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="214"/>
<source>IEEE adress</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, Type: thing, ID: {484bf80f-5d20-4029-b05e-6b4c9fbefd69})
----------
@ -115,21 +163,21 @@ The name of the ParamType (ThingClass: thermostat, Type: thing, ID: {f38746d8-00
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="162"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="217"/>
<source>Identify</source>
<extracomment>The name of the ActionType ({4e3b1430-d98e-4f05-bae6-301dac34bd4b}) of ThingClass powerSocket</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="165"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="220"/>
<source>Lock door</source>
<extracomment>The name of the ActionType ({c26e1908-25d0-4475-8f82-5aaf034640f1}) of ThingClass doorLock</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="168"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="171"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="174"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="223"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="226"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="229"/>
<source>Manufacturer</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, Type: thing, ID: {1b177eb8-a13f-4975-92a7-a6bf54670c8f})
----------
@ -139,9 +187,9 @@ The name of the ParamType (ThingClass: thermostat, Type: thing, ID: {ae76acb0-40
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="177"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="180"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="183"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="232"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="235"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="238"/>
<source>Model</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, Type: thing, ID: {b13f86a7-dc65-4ed6-860c-cdb099f90916})
----------
@ -151,9 +199,9 @@ The name of the ParamType (ThingClass: thermostat, Type: thing, ID: {4262cfc6-4b
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="186"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="189"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="192"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="241"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="244"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="247"/>
<source>Power</source>
<extracomment>The name of the ParamType (ThingClass: powerSocket, ActionType: power, ID: {2c8268b9-d76b-415a-b2e9-6bfeabd98a76})
----------
@ -163,30 +211,36 @@ The name of the StateType ({2c8268b9-d76b-415a-b2e9-6bfeabd98a76}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="195"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="250"/>
<source>Power changed</source>
<extracomment>The name of the EventType ({2c8268b9-d76b-415a-b2e9-6bfeabd98a76}) of ThingClass powerSocket</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="198"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="253"/>
<source>Power socket</source>
<extracomment>The name of the ThingClass ({800a8df8-06cb-4d93-8334-944fcce9651a})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="201"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="256"/>
<source>Set power</source>
<extracomment>The name of the ActionType ({2c8268b9-d76b-415a-b2e9-6bfeabd98a76}) of ThingClass powerSocket</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="204"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="207"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="210"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="213"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="216"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="219"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="259"/>
<source>Set target temperature</source>
<extracomment>The name of the ActionType ({88ad3957-2912-4de1-b53d-b360565dd361}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="262"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="265"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="268"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="271"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="274"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="277"/>
<source>Signal strength</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, EventType: signalStrength, ID: {6c8f8db5-464c-408a-9c65-4e8096663019})
----------
@ -202,9 +256,9 @@ The name of the StateType ({8f0512ab-ced2-4dcb-90fe-aaa532efd0dd}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="222"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="225"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="228"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="280"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="283"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="286"/>
<source>Signal strength changed</source>
<extracomment>The name of the EventType ({6c8f8db5-464c-408a-9c65-4e8096663019}) of ThingClass doorLock
----------
@ -214,33 +268,36 @@ The name of the EventType ({8f0512ab-ced2-4dcb-90fe-aaa532efd0dd}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="231"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="234"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="289"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="292"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="295"/>
<source>Target temperature</source>
<extracomment>The name of the ParamType (ThingClass: thermostat, EventType: targetTemperature, ID: {88ad3957-2912-4de1-b53d-b360565dd361})
<extracomment>The name of the ParamType (ThingClass: thermostat, ActionType: targetTemperature, ID: {88ad3957-2912-4de1-b53d-b360565dd361})
----------
The name of the ParamType (ThingClass: thermostat, EventType: targetTemperature, ID: {88ad3957-2912-4de1-b53d-b360565dd361})
----------
The name of the StateType ({88ad3957-2912-4de1-b53d-b360565dd361}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="237"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="298"/>
<source>Target temperature changed</source>
<extracomment>The name of the EventType ({88ad3957-2912-4de1-b53d-b360565dd361}) of ThingClass thermostat</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="240"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="301"/>
<source>Unlock door</source>
<extracomment>The name of the ActionType ({6e112e3b-080f-47e4-8e2b-453029f0eacb}) of ThingClass doorLock</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="243"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="246"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="249"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="252"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="255"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="258"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="304"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="307"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="310"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="313"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="316"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="319"/>
<source>Version</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, EventType: version, ID: {9e27850b-99d8-40df-9bc7-4b3c7c01faf8})
----------
@ -256,9 +313,9 @@ The name of the StateType ({c8bd12d2-b425-4422-9e0e-a65542a47b70}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="261"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="264"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="267"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="322"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="325"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="328"/>
<source>Version changed</source>
<extracomment>The name of the EventType ({9e27850b-99d8-40df-9bc7-4b3c7c01faf8}) of ThingClass doorLock
----------
@ -268,21 +325,21 @@ The name of the EventType ({c8bd12d2-b425-4422-9e0e-a65542a47b70}) of ThingClass
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="270"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="331"/>
<source>Zigbee Generic</source>
<extracomment>The name of the plugin ZigbeeGeneric ({6a4343be-9fd6-4015-9ff5-38542651c534})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="273"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="334"/>
<source>Zigbee Thermostat</source>
<extracomment>The name of the ThingClass ({ca9af6cf-2d15-4d54-ba07-3d2ce03445b8})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="276"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="279"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="282"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="337"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="340"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="343"/>
<source>Zigbee network UUID</source>
<extracomment>The name of the ParamType (ThingClass: doorLock, Type: thing, ID: {4d50cbd3-f297-421c-9938-65ec0bb4bd34})
----------
@ -292,7 +349,7 @@ The name of the ParamType (ThingClass: thermostat, Type: thing, ID: {4a92b536-de
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="285"/>
<location filename="../../../build-nymea-plugins-Desktop-Debug/zigbeegeneric/plugininfo.h" line="346"/>
<source>nymea</source>
<extracomment>The name of the vendor ({2062d64d-3232-433c-88bc-0d33c0ba2ba6})</extracomment>
<translation type="unfinished"></translation>

View File

@ -97,7 +97,7 @@ bool IntegrationPluginZigbeeGenericLights::handleNode(ZigbeeNode *node, const QU
(endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation &&
endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOffLight)) {
qCDebug(dcZigbeeGenericLights()) << "Handeling on/off light for" << node << endpoint;
qCDebug(dcZigbeeGenericLights()) << "Handling on/off light for" << node << endpoint;
createLightThing(onOffLightThingClassId, networkUuid, node, endpoint);
handled = true;
}
@ -107,7 +107,7 @@ bool IntegrationPluginZigbeeGenericLights::handleNode(ZigbeeNode *node, const QU
(endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation &&
endpoint->deviceId() == Zigbee::HomeAutomationDeviceDimmableLight)) {
qCDebug(dcZigbeeGenericLights()) << "Handeling dimmable light for" << node << endpoint;
qCDebug(dcZigbeeGenericLights()) << "Handling dimmable light for" << node << endpoint;
createLightThing(dimmableLightThingClassId, networkUuid, node, endpoint);
handled = true;
}
@ -118,7 +118,7 @@ bool IntegrationPluginZigbeeGenericLights::handleNode(ZigbeeNode *node, const QU
(endpoint->profile() == Zigbee::ZigbeeProfileHomeAutomation &&
endpoint->deviceId() == Zigbee::HomeAutomationDeviceColourTemperatureLight)) {
qCDebug(dcZigbeeGenericLights()) << "Handeling color temperature light for" << node << endpoint;
qCDebug(dcZigbeeGenericLights()) << "Handling color temperature light for" << node << endpoint;
createLightThing(colorTemperatureLightThingClassId, networkUuid, node, endpoint);
handled = true;
}
@ -127,7 +127,7 @@ bool IntegrationPluginZigbeeGenericLights::handleNode(ZigbeeNode *node, const QU
(endpoint->profile() == Zigbee::ZigbeeProfileLightLink && endpoint->deviceId() == Zigbee::LightLinkDeviceExtendedColourLight) ||
(endpoint->profile() == Zigbee::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceExtendedColourLight)) {
qCDebug(dcZigbeeGenericLights()) << "Handeling color light for" << node << endpoint;
qCDebug(dcZigbeeGenericLights()) << "Handling color light for" << node << endpoint;
createLightThing(colorLightThingClassId, networkUuid, node, endpoint);
handled = true;
}