Shelly: Add support for the Shelly TRV
This commit is contained in:
parent
860fbac0e8
commit
fd5307772c
@ -19,6 +19,7 @@ The currently supported devices are:
|
|||||||
* Shelly i3
|
* Shelly i3
|
||||||
* Shelly Motion
|
* Shelly Motion
|
||||||
* Shelly Vintage
|
* Shelly Vintage
|
||||||
|
* Shelly TRV
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
The Shelly device needs to be connected to the same WiFi as nymea is in. New Shelly devices will open a WiFi named with
|
The Shelly device needs to be connected to the same WiFi as nymea is in. New Shelly devices will open a WiFi named with
|
||||||
|
|||||||
@ -75,6 +75,7 @@ static QHash<ThingClassId, ParamTypeId> idParamTypeMap = {
|
|||||||
{shellyHTThingClassId, shellyHTThingIdParamTypeId},
|
{shellyHTThingClassId, shellyHTThingIdParamTypeId},
|
||||||
{shellyI3ThingClassId, shellyI3ThingIdParamTypeId},
|
{shellyI3ThingClassId, shellyI3ThingIdParamTypeId},
|
||||||
{shellyMotionThingClassId, shellyMotionThingIdParamTypeId},
|
{shellyMotionThingClassId, shellyMotionThingIdParamTypeId},
|
||||||
|
{shellyTrvThingClassId, shellyTrvThingIdParamTypeId},
|
||||||
};
|
};
|
||||||
|
|
||||||
static QHash<ThingClassId, ParamTypeId> usernameParamTypeMap = {
|
static QHash<ThingClassId, ParamTypeId> usernameParamTypeMap = {
|
||||||
@ -91,7 +92,8 @@ static QHash<ThingClassId, ParamTypeId> usernameParamTypeMap = {
|
|||||||
{shellyEm3ThingClassId, shellyEm3ThingUsernameParamTypeId},
|
{shellyEm3ThingClassId, shellyEm3ThingUsernameParamTypeId},
|
||||||
{shellyHTThingClassId, shellyHTThingUsernameParamTypeId},
|
{shellyHTThingClassId, shellyHTThingUsernameParamTypeId},
|
||||||
{shellyI3ThingClassId, shellyI3ThingUsernameParamTypeId},
|
{shellyI3ThingClassId, shellyI3ThingUsernameParamTypeId},
|
||||||
{shellyMotionThingClassId, shellyMotionThingUsernameParamTypeId}
|
{shellyMotionThingClassId, shellyMotionThingUsernameParamTypeId},
|
||||||
|
{shellyTrvThingClassId, shellyTrvThingUsernameParamTypeId},
|
||||||
};
|
};
|
||||||
|
|
||||||
static QHash<ThingClassId, ParamTypeId> passwordParamTypeMap = {
|
static QHash<ThingClassId, ParamTypeId> passwordParamTypeMap = {
|
||||||
@ -108,7 +110,8 @@ static QHash<ThingClassId, ParamTypeId> passwordParamTypeMap = {
|
|||||||
{shellyEm3ThingClassId, shellyEm3ThingPasswordParamTypeId},
|
{shellyEm3ThingClassId, shellyEm3ThingPasswordParamTypeId},
|
||||||
{shellyHTThingClassId, shellyHTThingPasswordParamTypeId},
|
{shellyHTThingClassId, shellyHTThingPasswordParamTypeId},
|
||||||
{shellyI3ThingClassId, shellyI3ThingPasswordParamTypeId},
|
{shellyI3ThingClassId, shellyI3ThingPasswordParamTypeId},
|
||||||
{shellyMotionThingClassId, shellyMotionThingPasswordParamTypeId}
|
{shellyMotionThingClassId, shellyMotionThingPasswordParamTypeId},
|
||||||
|
{shellyTrvThingClassId, shellyTrvThingPasswordParamTypeId}
|
||||||
};
|
};
|
||||||
|
|
||||||
static QHash<ThingClassId, ParamTypeId> rollerModeParamTypeMap = {
|
static QHash<ThingClassId, ParamTypeId> rollerModeParamTypeMap = {
|
||||||
@ -138,6 +141,7 @@ static QHash<ActionTypeId, ThingClassId> rebootActionTypeMap = {
|
|||||||
{shelly2RebootActionTypeId, shelly2ThingClassId},
|
{shelly2RebootActionTypeId, shelly2ThingClassId},
|
||||||
{shelly25RebootActionTypeId, shelly25ThingClassId},
|
{shelly25RebootActionTypeId, shelly25ThingClassId},
|
||||||
{shellyI3RebootActionTypeId, shellyI3ThingClassId},
|
{shellyI3RebootActionTypeId, shellyI3ThingClassId},
|
||||||
|
{shellyTrvRebootActionTypeId, shellyTrvThingClassId},
|
||||||
};
|
};
|
||||||
|
|
||||||
static QHash<ActionTypeId, ThingClassId> powerActionTypesMap = {
|
static QHash<ActionTypeId, ThingClassId> powerActionTypesMap = {
|
||||||
@ -228,7 +232,8 @@ static QHash<ActionTypeId, ThingClassId> updateActionTypesMap = {
|
|||||||
{shellyEm3PerformUpdateActionTypeId, shellyEm3ThingClassId},
|
{shellyEm3PerformUpdateActionTypeId, shellyEm3ThingClassId},
|
||||||
{shellyHTPerformUpdateActionTypeId, shellyHTThingClassId},
|
{shellyHTPerformUpdateActionTypeId, shellyHTThingClassId},
|
||||||
{shellyI3PerformUpdateActionTypeId, shellyI3ThingClassId},
|
{shellyI3PerformUpdateActionTypeId, shellyI3ThingClassId},
|
||||||
{shellyMotionPerformUpdateActionTypeId, shellyMotionThingClassId}
|
{shellyMotionPerformUpdateActionTypeId, shellyMotionThingClassId},
|
||||||
|
{shellyTrvPerformUpdateActionTypeId, shellyTrvThingClassId}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
@ -294,6 +299,8 @@ void IntegrationPluginShelly::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
namePattern = QRegExp("shellyix3-[0-9A-Z]+$");
|
namePattern = QRegExp("shellyix3-[0-9A-Z]+$");
|
||||||
} else if (info->thingClassId() == shellyMotionThingClassId) {
|
} else if (info->thingClassId() == shellyMotionThingClassId) {
|
||||||
namePattern = QRegExp("shellymotionsensor-[0-9A-Z]+$");
|
namePattern = QRegExp("shellymotionsensor-[0-9A-Z]+$");
|
||||||
|
} else if (info->thingClassId() == shellyTrvThingClassId) {
|
||||||
|
namePattern = QRegExp("shellytrv-[0-9A-Z]+$");
|
||||||
}
|
}
|
||||||
if (!entry.name().contains(namePattern)) {
|
if (!entry.name().contains(namePattern)) {
|
||||||
continue;
|
continue;
|
||||||
@ -384,8 +391,10 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||||||
QUrl url;
|
QUrl url;
|
||||||
url.setScheme("http");
|
url.setScheme("http");
|
||||||
url.setHost(getIP(info->thing()).toString());
|
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.setUserName(thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString());
|
||||||
url.setPassword(thing->paramValue(passwordParamTypeMap.value(thing->thingClassId())).toString());
|
url.setPassword(thing->paramValue(passwordParamTypeMap.value(thing->thingClassId())).toString());
|
||||||
|
}
|
||||||
|
|
||||||
if (rebootActionTypeMap.contains(action.actionTypeId())) {
|
if (rebootActionTypeMap.contains(action.actionTypeId())) {
|
||||||
if (shellyId.contains("Plus")) {
|
if (shellyId.contains("Plus")) {
|
||||||
@ -574,6 +583,61 @@ void IntegrationPluginShelly::executeAction(ThingActionInfo *info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.actionTypeId() == shellyTrvTargetTemperatureActionTypeId) {
|
||||||
|
double targetValue = action.paramValue(shellyTrvTargetTemperatureActionTargetTemperatureParamTypeId).toDouble();
|
||||||
|
url.setPath(QString("/thermostats/0"));
|
||||||
|
QUrlQuery query;
|
||||||
|
query.addQueryItem("target_t", QString::number(targetValue));
|
||||||
|
query.addQueryItem("target_t_enabled", "true");
|
||||||
|
url.setQuery(query);
|
||||||
|
qCDebug(dcShelly()) << "Requesting:" << url;
|
||||||
|
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
|
||||||
|
connect(reply, &QNetworkReply::finished, &QNetworkReply::deleteLater);
|
||||||
|
connect(reply, &QNetworkReply::finished, info, [info, reply, targetValue](){
|
||||||
|
// The Shelly TRV seems to reply with OK, but then takes ages to actually set the value
|
||||||
|
// If we send another value within that time frame, it will again reply with OK but just ognore it...
|
||||||
|
// As a workaround we'll make nymea wait for a second until allowing to send the next action.
|
||||||
|
info->thing()->setStateValue(shellyTrvTargetTemperatureStateTypeId, targetValue);
|
||||||
|
Thing::ThingError status = reply->error() == QNetworkReply::NoError ? Thing::ThingErrorNoError : Thing::ThingErrorHardwareFailure;
|
||||||
|
QTimer::singleShot(1000, info, [info, status](){
|
||||||
|
info->finish(status);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action.actionTypeId() == shellyTrvValvePositionActionTypeId) {
|
||||||
|
int targetValue = action.paramValue(shellyTrvValvePositionActionValvePositionParamTypeId).toInt();
|
||||||
|
url.setPath(QString("/thermostats/0"));
|
||||||
|
QUrlQuery query;
|
||||||
|
query.addQueryItem("pos", QString::number(targetValue));
|
||||||
|
url.setQuery(query);
|
||||||
|
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
|
||||||
|
connect(reply, &QNetworkReply::finished, &QNetworkReply::deleteLater);
|
||||||
|
connect(reply, &QNetworkReply::finished, info, [info, reply, targetValue](){
|
||||||
|
// The Shelly TRV seems to reply with OK, but then takes ages to actually set the value
|
||||||
|
// If we send another value within that time frame, it will again reply with OK but just ognore it...
|
||||||
|
// As a workaround we'll make nymea wait for a second until allowing to send the next action.
|
||||||
|
info->thing()->setStateValue(shellyTrvValvePositionStateTypeId, targetValue);
|
||||||
|
Thing::ThingError status = reply->error() == QNetworkReply::NoError ? Thing::ThingErrorNoError : Thing::ThingErrorHardwareFailure;
|
||||||
|
QTimer::singleShot(1000, info, [info, status](){
|
||||||
|
info->finish(status);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (action.actionTypeId() == shellyTrvBoostActionTypeId) {
|
||||||
|
url.setPath(QString("/thermostats/0"));
|
||||||
|
QUrlQuery query;
|
||||||
|
query.addQueryItem("boost_minutes", thing->setting(shellyTrvSettingsBoostDurationParamTypeId).toString());
|
||||||
|
url.setQuery(query);
|
||||||
|
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
|
||||||
|
connect(reply, &QNetworkReply::finished, &QNetworkReply::deleteLater);
|
||||||
|
connect(reply, &QNetworkReply::finished, info, [info, reply](){
|
||||||
|
info->finish(reply->error() == QNetworkReply::NoError ? Thing::ThingErrorNoError : Thing::ThingErrorHardwareFailure);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == shellyRollerOpenActionTypeId) {
|
if (action.actionTypeId() == shellyRollerOpenActionTypeId) {
|
||||||
url.setPath(QString("/roller/%1").arg(info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1));
|
url.setPath(QString("/roller/%1").arg(info->thing()->paramValue(shellyRollerThingChannelParamTypeId).toInt() - 1));
|
||||||
QUrlQuery query;
|
QUrlQuery query;
|
||||||
@ -790,8 +854,12 @@ void IntegrationPluginShelly::onMulticastMessageReceived(const QHostAddress &sou
|
|||||||
case 3101:
|
case 3101:
|
||||||
thing->setStateValue("temperature", value.toDouble());
|
thing->setStateValue("temperature", value.toDouble());
|
||||||
break;
|
break;
|
||||||
case 3103:
|
case 3103: // This is target tempererature for the TRV, but humidity for other sensors
|
||||||
|
if (thing->thingClassId() == shellyTrvThingClassId) {
|
||||||
|
thing->setStateValue("targetTemperature", value.toDouble());
|
||||||
|
} else {
|
||||||
thing->setStateValue("humidity", value.toDouble());
|
thing->setStateValue("humidity", value.toDouble());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3106:
|
case 3106:
|
||||||
thing->setStateValue("lightIntensity", value.toInt());
|
thing->setStateValue("lightIntensity", value.toInt());
|
||||||
@ -804,6 +872,13 @@ void IntegrationPluginShelly::onMulticastMessageReceived(const QHostAddress &sou
|
|||||||
}
|
}
|
||||||
thing->setStateValue("batteryCritical", thing->stateValue("batteryLevel").toUInt() < 10);
|
thing->setStateValue("batteryCritical", thing->stateValue("batteryLevel").toUInt() < 10);
|
||||||
break;
|
break;
|
||||||
|
case 3121:
|
||||||
|
thing->setStateValue("valvePosition", value.toUInt());
|
||||||
|
thing->setStateValue("heatingOn", value.toUInt() > 0);
|
||||||
|
break;
|
||||||
|
case 3122:
|
||||||
|
thing->setStateValue("boost", value.toUInt() > 0);
|
||||||
|
break;
|
||||||
case 4101: // power meter for channel 1
|
case 4101: // power meter for channel 1
|
||||||
if (thing->hasState("currentPower")) {
|
if (thing->hasState("currentPower")) {
|
||||||
thing->setStateValue("currentPower", value);
|
thing->setStateValue("currentPower", value);
|
||||||
@ -1132,8 +1207,10 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||||||
url.setHost(address.toString());
|
url.setHost(address.toString());
|
||||||
url.setPort(80);
|
url.setPort(80);
|
||||||
url.setPath("/settings");
|
url.setPath("/settings");
|
||||||
|
if (!thing->paramValue(usernameParamTypeMap.value(thing->thingClassId())).toString().isEmpty()) {
|
||||||
url.setUserName(info->thing()->paramValue(usernameParamTypeMap.value(info->thing()->thingClassId())).toString());
|
url.setUserName(info->thing()->paramValue(usernameParamTypeMap.value(info->thing()->thingClassId())).toString());
|
||||||
url.setPassword(info->thing()->paramValue(passwordParamTypeMap.value(info->thing()->thingClassId())).toString());
|
url.setPassword(info->thing()->paramValue(passwordParamTypeMap.value(info->thing()->thingClassId())).toString());
|
||||||
|
}
|
||||||
|
|
||||||
QUrlQuery query;
|
QUrlQuery query;
|
||||||
query.addQueryItem("coiot_enable", "true");
|
query.addQueryItem("coiot_enable", "true");
|
||||||
@ -1181,6 +1258,10 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||||||
info->thing()->setSettingValue(shellyI3SettingsLongpushMinDurationParamTypeId, settingsMap.value("longpush_duration_ms").toMap().value("min").toUInt());
|
info->thing()->setSettingValue(shellyI3SettingsLongpushMinDurationParamTypeId, settingsMap.value("longpush_duration_ms").toMap().value("min").toUInt());
|
||||||
info->thing()->setSettingValue(shellyI3SettingsLongpushMaxDurationParamTypeId, settingsMap.value("longpush_duration_ms").toMap().value("max").toUInt());
|
info->thing()->setSettingValue(shellyI3SettingsLongpushMaxDurationParamTypeId, settingsMap.value("longpush_duration_ms").toMap().value("max").toUInt());
|
||||||
info->thing()->setSettingValue(shellyI3SettingsMultipushTimeBetweenPushesParamTypeId, settingsMap.value("multipush_time_between_pushes_ms").toMap().value("max").toUInt());
|
info->thing()->setSettingValue(shellyI3SettingsMultipushTimeBetweenPushesParamTypeId, settingsMap.value("multipush_time_between_pushes_ms").toMap().value("max").toUInt());
|
||||||
|
} else if (info->thing()->thingClassId() == shellyTrvThingClassId) {
|
||||||
|
info->thing()->setSettingValue(shellyTrvSettingsChildLockParamTypeId, settingsMap.value("child_lock").toBool());
|
||||||
|
info->thing()->setSettingValue(shellyTrvSettingsDisplayFlippedParamTypeId, settingsMap.value("display").toMap().value("flipped").toBool());
|
||||||
|
info->thing()->setSettingValue(shellyTrvSettingsDisplayBrightnessParamTypeId, settingsMap.value("display").toMap().value("brightness").toUInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
ThingDescriptors autoChilds;
|
ThingDescriptors autoChilds;
|
||||||
@ -1235,6 +1316,7 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
info->thing()->setStateValue("connected", true);
|
||||||
|
|
||||||
emit autoThingsAppeared(autoChilds);
|
emit autoThingsAppeared(autoChilds);
|
||||||
|
|
||||||
@ -1281,7 +1363,8 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||||||
// Handle thing settings of gateway devices
|
// Handle thing settings of gateway devices
|
||||||
if (info->thing()->thingClassId() == shellyPlugThingClassId ||
|
if (info->thing()->thingClassId() == shellyPlugThingClassId ||
|
||||||
info->thing()->thingClassId() == shellyButton1ThingClassId ||
|
info->thing()->thingClassId() == shellyButton1ThingClassId ||
|
||||||
info->thing()->thingClassId() == shellyI3ThingClassId) {
|
info->thing()->thingClassId() == shellyI3ThingClassId ||
|
||||||
|
info->thing()->thingClassId() == shellyTrvThingClassId) {
|
||||||
connect(info->thing(), &Thing::settingChanged, this, [this, thing, shellyId](const ParamTypeId &settingTypeId, const QVariant &value) {
|
connect(info->thing(), &Thing::settingChanged, this, [this, thing, shellyId](const ParamTypeId &settingTypeId, const QVariant &value) {
|
||||||
|
|
||||||
pluginStorage()->beginGroup(thing->id().toString());
|
pluginStorage()->beginGroup(thing->id().toString());
|
||||||
@ -1316,6 +1399,15 @@ void IntegrationPluginShelly::setupGen1(ThingSetupInfo *info)
|
|||||||
|| settingTypeId == shellyI3SettingsMultipushTimeBetweenPushesParamTypeId) {
|
|| settingTypeId == shellyI3SettingsMultipushTimeBetweenPushesParamTypeId) {
|
||||||
url.setPath("/settings");
|
url.setPath("/settings");
|
||||||
query.addQueryItem("multipush_time_between_pushes_ms_max", value.toString());
|
query.addQueryItem("multipush_time_between_pushes_ms_max", value.toString());
|
||||||
|
} else if (settingTypeId == shellyTrvSettingsChildLockParamTypeId) {
|
||||||
|
url.setPath("/settings");
|
||||||
|
query.addQueryItem("child_lock", value.toString());
|
||||||
|
} else if (settingTypeId == shellyTrvSettingsDisplayBrightnessParamTypeId) {
|
||||||
|
url.setPath("/settings");
|
||||||
|
query.addQueryItem("display_brightness", value.toString());
|
||||||
|
} else if (settingTypeId == shellyTrvSettingsDisplayFlippedParamTypeId) {
|
||||||
|
url.setPath("/settings");
|
||||||
|
query.addQueryItem("display_flipped", value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
url.setQuery(query);
|
url.setQuery(query);
|
||||||
|
|||||||
@ -1458,6 +1458,209 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "52932a47-38cd-4dce-b338-88122ce4ab8a",
|
||||||
|
"name": "shellyTrv",
|
||||||
|
"displayName": "Shelly TRV",
|
||||||
|
"createMethods": ["discovery"],
|
||||||
|
"interfaces": ["thermostat", "temperaturesensor", "wirelessconnectable", "battery", "update"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "20e21853-cfc1-4f78-9ba3-12682f81e021",
|
||||||
|
"name":"id",
|
||||||
|
"displayName": "Shelly ID",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ee942141-3102-4b6a-87dc-0fc6481924e5",
|
||||||
|
"name": "username",
|
||||||
|
"displayName": "Username (optional)",
|
||||||
|
"type": "QString"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bf4fead2-7a1a-44e7-bd32-ea2064944098",
|
||||||
|
"name": "password",
|
||||||
|
"displayName": "Password (optional)",
|
||||||
|
"type": "QString"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settingsTypes": [
|
||||||
|
{
|
||||||
|
"id": "3a1dbc59-5b61-4650-a0fa-e127d337169e",
|
||||||
|
"name": "boostDuration",
|
||||||
|
"displayName": "Boost duration (minutes)",
|
||||||
|
"type": "uint",
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 120,
|
||||||
|
"defaultValue": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "38a98b85-9c6e-4dc8-8d73-5248532d2ed8",
|
||||||
|
"name": "childLock",
|
||||||
|
"displayName": "Child lock",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "83cfbdb7-a807-4a81-9eb0-5e0d62efdbaf",
|
||||||
|
"name": "displayFlipped",
|
||||||
|
"displayName": "Display flipped",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e0f7aae7-d576-4897-9626-2cc7e452b30a",
|
||||||
|
"name": "displayBrightness",
|
||||||
|
"displayName": "Display brightness",
|
||||||
|
"type": "uint",
|
||||||
|
"minValue": 1,
|
||||||
|
"maxValue": 7,
|
||||||
|
"defaultValue": 7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "d9a26a08-5735-403a-ab02-7638bd0a471f",
|
||||||
|
"name": "temperature",
|
||||||
|
"displayName": "Temperature",
|
||||||
|
"displayNameEvent": "Temperature changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "DegreeCelsius",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9800babf-a6cc-4eda-b42e-8f5481b61aea",
|
||||||
|
"name": "targetTemperature",
|
||||||
|
"displayName": "Target temperature",
|
||||||
|
"displayNameEvent": "Target temperature changed",
|
||||||
|
"displayNameAction": "Set target temperature",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "DegreeCelsius",
|
||||||
|
"defaultValue": 0,
|
||||||
|
"minValue": 4,
|
||||||
|
"maxValue": 31,
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e442ca7a-ee17-482b-aae4-579915029abf",
|
||||||
|
"name": "valvePosition",
|
||||||
|
"displayName": "Valve position",
|
||||||
|
"displayNameEvent": "Valve position changed",
|
||||||
|
"displayNameAction": "Set valve position",
|
||||||
|
"type": "uint",
|
||||||
|
"unit": "Percentage",
|
||||||
|
"defaultValue": 0,
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 100,
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1935b7fa-72a5-4aee-877e-d656cd79d688",
|
||||||
|
"name": "heatingOn",
|
||||||
|
"displayName": "Heating",
|
||||||
|
"displayNameEvent": "Heating changed",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ef74da4d-70f4-49cd-9697-a8e2bf25dee1",
|
||||||
|
"name": "boost",
|
||||||
|
"displayName": "Boost",
|
||||||
|
"displayNameEvent": "Boost enabled/disabled",
|
||||||
|
"displayNameAction": "Enable/disable boost",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false,
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a5944856-6b0f-4b45-9d9f-fe0f3c2de8aa",
|
||||||
|
"name": "windowOpen",
|
||||||
|
"displayName": "Window open",
|
||||||
|
"displayNameEvent": "Window opened/closed",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "92fa20b0-2b66-4d68-8819-6eeb43f1c0fb",
|
||||||
|
"name": "connected",
|
||||||
|
"displayName": "Connected",
|
||||||
|
"displayNameEvent": "Connected or disconnected",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "42e080f3-c00c-49d2-b046-7bd26331b8f0",
|
||||||
|
"name": "signalStrength",
|
||||||
|
"displayName": "Signal strength",
|
||||||
|
"displayNameEvent": "Signal strength changed",
|
||||||
|
"type": "uint",
|
||||||
|
"unit": "Percentage",
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 100,
|
||||||
|
"defaultValue": 0,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f45dff98-41ac-43bb-a005-24294973611b",
|
||||||
|
"name": "batteryLevel",
|
||||||
|
"displayName": "Battery level",
|
||||||
|
"displayNameEvent": "Battery level changed",
|
||||||
|
"type": "int",
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 100,
|
||||||
|
"unit": "Percentage",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "48c3a619-331e-44eb-b080-877fdcfd03f6",
|
||||||
|
"name": "batteryCritical",
|
||||||
|
"displayName": "Battery level critical",
|
||||||
|
"displayNameEvent": "Battery critical changed",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "113625e0-e171-48e6-a9ca-6a13b75b9234",
|
||||||
|
"name": "updateStatus",
|
||||||
|
"displayName": "Update status",
|
||||||
|
"displayNameEvent": "Update status changed",
|
||||||
|
"type": "QString",
|
||||||
|
"possibleValues": ["idle", "available", "updating"],
|
||||||
|
"defaultValue": "idle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ad5cdb22-42ce-4592-ad72-61a854981f69",
|
||||||
|
"name": "currentVersion",
|
||||||
|
"displayName": "Current firmware version",
|
||||||
|
"displayNameEvent": "Current firmware version changed",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "f3e00825-cd05-45e6-bc99-457bf74255c5",
|
||||||
|
"name": "availableVersion",
|
||||||
|
"displayName": "Available firmware version",
|
||||||
|
"displayNameEvent": "Available firmware version changed",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actionTypes": [
|
||||||
|
{
|
||||||
|
"id": "27e4c7f5-1828-443c-a18d-6d79382e001d",
|
||||||
|
"name": "performUpdate",
|
||||||
|
"displayName": "Start firmware update"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4cef8e3a-853b-4313-8f70-d22122e7bb04",
|
||||||
|
"name": "reboot",
|
||||||
|
"displayName": "Reboot device"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "6de35a17-0f54-4397-894d-4321b64c53d1",
|
"id": "6de35a17-0f54-4397-894d-4321b64c53d1",
|
||||||
"name": "shellySwitch",
|
"name": "shellySwitch",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user