Shelly: Add support for the plus addon

master
Michael Zanetti 2023-04-13 16:31:57 +02:00
parent ca3329909b
commit 86493eaf56
2 changed files with 183 additions and 91 deletions

View File

@ -240,6 +240,44 @@ void IntegrationPluginShelly::postSetupThing(Thing *thing)
fetchStatusGen1(thing);
}
}
// Check if a Addon is connected
if (thing->thingClassId() == shellyPlus1ThingClassId
|| thing->thingClassId() == shellyPlus1pmThingClassId
|| thing->thingClassId() == shellyPlus25ThingClassId) {
// Narf... seems they forgot to register the SensorAddon namespace on the RPC interface
ShellyJsonRpcClient *client = m_rpcClients.value(thing);
ShellyRpcReply *reply = client->sendRequest("SensorAddon.GetPeripherals");
connect(reply, &ShellyRpcReply::finished, thing, [this, thing](ShellyRpcReply::Status status, const QVariantMap &response){
if (status != ShellyRpcReply::StatusSuccess) {
qCWarning(dcShelly()) << "Error fetching peripherals for shelly";
return;
}
qCDebug(dcShelly()) << "Peripherals:" << qUtf8Printable(QJsonDocument::fromVariant(response).toJson());
QVariantMap ds18b20 = response.value("ds18b20").toMap();
if (!ds18b20.isEmpty()) {
foreach (const QVariant &key, ds18b20.keys()) {
if (key.toString().startsWith("temperature")) {
QVariantMap temp = ds18b20.value(key.toString()).toMap();
QString addr = temp.value("addr").toString();
qCDebug(dcShelly()) << "Detected OneWire Temp sensor with id" << key.toString() << "at" << addr;
Thing *existingThing = myThings().filterByParentId(thing->id()).findByParams(ParamList({{shellyAddonTempSensorThingAddonIdParamTypeId, key}}));
if (!existingThing) {
qCDebug(dcShelly()) << "Creating new Temp sensor thing" << key.toString();
ThingClass addonTempThingClass = supportedThings().findById(shellyAddonTempSensorThingClassId);
ThingDescriptor descriptor(shellyAddonTempSensorThingClassId, addonTempThingClass.displayName(), QString(), thing->id());
descriptor.setParams(ParamList{{shellyAddonTempSensorThingAddonIdParamTypeId, key}});
emit autoThingsAppeared({descriptor});
} else {
qCDebug(dcShelly()) << "Temp sensor thing already exists";
}
}
}
}
});
}
}
void IntegrationPluginShelly::thingRemoved(Thing *thing)
@ -1674,7 +1712,9 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
});
connect(client, &ShellyJsonRpcClient::notificationReceived, thing, [thing, this](const QVariantMap &notification){
qCDebug(dcShelly) << "notification received" << qUtf8Printable(QJsonDocument::fromVariant(notification).toJson());
if (notification.contains("switch:0")) {
foreach (const QVariant &key, notification.keys()) {
QString id = key.toString();
if (id == "switch:0") {
QVariantMap switch0 = notification.value("switch:0").toMap();
if (switch0.contains("apower") && thing->hasState("currentPower")) { // for shellyplus1pm
thing->setStateValue("currentPower", switch0.value("apower").toDouble());
@ -1698,7 +1738,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
thing->setStateValue("channel1", switch0.value("output").toBool());
}
}
if (notification.contains("switch:1")) {
if (id == "switch:1") {
QVariantMap switch1 = notification.value("switch:1").toMap();
Thing *parentThing = myThings().filterByParentId(thing->id()).findByParams({Param(shellyPowerMeterChannelThingChannelParamTypeId, 2)});
if (parentThing) {
@ -1713,7 +1753,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
thing->setStateValue("channel2", switch1.value("output").toBool());
}
}
if (notification.contains("cover:0")) {
if (id == "cover:0") {
QVariantMap cover0 = notification.value("cover:0").toMap();
Thing *t = myThings().filterByParentId(thing->id()).findByParams({Param(shellyRollerThingChannelParamTypeId, 1)});
if (cover0.contains("apower") && t) {
@ -1737,7 +1777,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
thing->setStateValue("power", cover0.value("output").toBool());
}
}
if (notification.contains("input:0")) {
if (id == "input:0") {
QVariantMap input0 = notification.value("input:0").toMap();
Thing *t = myThings().filterByParentId(thing->id()).findByParams({Param(shellySwitchThingChannelParamTypeId, 1)});
if (t) {
@ -1745,7 +1785,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
t->emitEvent("pressed");
}
}
if (notification.contains("input:1")) {
if (id == "input:1") {
QVariantMap input1 = notification.value("input:1").toMap();
Thing *t = myThings().filterByParentId(thing->id()).findByParams({Param(shellySwitchThingChannelParamTypeId, 2)});
if (t) {
@ -1753,7 +1793,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
t->emitEvent("pressed");
}
}
if (notification.contains("em:0")) {
if (id == "em:0") {
QVariantMap em0 = notification.value("em:0").toMap();
thing->setStateValue(shellyPro3EMCurrentPowerPhaseAStateTypeId, em0.value("a_act_power").toDouble());
thing->setStateValue(shellyPro3EMVoltagePhaseAStateTypeId, em0.value("a_voltage").toDouble());
@ -1767,7 +1807,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
thing->setStateValue(shellyPro3EMCurrentPowerStateTypeId, em0.value("total_act_power").toDouble());
}
if (notification.contains("emdata:0")) {
if (id == "emdata:0") {
QVariantMap emdata0 = notification.value("emdata:0").toMap();
thing->setStateValue(shellyPro3EMEnergyConsumedPhaseAStateTypeId, emdata0.value("a_total_act_energy").toDouble() / 1000);
thing->setStateValue(shellyPro3EMEnergyProducedPhaseAStateTypeId, emdata0.value("a_total_act_ret_energy").toDouble() / 1000);
@ -1778,6 +1818,16 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
thing->setStateValue(shellyPro3EMTotalEnergyConsumedStateTypeId, emdata0.value("total_act").toDouble() / 1000);
thing->setStateValue(shellyPro3EMTotalEnergyProducedStateTypeId, emdata0.value("total_act_ret").toDouble() / 1000);
}
if (id.startsWith("temperature")) {
Thing *addonTempSensor = myThings().filterByParentId(thing->id()).findByParams({{shellyAddonTempSensorThingAddonIdParamTypeId, id}});
if (addonTempSensor) {
QVariantMap temperatureMap = notification.value(id).toMap();
addonTempSensor->setStateValue(shellyAddonTempSensorTemperatureStateTypeId, temperatureMap.value("tC").toDouble());
}
}
}
});
// Handle thing settings of devices

View File

@ -3768,6 +3768,48 @@
"displayName": "Calibrate"
}
]
},
{
"id": "dffcc66b-bb93-4de0-9ad4-0b2ca0fa813a",
"name": "shellyAddonTempSensor",
"displayName": "Shelly Addon temperature sensor",
"createMethods": ["auto"],
"interfaces": ["temperaturesensor", "wirelessconnectable"],
"paramTypes": [
{
"id": "85845b89-0c78-4f9b-8107-d179604e1ad8",
"name": "addonId",
"displayName": "ID",
"type": "QString"
}
],
"stateTypes": [
{
"id": "982846ff-e045-4e4d-8959-b5ea65b83082",
"name": "connected",
"displayName": "Connected",
"type": "bool",
"defaultValue": false
},
{
"id": "5e9ed1dd-a1f7-4755-ac6f-30013580d363",
"name": "signalStrength",
"displayName": "Signal strength",
"type": "uint",
"unit": "Percentage",
"minValue": 0,
"maxValue": 100,
"defaultValue": 0
},
{
"id": "b0062fc6-8fa1-4754-904a-c18614114998",
"name": "temperature",
"displayName": "Temperature",
"type": "double",
"unit": "DegreeCelsius",
"defaultValue": 0
}
]
}
]
}