Merge PR #675: Shelly plus plug s

dependabot/pip/sunposition/numpy-1.22.0
jenkins 2023-03-07 19:21:43 +01:00
commit 4d042e47f0
6 changed files with 1204 additions and 832 deletions

View File

@ -11,6 +11,7 @@ The currently supported devices are:
* Shelly 2.5
* Shelly Plus 2PM
* Shelly Plug / PlugS
* Shelly Plus Plug S
* Shelly RGBW2
* Shelly Dimmer / Dimmer 2
* Shelly Button 1

View File

@ -66,6 +66,7 @@ static QHash<ThingClassId, ParamTypeId> idParamTypeMap = {
{shelly1pmThingClassId, shelly1pmThingIdParamTypeId},
{shelly1lThingClassId, shelly1lThingIdParamTypeId},
{shellyPlugThingClassId, shellyPlugThingIdParamTypeId},
{shellyPlusPlugThingClassId, shellyPlusPlugThingIdParamTypeId},
{shellyRgbw2ThingClassId, shellyRgbw2ThingIdParamTypeId},
{shellyDimmerThingClassId, shellyDimmerThingIdParamTypeId},
{shelly2ThingClassId, shelly2ThingIdParamTypeId},
@ -87,6 +88,7 @@ static QHash<ThingClassId, ParamTypeId> usernameParamTypeMap = {
{shelly1pmThingClassId, shelly1pmThingUsernameParamTypeId},
{shelly1lThingClassId, shelly1lThingUsernameParamTypeId},
{shellyPlugThingClassId, shellyPlugThingUsernameParamTypeId},
{shellyPlusPlugThingClassId, shellyPlusPlugThingUsernameParamTypeId},
{shellyRgbw2ThingClassId, shellyRgbw2ThingUsernameParamTypeId},
{shellyDimmerThingClassId, shellyDimmerThingUsernameParamTypeId},
{shelly2ThingClassId, shelly2ThingUsernameParamTypeId},
@ -108,6 +110,7 @@ static QHash<ThingClassId, ParamTypeId> passwordParamTypeMap = {
{shelly1pmThingClassId, shelly1pmThingPasswordParamTypeId},
{shelly1lThingClassId, shelly1lThingPasswordParamTypeId},
{shellyPlugThingClassId, shellyPlugThingPasswordParamTypeId},
{shellyPlusPlugThingClassId, shellyPlusPlugThingPasswordParamTypeId},
{shellyRgbw2ThingClassId, shellyRgbw2ThingPasswordParamTypeId},
{shellyDimmerThingClassId, shellyDimmerThingPasswordParamTypeId},
{shelly2ThingClassId, shelly2ThingPasswordParamTypeId},
@ -146,6 +149,7 @@ static QHash<ActionTypeId, ThingClassId> rebootActionTypeMap = {
{shelly1pmRebootActionTypeId, shelly1pmThingClassId},
{shelly1lRebootActionTypeId, shelly1lThingClassId},
{shellyPlugRebootActionTypeId, shellyPlugThingClassId},
{shellyPlusPlugRebootActionTypeId, shellyPlusPlugThingClassId},
{shellyRgbw2RebootActionTypeId, shellyRgbw2ThingClassId},
{shellyDimmerRebootActionTypeId, shellyDimmerThingClassId},
{shelly2RebootActionTypeId, shelly2ThingClassId},
@ -159,6 +163,7 @@ static QHash<ActionTypeId, ThingClassId> powerActionTypesMap = {
{shelly1pmPowerActionTypeId, shelly1pmThingClassId},
{shelly1lPowerActionTypeId, shelly1lThingClassId},
{shellyPlugPowerActionTypeId, shellyPlugThingClassId},
{shellyPlusPlugPowerActionTypeId, shellyPlusPlugThingClassId},
{shellyEmPowerActionTypeId, shellyEmThingClassId},
{shellyEm3PowerActionTypeId, shellyEm3ThingClassId},
{shelly2Channel1ActionTypeId, shelly2ThingClassId},
@ -172,6 +177,7 @@ static QHash<ActionTypeId, ThingClassId> powerActionParamTypesMap = {
{shelly1pmPowerActionTypeId, shelly1pmPowerActionPowerParamTypeId},
{shelly1lPowerActionTypeId, shelly1lPowerActionPowerParamTypeId},
{shellyPlugPowerActionTypeId, shellyPlugPowerActionPowerParamTypeId},
{shellyPlusPlugPowerActionTypeId, shellyPlusPlugPowerActionPowerParamTypeId},
{shellyEmPowerActionTypeId, shellyEmPowerActionPowerParamTypeId},
{shellyEm3PowerActionTypeId, shellyEm3PowerActionPowerParamTypeId},
{shelly2Channel1ActionTypeId, shelly2Channel1ActionChannel1ParamTypeId},
@ -235,6 +241,7 @@ static QHash<ActionTypeId, ThingClassId> updateActionTypesMap = {
{shelly2PerformUpdateActionTypeId, shelly2ThingClassId},
{shelly25PerformUpdateActionTypeId, shelly25ThingClassId},
{shellyPlugPerformUpdateActionTypeId, shellyPlugThingClassId},
{shellyPlusPlugPerformUpdateActionTypeId, shellyPlusPlugThingClassId},
{shellyRgbw2PerformUpdateActionTypeId, shellyRgbw2ThingClassId},
{shellyDimmerPerformUpdateActionTypeId, shellyDimmerThingClassId},
{shellyButton1PerformUpdateActionTypeId, shellyButton1ThingClassId},
@ -261,6 +268,12 @@ static QHash<ThingClassId, ParamTypeId> multipushTimeBetweenPushesSettingIds = {
{shellyButton1ThingClassId, shellyButton1SettingsMultipushTimeBetweenPushesParamTypeId},
{shellyI3ThingClassId, shellyI3SettingsMultipushTimeBetweenPushesParamTypeId}
};
static QHash<ThingClassId, ParamTypeId> defaultStateSettingIds = {
{shellyPlusPlugThingClassId, shellyPlusPlugSettingsDefaultStateParamTypeId}
};
static QHash<ThingClassId, ParamTypeId> ledModeSettingIds = {
{shellyPlusPlugThingClassId, shellyPlusPlugSettingsLedModeParamTypeId}
};
IntegrationPluginShelly::IntegrationPluginShelly()
{
@ -292,6 +305,8 @@ void IntegrationPluginShelly::discoverThings(ThingDiscoveryInfo *info)
namePattern = QRegExp("^shelly1l-[0-9A-Z]+$");
} else if (info->thingClassId() == shellyPlugThingClassId) {
namePattern = QRegExp("^shellyplug(-s)?-[0-9A-Z]+$");
} else if (info->thingClassId() == shellyPlusPlugThingClassId) {
namePattern = QRegExp("^(ShellyPlusPlugS|ShellyPlug(US|IT|UK))-[0-9A-Z]+$");
} else if (info->thingClassId() == shellyRgbw2ThingClassId) {
namePattern = QRegExp("^shellyrgbw2-[0-9A-Z]+$");
} else if (info->thingClassId() == shellyDimmerThingClassId) {
@ -356,10 +371,12 @@ void IntegrationPluginShelly::setupThing(ThingSetupInfo *info)
if (idParamTypeMap.contains(thing->thingClassId())) {
QString shellyId = info->thing()->paramValue(idParamTypeMap.value(info->thing()->thingClassId())).toString();
if (!shellyId.contains("Plus")) {
setupGen1(info);
} else {
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
) {
setupGen2(info);
} else {
setupGen1(info);
}
return;
@ -1653,6 +1670,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
m_rpcClients.insert(info->thing(), client);
if (info->thing()->thingClassId() == shelly1pmThingClassId) {
info->finish(Thing::ThingErrorNoError);
if (myThings().filterByParentId(info->thing()->id()).count() == 0) {
@ -1660,6 +1678,7 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
switchChild.setParams(ParamList() << Param(shellySwitchThingChannelParamTypeId, 1));
emit autoThingsAppeared({switchChild});
}
return;
}
if (info->thing()->thingClassId() == shelly25ThingClassId) {
@ -1703,6 +1722,48 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
channel2Child.setParams(ParamList() << Param(shellyPowerMeterChannelThingChannelParamTypeId, 2));
emit autoThingsAppeared({channel2Child});
}
return;
}
if (info->thing()->thingClassId() == shellyPlusPlugThingClassId) {
// Set default state & led mode of the Plus Plug (S)
QString defaultState = "off";
QString ledMode = "switch";
defaultState = info->thing()->setting(defaultStateSettingIds.value(info->thing()->thingClassId())).toString();
QVariantMap config;
config.insert("initial_state", defaultState);
QVariantMap params;
params.insert("id", 0);
params.insert("config", config);
ShellyRpcReply *reply2 = client->sendRequest("Switch.SetConfig", params);
connect(reply2, &ShellyRpcReply::finished, info, [info](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
if (status != ShellyRpcReply::StatusSuccess) {
qCWarning(dcShelly) << "Error during shelly setup";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
info->finish(Thing::ThingErrorNoError);
});
ledMode = info->thing()->setting(ledModeSettingIds.value(info->thing()->thingClassId())).toString();
QVariantMap leds;
leds.insert("mode", ledMode);
QVariantMap config2;
config2.insert("leds", leds);
QVariantMap params2;
params2.insert("config", config2);
ShellyRpcReply *reply3 = client->sendRequest("PLUGS_UI.SetConfig", params2);
connect(reply3, &ShellyRpcReply::finished, info, [info](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
if (status != ShellyRpcReply::StatusSuccess) {
qCWarning(dcShelly) << "Error during shelly setup";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
});
return;
}
});
});
@ -1801,6 +1862,47 @@ void IntegrationPluginShelly::setupGen2(ThingSetupInfo *info)
}
}
});
// 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) {
if (settingTypeId == shellyPlusPlugSettingsDefaultStateParamTypeId) { // this works
QString defaultState = value.toString();
QVariantMap config;
config.insert("initial_state", defaultState);
QVariantMap params;
params.insert("id", 0);
params.insert("config", config);
ShellyRpcReply *reply3 = client->sendRequest("Switch.SetConfig", params);
connect(reply3, &ShellyRpcReply::finished, thing, [thing](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
if (status != ShellyRpcReply::StatusSuccess) {
qCWarning(dcShelly) << "Error setting new value";
return;
}
});
};
if (settingTypeId == shellyPlusPlugSettingsLedModeParamTypeId) { // this gives a segmentation fault
QString ledMode = value.toString();
QVariantMap leds;
leds.insert("mode", ledMode);
QVariantMap config;
config.insert("leds", leds);
QVariantMap params;
params.insert("config", config);
ShellyRpcReply *reply3 = client->sendRequest("PLUGS_UI.SetConfig", params);
connect(reply3, &ShellyRpcReply::finished, thing, [thing](ShellyRpcReply::Status status, const QVariantMap &/*response*/){
if (status != ShellyRpcReply::StatusSuccess) {
qCWarning(dcShelly) << "Error setting LED mode";
return;
}
});
}
});
}
}
void IntegrationPluginShelly::setupShellyChild(ThingSetupInfo *info)

View File

@ -617,6 +617,150 @@
}
]
},
{
"id": "2c470ea4-6ef2-4aa2-b2f3-b6d8750ac577",
"name": "shellyPlusPlug",
"displayName": "Shelly Plus Plug S",
"createMethods": ["discovery"],
"interfaces": [ "powersocket", "smartmeterconsumer", "wirelessconnectable", "update" ],
"paramTypes": [
{
"id": "ed5fcf4d-b102-4018-a9c9-0e7e9f01650d",
"name":"id",
"displayName": "Shelly ID",
"type": "QString",
"readOnly": true
},
{
"id": "c0276036-aba0-4161-bba6-86979a151611",
"name": "coapMode",
"displayName": "CoIoT peer mode",
"type": "QString",
"allowedValues": ["unicast", "multicast"],
"defaultValue": "unicast"
},
{
"id": "c6b1e47a-d7c3-4c7a-aac5-18c035fd4f79",
"name": "username",
"displayName": "Username (optional)",
"type": "QString"
},
{
"id": "42798bf7-cca6-4730-ba8e-04dac3d99a47",
"name": "password",
"displayName": "Password (optional)",
"type": "QString"
}
],
"settingsTypes": [
{
"id": "d0c0fbe7-42e6-426c-b1ec-c286a11ce52d",
"name": "defaultState",
"displayName": "Default state",
"allowedValues": ["on", "off", "restore_last"],
"defaultValue": "off",
"type": "QString"
},
{
"id": "c7d8d0f4-21c9-4222-961d-2d3080588301",
"name": "ledMode",
"displayName": "LED mode",
"allowedValues": ["power", "switch", "off"],
"defaultValue": "switch",
"type": "QString"
}
],
"stateTypes": [
{
"id": "87a60ee4-a6b8-463a-a4bc-c7c5e412239f",
"name": "power",
"displayName": "Powered",
"displayNameEvent": "Turned on/off",
"displayNameAction": "Turn on/off",
"type": "bool",
"defaultValue": false,
"writable": true,
"ioType": "digitalOutput"
},
{
"id": "ee89944e-eab9-4554-9c7b-0b433f3cf287",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "e244927d-0003-4107-83e1-3fad923cf738",
"name": "signalStrength",
"displayName": "Signal strength",
"displayNameEvent": "Signal strength changed",
"type": "uint",
"unit": "Percentage",
"minValue": 0,
"maxValue": 100,
"defaultValue": 0,
"cached": false
},
{
"id": "8e16b8c8-6981-4eb9-88fe-a863f263f5ba",
"name": "updateStatus",
"displayName": "Update status",
"displayNameEvent": "Update status changed",
"type": "QString",
"possibleValues": ["idle", "available", "updating"],
"defaultValue": "idle"
},
{
"id": "78174fac-2cec-4f1b-94c4-d413dd1a54ba",
"name": "currentVersion",
"displayName": "Firmware version",
"displayNameEvent": "Firmware version changed",
"type": "QString",
"defaultValue": ""
},
{
"id": "89da9eb8-a01f-4bc2-9d96-d2d6305a08d7",
"name": "availableVersion",
"displayName": "Available firmware version",
"displayNameEvent": "Available firmware version changed",
"type": "QString",
"defaultValue": ""
},
{
"id": "5493ecc3-8596-436b-9334-0fe4154656ec",
"name": "totalEnergyConsumed",
"displayName": "Total energy consumed",
"displayNameEvent": "Total consumed energy changed",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0
},
{
"id": "1dcc910d-ab0e-4c31-b6fa-8105324e416b",
"name": "currentPower",
"displayName": "Current power consumption",
"displayNameEvent": "Current power consumption changed",
"type": "double",
"unit": "Watt",
"defaultValue": 0,
"cached": false
}
],
"actionTypes": [
{
"id": "e4a997c5-072f-4212-9ccc-7bfebd20b333",
"name": "reboot",
"displayName": "Reboot"
},
{
"id": "ae862b2d-0bad-4c37-9d7f-b1fca93f00a0",
"name": "performUpdate",
"displayName": "Update firmware"
}
]
},
{
"id": "22229a6d-2af8-44e0-bea9-310a0f2769ef",
"name": "shellyPlug",

View File

@ -28,7 +28,6 @@ ShellyJsonRpcClient::ShellyJsonRpcClient(QObject *parent)
{
m_socket = new QWebSocket("nymea", QWebSocketProtocol::VersionLatest, this);
connect(m_socket, &QWebSocket::stateChanged, this, &ShellyJsonRpcClient::stateChanged);
connect(m_socket, &QWebSocket::textMessageReceived, this, &ShellyJsonRpcClient::onTextMessageReceived);
}