Add lumi smart power socket basics

master
Simon Stürz 2020-11-16 16:41:39 +01:00
parent 20813ef401
commit 4c367bbce6
3 changed files with 138 additions and 34 deletions

View File

@ -165,7 +165,7 @@ void IntegrationPluginZigbeeGenericLights::setupThing(ThingSetupInfo *info)
ZigbeeAddress zigbeeAddress = ZigbeeAddress(thing->paramValue(m_ieeeAddressParamTypeIds.value(thing->thingClassId())).toString());
ZigbeeNode *node = hardwareManager()->zigbeeResource()->claimNode(this, networkUuid, zigbeeAddress);
if (!node) {
qCWarning(dcZigbeeGenericLights()) << "Zigbee node for" << info->thing()->name() << "not found.´";
qCWarning(dcZigbeeGenericLights()) << "Zigbee node for" << info->thing()->name() << "not found.";
info->finish(Thing::ThingErrorHardwareNotAvailable);
return;
}

View File

@ -556,6 +556,81 @@
"displayName": "Vibration detected"
}
]
},
{
"name": "lumiPowerSocket",
"displayName": "Power socket",
"id": "76afde12-e781-4723-94ca-5704e800e821",
"setupMethod": "JustAdd",
"createMethods": [ "Auto" ],
"interfaces": [ "powersocket", "alert", "wirelessconnectable" ],
"paramTypes": [
{
"id": "0ebea7b9-488d-490e-9d70-e04ec92efd67",
"name": "ieeeAddress",
"displayName": "IEEE adress",
"type": "QString",
"defaultValue": "00:00:00:00:00:00:00:00"
},
{
"id": "f92b9d8b-6dbd-45dd-91f7-cd5f4d496877",
"name": "networkUuid",
"displayName": "Zigbee network UUID",
"type": "QString",
"defaultValue": ""
}
],
"stateTypes": [
{
"id": "58e01e24-fa6e-4518-ad05-f3b118901f69",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"type": "bool",
"cached": false,
"defaultValue": false
},
{
"id": "81926f63-4dc8-4701-a62d-07b20a849b37",
"name": "signalStrength",
"displayName": "Signal strength",
"displayNameEvent": "Signal strength changed",
"defaultValue": 0,
"maxValue": 100,
"minValue": 0,
"type": "uint",
"unit": "Percentage"
},
{
"id": "e4a8e90c-4e38-4b3b-b5e6-fd336e3fa2a8",
"name": "version",
"displayName": "Version",
"displayNameEvent": "Version changed",
"type": "QString",
"cached": true,
"defaultValue": ""
},
{
"id": "4c81aa6b-3a8a-4d2c-be87-29486ca242af",
"name": "power",
"displayName": "Power",
"displayNameEvent": "Power changed",
"displayNameAction": "Set power",
"type": "bool",
"defaultValue": false,
"writable": true
}
],
"actionTypes": [
{
"id": "67052e4d-350a-406f-91a9-3ce3f8eaaa7f",
"name": "alert",
"displayName": "Identify"
}
],
"eventTypes": [
]
}
]
}

View File

@ -46,6 +46,7 @@ IntegrationPluginZigbeeLumi::IntegrationPluginZigbeeLumi()
m_networkUuidParamTypeIds[lumiWaterSensorThingClassId] = lumiWaterSensorThingNetworkUuidParamTypeId;
m_networkUuidParamTypeIds[lumiWeatherSensorThingClassId] = lumiWeatherSensorThingNetworkUuidParamTypeId;
m_networkUuidParamTypeIds[lumiVibrationSensorThingClassId] = lumiVibrationSensorThingNetworkUuidParamTypeId;
m_networkUuidParamTypeIds[lumiPowerSocketThingClassId] = lumiPowerSocketThingNetworkUuidParamTypeId;
m_zigbeeAddressParamTypeIds[lumiHTSensorThingClassId] = lumiHTSensorThingIeeeAddressParamTypeId;
m_zigbeeAddressParamTypeIds[lumiButtonSensorThingClassId] = lumiButtonSensorThingIeeeAddressParamTypeId;
@ -54,6 +55,7 @@ IntegrationPluginZigbeeLumi::IntegrationPluginZigbeeLumi()
m_zigbeeAddressParamTypeIds[lumiWaterSensorThingClassId] = lumiWaterSensorThingIeeeAddressParamTypeId;
m_zigbeeAddressParamTypeIds[lumiWeatherSensorThingClassId] = lumiWeatherSensorThingIeeeAddressParamTypeId;
m_zigbeeAddressParamTypeIds[lumiVibrationSensorThingClassId] = lumiVibrationSensorThingIeeeAddressParamTypeId;
m_zigbeeAddressParamTypeIds[lumiPowerSocketThingClassId] = lumiPowerSocketThingIeeeAddressParamTypeId;
m_connectedStateTypeIds[lumiHTSensorThingClassId] = lumiHTSensorConnectedStateTypeId;
m_connectedStateTypeIds[lumiButtonSensorThingClassId] = lumiButtonSensorConnectedStateTypeId;
@ -62,6 +64,7 @@ IntegrationPluginZigbeeLumi::IntegrationPluginZigbeeLumi()
m_connectedStateTypeIds[lumiWaterSensorThingClassId] = lumiWaterSensorConnectedStateTypeId;
m_connectedStateTypeIds[lumiWeatherSensorThingClassId] = lumiWeatherSensorConnectedStateTypeId;
m_connectedStateTypeIds[lumiVibrationSensorThingClassId] = lumiVibrationSensorConnectedStateTypeId;
m_connectedStateTypeIds[lumiPowerSocketThingClassId] = lumiPowerSocketConnectedStateTypeId;
m_versionStateTypeIds[lumiHTSensorThingClassId] = lumiHTSensorVersionStateTypeId;
m_versionStateTypeIds[lumiButtonSensorThingClassId] = lumiButtonSensorVersionStateTypeId;
@ -70,6 +73,7 @@ IntegrationPluginZigbeeLumi::IntegrationPluginZigbeeLumi()
m_versionStateTypeIds[lumiWaterSensorThingClassId] = lumiWaterSensorVersionStateTypeId;
m_versionStateTypeIds[lumiWeatherSensorThingClassId] = lumiWeatherSensorVersionStateTypeId;
m_versionStateTypeIds[lumiVibrationSensorThingClassId] = lumiVibrationSensorVersionStateTypeId;
m_versionStateTypeIds[lumiPowerSocketThingClassId] = lumiPowerSocketVersionStateTypeId;
m_signalStrengthStateTypeIds[lumiHTSensorThingClassId] = lumiHTSensorSignalStrengthStateTypeId;
m_signalStrengthStateTypeIds[lumiButtonSensorThingClassId] = lumiButtonSensorSignalStrengthStateTypeId;
@ -78,6 +82,7 @@ IntegrationPluginZigbeeLumi::IntegrationPluginZigbeeLumi()
m_signalStrengthStateTypeIds[lumiWaterSensorThingClassId] = lumiWaterSensorSignalStrengthStateTypeId;
m_signalStrengthStateTypeIds[lumiWeatherSensorThingClassId] = lumiWeatherSensorSignalStrengthStateTypeId;
m_signalStrengthStateTypeIds[lumiVibrationSensorThingClassId] = lumiVibrationSensorSignalStrengthStateTypeId;
m_signalStrengthStateTypeIds[lumiPowerSocketThingClassId] = lumiPowerSocketSignalStrengthStateTypeId;
// Known model identifier
m_knownLumiDevices.insert("lumi.sensor_ht", lumiHTSensorThingClassId);
@ -87,6 +92,7 @@ IntegrationPluginZigbeeLumi::IntegrationPluginZigbeeLumi()
m_knownLumiDevices.insert("lumi.sensor_wleak", lumiWaterSensorThingClassId);
m_knownLumiDevices.insert("lumi.weather", lumiWeatherSensorThingClassId);
m_knownLumiDevices.insert("lumi.vibration", lumiVibrationSensorThingClassId);
m_knownLumiDevices.insert("lumi.plug", lumiPowerSocketThingClassId);
}
QString IntegrationPluginZigbeeLumi::name() const
@ -415,45 +421,68 @@ void IntegrationPluginZigbeeLumi::setupThing(ThingSetupInfo *info)
}
if (thing->thingClassId() == lumiPowerSocketThingClassId) {
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
if (onOffCluster) {
if (onOffCluster->hasAttribute(ZigbeeClusterOnOff::AttributeOnOff)) {
thing->setStateValue(lumiPowerSocketPowerStateTypeId, onOffCluster->power());
}
connect(onOffCluster, &ZigbeeClusterOnOff::powerChanged, thing, [thing](bool power){
qCDebug(dcZigbeeLumi()) << thing << "power changed" << power;
thing->setStateValue(lumiPowerSocketPowerStateTypeId, power);
});
} else {
qCWarning(dcZigbeeLumi()) << "Could not find the OnOff input cluster on" << thing << endpoint;
}
}
info->finish(Thing::ThingErrorNoError);
// if (thing->thingClassId() == lumiButtonSensorThingClassId) {
// qCDebug(dcZigbee()) << "Lumi button sensor" << thing;
// ZigbeeAddress ieeeAddress(thing->paramValue(lumiButtonSensorThingIeeeAddressParamTypeId).toString());
// ZigbeeNetwork *network = findParentNetwork(thing);
// LumiButtonSensor *sensor = new LumiButtonSensor(network, ieeeAddress, thing, this);
// connect(sensor, &LumiButtonSensor::buttonPressed, this, [this, thing](){
// qCDebug(dcZigbee()) << thing << "clicked event";
// emit emitEvent(Event(lumiButtonSensorPressedEventTypeId, thing->id()));
// });
// connect(sensor, &LumiButtonSensor::buttonLongPressed, this, [this, thing](){
// qCDebug(dcZigbee()) << thing << "long pressed event";
// emit emitEvent(Event(lumiButtonSensorLongPressedEventTypeId, thing->id()));
// });
// m_zigbeeDevices.insert(thing, sensor);
// info->finish(Thing::ThingErrorNoError);
// return;
// }
// if (thing->thingClassId() == lumiWaterSensorThingClassId) {
// qCDebug(dcZigbee()) << "Lumi water sensor" << thing;
// ZigbeeAddress ieeeAddress(thing->paramValue(lumiWaterSensorThingIeeeAddressParamTypeId).toString());
// ZigbeeNetwork *network = findParentNetwork(thing);
// LumiWaterSensor *sensor = new LumiWaterSensor(network, ieeeAddress, thing, this);
// m_zigbeeDevices.insert(thing, sensor);
// info->finish(Thing::ThingErrorNoError);
// return;
// }
// info->finish(Thing::ThingErrorThingClassNotFound);
}
void IntegrationPluginZigbeeLumi::executeAction(ThingActionInfo *info)
{
Thing *thing = info->thing();
if (thing->thingClassId() == lumiPowerSocketThingClassId) {
ZigbeeNode *node = m_thingNodes.value(thing);
if (!node) {
qCWarning(dcZigbeeLumi()) << "Zigbee node for" << thing->name() << "not found.";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
ZigbeeNodeEndpoint *endpoint = node->getEndpoint(0x01);
if (!endpoint) {
qCWarning(dcZigbeeLumi()) << "Unable to get the endpoint from node" << node << "for" << thing;
info->finish(Thing::ThingErrorSetupFailed);
return;
}
ZigbeeClusterOnOff *onOffCluster = endpoint->inputCluster<ZigbeeClusterOnOff>(ZigbeeClusterLibrary::ClusterIdOnOff);
if (!onOffCluster) {
qCWarning(dcZigbeeLumi()) << "Could not find on/off cluster for" << thing << "in" << node;
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
bool power = info->action().param(lumiPowerSocketPowerActionPowerParamTypeId).value().toBool();
qCDebug(dcZigbeeLumi()) << "Set power for" << info->thing() << "to" << power;
ZigbeeClusterReply *reply = (power ? onOffCluster->commandOn() : onOffCluster->commandOff());
connect(reply, &ZigbeeClusterReply::finished, info, [=](){
// Note: reply will be deleted automatically
if (reply->error() != ZigbeeClusterReply::ErrorNoError) {
qCWarning(dcZigbeeLumi()) << "Failed to set power on" << thing << reply->error();
info->finish(Thing::ThingErrorHardwareFailure);
} else {
info->finish(Thing::ThingErrorNoError);
qCDebug(dcZigbeeLumi()) << "Set power finished successfully for" << thing;
thing->setStateValue(lumiPowerSocketPowerStateTypeId, power);
}
});
return;
}
info->finish(Thing::ThingErrorUnsupportedFeature);
}