Try add a generic thermostat
This commit is contained in:
parent
5b533ab77f
commit
3cdc3414da
@ -8,6 +8,62 @@
|
|||||||
"displayName": "nymea",
|
"displayName": "nymea",
|
||||||
"id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6",
|
"id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6",
|
||||||
"thingClasses": [
|
"thingClasses": [
|
||||||
|
{
|
||||||
|
"id": "ca9af6cf-2d15-4d54-ba07-3d2ce03445b8",
|
||||||
|
"name": "thermostat",
|
||||||
|
"displayName": "Zigbee Thermostat",
|
||||||
|
"createMethods": ["auto"],
|
||||||
|
"interfaces": ["thermostat", "wirelessconnectable"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "f38746d8-0084-43a3-b645-3ec743ea5fbc",
|
||||||
|
"name": "ieeeAddress",
|
||||||
|
"displayName": "IEEE adress",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "00:00:00:00:00:00:00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4a92b536-de4c-4701-8117-9bb26dd51c3e",
|
||||||
|
"name": "networkUuid",
|
||||||
|
"displayName": "Zigbee network UUID",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "88ad3957-2912-4de1-b53d-b360565dd361",
|
||||||
|
"name": "targetTemperature",
|
||||||
|
"displayName": "Target temperature",
|
||||||
|
"displayNameEvent": "Target temperature changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "DegreeCelsius",
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 50,
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e9fb2b10-96da-4b70-afda-46e948399af8",
|
||||||
|
"name": "connected",
|
||||||
|
"displayName": "Connected",
|
||||||
|
"displayNameEvent": "Connected/disconnected",
|
||||||
|
"type": "bool",
|
||||||
|
"cached": false,
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8f0512ab-ced2-4dcb-90fe-aaa532efd0dd",
|
||||||
|
"name": "signalStrength",
|
||||||
|
"displayName": "Signal strength",
|
||||||
|
"displayNameEvent": "Signal strength changed",
|
||||||
|
"defaultValue": 0,
|
||||||
|
"maxValue": 100,
|
||||||
|
"minValue": 0,
|
||||||
|
"type": "uint",
|
||||||
|
"unit": "Percentage"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -37,7 +37,13 @@
|
|||||||
|
|
||||||
IntegrationPluginZigbeeGeneric::IntegrationPluginZigbeeGeneric()
|
IntegrationPluginZigbeeGeneric::IntegrationPluginZigbeeGeneric()
|
||||||
{
|
{
|
||||||
|
m_ieeeAddressParamTypeIds[thermostatThingClassId] = thermostatThingIeeeAddressParamTypeId;
|
||||||
|
|
||||||
|
m_networkUuidParamTypeIds[thermostatThingClassId] = thermostatThingNetworkUuidParamTypeId;
|
||||||
|
|
||||||
|
m_connectedStateTypeIds[thermostatThingClassId] = thermostatConnectedStateTypeId;
|
||||||
|
|
||||||
|
m_signalStrengthStateTypeIds[thermostatThingClassId] = thermostatSignalStrengthStateTypeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString IntegrationPluginZigbeeGeneric::name() const
|
QString IntegrationPluginZigbeeGeneric::name() const
|
||||||
@ -47,36 +53,29 @@ QString IntegrationPluginZigbeeGeneric::name() const
|
|||||||
|
|
||||||
bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &networkUuid)
|
bool IntegrationPluginZigbeeGeneric::handleNode(ZigbeeNode *node, const QUuid &networkUuid)
|
||||||
{
|
{
|
||||||
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
|
qCDebug(dcZigbeeGeneric()) << "handleNode called for:" << node;
|
||||||
qCDebug(dcZigbeeGeneric) << "Endpoint profile:" << endpoint->profile() << endpoint->deviceId() << networkUuid;
|
|
||||||
// if ((endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileLightLink && endpoint->deviceId() == Zigbee::LightLinkDevice::LightLinkDeviceOnOff
|
|
||||||
// (endpoint->profile() == Zigbee::ZigbeeProfile::ZigbeeProfileHomeAutomation && endpoint->deviceId() == Zigbee::HomeAutomationDeviceOnOf>
|
|
||||||
|
|
||||||
// // Create generic power socket
|
QHash<quint16, ThingClassId> devicesThingClassIdsMap;
|
||||||
// qCDebug(dcZigbee()) << "This device is an power socket";
|
devicesThingClassIdsMap.insert(Zigbee::HomeAutomationDeviceThermostat, thermostatThingClassId);
|
||||||
// if (myThings().filterByThingClassId(genericPowerSocketThingClassId)
|
|
||||||
// .filterByParam(genericPowerSocketThingIeeeAddressParamTypeId, node->extendedAddress().toString())
|
bool handled = false;
|
||||||
// .isEmpty()) {
|
|
||||||
// qCDebug(dcZigbee()) << "Adding new generic power socket";
|
foreach (ZigbeeNodeEndpoint *endpoint, node->endpoints()) {
|
||||||
// ThingDescriptor descriptor(genericPowerSocketThingClassId);
|
|
||||||
// QString deviceClassName = supportedThings().findById(genericPowerSocketThingClassId).displayName();
|
if (devicesThingClassIdsMap.contains(endpoint->deviceId())) {
|
||||||
// descriptor.setTitle(QString("%1 (%2 - %3)").arg(deviceClassName).arg(endpoint->manufacturerName()).arg(endpoint->modelIdentifier()));
|
ThingClassId thingClassId = devicesThingClassIdsMap.value(endpoint->deviceId());
|
||||||
// ParamList params;
|
ThingDescriptor descriptor(thingClassId, endpoint->modelIdentifier(), endpoint->manufacturerName());
|
||||||
// params.append(Param(genericPowerSocketThingIeeeAddressParamTypeId, node->extendedAddress().toString()));
|
ParamList params;
|
||||||
// params.append(Param(genericPowerSocketThingManufacturerParamTypeId, endpoint->manufacturerName()));
|
params << Param(m_ieeeAddressParamTypeIds.value(thingClassId), node->extendedAddress().toString());
|
||||||
// params.append(Param(genericPowerSocketThingModelParamTypeId, endpoint->modelIdentifier()));
|
params << Param(m_networkUuidParamTypeIds.value(thingClassId), networkUuid.toString());
|
||||||
// descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
// descriptor.setParentId(networkManagerDevice->id());
|
emit autoThingsAppeared({descriptor});
|
||||||
// emit autoThingsAppeared({descriptor});
|
|
||||||
// } else {
|
handled = true;
|
||||||
// qCDebug(dcZigbee()) << "The device for this node has already been created.";
|
}
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return handled;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntegrationPluginZigbeeGeneric::init()
|
void IntegrationPluginZigbeeGeneric::init()
|
||||||
@ -86,6 +85,53 @@ void IntegrationPluginZigbeeGeneric::init()
|
|||||||
|
|
||||||
void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
|
void IntegrationPluginZigbeeGeneric::setupThing(ThingSetupInfo *info)
|
||||||
{
|
{
|
||||||
|
if (!hardwareManager()->zigbeeResource()->available()) {
|
||||||
|
qCWarning(dcZigbeeGeneric()) << "Zigbee is not available. Not setting up" << info->thing()->name();
|
||||||
|
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Thing *thing = info->thing();
|
||||||
|
QUuid networkUuid = thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid();
|
||||||
|
qCDebug(dcZigbeeGeneric()) << "Nework uuid:" << networkUuid;
|
||||||
|
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(m_ieeeAddressParamTypeIds.value(thing->thingClassId())).toString());
|
||||||
|
ZigbeeNode *node = hardwareManager()->zigbeeResource()->getNode(networkUuid, zigbeeAddress);
|
||||||
|
if (!node) {
|
||||||
|
qCWarning(dcZigbeeGeneric()) << "Zigbee node for" << info->thing()->name() << "not found.´";
|
||||||
|
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeNodeEndpoint *endpoint = node->getEndpoint(0x01);
|
||||||
|
if (!endpoint) {
|
||||||
|
qCWarning(dcZigbeeGeneric()) << "Zigbee endpoint 1 not found on" << thing->name();
|
||||||
|
info->finish(Thing::ThingErrorSetupFailed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update connected state
|
||||||
|
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), hardwareManager()->zigbeeResource()->networkState(networkUuid) == ZigbeeNetwork::StateRunning);
|
||||||
|
connect(hardwareManager()->zigbeeResource(), &ZigbeeHardwareResource::networkStateChanged, thing, [thing, this](const QUuid &networkUuid, ZigbeeNetwork::State state){
|
||||||
|
if (thing->paramValue(m_networkUuidParamTypeIds.value(thing->thingClassId())).toUuid() == networkUuid) {
|
||||||
|
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), state == ZigbeeNetwork::StateRunning);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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(dcZigbeeGeneric()) << thing << "signal strength changed" << signalStrength << "%";
|
||||||
|
thing->setStateValue(m_signalStrengthStateTypeIds.value(thing->thingClassId()), signalStrength);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Type specific setup
|
||||||
|
if (thing->thingClassId() == thermostatThingClassId) {
|
||||||
|
// TODO: Thermostat cluster is missing
|
||||||
|
// ZigbeeClusterThermostat *thermostatCluster = endpoint->inputCluster<ZigbeeClusterThermostat>(ZigbeeClusterLibrary::ClusterIdThermostat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,12 @@ public:
|
|||||||
void thingRemoved(Thing *thing) override;
|
void thingRemoved(Thing *thing) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
QHash<ThingClassId, ParamTypeId> m_ieeeAddressParamTypeIds;
|
||||||
|
QHash<ThingClassId, ParamTypeId> m_networkUuidParamTypeIds;
|
||||||
|
|
||||||
|
QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds;
|
||||||
|
QHash<ThingClassId, StateTypeId> m_signalStrengthStateTypeIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INTEGRATIONPLUGINZIGBEEGENERIC_H
|
#endif // INTEGRATIONPLUGINZIGBEEGENERIC_H
|
||||||
|
|||||||
@ -167,7 +167,7 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
|||||||
if (thing->thingClassId() == lumiMagnetSensorThingClassId) {
|
if (thing->thingClassId() == lumiMagnetSensorThingClassId) {
|
||||||
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
|
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
|
||||||
if (onOffCluster) {
|
if (onOffCluster) {
|
||||||
thing->setStateValue(lumiMagnetSensorClosedStateTypeId, !onOffCluster->powered());
|
// thing->setStateValue(lumiMagnetSensorClosedStateTypeId, !onOffCluster->powered());
|
||||||
connect(onOffCluster, &ZigbeeClusterOnOff::powerChanged, thing, [thing](bool power){
|
connect(onOffCluster, &ZigbeeClusterOnOff::powerChanged, thing, [thing](bool power){
|
||||||
qCDebug(dcZigbeeLumi()) << thing << "state changed" << (power ? "closed" : "open");
|
qCDebug(dcZigbeeLumi()) << thing << "state changed" << (power ? "closed" : "open");
|
||||||
thing->setStateValue(lumiMagnetSensorClosedStateTypeId, !power);
|
thing->setStateValue(lumiMagnetSensorClosedStateTypeId, !power);
|
||||||
@ -180,7 +180,7 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
|||||||
if (thing->thingClassId() == lumiMotionSensorThingClassId) {
|
if (thing->thingClassId() == lumiMotionSensorThingClassId) {
|
||||||
ZigbeeClusterOccupancySensing *occupancyCluster = endpoint->inputCluster<ZigbeeClusterOccupancySensing>(ZigbeeClusterLibrary::ClusterIdOccupancySensing);
|
ZigbeeClusterOccupancySensing *occupancyCluster = endpoint->inputCluster<ZigbeeClusterOccupancySensing>(ZigbeeClusterLibrary::ClusterIdOccupancySensing);
|
||||||
if (occupancyCluster) {
|
if (occupancyCluster) {
|
||||||
thing->setStateValue(lumiMotionSensorIsPresentStateTypeId, occupancyCluster->occupancy());
|
// thing->setStateValue(lumiMotionSensorIsPresentStateTypeId, occupancyCluster->occupancy());
|
||||||
connect(occupancyCluster, &ZigbeeClusterOccupancySensing::occupancyChanged, thing, [thing](bool occupancy){
|
connect(occupancyCluster, &ZigbeeClusterOccupancySensing::occupancyChanged, thing, [thing](bool occupancy){
|
||||||
qCDebug(dcZigbeeLumi()) << "occupancy changed" << occupancy;
|
qCDebug(dcZigbeeLumi()) << "occupancy changed" << occupancy;
|
||||||
thing->setStateValue(lumiMotionSensorIsPresentStateTypeId, occupancy);
|
thing->setStateValue(lumiMotionSensorIsPresentStateTypeId, occupancy);
|
||||||
@ -207,7 +207,7 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
|||||||
|
|
||||||
ZigbeeClusterIlluminanceMeasurment *illuminanceCluster = endpoint->inputCluster<ZigbeeClusterIlluminanceMeasurment>(ZigbeeClusterLibrary::ClusterIdIlluminanceMeasurement);
|
ZigbeeClusterIlluminanceMeasurment *illuminanceCluster = endpoint->inputCluster<ZigbeeClusterIlluminanceMeasurment>(ZigbeeClusterLibrary::ClusterIdIlluminanceMeasurement);
|
||||||
if (illuminanceCluster) {
|
if (illuminanceCluster) {
|
||||||
thing->setStateValue(lumiHTSensorTemperatureStateTypeId, illuminanceCluster->illuminance());
|
// thing->setStateValue(lumiHTSensorTemperatureStateTypeId, illuminanceCluster->illuminance());
|
||||||
connect(illuminanceCluster, &ZigbeeClusterIlluminanceMeasurment::illuminanceChanged, thing, [thing](quint16 illuminance){
|
connect(illuminanceCluster, &ZigbeeClusterIlluminanceMeasurment::illuminanceChanged, thing, [thing](quint16 illuminance){
|
||||||
thing->setStateValue(lumiMotionSensorLightIntensityStateTypeId, illuminance);
|
thing->setStateValue(lumiMotionSensorLightIntensityStateTypeId, illuminance);
|
||||||
});
|
});
|
||||||
@ -219,7 +219,7 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
|||||||
if (thing->thingClassId() == lumiHTSensorThingClassId) {
|
if (thing->thingClassId() == lumiHTSensorThingClassId) {
|
||||||
ZigbeeClusterTemperatureMeasurement *temperatureCluster = endpoint->inputCluster<ZigbeeClusterTemperatureMeasurement>(ZigbeeClusterLibrary::ClusterIdTemperatureMeasurement);
|
ZigbeeClusterTemperatureMeasurement *temperatureCluster = endpoint->inputCluster<ZigbeeClusterTemperatureMeasurement>(ZigbeeClusterLibrary::ClusterIdTemperatureMeasurement);
|
||||||
if (temperatureCluster) {
|
if (temperatureCluster) {
|
||||||
thing->setStateValue(lumiHTSensorTemperatureStateTypeId, temperatureCluster->temperature());
|
// thing->setStateValue(lumiHTSensorTemperatureStateTypeId, temperatureCluster->temperature());
|
||||||
connect(temperatureCluster, &ZigbeeClusterTemperatureMeasurement::temperatureChanged, thing, [thing](double temperature){
|
connect(temperatureCluster, &ZigbeeClusterTemperatureMeasurement::temperatureChanged, thing, [thing](double temperature){
|
||||||
thing->setStateValue(lumiHTSensorTemperatureStateTypeId, temperature);
|
thing->setStateValue(lumiHTSensorTemperatureStateTypeId, temperature);
|
||||||
});
|
});
|
||||||
@ -229,7 +229,7 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
|
|||||||
|
|
||||||
ZigbeeClusterRelativeHumidityMeasurement *humidityCluster = endpoint->inputCluster<ZigbeeClusterRelativeHumidityMeasurement>(ZigbeeClusterLibrary::ClusterIdRelativeHumidityMeasurement);
|
ZigbeeClusterRelativeHumidityMeasurement *humidityCluster = endpoint->inputCluster<ZigbeeClusterRelativeHumidityMeasurement>(ZigbeeClusterLibrary::ClusterIdRelativeHumidityMeasurement);
|
||||||
if (humidityCluster) {
|
if (humidityCluster) {
|
||||||
thing->setStateValue(lumiHTSensorHumidityStateTypeId, humidityCluster->humidity());
|
// thing->setStateValue(lumiHTSensorHumidityStateTypeId, humidityCluster->humidity());
|
||||||
connect(humidityCluster, &ZigbeeClusterRelativeHumidityMeasurement::humidityChanged, thing, [thing](double humidity){
|
connect(humidityCluster, &ZigbeeClusterRelativeHumidityMeasurement::humidityChanged, thing, [thing](double humidity){
|
||||||
thing->setStateValue(lumiHTSensorHumidityStateTypeId, humidity);
|
thing->setStateValue(lumiHTSensorHumidityStateTypeId, humidity);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user