New plugin: somfytahoma
Add support for controlling Somfy smart home devices through their Tahoma box (and the Somfy API). The plugin currently contains support for roller shutters as well as for venetian blinds.master
parent
34ac58feaa
commit
a59b14dc95
|
|
@ -857,6 +857,21 @@ Description: nymea.io plugin for simulated devices
|
|||
This package will install the nymea.io plugin for simulated devices
|
||||
|
||||
|
||||
Package: nymea-plugin-somfytahoma
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io plugin for Somfy TaHoma
|
||||
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||
server works like a translator for devices, things and services and
|
||||
allows them to interact.
|
||||
With the powerful rule engine you are able to connect any device available
|
||||
in the system and create individual scenes and behaviors for your environment.
|
||||
.
|
||||
This package will install the nymea.io plugin for Somfy TaHoma devices
|
||||
|
||||
|
||||
Package: nymea-plugin-sonos
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
|
|
@ -1015,6 +1030,7 @@ Depends: nymea-plugin-anel,
|
|||
nymea-plugin-elgato,
|
||||
nymea-plugin-shelly,
|
||||
nymea-plugin-senic,
|
||||
nymea-plugin-somfytahoma,
|
||||
nymea-plugin-sonos,
|
||||
nymea-plugin-solarlog,
|
||||
nymea-plugin-tado,
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginsomfytahoma.so
|
||||
|
|
@ -48,6 +48,7 @@ PLUGIN_DIRS = \
|
|||
serialportcommander \
|
||||
simulation \
|
||||
snapd \
|
||||
somfytahoma \
|
||||
sonos \
|
||||
tado \
|
||||
tasmota \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# Somfy TaHoma
|
||||
|
||||
This plugin adds support for Somfy smarthome devices through the Somfy TaHoma
|
||||
API.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This plugin requires a Somfy TaHoma gateway to which your Somfy devices
|
||||
are connected. The gateway needs to be registered to the Somfy API.
|
||||
Follow the user guide of the gateway for detailed instructions.
|
||||
|
||||
## Usage
|
||||
|
||||
In order to interact with your Somfy devices, add your TaHoma gateway as new
|
||||
'Thing' to nymea. All supported devices will show up automatically after
|
||||
entering your personal username + password for the Somfy TaHoma API.
|
||||
|
||||
## Supported devices
|
||||
|
||||
Currently this plugin supports all roller shutters and blinds that are
|
||||
connectable to the TaHoma gateway. These are Somfy iO devices as well as RTS
|
||||
devices.
|
||||
|
|
@ -0,0 +1,458 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "integrationpluginsomfytahoma.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "network/networkaccessmanager.h"
|
||||
|
||||
#include "plugininfo.h"
|
||||
#include "somfytahomarequests.h"
|
||||
|
||||
void IntegrationPluginSomfyTahoma::startPairing(ThingPairingInfo *info)
|
||||
{
|
||||
info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please enter the login credentials for Somfy Tahoma."));
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &password)
|
||||
{
|
||||
SomfyTahomaLoginRequest *request = new SomfyTahomaLoginRequest(hardwareManager()->networkManager(), username, password, this);
|
||||
connect(request, &SomfyTahomaLoginRequest::error, info, [info](){
|
||||
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Failed to login to Somfy Tahoma."));
|
||||
});
|
||||
connect(request, &SomfyTahomaLoginRequest::finished, info, [this, info, username, password](const QVariant &/*result*/){
|
||||
pluginStorage()->beginGroup(info->thingId().toString());
|
||||
pluginStorage()->setValue("username", username);
|
||||
pluginStorage()->setValue("password", password);
|
||||
pluginStorage()->endGroup();
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
if (info->thing()->thingClassId() == tahomaThingClassId) {
|
||||
SomfyTahomaLoginRequest *request = createLoginRequestWithStoredCredentials(info->thing());
|
||||
connect(request, &SomfyTahomaLoginRequest::error, info, [info](){
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Failed to login to Somfy Tahoma."));
|
||||
});
|
||||
connect(request, &SomfyTahomaLoginRequest::finished, info, [this, info](const QVariant &/*result*/){
|
||||
QUuid accountId = info->thing()->id();
|
||||
SomfyTahomaGetRequest *request = new SomfyTahomaGetRequest(hardwareManager()->networkManager(), "/setup", this);
|
||||
connect(request, &SomfyTahomaGetRequest::finished, this, [this, accountId](const QVariant &result){
|
||||
QList<ThingDescriptor> unknownDevices;
|
||||
foreach (const QVariant &gatewayVariant, result.toMap()["gateways"].toList()) {
|
||||
QVariantMap gatewayMap = gatewayVariant.toMap();
|
||||
QString gatewayId = gatewayMap.value("gatewayId").toString();
|
||||
Thing *thing = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, gatewayId));
|
||||
if (thing) {
|
||||
qCDebug(dcSomfyTahoma()) << "Found existing gateway:" << gatewayId;
|
||||
} else {
|
||||
qCInfo(dcSomfyTahoma()) << "Found new gateway:" << gatewayId;
|
||||
ThingDescriptor descriptor(gatewayThingClassId, "TaHoma Gateway", QString(), accountId);
|
||||
descriptor.setParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, gatewayId));
|
||||
unknownDevices.append(descriptor);
|
||||
}
|
||||
}
|
||||
foreach (const QVariant &deviceVariant, result.toMap()["devices"].toList()) {
|
||||
QVariantMap deviceMap = deviceVariant.toMap();
|
||||
QString type = deviceMap.value("uiClass").toString();
|
||||
QString deviceUrl = deviceMap.value("deviceURL").toString();
|
||||
QString label = deviceMap.value("label").toString();
|
||||
if (type == QStringLiteral("RollerShutter")) {
|
||||
Thing *thing = myThings().findByParams(ParamList() << Param(rollershutterThingDeviceUrlParamTypeId, deviceUrl));
|
||||
if (thing) {
|
||||
qCDebug(dcSomfyTahoma()) << "Found existing roller shutter:" << label << deviceUrl;
|
||||
} else {
|
||||
qCInfo(dcSomfyTahoma()) << "Found new roller shutter:" << label << deviceUrl;
|
||||
ThingDescriptor descriptor(rollershutterThingClassId, label, QString(), accountId);
|
||||
descriptor.setParams(ParamList() << Param(rollershutterThingDeviceUrlParamTypeId, deviceUrl));
|
||||
unknownDevices.append(descriptor);
|
||||
}
|
||||
} else if (type == QStringLiteral("ExteriorVenetianBlind")) {
|
||||
Thing *thing = myThings().findByParams(ParamList() << Param(venetianblindThingDeviceUrlParamTypeId, deviceUrl));
|
||||
if (thing) {
|
||||
qCDebug(dcSomfyTahoma()) << "Found existing venetian blind:" << label << deviceUrl;
|
||||
} else {
|
||||
qCInfo(dcSomfyTahoma()) << "Found new venetian blind:" << label << deviceUrl;
|
||||
ThingDescriptor descriptor(venetianblindThingClassId, label, QString(), accountId);
|
||||
descriptor.setParams(ParamList() << Param(venetianblindThingDeviceUrlParamTypeId, deviceUrl));
|
||||
unknownDevices.append(descriptor);
|
||||
}
|
||||
} else {
|
||||
qCInfo(dcSomfyTahoma()) << "Found unsupperted Somfy device:" << label << type << deviceUrl;
|
||||
}
|
||||
}
|
||||
if (!unknownDevices.isEmpty()) {
|
||||
emit autoThingsAppeared(unknownDevices);
|
||||
}
|
||||
});
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
else if (info->thing()->thingClassId() == gatewayThingClassId ||
|
||||
info->thing()->thingClassId() == rollershutterThingClassId ||
|
||||
info->thing()->thingClassId() == venetianblindThingClassId) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::postSetupThing(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == tahomaThingClassId) {
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
thing->setStateValue(tahomaUserDisplayNameStateTypeId, pluginStorage()->value("username"));
|
||||
pluginStorage()->endGroup();
|
||||
|
||||
refreshAccount(thing);
|
||||
}
|
||||
|
||||
// Set parent of all devices to the respective gateway. We create all devices in setup() of the account.
|
||||
// But we don't have the ThingIds of the gateways, because they're created in setup() as well.
|
||||
QUrl deviceUrl;
|
||||
if (thing->thingClassId() == rollershutterThingClassId) {
|
||||
deviceUrl = QUrl(thing->paramValue(rollershutterThingDeviceUrlParamTypeId).toString());
|
||||
} else if (thing->thingClassId() == venetianblindThingClassId) {
|
||||
deviceUrl = QUrl(thing->paramValue(venetianblindThingDeviceUrlParamTypeId).toString());
|
||||
}
|
||||
if (!deviceUrl.isEmpty()) {
|
||||
Thing *gateway = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, deviceUrl.host()));
|
||||
if (gateway) {
|
||||
thing->setParentId(gateway->parentId());
|
||||
} else {
|
||||
qCWarning(dcSomfyTahoma()) << "Couldn't find gateway for thing" << thing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::refreshAccount(Thing *thing)
|
||||
{
|
||||
// Ensure that even't polling doesn't interfere the refreshing.
|
||||
if (m_eventPollTimer.contains(thing)) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_eventPollTimer[thing]);
|
||||
}
|
||||
|
||||
SomfyTahomaGetRequest *setupRequest = new SomfyTahomaGetRequest(hardwareManager()->networkManager(), "/setup", this);
|
||||
connect(setupRequest, &SomfyTahomaGetRequest::error, this, [this, thing](){
|
||||
markDisconnected(thing);
|
||||
});
|
||||
connect(setupRequest, &SomfyTahomaGetRequest::finished, this, [this, thing](const QVariant &result){
|
||||
thing->setStateValue(tahomaLoggedInStateTypeId, true);
|
||||
thing->setStateValue(tahomaConnectedStateTypeId, true);
|
||||
foreach (const QVariant &gatewayVariant, result.toMap()["gateways"].toList()) {
|
||||
QVariantMap gatewayMap = gatewayVariant.toMap();
|
||||
QString gatewayId = gatewayMap.value("gatewayId").toString();
|
||||
Thing *thing = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, gatewayId));
|
||||
if (thing) {
|
||||
qCDebug(dcSomfyTahoma()) << "Setting initial state for gateway:" << gatewayId;
|
||||
thing->setStateValue(gatewayConnectedStateTypeId, gatewayMap["connectivity"].toMap()["status"] == "OK");
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
pluginStorage()->setValue("connected", gatewayMap["connectivity"].toMap()["status"] == "OK");
|
||||
pluginStorage()->endGroup();
|
||||
}
|
||||
}
|
||||
foreach (const QVariant &deviceVariant, result.toMap()["devices"].toList()) {
|
||||
updateThingStates(deviceVariant.toMap()["deviceURL"].toString(), deviceVariant.toMap()["states"].toList());
|
||||
}
|
||||
});
|
||||
|
||||
SomfyTahomaPostRequest *eventRegistrationRequest = new SomfyTahomaPostRequest(hardwareManager()->networkManager(), "/events/register", "application/json", QByteArray(), this);
|
||||
connect(eventRegistrationRequest, &SomfyTahomaPostRequest::error, this, [this, thing](){
|
||||
qCWarning(dcSomfyTahoma()) << "Failed to register for events.";
|
||||
markDisconnected(thing);
|
||||
});
|
||||
connect(eventRegistrationRequest, &SomfyTahomaPostRequest::finished, this, [this, thing](const QVariant &result){
|
||||
thing->setStateValue(tahomaConnectedStateTypeId, true);
|
||||
QString eventListenerId = result.toMap()["id"].toString();
|
||||
m_eventPollTimer[thing] = hardwareManager()->pluginTimerManager()->registerTimer(2 /*sec*/);
|
||||
connect(m_eventPollTimer[thing], &PluginTimer::timeout, thing, [this, thing, eventListenerId](){
|
||||
SomfyTahomaEventFetchRequest *eventFetchRequest = new SomfyTahomaEventFetchRequest(hardwareManager()->networkManager(), eventListenerId, this);
|
||||
connect(eventFetchRequest, &SomfyTahomaEventFetchRequest::error, thing, [this, thing](QNetworkReply::NetworkError error){
|
||||
markDisconnected(thing);
|
||||
if (error == QNetworkReply::AuthenticationRequiredError) {
|
||||
qCInfo(dcSomfyTahoma()) << "Failed to fetch events: Authentication expired, reauthenticating";
|
||||
SomfyTahomaLoginRequest *request = createLoginRequestWithStoredCredentials(thing);
|
||||
connect(request, &SomfyTahomaLoginRequest::error, this, [this, thing](){
|
||||
// This is a fatal error. The user needs to reconfigure the account to provide new credentials.
|
||||
qCWarning(dcSomfyTahoma()) << "Failed to reauthenticate";
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_eventPollTimer[thing]);
|
||||
m_eventPollTimer.remove(thing);
|
||||
});
|
||||
connect(request, &SomfyTahomaLoginRequest::finished, this, [this, thing](const QVariant &/*result*/){
|
||||
qCInfo(dcSomfyTahoma()) << "Reauthentication successful";
|
||||
refreshAccount(thing);
|
||||
});
|
||||
} else {
|
||||
qCWarning(dcSomfyTahoma()) << "Failed to fetch events:" << error;
|
||||
}
|
||||
});
|
||||
connect(eventFetchRequest, &SomfyTahomaEventFetchRequest::finished, thing, [this, thing](const QVariant &result){
|
||||
thing->setStateValue(tahomaConnectedStateTypeId, true);
|
||||
restoreChildConnectedState(thing);
|
||||
if (!result.toList().empty()) {
|
||||
qCDebug(dcSomfyTahoma()) << "Got events:" << qUtf8Printable(QJsonDocument::fromVariant(result).toJson());
|
||||
}
|
||||
handleEvents(result.toList());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::thingRemoved(Thing *thing)
|
||||
{
|
||||
m_eventPollTimer.remove(thing);
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::handleEvents(const QVariantList &eventList)
|
||||
{
|
||||
Thing *thing;
|
||||
foreach (const QVariant &eventVariant, eventList) {
|
||||
QVariantMap eventMap = eventVariant.toMap();
|
||||
if (eventMap["name"] == "DeviceStateChangedEvent") {
|
||||
updateThingStates(eventMap["deviceURL"].toString(), eventMap["deviceStates"].toList());
|
||||
} else if (eventMap["name"] == "ExecutionRegisteredEvent") {
|
||||
QList<Thing *> things;
|
||||
foreach (const QVariant &action, eventMap["actions"].toList()) {
|
||||
thing = myThings().findByParams(ParamList() << Param(rollershutterThingDeviceUrlParamTypeId, action.toMap()["deviceURL"]));
|
||||
if (thing) {
|
||||
thing->setStateValue(rollershutterMovingStateTypeId, true);
|
||||
things.append(thing);
|
||||
continue;
|
||||
}
|
||||
thing = myThings().findByParams(ParamList() << Param(venetianblindThingDeviceUrlParamTypeId, action.toMap()["deviceURL"]));
|
||||
if (thing) {
|
||||
thing->setStateValue(venetianblindMovingStateTypeId, true);
|
||||
things.append(thing);
|
||||
}
|
||||
}
|
||||
qCDebug(dcSomfyTahoma()) << "ExecutionRegisteredEvent" << eventMap["execId"];
|
||||
m_currentExecutions.insert(eventMap["execId"].toString(), things);
|
||||
} else if (eventMap["name"] == "ExecutionStateChangedEvent" &&
|
||||
(eventMap["newState"] == "COMPLETED" || eventMap["newState"] == "FAILED")) {
|
||||
QList<Thing *> things = m_currentExecutions.take(eventMap["execId"].toString());
|
||||
foreach (Thing *thing, things) {
|
||||
if (thing->thingClassId() == rollershutterThingClassId) {
|
||||
thing->setStateValue(rollershutterMovingStateTypeId, false);
|
||||
} else if (thing->thingClassId() == venetianblindThingClassId) {
|
||||
thing->setStateValue(venetianblindMovingStateTypeId, false);
|
||||
}
|
||||
}
|
||||
|
||||
QPointer<ThingActionInfo> thingActionInfo = m_pendingActions.take(eventMap["execId"].toString());
|
||||
if (!thingActionInfo.isNull()) {
|
||||
if (eventMap["newState"] == "COMPLETED") {
|
||||
qCDebug(dcSomfyTahoma()) << "Action finished" << thingActionInfo->thing() << thingActionInfo->action().actionTypeId();
|
||||
thingActionInfo->finish(Thing::ThingErrorNoError);
|
||||
} else if (eventMap["newState"] == "FAILED") {
|
||||
qCWarning(dcSomfyTahoma()) << "Action failed" << thingActionInfo->thing() << thingActionInfo->action().actionTypeId();
|
||||
thingActionInfo->finish(Thing::ThingErrorHardwareFailure);
|
||||
} else {
|
||||
qCWarning(dcSomfyTahoma()) << "Action in unknown state" << thingActionInfo->thing() << thingActionInfo->action().actionTypeId() << eventMap["newState"].toString();
|
||||
thingActionInfo->finish(Thing::ThingErrorHardwareFailure);
|
||||
}
|
||||
}
|
||||
} else if (eventMap["name"] == "GatewayAliveEvent") {
|
||||
thing = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, eventMap["gatewayId"]));
|
||||
if (thing) {
|
||||
qCInfo(dcSomfyTahoma()) << "Gateway connected event received:" << eventMap["gatewayId"];
|
||||
thing->setStateValue(gatewayConnectedStateTypeId, true);
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
pluginStorage()->setValue("connected", true);
|
||||
pluginStorage()->endGroup();
|
||||
restoreChildConnectedState(thing);
|
||||
} else {
|
||||
qCDebug(dcSomfyTahoma()) << "Ignoring gateway connected event for unknown gateway" << eventMap["gatewayId"];
|
||||
}
|
||||
} else if (eventMap["name"] == "GatewayDownEvent") {
|
||||
thing = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, eventMap["gatewayId"]));
|
||||
if (thing) {
|
||||
qCInfo(dcSomfyTahoma()) << "Gateway disconnected event received:" << eventMap["gatewayId"];
|
||||
thing->setStateValue(gatewayConnectedStateTypeId, false);
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
pluginStorage()->setValue("connected", false);
|
||||
pluginStorage()->endGroup();
|
||||
markDisconnected(thing);
|
||||
} else {
|
||||
qCDebug(dcSomfyTahoma()) << "Ignoring gateway disconnected event for unknown gateway" << eventMap["gatewayId"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::updateThingStates(const QString &deviceUrl, const QVariantList &stateList)
|
||||
{
|
||||
Thing *thing = myThings().findByParams(ParamList() << Param(rollershutterThingDeviceUrlParamTypeId, deviceUrl));
|
||||
if (thing) {
|
||||
foreach (const QVariant &stateVariant, stateList) {
|
||||
QVariantMap stateMap = stateVariant.toMap();
|
||||
if (stateMap["name"] == "core:ClosureState") {
|
||||
thing->setStateValue(rollershutterPercentageStateTypeId, stateMap["value"]);
|
||||
} else if (stateMap["name"] == "core:StatusState") {
|
||||
thing->setStateValue(rollershutterConnectedStateTypeId, stateMap["value"] == "available");
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
pluginStorage()->setValue("connected", stateMap["value"] == "available");
|
||||
pluginStorage()->endGroup();
|
||||
} else if (stateMap["name"] == "core:RSSILevelState") {
|
||||
thing->setStateValue(rollershutterSignalStrengthStateTypeId, stateMap["value"]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
thing = myThings().findByParams(ParamList() << Param(venetianblindThingDeviceUrlParamTypeId, deviceUrl));
|
||||
if (thing) {
|
||||
foreach (const QVariant &stateVariant, stateList) {
|
||||
QVariantMap stateMap = stateVariant.toMap();
|
||||
if (stateMap["name"] == "core:ClosureState") {
|
||||
thing->setStateValue(venetianblindPercentageStateTypeId, stateMap["value"]);
|
||||
} else if (stateMap["name"] == "core:SlateOrientationState") {
|
||||
// Convert percentage (0%/100%, 50%=open) into degree (-90/+90)
|
||||
int degree = (stateMap["value"].toInt() * 1.8) - 90;
|
||||
thing->setStateValue(venetianblindAngleStateTypeId, degree);
|
||||
} else if (stateMap["name"] == "core:StatusState") {
|
||||
thing->setStateValue(venetianblindConnectedStateTypeId, stateMap["value"] == "available");
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
pluginStorage()->setValue("connected", stateMap["value"] == "available");
|
||||
pluginStorage()->endGroup();
|
||||
} else if (stateMap["name"] == "core:RSSILevelState") {
|
||||
thing->setStateValue(venetianblindSignalStrengthStateTypeId, stateMap["value"]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
qCInfo(dcSomfyTahoma()) << "Action request:" << info->thing() << info->action().actionTypeId() << info->action().params();
|
||||
|
||||
QString deviceUrl;
|
||||
QString actionName;
|
||||
QJsonArray actionParameters;
|
||||
|
||||
if (info->thing()->thingClassId() == rollershutterThingClassId) {
|
||||
deviceUrl = info->thing()->paramValue(rollershutterThingDeviceUrlParamTypeId).toString();
|
||||
if (info->action().actionTypeId() == rollershutterPercentageActionTypeId) {
|
||||
actionName = "setClosureAndLinearSpeed";
|
||||
actionParameters = { info->action().param(rollershutterPercentageActionPercentageParamTypeId).value().toInt(), "lowspeed" };
|
||||
} else if (info->action().actionTypeId() == rollershutterOpenActionTypeId) {
|
||||
actionName = "setClosureAndLinearSpeed";
|
||||
actionParameters = { 0, "lowspeed" };
|
||||
} else if (info->action().actionTypeId() == rollershutterCloseActionTypeId) {
|
||||
actionName = "setClosureAndLinearSpeed";
|
||||
actionParameters = { 100, "lowspeed" };
|
||||
} else if (info->action().actionTypeId() == rollershutterStopActionTypeId) {
|
||||
actionName = "stop";
|
||||
}
|
||||
} else if (info->thing()->thingClassId() == venetianblindThingClassId) {
|
||||
deviceUrl = info->thing()->paramValue(venetianblindThingDeviceUrlParamTypeId).toString();
|
||||
if (info->action().actionTypeId() == venetianblindPercentageActionTypeId) {
|
||||
actionName = "setClosure";
|
||||
actionParameters = { info->action().param(venetianblindPercentageActionPercentageParamTypeId).value().toInt() };
|
||||
} else if (info->action().actionTypeId() == venetianblindAngleActionTypeId) {
|
||||
actionName = "setOrientation";
|
||||
// Convert degree (-90/+90) into percentage (0%/100%, 50%=open)
|
||||
int degree = (info->action().param(venetianblindAngleActionAngleParamTypeId).value().toInt() + 90) / 1.8;
|
||||
actionParameters = { degree };
|
||||
} else if (info->action().actionTypeId() == venetianblindOpenActionTypeId) {
|
||||
actionName = "open";
|
||||
} else if (info->action().actionTypeId() == venetianblindCloseActionTypeId) {
|
||||
actionName = "close";
|
||||
} else if (info->action().actionTypeId() == venetianblindStopActionTypeId) {
|
||||
actionName = "stop";
|
||||
}
|
||||
}
|
||||
|
||||
if (!actionName.isEmpty()) {
|
||||
QJsonDocument jsonRequest{QJsonObject
|
||||
{
|
||||
{"label", info->thing()->name()},
|
||||
{"actions", QJsonArray{QJsonObject{{"deviceURL", deviceUrl},
|
||||
{"commands", QJsonArray{QJsonObject{{"name", actionName},
|
||||
{"parameters", actionParameters}}}}}}}
|
||||
}};
|
||||
SomfyTahomaPostRequest *request = new SomfyTahomaPostRequest(hardwareManager()->networkManager(), "/exec/apply", "application/json", jsonRequest.toJson(QJsonDocument::Compact), this);
|
||||
connect(request, &SomfyTahomaPostRequest::error, info, [info](){
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
});
|
||||
connect(request, &SomfyTahomaPostRequest::finished, info, [this, info](const QVariant &result){
|
||||
qCInfo(dcSomfyTahoma()) << "Action started" << info->thing() << info->action().actionTypeId();
|
||||
m_pendingActions.insert(result.toMap()["execId"].toString(), info);
|
||||
});
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
SomfyTahomaLoginRequest *IntegrationPluginSomfyTahoma::createLoginRequestWithStoredCredentials(Thing *thing)
|
||||
{
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
QString username = pluginStorage()->value("username").toString();
|
||||
QString password = pluginStorage()->value("password").toString();
|
||||
pluginStorage()->endGroup();
|
||||
return new SomfyTahomaLoginRequest(hardwareManager()->networkManager(), username, password, this);
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::markDisconnected(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == tahomaThingClassId) {
|
||||
thing->setStateValue(tahomaConnectedStateTypeId, false);
|
||||
} else if (thing->thingClassId() == gatewayThingClassId) {
|
||||
thing->setStateValue(gatewayConnectedStateTypeId, false);
|
||||
} else if (thing->thingClassId() == rollershutterThingClassId) {
|
||||
thing->setStateValue(rollershutterConnectedStateTypeId, false);
|
||||
} else if (thing->thingClassId() == venetianblindThingClassId) {
|
||||
thing->setStateValue(venetianblindConnectedStateTypeId, false);
|
||||
}
|
||||
foreach (Thing *child, myThings().filterByParentId(thing->id())) {
|
||||
markDisconnected(child);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSomfyTahoma::restoreChildConnectedState(Thing *thing)
|
||||
{
|
||||
pluginStorage()->beginGroup(thing->id().toString());
|
||||
if (pluginStorage()->contains("connected")) {
|
||||
if (thing->thingClassId() == gatewayThingClassId) {
|
||||
thing->setStateValue(gatewayConnectedStateTypeId, pluginStorage()->value("connected").toBool());
|
||||
} else if (thing->thingClassId() == rollershutterThingClassId) {
|
||||
thing->setStateValue(rollershutterConnectedStateTypeId, pluginStorage()->value("connected").toBool());
|
||||
} else if (thing->thingClassId() == venetianblindThingClassId) {
|
||||
thing->setStateValue(venetianblindConnectedStateTypeId, pluginStorage()->value("connected").toBool());
|
||||
}
|
||||
}
|
||||
pluginStorage()->endGroup();
|
||||
foreach (Thing *child, myThings().filterByParentId(thing->id())) {
|
||||
restoreChildConnectedState(child);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef INTEGRATIONPLUGINSOMFYTAHOMA_H
|
||||
#define INTEGRATIONPLUGINSOMFYTAHOMA_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
class SomfyTahomaLoginRequest;
|
||||
|
||||
class IntegrationPluginSomfyTahoma : public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginsomfytahoma.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
void startPairing(ThingPairingInfo *info) override;
|
||||
void confirmPairing(ThingPairingInfo *info, const QString &username, const QString &password) override;
|
||||
|
||||
void setupThing(ThingSetupInfo *info) override;
|
||||
void postSetupThing(Thing *thing) override;
|
||||
void thingRemoved(Thing *thing) override;
|
||||
|
||||
void executeAction(ThingActionInfo *info) override;
|
||||
|
||||
private:
|
||||
SomfyTahomaLoginRequest *createLoginRequestWithStoredCredentials(Thing *thing);
|
||||
void refreshAccount(Thing *thing);
|
||||
void handleEvents(const QVariantList &eventList);
|
||||
void updateThingStates(const QString &deviceUrl, const QVariantList &stateList);
|
||||
void markDisconnected(Thing *thing);
|
||||
void restoreChildConnectedState(Thing *thing);
|
||||
|
||||
private:
|
||||
QMap<Thing *, PluginTimer *> m_eventPollTimer;
|
||||
QMap<QString, QPointer<ThingActionInfo>> m_pendingActions;
|
||||
QMap<QString, QList<Thing *>> m_currentExecutions;
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINSOMFYTAHOMA_H
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"name": "SomfyTahoma",
|
||||
"displayName": "Somfy Tahoma",
|
||||
"id": "4e8be1c1-daa8-4e21-9e85-b2372ab1a450",
|
||||
"vendors": [
|
||||
{
|
||||
"name": "Somfy",
|
||||
"displayName": "Somfy",
|
||||
"id": "4e42a22a-ccfb-4677-89e3-f7fa16bf6be0",
|
||||
"thingClasses": [
|
||||
{
|
||||
"id": "fedd72b8-547d-4e4f-b73e-71344a8ba0c1",
|
||||
"name": "tahoma",
|
||||
"displayName": "Tahoma Account",
|
||||
"createMethods": ["user"],
|
||||
"setupMethod": "userandpassword",
|
||||
"interfaces": ["account"],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "10ebf650-a93a-4ee3-945b-fba10d4e35a5",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"displayNameEvent": "Connetion state changed",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "97fefa85-db79-4efd-8d83-4a15d72996e1",
|
||||
"name": "loggedIn",
|
||||
"displayName": "Logged in",
|
||||
"type": "bool",
|
||||
"displayNameEvent": "Login state changed",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "75609987-be60-4932-94f6-ead791b5fa58",
|
||||
"name": "userDisplayName",
|
||||
"displayName": "User display name",
|
||||
"type": "QString",
|
||||
"displayNameEvent": "User display name changed",
|
||||
"defaultValue": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "6c09e0b9-f0cc-4dea-9994-9e039eff78f1",
|
||||
"name": "gateway",
|
||||
"displayName": "Tahoma Gateway",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["gateway"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "e321a7d6-6dcb-4a37-baf1-c7008f2d5bdb",
|
||||
"displayName": "Gateway Id",
|
||||
"name": "gatewayId",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "18ba7fb7-c9e8-4c61-86b3-a8d3b825ed00",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"displayNameEvent": "Connetion state changed",
|
||||
"defaultValue": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "6b187fe0-a987-462d-90ac-c48efc0d0fc0",
|
||||
"name": "rollershutter",
|
||||
"displayName": "Roller Shutter",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["extendedshutter", "wirelessconnectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "b3d20d6a-f4e1-4959-ab06-3d271ba5c3dc",
|
||||
"displayName": "Device URL",
|
||||
"name": "deviceUrl",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "f954ffc7-a6aa-4d30-aee0-0484631c3344",
|
||||
"name": "percentage",
|
||||
"displayName": "Percentage",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"displayNameEvent": "Percentage changed",
|
||||
"writable": true,
|
||||
"displayNameAction": "Set percentage",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "fa9446ba-da30-4d49-8fb6-f410ecc7dba0",
|
||||
"name": "moving",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"displayName": "Moving",
|
||||
"displayNameEvent": "Moving changed"
|
||||
},
|
||||
{
|
||||
"id": "67594d96-47a2-4360-a1b8-79e4f22f9ed0",
|
||||
"name": "signalStrength",
|
||||
"displayName": "Signal strength",
|
||||
"type": "uint",
|
||||
"unit": "Percentage",
|
||||
"displayNameEvent": "Signal strength changed",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "7a49865d-5ea5-43be-b61f-4e454c48e87e",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"displayNameEvent": "Connetion state changed",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "a0460180-e799-4bc6-83ba-11731ef124a3",
|
||||
"name": "open",
|
||||
"displayName": "Open"
|
||||
},
|
||||
{
|
||||
"id": "cbccf714-1188-4ac9-9c91-17fe2c99acb3",
|
||||
"name": "stop",
|
||||
"displayName": "Stop"
|
||||
},
|
||||
{
|
||||
"id": "baf377c6-9fba-44cf-9f14-af0101f874b5",
|
||||
"name": "close",
|
||||
"displayName": "Close"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "c7160205-d864-4194-b418-060fff60f0cb",
|
||||
"name": "venetianblind",
|
||||
"displayName": "Venetian Blind",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["venetianblind", "wirelessconnectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "e2541b7b-fbfa-4659-87b1-35d8993714c9",
|
||||
"displayName": "Device URL",
|
||||
"name": "deviceUrl",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "77ca50db-42a7-4434-83e2-8b5fc4438924",
|
||||
"name": "percentage",
|
||||
"displayName": "Percentage",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"displayNameEvent": "Percentage changed",
|
||||
"writable": true,
|
||||
"displayNameAction": "Set percentage",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "079c7a80-8a1c-4fd7-b40c-6800120c70fb",
|
||||
"name": "angle",
|
||||
"displayName": "Angle",
|
||||
"type": "int",
|
||||
"unit": "Degree",
|
||||
"displayNameEvent": "Angle changed",
|
||||
"writable": true,
|
||||
"displayNameAction": "Set angle",
|
||||
"defaultValue": 0,
|
||||
"minValue": -90,
|
||||
"maxValue": 90
|
||||
},
|
||||
{
|
||||
"id": "48d5de0a-11ab-4801-94e4-a1dd458c341d",
|
||||
"name": "moving",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"displayName": "Moving",
|
||||
"displayNameEvent": "Moving changed"
|
||||
},
|
||||
{
|
||||
"id": "aee4f4e3-3445-441d-bdbb-631b0c5db942",
|
||||
"name": "signalStrength",
|
||||
"displayName": "Signal strength",
|
||||
"type": "uint",
|
||||
"unit": "Percentage",
|
||||
"displayNameEvent": "Signal strength changed",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "57361115-edbe-49fb-9847-408b571d3108",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"displayNameEvent": "Connetion state changed",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "004e7294-59e6-498b-a0aa-e58eaeefdf2b",
|
||||
"name": "open",
|
||||
"displayName": "Open"
|
||||
},
|
||||
{
|
||||
"id": "31b07407-65ef-4fd1-880b-b5d9f69a9d07",
|
||||
"name": "stop",
|
||||
"displayName": "Stop"
|
||||
},
|
||||
{
|
||||
"id": "1a9707e7-9d64-4237-b150-234edcfed12a",
|
||||
"name": "close",
|
||||
"displayName": "Close"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"title": "Somfy Tahoma",
|
||||
"tagline": "Control Somfy smart home devices through the Somfy Tahoma box.",
|
||||
"icon": "somfy.svg",
|
||||
"stability": "community",
|
||||
"offline": false,
|
||||
"technologies": [
|
||||
"network"
|
||||
],
|
||||
"categories": [
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) by Marsupilami -->
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
width="1024"
|
||||
height="278"
|
||||
viewBox="-1.16119275 -1.16119275 151.1401955 41.0288105"
|
||||
id="svg3317">
|
||||
<defs
|
||||
id="defs3319" />
|
||||
<path
|
||||
d="m 130.83655,27.99125 c 0.20375,0.4425 0.30625,0.92 0.30625,1.42375 0,2.6475 -1.47125,3.78625 -2.1875,4.38375 -1.7925,1.48375 -4.35,1.3775 -4.3775,1.3775 l -1.39,0 c -0.8725,0 -1.8475,0.72375 -1.8475,1.7575 0,1.10375 0.74,1.77 1.97875,1.77 l 1.26375,0 c 0.0713,0 1.84875,0.0725 3.75875,-0.5375 1.93125,-0.61625 4.595,-2.06375 6.43375,-5.46125 0.44375,-0.80625 4.23625,-9.3575 7.00125,-15.59375 l 2.1125,-4.73625 c 0.12375,-0.29125 0.135,-0.57875 0.0575,-0.84125 -0.09,-0.29375 -0.31125,-0.53875 -0.63,-0.70875 -0.54625,-0.2825 -1.30375,-0.3 -2.05375,-0.0625 -0.77,0.24625 -1.41625,0.755 -1.6675,1.32125 -0.0238,0.0738 -3.15625,6.84125 -3.38375,7.31 -0.6125,1.22125 -1.35,1.93125 -2.02625,1.93125 -0.79625,0 -1.29125,-0.0975 -2.4325,-2.04 -0.085,-0.1525 -3.5125,-6.1975 -4.06,-7.14375 -0.3125,-0.59625 -0.97625,-1.10375 -1.78625,-1.36125 -0.81125,-0.255 -1.64875,-0.24375 -2.23625,0.0625 -0.3475,0.18375 -0.5925,0.45375 -0.69,0.77125 -0.0875,0.28375 -0.065,0.6 0.0675,0.91875 0.0262,0.0612 7.35125,14.54375 7.78875,15.45875 m -19.515,-8.76375 c 0.0375,-1.24375 1.04375,-2.20625 2.29875,-2.20625 l -0.002,0 0.0425,0 -0.0475,0 2.93125,0 c 0.95125,0 1.7075,-0.2775 2.24625,-0.82625 0.8525,-0.85 0.88375,-2.0975 0.88375,-2.3325 0.001,-0.3225 -0.0438,-1.375 -0.8125,-2.145 -0.53125,-0.5325 -1.2875,-0.81125 -2.2475,-0.81125 l -2.975,0 c -2.02,0 -2.02,-0.465 -2.02,-1.68625 0,-0.0275 0.0613,-2.51125 2.05,-3.21375 0.63,-0.2325 1.3375,-0.34125 2.0875,-0.345 l 3.585,0 c 1.24625,0 2.36375,-0.83375 2.7175,-2.025 0.08,-0.26375 0.12125,-0.53375 0.12125,-0.805 0,-1.5625 -1.28,-2.83125 -2.83875,-2.83125 -0.0538,0 -3.42125,0.01 -3.42125,0.01 -0.47,0 -0.97875,0.03 -1.505,0.0838 -1.6025,0.1725 -3.035,0.54 -4.28,1.09 -5.24125,2.3225 -5.48625,7.065 -5.48625,7.11625 l -0.005,0.0737 c -0.26125,1.64125 -0.69,2.5325 -2.2475,2.5325 -0.77375,0 -1.39875,0.2425 -1.8525,0.74125 -0.801247,0.85375 -0.773747,2.1775 -0.773747,2.195 l 0,-0.0175 c 0,2.69375 2.547497,3.19625 2.587497,3.20125 1.20125,0.0987 2.11,1.07375 2.11,2.2575 0,0.0587 -0.0162,6.12 -0.0162,9.31625 0,1.125 0.30875,1.995 0.895,2.59 0.775,0.77375 1.7725,0.78125 1.80875,0.78125 l 1.36625,0 c 0.0812,0 0.8325,-0.0138 1.53625,-0.505 0.575,-0.3875 1.26375,-1.20375 1.26375,-2.835 M 63.155303,13.2625 c 0,0 -0.135,-2.64875 2.6975,-2.64875 1.62,0 2.64125,1.46875 4.54625,1.46875 2.435,0 3.08,-1.46875 6.38125,-1.46875 3.77125,0 3.985,1.46875 6.31375,1.46875 2.46125,0 2.9025,-1.46875 7.24125,-1.46875 2.30125,0 4.83875,1.34 4.83875,4.2275 0,3.93625 0.01,14.3475 0.01,14.415 0,1.48125 -1.20875,2.70125 -2.705,2.70125 -1.48875,0 -2.69875,-1.22 -2.69875,-2.70125 l 0,-11.8125 c 0,-1.315 0.0175,-3.9525 -2.29125,-4.0075 0,0 -5.6275,-0.775 -5.6275,9.075 0,0.1575 0.009,6.69 0.009,6.745 0,1.48125 -1.2125,2.70125 -2.7025,2.70125 -1.4625,0 -2.66,-1.16875 -2.7,-2.62 l 0,-11.8975 c 0,-0.86 0.15125,-4.00375 -2.33,-4.00375 -4.79,0 -5.5825,4.89625 -5.5825,8.915 l 0,6.905 c 0,1.48125 -1.21125,2.70125 -2.7025,2.70125 -1.46375,0 -2.65875,-1.16875 -2.6975,-2.62 M 41.348003,4.58 c -9.1875,0 -16.62125,7.43875 -16.62125,16.62625 0,9.17875 7.43375,16.625 16.62125,16.625 9.18625,0 16.62875,-7.44625 16.62875,-16.625 0,-9.1875 -7.4425,-16.62625 -16.62875,-16.62625 m 0,22.56375 c -3.26375,0 -5.94125,-2.66375 -5.94125,-5.9375 0,-3.28125 2.6775,-5.9425 5.94125,-5.9425 3.27375,0 5.93875,2.66125 5.93875,5.9425 0,3.27375 -2.665,5.9375 -5.93875,5.9375 M 5.5730035,22.015 c 0.0375,0.0113 1.275,0.515 2.58875,1.0525 L 12.181753,24.7 c 0.9525,0.37125 1.44375,1.37625 1.1725,2.39625 -0.3275,1.2775 -1.855,2.48625 -5.1324995,2.04625 -1.30375,-0.17625 -4.335,-0.825 -4.36875,-0.83375 l 0.0238,0.009 c -0.0725,-0.0237 -1.8975,-0.68375 -3.02750005,-0.0788 -0.40125,0.22 -0.6625,0.55875 -0.7825,1.03375 -0.42625,1.7025 1.32625005,2.29375 1.33875005,2.3025 0.62625,0.2225 1.32,0.38375 1.87875,0.4975 l 0.46625,0.12375 c 0.0362,0.004 4.015,0.9475 7.1674995,0.905 2.075,-0.0288 7.11,-0.50125 9.08,-4.115 0.29125,-0.5275 0.695,-2.3875 0.4925,-3.565 -0.23625,-1.3675 -0.64625,-2.7275 -3.015,-4.26125 -0.6,-0.3825 -2.46625,-1.005 -4.12125,-1.55375 -0.86875,-0.28 -1.70375,-0.55875 -2.13625,-0.735 -2.9024995,-1.16875 -3.4187495,-2.2325 -3.4674995,-2.765 -0.035,-0.3075 0.0638,-1.01125 0.61875,-1.64125 0.6975,-0.74875 1.8562495,-1.14125 3.4449995,-1.14125 2.3925,0 3.3175,0.28125 4.305,0.57 0.18375,0.065 0.3725,0.125 0.57625,0.17625 0.7475,0.195 1.33875,0.1675 1.75875,-0.0888 0.49875,-0.315 0.6025,-0.8425 0.64375,-1.0275 0.0587,-0.3275 0.135,-1.4275 -1.60625,-2.12875 -0.14,-0.0563 -3.6975,-1.43875 -9.2987495,-0.6625 -0.78625,0.105 -2.3275,0.40875 -3.7725,1.21875 -2.11875,1.16125 -3.22,2.98 -3.18125,5.2325 0.0275,1.63125 0.7875,3.07 2.20375,4.19125 1.05625,0.83625 2.095,1.1975 2.14,1.21"
|
||||
id="path3092"
|
||||
style="fill:#ffb514;fill-opacity:1;fill-rule:nonzero;stroke:none" />
|
||||
<path
|
||||
d="m 145.63405,31.82375 c -1.87,0 -3.1325,-1.3475 -3.1325,-3.15375 0,-1.81125 1.2775,-3.17875 3.1475,-3.17875 1.80875,0 3.16875,1.3675 3.16875,3.17875 0,1.80625 -1.37875,3.15375 -3.18375,3.15375 m 0,-5.595 c -1.34125,0 -2.3075,1.06 -2.3075,2.44125 0,1.36625 0.96625,2.4275 2.3075,2.4275 1.3375,0 2.3075,-1.06125 2.3075,-2.4275 0,-1.38125 -0.97,-2.44125 -2.3075,-2.44125 m 0.51875,3.97 c -0.43375,-0.765 -0.68125,-1.24125 -0.7925,-1.24125 l -0.0787,0 0,1.24125 -0.6925,0 0,-3.15375 1.04875,0 c 0.69875,0 1.0775,0.36625 1.0775,0.855 0,0.5175 -0.43625,0.775 -0.715,0.8675 l 0,0.005 c 0.1525,0 0.585,0.735 0.97,1.42625 l -0.8175,0 z m -0.75625,-2.615 -0.115,0 0,0.83375 0.1025,0 c 0.32875,0 0.58875,-0.12375 0.58875,-0.45375 0,-0.3 -0.205,-0.38 -0.57625,-0.38"
|
||||
id="path3096"
|
||||
style="fill:#ffb514;fill-opacity:1;fill-rule:nonzero;stroke:none" />
|
||||
</svg>
|
||||
<!-- version: 20110311, original size: 148.81781 38.706425, border: 3% -->
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
include(../plugins.pri)
|
||||
|
||||
QT += network
|
||||
|
||||
SOURCES += \
|
||||
integrationpluginsomfytahoma.cpp \
|
||||
somfytahomarequests.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationpluginsomfytahoma.h \
|
||||
somfytahomarequests.h
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "somfytahomarequests.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "network/networkaccessmanager.h"
|
||||
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
SomfyTahomaPostRequest::SomfyTahomaPostRequest(NetworkAccessManager *networkManager, const QString &path, const QString &contentType, const QByteArray &body, QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
QUrl url("https://tahomalink.com/enduser-mobile-web/enduserAPI" + path);
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, contentType);
|
||||
QNetworkReply *reply = networkManager->post(request, body);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply, path] {
|
||||
deleteLater();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcSomfyTahoma()) << "Request for" << path << "failed:" << reply->errorString();
|
||||
emit error(reply->error());
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcSomfyTahoma()) << "Json parse error in reply for" << path << ":" << parseError.errorString();
|
||||
emit error(QNetworkReply::UnknownContentError);
|
||||
return;
|
||||
}
|
||||
|
||||
emit finished(jsonDoc.toVariant());
|
||||
});
|
||||
}
|
||||
|
||||
SomfyTahomaGetRequest::SomfyTahomaGetRequest(NetworkAccessManager *networkManager, const QString &path, QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
QUrl url("https://tahomalink.com/enduser-mobile-web/enduserAPI" + path);
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = networkManager->get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply, path] {
|
||||
deleteLater();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcSomfyTahoma()) << "Request for" << path << "failed:" << reply->errorString();
|
||||
emit error(reply->error());
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcSomfyTahoma()) << "Json parse error in reply for" << path << ":" << parseError.errorString();
|
||||
emit error(QNetworkReply::UnknownContentError);
|
||||
return;
|
||||
}
|
||||
|
||||
emit finished(jsonDoc.toVariant());
|
||||
});
|
||||
}
|
||||
|
||||
SomfyTahomaLoginRequest::SomfyTahomaLoginRequest(NetworkAccessManager *networkManager, const QString &username, const QString &password, QObject *parent):
|
||||
SomfyTahomaPostRequest(networkManager, "/login", "application/x-www-form-urlencoded", QString("userId=" + username + "&userPassword=" + password).toUtf8(), parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SomfyTahomaEventFetchRequest::SomfyTahomaEventFetchRequest(NetworkAccessManager *networkManager, const QString &eventListenerId, QObject *parent):
|
||||
SomfyTahomaPostRequest(networkManager, "/events/" + eventListenerId + "/fetch", "application/json", QByteArray(), parent)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SOMFYTAHOMAREQUESTS_H
|
||||
#define SOMFYTAHOMAREQUESTS_H
|
||||
|
||||
#include <QNetworkReply>
|
||||
|
||||
class NetworkAccessManager;
|
||||
|
||||
class SomfyTahomaPostRequest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SomfyTahomaPostRequest(NetworkAccessManager *networkManager, const QString &path, const QString &contentType, const QByteArray &body, QObject *parent);
|
||||
|
||||
signals:
|
||||
void error(QNetworkReply::NetworkError error);
|
||||
void finished(const QVariant &results);
|
||||
};
|
||||
|
||||
class SomfyTahomaGetRequest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SomfyTahomaGetRequest(NetworkAccessManager *networkManager, const QString &path, QObject *parent);
|
||||
|
||||
signals:
|
||||
void error(QNetworkReply::NetworkError error);
|
||||
void finished(const QVariant &results);
|
||||
};
|
||||
|
||||
class SomfyTahomaLoginRequest : public SomfyTahomaPostRequest
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SomfyTahomaLoginRequest(NetworkAccessManager *networkManager, const QString &username, const QString &password, QObject *parent);
|
||||
};
|
||||
|
||||
class SomfyTahomaEventFetchRequest : public SomfyTahomaPostRequest
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SomfyTahomaEventFetchRequest(NetworkAccessManager *networkManager, const QString &eventListenerId, QObject *parent);
|
||||
};
|
||||
|
||||
#endif // SOMFYTAHOMAREQUESTS_H
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<context>
|
||||
<name>IntegrationPluginSomfyTahoma</name>
|
||||
<message>
|
||||
<location filename="../integrationpluginsomfytahoma.cpp" line="44"/>
|
||||
<source>Please enter the login credentials for Somfy Tahoma.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationpluginsomfytahoma.cpp" line="51"/>
|
||||
<location filename="../integrationpluginsomfytahoma.cpp" line="67"/>
|
||||
<source>Failed to login to Somfy Tahoma.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SomfyTahoma</name>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="80"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="83"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="86"/>
|
||||
<source>Angle</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: venetianblind, ActionType: angle, ID: {079c7a80-8a1c-4fd7-b40c-6800120c70fb})
|
||||
----------
|
||||
The name of the ParamType (ThingClass: venetianblind, EventType: angle, ID: {079c7a80-8a1c-4fd7-b40c-6800120c70fb})
|
||||
----------
|
||||
The name of the StateType ({079c7a80-8a1c-4fd7-b40c-6800120c70fb}) of ThingClass venetianblind</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="89"/>
|
||||
<source>Angle changed</source>
|
||||
<extracomment>The name of the EventType ({079c7a80-8a1c-4fd7-b40c-6800120c70fb}) of ThingClass venetianblind</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="92"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="95"/>
|
||||
<source>Close</source>
|
||||
<extracomment>The name of the ActionType ({1a9707e7-9d64-4237-b150-234edcfed12a}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ActionType ({baf377c6-9fba-44cf-9f14-af0101f874b5}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="98"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="101"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="104"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="107"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="110"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="113"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="116"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="119"/>
|
||||
<source>Connected</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: venetianblind, EventType: connected, ID: {57361115-edbe-49fb-9847-408b571d3108})
|
||||
----------
|
||||
The name of the StateType ({57361115-edbe-49fb-9847-408b571d3108}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ParamType (ThingClass: rollershutter, EventType: connected, ID: {7a49865d-5ea5-43be-b61f-4e454c48e87e})
|
||||
----------
|
||||
The name of the StateType ({7a49865d-5ea5-43be-b61f-4e454c48e87e}) of ThingClass rollershutter
|
||||
----------
|
||||
The name of the ParamType (ThingClass: gateway, EventType: connected, ID: {18ba7fb7-c9e8-4c61-86b3-a8d3b825ed00})
|
||||
----------
|
||||
The name of the StateType ({18ba7fb7-c9e8-4c61-86b3-a8d3b825ed00}) of ThingClass gateway
|
||||
----------
|
||||
The name of the ParamType (ThingClass: tahoma, EventType: connected, ID: {10ebf650-a93a-4ee3-945b-fba10d4e35a5})
|
||||
----------
|
||||
The name of the StateType ({10ebf650-a93a-4ee3-945b-fba10d4e35a5}) of ThingClass tahoma</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="122"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="125"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="128"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="131"/>
|
||||
<source>Connetion state changed</source>
|
||||
<extracomment>The name of the EventType ({57361115-edbe-49fb-9847-408b571d3108}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the EventType ({7a49865d-5ea5-43be-b61f-4e454c48e87e}) of ThingClass rollershutter
|
||||
----------
|
||||
The name of the EventType ({18ba7fb7-c9e8-4c61-86b3-a8d3b825ed00}) of ThingClass gateway
|
||||
----------
|
||||
The name of the EventType ({10ebf650-a93a-4ee3-945b-fba10d4e35a5}) of ThingClass tahoma</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="134"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="137"/>
|
||||
<source>Device URL</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: venetianblind, Type: thing, ID: {e2541b7b-fbfa-4659-87b1-35d8993714c9})
|
||||
----------
|
||||
The name of the ParamType (ThingClass: rollershutter, Type: thing, ID: {b3d20d6a-f4e1-4959-ab06-3d271ba5c3dc})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="140"/>
|
||||
<source>Gateway Id</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: gateway, Type: thing, ID: {e321a7d6-6dcb-4a37-baf1-c7008f2d5bdb})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="143"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="146"/>
|
||||
<source>Logged in</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: tahoma, EventType: loggedIn, ID: {97fefa85-db79-4efd-8d83-4a15d72996e1})
|
||||
----------
|
||||
The name of the StateType ({97fefa85-db79-4efd-8d83-4a15d72996e1}) of ThingClass tahoma</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="149"/>
|
||||
<source>Login state changed</source>
|
||||
<extracomment>The name of the EventType ({97fefa85-db79-4efd-8d83-4a15d72996e1}) of ThingClass tahoma</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="152"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="155"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="158"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="161"/>
|
||||
<source>Moving</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: venetianblind, EventType: moving, ID: {48d5de0a-11ab-4801-94e4-a1dd458c341d})
|
||||
----------
|
||||
The name of the StateType ({48d5de0a-11ab-4801-94e4-a1dd458c341d}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ParamType (ThingClass: rollershutter, EventType: moving, ID: {fa9446ba-da30-4d49-8fb6-f410ecc7dba0})
|
||||
----------
|
||||
The name of the StateType ({fa9446ba-da30-4d49-8fb6-f410ecc7dba0}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="164"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="167"/>
|
||||
<source>Moving changed</source>
|
||||
<extracomment>The name of the EventType ({48d5de0a-11ab-4801-94e4-a1dd458c341d}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the EventType ({fa9446ba-da30-4d49-8fb6-f410ecc7dba0}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="170"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="173"/>
|
||||
<source>Open</source>
|
||||
<extracomment>The name of the ActionType ({004e7294-59e6-498b-a0aa-e58eaeefdf2b}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ActionType ({a0460180-e799-4bc6-83ba-11731ef124a3}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="176"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="179"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="182"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="185"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="188"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="191"/>
|
||||
<source>Percentage</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: venetianblind, ActionType: percentage, ID: {77ca50db-42a7-4434-83e2-8b5fc4438924})
|
||||
----------
|
||||
The name of the ParamType (ThingClass: venetianblind, EventType: percentage, ID: {77ca50db-42a7-4434-83e2-8b5fc4438924})
|
||||
----------
|
||||
The name of the StateType ({77ca50db-42a7-4434-83e2-8b5fc4438924}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ParamType (ThingClass: rollershutter, ActionType: percentage, ID: {f954ffc7-a6aa-4d30-aee0-0484631c3344})
|
||||
----------
|
||||
The name of the ParamType (ThingClass: rollershutter, EventType: percentage, ID: {f954ffc7-a6aa-4d30-aee0-0484631c3344})
|
||||
----------
|
||||
The name of the StateType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="194"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="197"/>
|
||||
<source>Percentage changed</source>
|
||||
<extracomment>The name of the EventType ({77ca50db-42a7-4434-83e2-8b5fc4438924}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the EventType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="200"/>
|
||||
<source>Roller Shutter</source>
|
||||
<extracomment>The name of the ThingClass ({6b187fe0-a987-462d-90ac-c48efc0d0fc0})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="203"/>
|
||||
<source>Set angle</source>
|
||||
<extracomment>The name of the ActionType ({079c7a80-8a1c-4fd7-b40c-6800120c70fb}) of ThingClass venetianblind</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="206"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="209"/>
|
||||
<source>Set percentage</source>
|
||||
<extracomment>The name of the ActionType ({77ca50db-42a7-4434-83e2-8b5fc4438924}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ActionType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="212"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="215"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="218"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="221"/>
|
||||
<source>Signal strength</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: venetianblind, EventType: signalStrength, ID: {aee4f4e3-3445-441d-bdbb-631b0c5db942})
|
||||
----------
|
||||
The name of the StateType ({aee4f4e3-3445-441d-bdbb-631b0c5db942}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ParamType (ThingClass: rollershutter, EventType: signalStrength, ID: {67594d96-47a2-4360-a1b8-79e4f22f9ed0})
|
||||
----------
|
||||
The name of the StateType ({67594d96-47a2-4360-a1b8-79e4f22f9ed0}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="224"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="227"/>
|
||||
<source>Signal strength changed</source>
|
||||
<extracomment>The name of the EventType ({aee4f4e3-3445-441d-bdbb-631b0c5db942}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the EventType ({67594d96-47a2-4360-a1b8-79e4f22f9ed0}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="230"/>
|
||||
<source>Somfy</source>
|
||||
<extracomment>The name of the vendor ({4e42a22a-ccfb-4677-89e3-f7fa16bf6be0})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="233"/>
|
||||
<source>Somfy Tahoma</source>
|
||||
<extracomment>The name of the plugin SomfyTahoma ({4e8be1c1-daa8-4e21-9e85-b2372ab1a450})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="236"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="239"/>
|
||||
<source>Stop</source>
|
||||
<extracomment>The name of the ActionType ({31b07407-65ef-4fd1-880b-b5d9f69a9d07}) of ThingClass venetianblind
|
||||
----------
|
||||
The name of the ActionType ({cbccf714-1188-4ac9-9c91-17fe2c99acb3}) of ThingClass rollershutter</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="242"/>
|
||||
<source>Tahoma Account</source>
|
||||
<extracomment>The name of the ThingClass ({fedd72b8-547d-4e4f-b73e-71344a8ba0c1})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="245"/>
|
||||
<source>Tahoma Gateway</source>
|
||||
<extracomment>The name of the ThingClass ({6c09e0b9-f0cc-4dea-9994-9e039eff78f1})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="248"/>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="251"/>
|
||||
<source>User display name</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: tahoma, EventType: userDisplayName, ID: {75609987-be60-4932-94f6-ead791b5fa58})
|
||||
----------
|
||||
The name of the StateType ({75609987-be60-4932-94f6-ead791b5fa58}) of ThingClass tahoma</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="254"/>
|
||||
<source>User display name changed</source>
|
||||
<extracomment>The name of the EventType ({75609987-be60-4932-94f6-ead791b5fa58}) of ThingClass tahoma</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins/somfytahoma/plugininfo.h" line="257"/>
|
||||
<source>Venetian Blind</source>
|
||||
<extracomment>The name of the ThingClass ({c7160205-d864-4194-b418-060fff60f0cb})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
Loading…
Reference in New Issue