Merge PR #686: Shelly: Add support for the Shelly Pro 3EM
commit
6ae918003b
|
|
@ -17,6 +17,7 @@ The currently supported devices are:
|
|||
* Shelly Button 1
|
||||
* Shelly EM
|
||||
* Shelly 3EM
|
||||
* Shelly Pro 3EM
|
||||
* Shelly H+T
|
||||
* Shelly i3
|
||||
* Shelly Motion
|
||||
|
|
|
|||
|
|
@ -61,84 +61,6 @@ static QHash<QString, QString> updateStatusMap = {
|
|||
{"unknown", "idle"}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> idParamTypeMap = {
|
||||
{shelly1ThingClassId, shelly1ThingIdParamTypeId},
|
||||
{shelly1pmThingClassId, shelly1pmThingIdParamTypeId},
|
||||
{shelly1lThingClassId, shelly1lThingIdParamTypeId},
|
||||
{shellyPlugThingClassId, shellyPlugThingIdParamTypeId},
|
||||
{shellyPlusPlugThingClassId, shellyPlusPlugThingIdParamTypeId},
|
||||
{shellyRgbw2ThingClassId, shellyRgbw2ThingIdParamTypeId},
|
||||
{shellyDimmerThingClassId, shellyDimmerThingIdParamTypeId},
|
||||
{shelly2ThingClassId, shelly2ThingIdParamTypeId},
|
||||
{shelly25ThingClassId, shelly25ThingIdParamTypeId},
|
||||
{shellyButton1ThingClassId, shellyButton1ThingIdParamTypeId},
|
||||
{shellyEmThingClassId, shellyEmThingIdParamTypeId},
|
||||
{shellyEm3ThingClassId, shellyEm3ThingIdParamTypeId},
|
||||
{shellyHTThingClassId, shellyHTThingIdParamTypeId},
|
||||
{shellyI3ThingClassId, shellyI3ThingIdParamTypeId},
|
||||
{shellyMotionThingClassId, shellyMotionThingIdParamTypeId},
|
||||
{shellyTrvThingClassId, shellyTrvThingIdParamTypeId},
|
||||
{shellyFloodThingClassId, shellyFloodThingIdParamTypeId},
|
||||
{shellySmokeThingClassId, shellySmokeThingIdParamTypeId},
|
||||
{shellyGasThingClassId, shellyGasThingIdParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> usernameParamTypeMap = {
|
||||
{shelly1ThingClassId, shelly1ThingUsernameParamTypeId},
|
||||
{shelly1pmThingClassId, shelly1pmThingUsernameParamTypeId},
|
||||
{shelly1lThingClassId, shelly1lThingUsernameParamTypeId},
|
||||
{shellyPlugThingClassId, shellyPlugThingUsernameParamTypeId},
|
||||
{shellyPlusPlugThingClassId, shellyPlusPlugThingUsernameParamTypeId},
|
||||
{shellyRgbw2ThingClassId, shellyRgbw2ThingUsernameParamTypeId},
|
||||
{shellyDimmerThingClassId, shellyDimmerThingUsernameParamTypeId},
|
||||
{shelly2ThingClassId, shelly2ThingUsernameParamTypeId},
|
||||
{shelly25ThingClassId, shelly25ThingUsernameParamTypeId},
|
||||
{shellyButton1ThingClassId, shellyButton1ThingUsernameParamTypeId},
|
||||
{shellyEmThingClassId, shellyEmThingUsernameParamTypeId},
|
||||
{shellyEm3ThingClassId, shellyEm3ThingUsernameParamTypeId},
|
||||
{shellyHTThingClassId, shellyHTThingUsernameParamTypeId},
|
||||
{shellyI3ThingClassId, shellyI3ThingUsernameParamTypeId},
|
||||
{shellyMotionThingClassId, shellyMotionThingUsernameParamTypeId},
|
||||
{shellyTrvThingClassId, shellyTrvThingUsernameParamTypeId},
|
||||
{shellyFloodThingClassId, shellyFloodThingUsernameParamTypeId},
|
||||
{shellySmokeThingClassId, shellySmokeThingUsernameParamTypeId},
|
||||
{shellyGasThingClassId, shellyGasThingUsernameParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> passwordParamTypeMap = {
|
||||
{shelly1ThingClassId, shelly1ThingPasswordParamTypeId},
|
||||
{shelly1pmThingClassId, shelly1pmThingPasswordParamTypeId},
|
||||
{shelly1lThingClassId, shelly1lThingPasswordParamTypeId},
|
||||
{shellyPlugThingClassId, shellyPlugThingPasswordParamTypeId},
|
||||
{shellyPlusPlugThingClassId, shellyPlusPlugThingPasswordParamTypeId},
|
||||
{shellyRgbw2ThingClassId, shellyRgbw2ThingPasswordParamTypeId},
|
||||
{shellyDimmerThingClassId, shellyDimmerThingPasswordParamTypeId},
|
||||
{shelly2ThingClassId, shelly2ThingPasswordParamTypeId},
|
||||
{shelly25ThingClassId, shelly25ThingPasswordParamTypeId},
|
||||
{shellyButton1ThingClassId, shellyButton1ThingPasswordParamTypeId},
|
||||
{shellyEmThingClassId, shellyEmThingPasswordParamTypeId},
|
||||
{shellyEm3ThingClassId, shellyEm3ThingPasswordParamTypeId},
|
||||
{shellyHTThingClassId, shellyHTThingPasswordParamTypeId},
|
||||
{shellyI3ThingClassId, shellyI3ThingPasswordParamTypeId},
|
||||
{shellyMotionThingClassId, shellyMotionThingPasswordParamTypeId},
|
||||
{shellyTrvThingClassId, shellyTrvThingPasswordParamTypeId},
|
||||
{shellyFloodThingClassId, shellyFloodThingPasswordParamTypeId},
|
||||
{shellySmokeThingClassId, shellySmokeThingPasswordParamTypeId},
|
||||
{shellyGasThingClassId, shellyGasThingPasswordParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> rollerModeParamTypeMap = {
|
||||
{shelly2ThingClassId, shelly2ThingRollerModeParamTypeId},
|
||||
{shelly25ThingClassId, shelly25ThingRollerModeParamTypeId}
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, ParamTypeId> channelParamTypeMap = {
|
||||
{shellySwitchThingClassId, shellySwitchThingChannelParamTypeId},
|
||||
{shellyRollerThingClassId, shellyRollerThingChannelParamTypeId},
|
||||
{shellyPowerMeterChannelThingClassId, shellyPowerMeterChannelThingChannelParamTypeId},
|
||||
{shellyEmChannelThingClassId, shellyEmChannelThingChannelParamTypeId},
|
||||
};
|
||||
|
||||
static QHash<ThingClassId, StateTypeId> colorTemperatureStateTypeMap = {
|
||||
{shellyRgbw2ThingClassId, shellyRgbw2ColorTemperatureStateTypeId},
|
||||
};
|
||||
|
|
@ -321,6 +243,8 @@ void IntegrationPluginShelly::discoverThings(ThingDiscoveryInfo *info)
|
|||
namePattern = QRegExp("^shellyem-[0-9A-Z]+$");
|
||||
} else if (info->thingClassId() == shellyEm3ThingClassId) {
|
||||
namePattern = QRegExp("^shellyem3-[0-9A-Z]+$");
|
||||
} else if (info->thingClassId() == shellyPro3EMThingClassId) {
|
||||
namePattern = QRegExp("^ShellyPro3EM-[0-9A-Z]+$");
|
||||
} else if (info->thingClassId() == shellyHTThingClassId) {
|
||||
namePattern = QRegExp("shellyht-[0-9A-Z]+$");
|
||||
} else if (info->thingClassId() == shellyI3ThingClassId) {
|
||||
|
|
@ -342,15 +266,17 @@ void IntegrationPluginShelly::discoverThings(ThingDiscoveryInfo *info)
|
|||
|
||||
ThingDescriptor descriptor(info->thingClassId(), entry.name(), entry.hostAddress().toString());
|
||||
ParamList params;
|
||||
params << Param(idParamTypeMap.value(info->thingClassId()), entry.name());
|
||||
params << Param(usernameParamTypeMap.value(info->thingClassId()), "");
|
||||
params << Param(passwordParamTypeMap.value(info->thingClassId()), "");
|
||||
if (rollerModeParamTypeMap.contains(info->thingClassId())) {
|
||||
params << Param(rollerModeParamTypeMap.value(info->thingClassId()), false);
|
||||
ThingClass thingClass = supportedThings().findById(info->thingClassId());
|
||||
|
||||
params << Param(thingClass.paramTypes().findByName("id").id(), entry.name());
|
||||
params << Param(thingClass.paramTypes().findByName("username").id(), "");
|
||||
params << Param(thingClass.paramTypes().findByName("password").id(), "");
|
||||
if (!thingClass.paramTypes().findByName("rollerMode").id().isNull()) {
|
||||
params << Param(thingClass.paramTypes().findByName("rollerMode").id(), false);
|
||||
}
|
||||
descriptor.setParams(params);
|
||||
|
||||
Things existingThings = myThings().filterByParam(idParamTypeMap.value(info->thingClassId()), entry.name());
|
||||
Things existingThings = myThings().filterByParam(thingClass.paramTypes().findByName("id").id(), entry.name());
|
||||
if (existingThings.count() == 1) {
|
||||
qCInfo(dcShelly()) << "This existing shelly:" << entry;
|
||||
descriptor.setThingId(existingThings.first()->id());
|
||||
|
|
@ -368,12 +294,10 @@ void IntegrationPluginShelly::setupThing(ThingSetupInfo *info)
|
|||
{
|
||||
Thing *thing = info->thing();
|
||||
|
||||
if (idParamTypeMap.contains(thing->thingClassId())) {
|
||||
if (!thing->thingClass().paramTypes().findByName("id").id().isNull()) {
|
||||
|
||||
QString shellyId = info->thing()->paramValue(idParamTypeMap.value(info->thing()->thingClassId())).toString();
|
||||
if (shellyId.contains("Plus")
|
||||
|| shellyId.startsWith("ShellyPlug") // Plus plug variants don't have Plus in the name, but are camelcased as opposed to 1st gen plugs
|
||||
) {
|
||||
QString shellyId = info->thing()->paramValue("id").toString();
|
||||
if (isGen2(shellyId)) {
|
||||
setupGen2(info);
|
||||
} else {
|
||||
setupGen1(info);
|
||||
|
|
@ -393,7 +317,7 @@ void IntegrationPluginShelly::postSetupThing(Thing *thing)
|
|||
}
|
||||
|
||||
if (thing->parentId().isNull()) {
|
||||
if (thing->paramValue("id").toString().contains("Plus")) {
|
||||
if (isGen2(thing->paramValue("id").toString())) {
|
||||
fetchStatusGen2(thing);
|
||||
} else {
|
||||
fetchStatusGen1(thing);
|
||||
|
|
@ -427,13 +351,13 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
QUrl url;
|
||||
url.setScheme("http");
|
||||
url.setHost(getIP(info->thing()).toString());
|
||||
if (!thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString().isEmpty()) {
|
||||
url.setUserName(thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString());
|
||||
url.setPassword(thing->paramValue(passwordParamTypeMap.value(thing->thingClassId())).toString());
|
||||
if (!thing->paramValue("id").toString().isEmpty()) {
|
||||
url.setUserName(thing->paramValue("username").toString());
|
||||
url.setPassword(thing->paramValue("password").toString());
|
||||
}
|
||||
|
||||
if (rebootActionTypeMap.contains(action.actionTypeId())) {
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
ShellyRpcReply *reply = m_rpcClients.value(thing)->sendRequest("Shelly.Reboot");
|
||||
connect(reply, &ShellyRpcReply::finished, info, [info](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
|
||||
info->finish(status == ShellyRpcReply::StatusSuccess ? Thing::ThingErrorNoError : Thing::ThingErrorHardwareFailure);
|
||||
|
|
@ -471,8 +395,8 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
{shelly25Channel1ActionTypeId, 1},
|
||||
{shelly25Channel2ActionTypeId, 2}
|
||||
};
|
||||
if (channelParamTypeMap.contains(thing->thingClassId())) {
|
||||
relay = thing->paramValue(channelParamTypeMap.value(thing->thingClassId())).toInt();
|
||||
if (!thing->thingClass().paramTypes().findByName("channel").id().isNull()) {
|
||||
relay = thing->paramValue("channel").toInt();
|
||||
} else if (actionChannelMap.contains(action.actionTypeId())) {
|
||||
relay = actionChannelMap.value(action.actionTypeId());
|
||||
}
|
||||
|
|
@ -480,7 +404,7 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
ParamTypeId powerParamTypeId = powerActionParamTypesMap.value(action.actionTypeId());
|
||||
bool on = action.param(powerParamTypeId).value().toBool();
|
||||
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
QVariantMap params;
|
||||
params.insert("id", relay - 1);
|
||||
params.insert("on", on);
|
||||
|
|
@ -675,7 +599,7 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
}
|
||||
|
||||
if (action.actionTypeId() == shellyRollerOpenActionTypeId) {
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
QVariantMap params;
|
||||
int channelNbr = info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1;
|
||||
params.insert("id", channelNbr);
|
||||
|
|
@ -698,7 +622,7 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
}
|
||||
|
||||
if (action.actionTypeId() == shellyRollerCloseActionTypeId) {
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
QVariantMap params;
|
||||
int channelNbr = info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1;
|
||||
params.insert("id", channelNbr);
|
||||
|
|
@ -721,7 +645,7 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
}
|
||||
|
||||
if (action.actionTypeId() == shellyRollerStopActionTypeId) {
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
QVariantMap params;
|
||||
int channelNbr = info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1;
|
||||
params.insert("id", channelNbr);
|
||||
|
|
@ -744,7 +668,7 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
}
|
||||
|
||||
if (action.actionTypeId() == shellyRollerCalibrateActionTypeId) {
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
QVariantMap params;
|
||||
int channelNbr = info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1;
|
||||
params.insert("id", channelNbr);
|
||||
|
|
@ -764,7 +688,7 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||
}
|
||||
|
||||
if (action.actionTypeId() == shellyRollerPercentageActionTypeId) {
|
||||
if (shellyId.contains("Plus")) {
|
||||
if (isGen2(shellyId)) {
|
||||
QVariantMap params;
|
||||
int channelNbr = info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1;
|
||||
int positionTarget = info->action().paramValue(shellyRollerPercentageActionPercentageParamTypeId).toInt();
|
||||
|
|
@ -1281,7 +1205,7 @@ void IntegrationPluginShelly::onMulticastMessageReceived(const QHostAddress &sou
|
|||
void IntegrationPluginShelly::updateStatus()
|
||||
{
|
||||
foreach (Thing *thing, myThings().filterByParentId(ThingId())) {
|
||||
if (thing->paramValue("id").toString().contains("Plus")) {
|
||||
if (isGen2(thing->paramValue("id").toString())) {
|
||||
fetchStatusGen2(thing);
|
||||
} else {
|
||||
//Skipping sleepy devices, as they won't reply to cyclic requests.
|
||||
|
|
@ -1302,8 +1226,8 @@ void IntegrationPluginShelly::fetchStatusGen1(Thing *thing)
|
|||
url.setScheme("http");
|
||||
url.setHost(address.toString());
|
||||
url.setPath("/status");
|
||||
url.setUserName(thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString());
|
||||
url.setPassword(thing->paramValue(passwordParamTypeMap.value(thing->thingClassId())).toString());
|
||||
url.setUserName(thing->paramValue("username").toString());
|
||||
url.setPassword(thing->paramValue("password").toString());
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, thing, [this, thing, reply](){
|
||||
|
|
@ -1437,7 +1361,7 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||
|
||||
bool rollerMode = false;
|
||||
if (info->thing()->thingClassId() == shelly2ThingClassId || info->thing()->thingClassId() == shelly25ThingClassId) {
|
||||
rollerMode = info->thing()->paramValue(rollerModeParamTypeMap.value(info->thing()->thingClassId())).toBool();
|
||||
rollerMode = info->thing()->paramValue("rollerMode").toBool();
|
||||
}
|
||||
|
||||
QUrl url;
|
||||
|
|
@ -1445,9 +1369,9 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||
url.setHost(address.toString());
|
||||
url.setPort(80);
|
||||
url.setPath("/settings");
|
||||
if (!thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString().isEmpty()) {
|
||||
url.setUserName(info->thing()->paramValue(usernameParamTypeMap.value(info->thing()->thingClassId())).toString());
|
||||
url.setPassword(info->thing()->paramValue(passwordParamTypeMap.value(info->thing()->thingClassId())).toString());
|
||||
if (!thing->paramValue("username").toString().isEmpty()) {
|
||||
url.setUserName(info->thing()->paramValue("username").toString());
|
||||
url.setPassword(info->thing()->paramValue("password").toString());
|
||||
}
|
||||
|
||||
QUrlQuery query;
|
||||
|
|
@ -1582,8 +1506,8 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||
emit autoThingsAppeared(autoChilds);
|
||||
|
||||
// Make sure authentication is enalbed if the user wants it
|
||||
QString username = info->thing()->paramValue(usernameParamTypeMap.value(info->thing()->thingClassId())).toString();
|
||||
QString password = info->thing()->paramValue(passwordParamTypeMap.value(info->thing()->thingClassId())).toString();
|
||||
QString username = info->thing()->paramValue("username").toString();
|
||||
QString password = info->thing()->paramValue("password").toString();
|
||||
if (!username.isEmpty()) {
|
||||
QUrl url;
|
||||
url.setScheme("http");
|
||||
|
|
@ -1637,8 +1561,8 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||
url.setScheme("http");
|
||||
url.setHost(address);
|
||||
url.setPort(80);
|
||||
url.setUserName(thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString());
|
||||
url.setPassword(thing->paramValue(passwordParamTypeMap.value(thing->thingClassId())).toString());
|
||||
url.setUserName(thing->paramValue("username").toString());
|
||||
url.setPassword(thing->paramValue("password").toString());
|
||||
|
||||
QUrlQuery query;
|
||||
if (settingTypeId == shellyPlugSettingsDefaultStateParamTypeId) {
|
||||
|
|
@ -1734,7 +1658,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
|
|||
|
||||
if (info->thing()->thingClassId() == shelly25ThingClassId) {
|
||||
// Make sure the shelly 2.5 is in the mode we expect it to be (roller/cover or relay/switch)
|
||||
bool rollerMode = info->thing()->paramValue(rollerModeParamTypeMap.value(info->thing()->thingClassId())).toBool();
|
||||
bool rollerMode = info->thing()->paramValue("rollerMode").toBool();
|
||||
QVariantMap params;
|
||||
if(rollerMode) {
|
||||
params.insert("name", "cover");
|
||||
|
|
@ -1819,6 +1743,11 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
|
|||
return;
|
||||
|
||||
}
|
||||
|
||||
if (info->thing()->thingClassId() == shellyPro3EMThingClassId) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -1915,11 +1844,35 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
|
|||
t->emitEvent("pressed");
|
||||
}
|
||||
}
|
||||
if (notification.contains("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());
|
||||
thing->setStateValue(shellyPro3EMCurrentPhaseAStateTypeId, em0.value("a_current").toDouble());
|
||||
thing->setStateValue(shellyPro3EMCurrentPowerPhaseBStateTypeId, em0.value("b_act_power").toDouble());
|
||||
thing->setStateValue(shellyPro3EMVoltagePhaseBStateTypeId, em0.value("b_voltage").toDouble());
|
||||
thing->setStateValue(shellyPro3EMCurrentPhaseCStateTypeId, em0.value("c_current").toDouble());
|
||||
thing->setStateValue(shellyPro3EMCurrentPowerPhaseCStateTypeId, em0.value("c_act_power").toDouble());
|
||||
thing->setStateValue(shellyPro3EMVoltagePhaseCStateTypeId, em0.value("c_voltage").toDouble());
|
||||
thing->setStateValue(shellyPro3EMCurrentPhaseCStateTypeId, em0.value("c_current").toDouble());
|
||||
|
||||
thing->setStateValue(shellyPro3EMCurrentPowerStateTypeId, em0.value("total_act_power").toDouble());
|
||||
}
|
||||
if (notification.contains("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);
|
||||
thing->setStateValue(shellyPro3EMEnergyConsumedPhaseBStateTypeId, emdata0.value("b_total_act_energy").toDouble() / 1000);
|
||||
thing->setStateValue(shellyPro3EMEnergyProducedPhaseBStateTypeId, emdata0.value("b_total_act_ret_energy").toDouble() / 1000);
|
||||
thing->setStateValue(shellyPro3EMEnergyConsumedPhaseCStateTypeId, emdata0.value("c_total_act_energy").toDouble() / 1000);
|
||||
thing->setStateValue(shellyPro3EMEnergyProducedPhaseCStateTypeId, emdata0.value("c_total_act_ret_energy").toDouble() / 1000); thing->setStateValue(shellyPro3EMTotalEnergyConsumedStateTypeId, emdata0.value("total_act").toDouble() / 1000);
|
||||
thing->setStateValue(shellyPro3EMTotalEnergyProducedStateTypeId, emdata0.value("total_act_ret").toDouble() / 1000);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle thing settings of devices
|
||||
if (info->thing()->thingClassId() == shellyPlusPlugThingClassId) {
|
||||
connect(info->thing(), &Thing::settingChanged, this, [this, thing, client, shellyId](const ParamTypeId &settingTypeId, const QVariant &value) {
|
||||
connect(info->thing(), &Thing::settingChanged, this, [thing, client, shellyId](const ParamTypeId &settingTypeId, const QVariant &value) {
|
||||
if (settingTypeId == shellyPlusPlugSettingsDefaultStateParamTypeId) { // this works
|
||||
QString defaultState = value.toString();
|
||||
QVariantMap config;
|
||||
|
|
@ -1929,7 +1882,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
|
|||
params.insert("config", config);
|
||||
|
||||
ShellyRpcReply *reply3 = client->sendRequest("Switch.SetConfig", params);
|
||||
connect(reply3, &ShellyRpcReply::finished, thing, [thing](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
|
||||
connect(reply3, &ShellyRpcReply::finished, thing, [](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
|
||||
if (status != ShellyRpcReply::StatusSuccess) {
|
||||
qCWarning(dcShelly) << "Error setting new value";
|
||||
return;
|
||||
|
|
@ -1946,7 +1899,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
|
|||
params.insert("config", config);
|
||||
|
||||
ShellyRpcReply *reply3 = client->sendRequest("PLUGS_UI.SetConfig", params);
|
||||
connect(reply3, &ShellyRpcReply::finished, thing, [thing](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
|
||||
connect(reply3, &ShellyRpcReply::finished, thing, [](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
|
||||
if (status != ShellyRpcReply::StatusSuccess) {
|
||||
qCWarning(dcShelly) << "Error setting LED mode";
|
||||
return;
|
||||
|
|
@ -2019,9 +1972,9 @@ void IntegrationPluginShelly::setupShellyChild(ThingSetupInfo *info)
|
|||
url.setScheme("http");
|
||||
url.setHost(address);
|
||||
url.setPort(80);
|
||||
url.setPath(QString("/settings/relay/%0").arg(thing->paramValue(channelParamTypeMap.value(thing->thingClassId())).toInt() - 1));
|
||||
url.setUserName(parent->paramValue(usernameParamTypeMap.value(parent->thingClassId())).toString());
|
||||
url.setPassword(parent->paramValue(passwordParamTypeMap.value(parent->thingClassId())).toString());
|
||||
url.setPath(QString("/settings/relay/%0").arg(thing->paramValue("channel").toInt() - 1));
|
||||
url.setUserName(parent->paramValue("username").toString());
|
||||
url.setPassword(parent->paramValue("password").toString());
|
||||
|
||||
QUrlQuery query;
|
||||
if (paramTypeId == shellySwitchSettingsButtonTypeParamTypeId) {
|
||||
|
|
@ -2077,6 +2030,14 @@ QHostAddress IntegrationPluginShelly::getIP(Thing *thing) const
|
|||
return address;
|
||||
}
|
||||
|
||||
bool IntegrationPluginShelly::isGen2(const QString &shellyId) const
|
||||
{
|
||||
return shellyId.contains("Plus")
|
||||
|| shellyId.contains("Pro")
|
||||
|| shellyId.startsWith("ShellyPlug") // Plus plug variants don't have Plus in the name, but are camelcased as opposed to 1st gen plugs
|
||||
;
|
||||
}
|
||||
|
||||
void IntegrationPluginShelly::handleInputEvent(Thing *thing, const QString &buttonName, const QString &inputEventString, int inputEventCount)
|
||||
{
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ private:
|
|||
void setupShellyChild(ThingSetupInfo *info);
|
||||
|
||||
QHostAddress getIP(Thing *thing) const;
|
||||
bool isGen2(const QString &shellyId) const;
|
||||
|
||||
void handleInputEvent(Thing *thing, const QString &buttonName, const QString &inputEventString, int inputEventCount);
|
||||
|
||||
|
|
|
|||
|
|
@ -2713,6 +2713,256 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "d7962c7c-82fe-4d2c-8e79-0b9ff2ee5573",
|
||||
"name": "shellyPro3EM",
|
||||
"displayName": "Shelly Pro 3EM",
|
||||
"createMethods": ["discovery"],
|
||||
"interfaces": [ "energymeter", "wirelessconnectable", "update"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "0896373b-545e-4765-9ea6-22c4161c916d",
|
||||
"name":"id",
|
||||
"displayName": "Shelly ID",
|
||||
"type": "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "32e1d2a2-7d03-466e-aa87-0fc507ae2d3a",
|
||||
"name": "username",
|
||||
"displayName": "Username (optional)",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "5713d503-7975-4500-a254-23aa1e3a97f9",
|
||||
"name": "password",
|
||||
"displayName": "Password (optional)",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "a29300d0-cfde-465b-9aca-9f48f15360bc",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "837618f5-cb59-40c1-a7b7-c036d9d8772f",
|
||||
"name": "signalStrength",
|
||||
"displayName": "Signal strength",
|
||||
"type": "uint",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "c09b5307-b0f8-4cc3-95f2-544513424623",
|
||||
"name": "totalEnergyConsumed",
|
||||
"displayName": "Total consumed energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "8e6ddedc-7764-470d-b319-36b39c9ff62e",
|
||||
"name": "totalEnergyProduced",
|
||||
"displayName": "Total returned energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "eec71598-e307-4917-abb3-53a2b8c14625",
|
||||
"name": "currentPower",
|
||||
"displayName": "Current power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "a2577f97-70c5-406c-90df-63228c6ce30b",
|
||||
"name": "currentPowerPhaseA",
|
||||
"displayName": "Power usage (Phase A)",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "821e323f-0f51-4a81-a1c4-c31b8f41fa19",
|
||||
"name": "currentPhaseA",
|
||||
"displayName": "Current (Phase A)",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "134e412f-5a2e-4e65-b4f2-e8f0698e7000",
|
||||
"name": "voltagePhaseA",
|
||||
"displayName": "Voltage (Phase A)",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0,
|
||||
"cached": false,
|
||||
"filter": "adaptive"
|
||||
},
|
||||
{
|
||||
"id": "0cce4d7b-c673-401b-a654-b2e3ab27bd61",
|
||||
"name": "energyConsumedPhaseA",
|
||||
"displayName": "Total consumed energy (Phase A)",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "9042012f-64e7-4594-a900-599f635f93b1",
|
||||
"name": "energyProducedPhaseA",
|
||||
"displayName": "Total returned energy (Phase A)",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "0852caaa-6704-4b03-8ba6-c1460c2f023d",
|
||||
"name": "currentPowerPhaseB",
|
||||
"displayName": "Power usage (Phase B)",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "f1ea6d35-c74a-43e3-8f06-8387a4595b51",
|
||||
"name": "currentPhaseB",
|
||||
"displayName": "Current (Phase B)",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "37bcd9a2-1f98-45e1-83bc-e9bfb40d0353",
|
||||
"name": "voltagePhaseB",
|
||||
"displayName": "Voltage (Phase B)",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0,
|
||||
"cached": false,
|
||||
"filter": "adaptive"
|
||||
},
|
||||
{
|
||||
"id": "aef8d193-75c6-431f-b013-0a5c08d6225d",
|
||||
"name": "energyConsumedPhaseB",
|
||||
"displayName": "Total consumed energy (Phase B)",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "74c234fd-22c9-4eab-ab8f-e0ba17b7403a",
|
||||
"name": "energyProducedPhaseB",
|
||||
"displayName": "Total returned energy (Phase B)",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "0c615174-562b-428a-9879-687cfeb5a9bd",
|
||||
"name": "currentPowerPhaseC",
|
||||
"displayName": "Power usage (Phase C)",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "b75373ed-acd5-4980-a0f1-565db2f1351c",
|
||||
"name": "currentPhaseC",
|
||||
"displayName": "Current (Phase C)",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "f6d5128a-305f-488b-b586-b52ba163c8a7",
|
||||
"name": "voltagePhaseC",
|
||||
"displayName": "Voltage (Phase C)",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0,
|
||||
"cached": false,
|
||||
"filter": "adaptive"
|
||||
},
|
||||
{
|
||||
"id": "cf1761b5-09b5-4688-8875-40627fa945bc",
|
||||
"name": "energyConsumedPhaseC",
|
||||
"displayName": "Total consumed energy (Phase C)",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "6a30cfcf-601d-4fdc-9465-f58b5d0caab8",
|
||||
"name": "energyProducedPhaseC",
|
||||
"displayName": "Total returned energy (Phase C)",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "839f3192-1841-4293-b60f-8e7976510d36",
|
||||
"name": "updateStatus",
|
||||
"displayName": "Update status",
|
||||
"type": "QString",
|
||||
"possibleValues": ["idle", "available", "updating"],
|
||||
"defaultValue": "idle"
|
||||
},
|
||||
{
|
||||
"id": "a8c8e190-ab9f-49f7-9690-f12fb49920cb",
|
||||
"name": "currentVersion",
|
||||
"displayName": "Current firmware version",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "2acba99c-9c4a-40bb-850a-036312995e8b",
|
||||
"name": "availableVersion",
|
||||
"displayName": "Available firmware version",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "f8621a0a-5b03-4a78-be48-934472b82900",
|
||||
"name": "power",
|
||||
"displayName": "Powered",
|
||||
"displayNameAction": "Turn on or off",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true,
|
||||
"ioType": "digitalOutput"
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "9b268961-5aa4-4a59-a533-aeaf8c376919",
|
||||
"name": "performUpdate",
|
||||
"displayName": "Start firmware update"
|
||||
},
|
||||
{
|
||||
"id": "b0043a22-21e4-4dfc-a813-2a11908a6c04",
|
||||
"name": "reset",
|
||||
"displayName": "Reset data"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "bcc7326d-555a-4763-80ce-7354e67cc700",
|
||||
"name": "shellyEm",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue