From ff03f6d28bf6770deda79fd821c44046076f0ec8 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Mon, 18 Oct 2021 09:42:59 -0400 Subject: [PATCH] initial setup configuration - not receiving published data --- Garadget | 1 - garadget/Garadget.pro.user | 4 +- garadget/integrationpluginGaradget.cpp | 224 ++++++++++--- garadget/integrationpluginGaradget.cpp~ | 301 ------------------ garadget/integrationpluginGaradget.h | 13 + garadget/integrationpluginGaradget.json | 87 ++++- ...067fe-719b-493b-9cce-0f170978c8f7-en_US.ts | 152 +++++++++ ...67fe-719b-493b-9cce-0f170978c8f7-en_US.ts~ | 91 ------ 8 files changed, 429 insertions(+), 444 deletions(-) delete mode 160000 Garadget delete mode 100644 garadget/integrationpluginGaradget.cpp~ delete mode 100644 garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts~ diff --git a/Garadget b/Garadget deleted file mode 160000 index 9de1de8d..00000000 --- a/Garadget +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9de1de8da96224f315f858178506dbc09ef1602b diff --git a/garadget/Garadget.pro.user b/garadget/Garadget.pro.user index fb6e084f..8e259bf9 100644 --- a/garadget/Garadget.pro.user +++ b/garadget/Garadget.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -250,7 +250,7 @@ 4096 false false - 1000 + 0 true diff --git a/garadget/integrationpluginGaradget.cpp b/garadget/integrationpluginGaradget.cpp index db7ee9d0..77ddd049 100644 --- a/garadget/integrationpluginGaradget.cpp +++ b/garadget/integrationpluginGaradget.cpp @@ -48,6 +48,41 @@ static QHash> stateMaps = { {sonoff_basicThingClassId, sonoff_basicPowerStateTypeIds}, }; +// bee add static id + +static QHash sonoff_basicstateStateTypeIds = { + {"closed", sonoff_basicStateStateTypeId}, +}; + +static QHash> stateStateMAPS = { + {sonoff_basicThingClassId, sonoff_basicstateStateTypeIds}, +}; + +static QHash sonoff_basicClosingOutputStateTypeIds = { + {"CLOSE1", sonoff_basicClosingOutputStateTypeId}, +}; + +static QHash> stateClosingOutputMaps = { + {sonoff_basicThingClassId, sonoff_basicClosingOutputStateTypeIds}, +}; + +static QHash sonoff_basicOpeningOutputStateTypeIds = { + {"OPEN1", sonoff_basicOpeningOutputStateTypeId}, +}; + +static QHash> stateOpeningMaps = { + {sonoff_basicThingClassId, sonoff_basicOpeningOutputStateTypeIds}, +}; + +static QHash sonoff_basicMovingStateTypeIds = { + {"STOP1", sonoff_basicMovingStateTypeId}, +}; + +static QHash> stateMovingMaps = { + {sonoff_basicThingClassId, sonoff_basicMovingStateTypeIds}, +}; + + IntegrationPluginGaradget::IntegrationPluginGaradget() { // Helper maps for parent devices (aka sonoff_*) @@ -58,6 +93,19 @@ IntegrationPluginGaradget::IntegrationPluginGaradget() m_connectedStateTypeMap[sonoff_basicThingClassId] = sonoff_basicConnectedStateTypeId; m_signalStrengthStateTypeMap[sonoff_basicThingClassId] = sonoff_basicSignalStrengthStateTypeId; + + // bee adders for extendedgaragestate + + m_stateStateTypeMap[sonoff_basicThingClassId] = sonoff_basicStateStateTypeId; + + m_movingStateTypeMap[sonoff_basicThingClassId] = sonoff_basicMovingStateTypeId; + + m_percentageStateTypeMap[sonoff_basicThingClassId] = sonoff_basicPercentageStateTypeId; + + m_closingOutputStateTypeMap[sonoff_basicThingClassId] = sonoff_basicClosingOutputStateTypeId; + + m_openingOutputStateTypeMap[sonoff_basicThingClassId] = sonoff_basicOpeningOutputStateTypeId; + } IntegrationPluginGaradget::~IntegrationPluginGaradget() @@ -73,29 +121,64 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) Thing *thing = info->thing(); if (m_ipAddressParamTypeMap.contains(thing->thingClassId())) { - ParamTypeId ipAddressParamTypeId = m_ipAddressParamTypeMap.value(thing->thingClassId()); +// ParamTypeId ipAddressParamTypeId = m_ipAddressParamTypeMap.value(thing->thingClassId()); - QHostAddress deviceAddress = QHostAddress(thing->paramValue(ipAddressParamTypeId).toString()); +// QHostAddress deviceAddress = QHostAddress(thing->paramValue(ipAddressParamTypeId).toString()); + // ipaddress is defined here but not sure how to get rid of and still have the mqtt channel. Garadget only works with the broker. + QHostAddress deviceAddress = QHostAddress("192.168.1.174"); if (deviceAddress.isNull()) { qCWarning(dcGaradget) << "Not a valid IP address given for IP address parameter"; //: Error setting up thing return info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The given IP address is not valid.")); } - MqttChannel *channel = hardwareManager()->mqttProvider()->createChannel(thing->id().toString().remove(QRegExp("[{}-]")), deviceAddress ); +// MqttChannel *channel = hardwareManager()->mqttProvider()->createChannel(thing->id().toString().remove(QRegExp("[{}-]")), deviceAddress ); + MqttChannel *channel = hardwareManager()->mqttProvider()->createChannel("garage", deviceAddress ); if (!channel) { qCWarning(dcGaradget) << "Failed to create MQTT channel."; //: Error setting up thing return info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Error creating MQTT channel. Please check MQTT server settings.")); } -// ipaddress is defined here but not sure how to get rid of and still have the mqtt channel. Garadget only works with the broker. - qCDebug(dcGaradget) << "BEE initial setup instructions:" << deviceAddress.toString() << channel; + qCDebug(dcGaradget) << "initial setup instructions:" << deviceAddress.toString() << channel; +/* + QUrl url(QString("http://%1/cm").arg(deviceAddress.toString())); + QUrlQuery query; + QMap configItems; + configItems.insert("MqttHost", channel->serverAddress().toString()); + configItems.insert("MqttPort", QString::number(channel->serverPort())); + configItems.insert("MqttClient", channel->clientId()); + configItems.insert("MqttUser", channel->username()); + configItems.insert("MqttPassword", channel->password()); + configItems.insert("Topic", "sonoff"); + configItems.insert("FullTopic", channel->topicPrefixList().first() + "/%topic%/"); + + QStringList configList; + foreach (const QString &key, configItems.keys()) { + configList << key + ' ' + configItems.value(key); + } + QString fullCommand = "Backlog " + configList.join(';'); + query.addQueryItem("cmnd", fullCommand.toUtf8().toPercentEncoding()); + + url.setQuery(query); + + QNetworkRequest request(url); + QNetworkReply *reply = hardwareManager()->networkManager()->get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, info, [this, info, channel, reply](){ + if (reply->error() != QNetworkReply::NoError) { + qCDebug(dcTasmota) << "Sonoff thing setup call failed:" << reply->error() << reply->errorString() << reply->readAll(); + hardwareManager()->mqttProvider()->releaseChannel(channel); + //: Error setting up thing + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Could not connect to Tasmota device.")); + return; + } +*/ +//BEE mod m_mqttChannels.insert(info->thing(), channel); connect(channel, &MqttChannel::clientConnected, this, &IntegrationPluginGaradget::onClientConnected); connect(channel, &MqttChannel::clientDisconnected, this, &IntegrationPluginGaradget::onClientDisconnected); connect(channel, &MqttChannel::publishReceived, this, &IntegrationPluginGaradget::onPublishReceived); - qCDebug(dcGaradget) << "Garadget setup complete"; info->finish(Thing::ThingErrorNoError); foreach (Thing *child, myThings()) { @@ -104,22 +187,21 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) return; } } +// }); // insert to reprogram client Garadget to new device/topic name - QJsonObject beeobj; - beeobj.insert("nme", QString(channel->topicPrefixList().first())); - QJsonDocument beedoc(beeobj); - QByteArray beedata = beedoc.toJson(QJsonDocument::Compact); - QString jsonString(beedata); - qCDebug(dcGaradget) << "Publishing:" << "garadget/garage/set-conf " << beedata; -// next line will not publish to the correct device as topic is 32 characters long and garadget only allows 30 characters. - channel->publish("garadget/garaged/set-config", beedata); - channel->publish("garadget/garage/command", "get-config"); -// need to develop test for correct modification of nme + QJsonObject garadgetobj; + garadgetobj.insert("nme", QString(channel->topicPrefixList().first())); + QJsonDocument garadgetdoc(garadgetobj); + QByteArray garadgetdata = garadgetdoc.toJson(QJsonDocument::Compact); + QString jsonString(garadgetdata); + qCDebug(dcGaradget) << "Publishing:" << "garadget/" + channel->topicPrefixList().first() << garadgetdata; + channel->publish("garadget/" + channel->topicPrefixList().first() + "/set-config", garadgetdata); return; } if (m_connectedStateTypeMap.contains(thing->thingClassId())) { + qCDebug(dcGaradget) << "entered connectedStateTypeMap function"; Thing* parentDevice = myThings().findById(thing->parentId()); StateTypeId connectedStateTypeId = m_connectedStateTypeMap.value(thing->thingClassId()); thing->setStateValue(m_connectedStateTypeMap.value(thing->thingClassId()), parentDevice->stateValue(connectedStateTypeId)); @@ -135,6 +217,16 @@ void IntegrationPluginGaradget::thingRemoved(Thing *thing) if (m_mqttChannels.contains(thing)) { qCDebug(dcGaradget) << "Releasing MQTT channel"; MqttChannel* channel = m_mqttChannels.take(thing); + + // insert to reprogram client Garadget to new device/topic name + QJsonObject garadgetobj; + garadgetobj.insert("nme","garage" ); + QJsonDocument garadgetdoc(garadgetobj); + QByteArray garadgetdata = garadgetdoc.toJson(QJsonDocument::Compact); + QString jsonString(garadgetdata); + qCDebug(dcGaradget) << "garadget/" + QString(channel->topicPrefixList().first()) + "/set-config" << " topic = " << garadgetdata; + channel->publish("garadget/" + QString(channel->topicPrefixList().first()) + "/set-config", garadgetdata); + hardwareManager()->mqttProvider()->releaseChannel(channel); } } @@ -144,38 +236,10 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) Thing *thing = info->thing(); Action action = info->action(); - if (thing->thingClassId() == sonoff_basicThingClassId) { - MqttChannel *channel = m_mqttChannels.value(thing); - if (!channel) { - qCWarning(dcGaradget()) << "No MQTT channel for this thing."; - info->finish(Thing::ThingErrorHardwareNotAvailable); - return; - } - QString channelName = stateMaps.value(thing->thingClassId()).key(action.actionTypeId()); - QByteArray payload = action.paramValue(action.actionTypeId()).toBool() ? "ON" : "OFF"; - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + channelName << payload; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + channelName, payload); - thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId())); - info->finish(Thing::ThingErrorNoError); - return; - } + qCDebug(dcGaradget) << "executeAction function" << (thing->thingClassId()); - // Legacy (deprecated) connected devices - if (m_powerStateTypeMap.contains(thing->thingClassId())) { - Thing *parentDev = myThings().findById(thing->parentId()); - MqttChannel *channel = m_mqttChannels.value(parentDev); - if (!channel) { - qCWarning(dcGaradget()) << "No mqtt channel for this thing."; - return info->finish(Thing::ThingErrorHardwareNotAvailable); - } - ParamTypeId channelParamTypeId = m_channelParamTypeMap.value(thing->thingClassId()); - ParamTypeId powerActionParamTypeId = ParamTypeId(m_powerStateTypeMap.value(thing->thingClassId()).toString()); - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(channelParamTypeId).toString() << (action.param(powerActionParamTypeId).value().toBool() ? "ON" : "OFF"); - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(channelParamTypeId).toString().toLower(), action.param(powerActionParamTypeId).value().toBool() ? "ON" : "OFF"); - thing->setStateValue(m_powerStateTypeMap.value(thing->thingClassId()), action.param(powerActionParamTypeId).value().toBool()); - return info->finish(Thing::ThingErrorNoError); - } if (m_closableStopActionTypeMap.contains(thing->thingClassId())) { + qCDebug(dcGaradget) << "Publishing: m_closableStopActionTypeMap" << "how did I get here?"; Thing *parentDev = myThings().findById(thing->parentId()); MqttChannel *channel = m_mqttChannels.value(parentDev); if (!channel) { @@ -202,7 +266,57 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } return info->finish(Thing::ThingErrorNoError); } - qCWarning(dcGaradget) << "Unhandled execute action call for devie" << thing; + + if (thing->thingClassId() == sonoff_basicThingClassId) { + MqttChannel *channel = m_mqttChannels.value(thing); + if (!channel) { + qCWarning(dcGaradget()) << "No MQTT channel for this thing."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + qCDebug(dcGaradget) << "entered sonoff_basicThingClassId function" << (thing->thingClassId()); +// QString channelName = stateMaps.value(thing->thingClassId()).key(action.actionTypeId()); +// QByteArray payload = action.paramValue(action.actionTypeId()).toBool() ? "ON" : "OFF"; +// qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + channelName << payload; +// channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + channelName, payload); +// qCDebug(dcGaradget) << "Publishing:" << "garadget/" + channel->topicPrefixList().first() + "/command" << payload; +// channel->publish("garadget/" + channel->topicPrefixList().first() + "/command", payload); +// thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId())); +// info->finish(Thing::ThingErrorNoError); +// return; + + if (action.actionTypeId() == sonoff_basicOpenActionTypeId) { + qCDebug(dcGaradget) << "Publishing:" << "garadget/" + channel->topicPrefixList().first() + "/command" << "open"; + channel->publish("garadget/" + channel->topicPrefixList().first() + "/command", "open"); +// qCDebug(dcGaradget) << "OpenAction stuff:" << action.actionTypeId() << action.paramValue(action.actionTypeId()); +// qCDebug(dcGaradget) << "OpenMapAction stuff:" << action.paramValue(action.actionTypeId()) << stateOpeningMaps.value(thing->thingClassId()).key(action.actionTypeId()); +// thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId())); + info->finish(Thing::ThingErrorNoError); + return; + } + if (action.actionTypeId() == sonoff_basicCloseActionTypeId) { + qCDebug(dcGaradget) << "Publishing:" << "garadget/" + channel->topicPrefixList().first() + "/command" << "close"; + channel->publish("garadget/" + channel->topicPrefixList().first() + "/command", "close"); +// qCDebug(dcGaradget) << "CloseAction stuff:" << thing << thing->thingClassId() << thing->thingClassId(); +// qCDebug(dcGaradget) << "CloseAction newparameter" << thing->paramValue(stateStateMAPS) ; +// thing->setStateValue(stateStateMAPS.value(thing->thingClassId()).key(action.actionTypeId()),"closed"); +// qCDebug(dcGaradget) << "CloseMapAction stuff:" << stateStateMAPS.value(thing->thingClassId()).key(action.actionTypeId()); +// thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId())); + info->finish(Thing::ThingErrorNoError); + return; + } + if (action.actionTypeId() == sonoff_basicStopActionTypeId) { + qCDebug(dcGaradget) << "Publishing:" << "garadget/" + channel->topicPrefixList().first() + "/command" << "stop"; + channel->publish("garadget/" + channel->topicPrefixList().first() + "/command", "stop"); +// qCDebug(dcGaradget) << "StopAction stuff:" << action.actionTypeId() << action.paramValue(action.actionTypeId()); +// qCDebug(dcGaradget) << "StopMapAction stuff:" << action.paramValue(action.actionTypeId()) << stateMovingMaps.value(thing->thingClassId()).key(action.actionTypeId()); +// thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId())); + info->finish(Thing::ThingErrorNoError); + return; + } + + } + qCWarning(dcGaradget) << "Unhandled execute action call for device" << thing; } void IntegrationPluginGaradget::onClientConnected(MqttChannel *channel) @@ -274,5 +388,19 @@ void IntegrationPluginGaradget::onPublishReceived(MqttChannel *channel, const QS child->setStateValue(m_signalStrengthStateTypeMap.value(child->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt()); } } -} + if (topic.startsWith("garadget/" + channel->topicPrefixList().first() + "/status")) { + qCDebug(dcGaradget) << "Garadget status received " << payload; + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(dcGaradget) << "Cannot parse JSON from Garadget device" << error.errorString(); + return; + } + QVariantMap dataMap = jsonDoc.toVariant().toMap(); +// thing->setStateValue(m_signalStrengthStateTypeMap.value(thing->thingClassId()), dataMap.value("Gstatus").toMap().value("status")); + thing->setStateValue(m_stateStateTypeMap.value(thing->thingClassId()), dataMap.value("status").toMap().value("state")); + qCDebug(dcGaradget) << "Datamap " << m_signalStrengthStateTypeMap.value(thing->thingClassId()); + qCDebug(dcGaradget) << "Garadget status decode " << jsonDoc; + } +} diff --git a/garadget/integrationpluginGaradget.cpp~ b/garadget/integrationpluginGaradget.cpp~ deleted file mode 100644 index 3f584483..00000000 --- a/garadget/integrationpluginGaradget.cpp~ +++ /dev/null @@ -1,301 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* 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 . -* -* 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 "integrationpluginGaradget.h" -#include "plugininfo.h" - -#include -#include -#include -#include - -#include "hardwaremanager.h" -#include "network/networkaccessmanager.h" -#include "network/mqtt/mqttprovider.h" -#include "network/mqtt/mqttchannel.h" - -static QHash sonoff_basicPowerStateTypeIds = { - {"POWER1", sonoff_basicPowerStateTypeId}, -}; -static QHash> stateMaps = { - {sonoff_basicThingClassId, sonoff_basicPowerStateTypeIds}, -}; - -IntegrationPluginGaradget::IntegrationPluginGaradget() -{ - // Helper maps for parent devices (aka sonoff_*) - m_ipAddressParamTypeMap[sonoff_basicThingClassId] = sonoff_basicThingIpAddressParamTypeId; - - - // Helper maps for all devices - m_connectedStateTypeMap[sonoff_basicThingClassId] = sonoff_basicConnectedStateTypeId; - - m_signalStrengthStateTypeMap[sonoff_basicThingClassId] = sonoff_basicSignalStrengthStateTypeId; -} - -IntegrationPluginGaradget::~IntegrationPluginGaradget() -{ -} - -void IntegrationPluginGaradget::init() -{ -} - -void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) -{ - Thing *thing = info->thing(); - - if (m_ipAddressParamTypeMap.contains(thing->thingClassId())) { - ParamTypeId ipAddressParamTypeId = m_ipAddressParamTypeMap.value(thing->thingClassId()); - - QHostAddress deviceAddress = QHostAddress(thing->paramValue(ipAddressParamTypeId).toString()); - if (deviceAddress.isNull()) { - qCWarning(dcGaradget) << "Not a valid IP address given for IP address parameter"; - //: Error setting up thing - return info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The given IP address is not valid.")); - } - - MqttChannel *channel = hardwareManager()->mqttProvider()->createChannel(thing->id().toString().remove(QRegExp("[{}-]")), deviceAddress ); - if (!channel) { - qCWarning(dcGaradget) << "Failed to create MQTT channel."; - //: Error setting up thing - return info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Error creating MQTT channel. Please check MQTT server settings.")); - } -// ipaddress is defined here but not sure how to get rid of and still have the mqtt channel. Garadget only works with the broker. - - qCDebug(dcGaradget) << "BEE initial setup instructions:" << deviceAddress.toString() << channel; - - m_mqttChannels.insert(info->thing(), channel); - connect(channel, &MqttChannel::clientConnected, this, &IntegrationPluginGaradget::onClientConnected); - connect(channel, &MqttChannel::clientDisconnected, this, &IntegrationPluginGaradget::onClientDisconnected); - connect(channel, &MqttChannel::publishReceived, this, &IntegrationPluginGaradget::onPublishReceived); - - qCDebug(dcGaradget) << "Garadget setup complete"; - info->finish(Thing::ThingErrorNoError); - foreach (Thing *child, myThings()) { - if (child->parentId() == info->thing()->id()) { - // Already have child devices... We're done here - return; - } - } - -// insert to reprogram client Garadget to new device/topic name - QJsonObject beeobj; - beeobj.insert("nme", QString(channel->topicPrefixList().first())); - QJsonDocument beedoc(beeobj); - QByteArray beedata = beedoc.toJson(QJsonDocument::Compact); - QString jsonString(beedata); - qCDebug(dcGaradget) << "Publishing:" << "garadget/garage/set-conf " << beedata; -// next line will not publish to the correct device as topic is 32 characters long and garadget only allows 30 characters. - channel->publish("garadget/garaged/set-config", beedata); - channel->publish("garadget/garage/command", "get-config"); -// need to develop test for correct modification of nme - return; - } - - if (m_connectedStateTypeMap.contains(thing->thingClassId())) { - Thing* parentDevice = myThings().findById(thing->parentId()); - StateTypeId connectedStateTypeId = m_connectedStateTypeMap.value(thing->thingClassId()); - thing->setStateValue(m_connectedStateTypeMap.value(thing->thingClassId()), parentDevice->stateValue(connectedStateTypeId)); - return info->finish(Thing::ThingErrorNoError); - } - - qCWarning(dcGaradget) << "Unhandled ThingClass in setupDevice" << thing->thingClassId(); -} - -void IntegrationPluginGaradget::onPublishReceivedSetup(MqttChannel *channel, const QString &topic, const QByteArray &payload) -{ - qCDebug(dcGaradget) << "Publish received from garadget/garage thing:" << topic << qUtf8Printable(payload); - Thing *thing = m_mqttChannels.key(channel); - if (topic.startsWith( "garadget/garage/config")) { - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); - qCWarning(dcGaradget) << "BEE on receive QJsonDocument: " << jsonDoc; - if (error.error != QJsonParseError::NoError) { - qCWarning(dcGaradget) << "Cannot parse JSON from Garadget device" << error.errorString(); - return; - } - QVariantMap dataMap = jsonDoc.toVariant().toMap(); - thing->setStateValue(m_signalStrengthStateTypeMap.value(thing->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt()); - - } - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); - qCWarning(dcGaradget) << "BEE on receive ending QJsonDocument: " << jsonDoc; -} - - -void IntegrationPluginGaradget::thingRemoved(Thing *thing) -{ - qCDebug(dcGaradget) << "Device removed" << thing->name(); - if (m_mqttChannels.contains(thing)) { - qCDebug(dcGaradget) << "Releasing MQTT channel"; - MqttChannel* channel = m_mqttChannels.take(thing); - hardwareManager()->mqttProvider()->releaseChannel(channel); - } -} - -void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) -{ - Thing *thing = info->thing(); - Action action = info->action(); - - if (thing->thingClassId() == sonoff_basicThingClassId) { - MqttChannel *channel = m_mqttChannels.value(thing); - if (!channel) { - qCWarning(dcGaradget()) << "No MQTT channel for this thing."; - info->finish(Thing::ThingErrorHardwareNotAvailable); - return; - } - QString channelName = stateMaps.value(thing->thingClassId()).key(action.actionTypeId()); - QByteArray payload = action.paramValue(action.actionTypeId()).toBool() ? "ON" : "OFF"; - qCDebug(dcGaradget) << "Publishing:" << "garadget/" + channel->topicPrefixList().first() + "/command " + channelName << payload; - channel->publish("garadget/" + channel->topicPrefixList().first() + "/command " + channelName, payload); - thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId())); - info->finish(Thing::ThingErrorNoError); - return; - } - - // Legacy (deprecated) connected devices - if (m_powerStateTypeMap.contains(thing->thingClassId())) { - Thing *parentDev = myThings().findById(thing->parentId()); - MqttChannel *channel = m_mqttChannels.value(parentDev); - if (!channel) { - qCWarning(dcGaradget()) << "No mqtt channel for this thing."; - return info->finish(Thing::ThingErrorHardwareNotAvailable); - } - ParamTypeId channelParamTypeId = m_channelParamTypeMap.value(thing->thingClassId()); - ParamTypeId powerActionParamTypeId = ParamTypeId(m_powerStateTypeMap.value(thing->thingClassId()).toString()); - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(channelParamTypeId).toString() << (action.param(powerActionParamTypeId).value().toBool() ? "ON" : "OFF"); - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(channelParamTypeId).toString().toLower(), action.param(powerActionParamTypeId).value().toBool() ? "ON" : "OFF"); - thing->setStateValue(m_powerStateTypeMap.value(thing->thingClassId()), action.param(powerActionParamTypeId).value().toBool()); - return info->finish(Thing::ThingErrorNoError); - } - if (m_closableStopActionTypeMap.contains(thing->thingClassId())) { - Thing *parentDev = myThings().findById(thing->parentId()); - MqttChannel *channel = m_mqttChannels.value(parentDev); - if (!channel) { - qCWarning(dcGaradget()) << "No mqtt channel for this thing."; - return info->finish(Thing::ThingErrorHardwareNotAvailable); - } - ParamTypeId openingChannelParamTypeId = m_openingChannelParamTypeMap.value(thing->thingClassId()); - ParamTypeId closingChannelParamTypeId = m_closingChannelParamTypeMap.value(thing->thingClassId()); - if (action.actionTypeId() == m_closableOpenActionTypeMap.value(thing->thingClassId())) { - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(closingChannelParamTypeId).toString() << "OFF"; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(closingChannelParamTypeId).toString().toLower(), "OFF"); - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(openingChannelParamTypeId).toString() << "ON"; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(openingChannelParamTypeId).toString().toLower(), "ON"); - } else if (action.actionTypeId() == m_closableCloseActionTypeMap.value(thing->thingClassId())) { - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(openingChannelParamTypeId).toString() << "OFF"; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(openingChannelParamTypeId).toString().toLower(), "OFF"); - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(closingChannelParamTypeId).toString() << "ON"; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(closingChannelParamTypeId).toString().toLower(), "ON"); - } else { // Stop - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(openingChannelParamTypeId).toString() << "OFF"; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(openingChannelParamTypeId).toString().toLower(), "OFF"); - qCDebug(dcGaradget) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(closingChannelParamTypeId).toString() << "OFF"; - channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + thing->paramValue(closingChannelParamTypeId).toString().toLower(), "OFF"); - } - return info->finish(Thing::ThingErrorNoError); - } - qCWarning(dcGaradget) << "Unhandled execute action call for devie" << thing; -} - -void IntegrationPluginGaradget::onClientConnected(MqttChannel *channel) -{ - qCDebug(dcGaradget) << "Sonoff thing connected!"; - Thing *dev = m_mqttChannels.key(channel); - dev->setStateValue(m_connectedStateTypeMap.value(dev->thingClassId()), true); - - foreach (Thing *child, myThings()) { - if (child->parentId() == dev->id()) { - child->setStateValue(m_connectedStateTypeMap.value(child->thingClassId()), true); - } - } -} - -void IntegrationPluginGaradget::onClientDisconnected(MqttChannel *channel) -{ - qCDebug(dcGaradget) << "Sonoff thing disconnected!"; - Thing *dev = m_mqttChannels.key(channel); - dev->setStateValue(m_connectedStateTypeMap.value(dev->thingClassId()), false); - - foreach (Thing *child, myThings()) { - if (child->parentId() == dev->id()) { - child->setStateValue(m_connectedStateTypeMap.value(child->thingClassId()), false); - } - } -} - -void IntegrationPluginGaradget::onPublishReceived(MqttChannel *channel, const QString &topic, const QByteArray &payload) -{ - qCDebug(dcGaradget) << "Publish received from Sonoff thing:" << topic << qUtf8Printable(payload); - Thing *thing = m_mqttChannels.key(channel); - if (topic.startsWith(channel->topicPrefixList().first() + "/sonoff/POWER")) { - QString channelName = topic.split("/").last(); - - thing->setStateValue(stateMaps.value(thing->thingClassId()).value(channelName), payload == "ON"); - - // Legacy (deprecated) connected things via params - foreach (Thing *child, myThings().filterByParentId(thing->id())) { - if (child->paramValue(m_channelParamTypeMap.value(child->thingClassId())).toString() != channelName) { - continue; - } - if (m_powerStateTypeMap.contains(child->thingClassId())) { - child->setStateValue(m_powerStateTypeMap.value(child->thingClassId()), payload == "ON"); - } - } - } - if (topic.startsWith(channel->topicPrefixList().first() + "/sonoff/STATE")) { - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); - if (error.error != QJsonParseError::NoError) { - qCWarning(dcGaradget) << "Cannot parse JSON from Garadget device" << error.errorString(); - return; - } - QVariantMap dataMap = jsonDoc.toVariant().toMap(); - thing->setStateValue(m_signalStrengthStateTypeMap.value(thing->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt()); - - if (m_brightnessStateTypeMap.contains(thing->thingClassId())) { - thing->setStateValue(m_brightnessStateTypeMap.value(thing->thingClassId()), dataMap.value("Dimmer").toInt()); - } - - // Legacy (deprecated) connected things by params - foreach (Thing *child, myThings().filterByParentId(thing->id())) { - if (m_powerStateTypeMap.contains(child->thingClassId())) { - QString childChannel = child->paramValue(m_channelParamTypeMap.value(child->thingClassId())).toString(); - QString valueString = jsonDoc.toVariant().toMap().value(childChannel).toString(); - child->setStateValue(m_powerStateTypeMap.value(child->thingClassId()), valueString == "ON"); - } - child->setStateValue(m_signalStrengthStateTypeMap.value(child->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt()); - } - } -} - diff --git a/garadget/integrationpluginGaradget.h b/garadget/integrationpluginGaradget.h index 5d1c4213..f6ff6123 100644 --- a/garadget/integrationpluginGaradget.h +++ b/garadget/integrationpluginGaradget.h @@ -63,6 +63,19 @@ private: // Helpers for parent devices (the ones starting with sonoff) QHash m_ipAddressParamTypeMap; QHash > m_attachedDeviceParamTypeIdMap; + + // helpers from bee + QHash m_stateParamTypeMap; + QHash m_movingParamTypeMap; + QHash m_percentageParamTypeMap; + QHash m_closingOutputParamTypeMap; + QHash m_openingOutputParamTypeMap; + + QHash m_stateStateTypeMap; + QHash m_movingStateTypeMap; + QHash m_percentageStateTypeMap; + QHash m_closingOutputStateTypeMap; + QHash m_openingOutputStateTypeMap; // Helpers for child devices (virtual ones, starting with Garadget) QHash m_channelParamTypeMap; diff --git a/garadget/integrationpluginGaradget.json b/garadget/integrationpluginGaradget.json index cbf896d4..60b780c7 100644 --- a/garadget/integrationpluginGaradget.json +++ b/garadget/integrationpluginGaradget.json @@ -14,7 +14,7 @@ "id": "e808b8ae-7608-41ce-8444-892f0648a4d3", "setupMethod": "JustAdd", "createMethods": ["User"], - "interfaces": [ ], + "interfaces": ["extendedstatefulgaragedoor"], "paramTypes": [ { "id": "54a11a17-fc37-4316-891f-001c55e38220", @@ -24,6 +24,16 @@ } ], + "settingsTypes": [ + { + "id": "cc818e83-40d4-4dc3-850e-acb25477aeae", + "name": "openingDuration", + "displayName": "Opening duration [ms]", + "type": "uint", + "minValue": 1000, + "defaultValue": 5000 + } + ], "stateTypes": [ { "id": "a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2", @@ -45,6 +55,65 @@ "maxValue": 100, "defaultValue": -1 }, + + + { + "id": "174509b5-fc3e-4f03-8c93-8e044f0a2ce0" , + "name": "state", + "displayName": "State", + "displayNameEvent": "State changed", + "displayNameAction": "Set state", + "type": "QString", + "possibleValues": ["open", "closed", "opening", "closing", "intermediate"], + "defaultValue": "closed", + "writable": true + }, + { + "id": "d3f711a1-9c79-459d-b697-d427280d9be8" , + "name": "moving", + "displayName": "Moving", + "displayNameEvent": "Moving changed", + "displayNameAction": "Set moving", + "type": "bool", + "writable": true, + "defaultValue": false + }, + { + "id": "b2bdaa74-a6e1-4208-9094-a38bae3f3672" , + "name": "percentage", + "displayName": "Open position", + "displayNameEvent": "Openposition changed", + "displayNameAction": "Set percentage", + "type": "int", + "minValue": 0, + "maxValue": 100, + "defaultValue": 100, + "writable": true + }, + { + "id": "1aadbcf4-314b-409b-9223-55d433433edf" , + "name": "openingOutput", + "displayName": "Openingoutput", + "displayNameEvent": "Openingoutput changed", + "displayNameAction": "Set openingOutput", + "type": "bool", + "writable": true, + "defaultValue": false, + "ioType": "digitalInput" + }, + { + "id": "e6b564ff-094d-45ba-a4db-f64a8bedf258" , + "name": "closingOutput", + "displayName": "Closingoutput", + "displayNameEvent": "Closingoutput changed", + "displayNameAction": "Set closingOutput", + "type": "bool", + "writable": true, + "defaultValue": false, + "ioType": "digitalInput" + }, + + { "id": "481a7cf8-418b-4774-8fd4-32693ab52299", "name": "power", @@ -62,6 +131,22 @@ ], "actionTypes": [ + { + "id": "ae3b1c67-7219-4768-a1c7-55c3b9a610cb" , + "name": "open", + "displayName": "Open" + }, + { + "id": "56a9e131-b65e-4622-9a9b-f5b42d0021ef" , + "name": "close", + "displayName": "Close" + }, + { + "id": "12ea84c1-0650-4ac1-a02c-de95965def92" , + "name": "stop", + "displayName": "Stop" + } + ], "eventTypes": [ diff --git a/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts b/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts index d9b0f53a..070289d5 100644 --- a/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts +++ b/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts @@ -31,6 +31,33 @@ The name of the EventType ({481a7cf8-418b-4774-8fd4-32693ab52299}) of ThingClass sonoff_basic + + + State changed + The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass sonoff_basic + + + + Moving changed + The name of the EventType ({d3f711a1-9c79-459d-b697-d427280d9be8}) of ThingClass sonoff_basic + + + + Openposition changed + The name of the EventType ({b2bdaa74-a6e1-4208-9094-a38bae3f3672}) of ThingClass sonoff_basic + + + + Openingoutput changed + The name of the EventType ({1aadbcf4-314b-409b-9223-55d433433edf}) of ThingClass sonoff_basic + + + + Closingoutput changed + The name of the EventType ({e6b564ff-094d-45ba-a4db-f64a8bedf258}) of ThingClass sonoff_basic + + + Power The name of the ParamType (ThingClass: sonoff_basic, ActionType: power, ID: {481a7cf8-418b-4774-8fd4-32693ab52299}) @@ -42,16 +69,141 @@ The name of the StateType ({481a7cf8-418b-4774-8fd4-32693ab52299}) of ThingClass The name of the ActionType ({481a7cf8-418b-4774-8fd4-32693ab52299}) of ThingClass sonoff_basic + + + + + State + The name of the ParamType (ThingClass: sonoff_basic, ActionType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) +---------- +The name of the ParamType (ThingClass: sonoff_basic, EventType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) +---------- +The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass sonoff_basic +---------- +The name of the ActionType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass sonoff_basic + + + + Moving + The name of the ParamType (ThingClass: sonoff_basic, ActionType: moving, ID: {d3f711a1-9c79-459d-b697-d427280d9be8}) +---------- +The name of the ParamType (ThingClass: sonoff_basic, EventType: moving, ID: {d3f711a1-9c79-459d-b697-d427280d9be8}) +---------- +The name of the StateType ({d3f711a1-9c79-459d-b697-d427280d9be8}) of ThingClass sonoff_basic +---------- +The name of the ActionType ({d3f711a1-9c79-459d-b697-d427280d9be8}) of ThingClass sonoff_basic + + + + "Open Position" + The name of the ParamType (ThingClass: sonoff_basic, ActionType: percentage, ID: {b2bdaa74-a6e1-4208-9094-a38bae3f3672}) +---------- +The name of the ParamType (ThingClass: sonoff_basic, EventType: percentage, ID: {b2bdaa74-a6e1-4208-9094-a38bae3f3672}) +---------- +The name of the StateType ({b2bdaa74-a6e1-4208-9094-a38bae3f3672}) of ThingClass sonoff_basic +---------- +The name of the ActionType ({b2bdaa74-a6e1-4208-9094-a38bae3f3672}) of ThingClass sonoff_basic + + + + "Openingoutput" + The name of the ParamType (ThingClass: sonoff_basic, ActionType: openingOutput, ID: {1aadbcf4-314b-409b-9223-55d433433edf}) +---------- +The name of the ParamType (ThingClass: sonoff_basic, EventType: openingOutput, ID: {1aadbcf4-314b-409b-9223-55d433433edf}) +---------- +The name of the StateType ({1aadbcf4-314b-409b-9223-55d433433edf}) of ThingClass sonoff_basic +---------- +The name of the ActionType ({1aadbcf4-314b-409b-9223-55d433433edf}) of ThingClass sonoff_basic + + + + "Closingoutput" + The name of the ParamType (ThingClass: sonoff_basic, ActionType: closingOutput, ID: {e6b564ff-094d-45ba-a4db-f64a8bedf258}) +---------- +The name of the ParamType (ThingClass: sonoff_basic, EventType: closingOutput, ID: {e6b564ff-094d-45ba-a4db-f64a8bedf258}) +---------- +The name of the StateType ({e6b564ff-094d-45ba-a4db-f64a8bedf258}) of ThingClass sonoff_basic +---------- +The name of the ActionType ({e6b564ff-094d-45ba-a4db-f64a8bedf258}) of ThingClass sonoff_basic + + + Set power The name of the ActionType ({481a7cf8-418b-4774-8fd4-32693ab52299}) of ThingClass sonoff_basic + + + Set state + The name of the ActionType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass sonoff_basic + + + + + Set moving + The name of the ActionType ({d3f711a1-9c79-459d-b697-d427280d9be8}) of ThingClass sonoff_basic + + + + + Set percentage + The name of the ActionType ({b2bdaa74-a6e1-4208-9094-a38bae3f3672}) of ThingClass sonoff_basic + + + + + Set openingOutput + The name of the ActionType ({1aadbcf4-314b-409b-9223-55d433433edf}) of ThingClass sonoff_basic + + + + + Set closingOutput + The name of the ActionType ({e6b564ff-094d-45ba-a4db-f64a8bedf258}) of ThingClass sonoff_basic + + + Garadget The name of the vendor ({22d59bee-79cc-4dea-b742-30ac6bdcf2c9}) +---------- + + + +The name of the StateType ({e6b564ff-094d-45ba-a4db-f64a8bedf258}) of ThingClass extendedStatefulGaragedoor +---------- +The name of the StateType ({d3f711a1-9c79-459d-b697-d427280d9be8}) of ThingClass extendedStatefulGaragedoor +---------- +The name of the StateType ({1aadbcf4-314b-409b-9223-55d433433edf}) of ThingClass extendedStatefulGaragedoor +---------- +The name of the ParamType (ThingClass: extendedStatefulGaragedoor, EventType: percentage, ID: {b2bdaa74-a6e1-4208-9094-a38bae3f3672}) +---------- +The name of the StateType ({b2bdaa74-a6e1-4208-9094-a38bae3f3672}) of ThingClass extendedStatefulGaragedoor + + + + Openposition changed + The name of the EventType ({b2bdaa74-a6e1-4208-9094-a38bae3f3672}) of ThingClass extendedStatefulGaragedoor + + + + Opening duration [ms] + The name of the ParamType (ThingClass: extendedStatefulGaragedoor, Type: settings, ID: {cc818e83-40d4-4dc3-850e-acb25477aeae}) + + +---------- +The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass extendedStatefulGaragedoor + + + + State changed + The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass extendedStatefulGaragedoor + + + diff --git a/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts~ b/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts~ deleted file mode 100644 index 4bb61265..00000000 --- a/garadget/translations/068067fe-719b-493b-9cce-0f170978c8f7-en_US.ts~ +++ /dev/null @@ -1,91 +0,0 @@ - - - - - IntegrationPluginGaradget - - The given IP address is not valid. - Error setting up thing - - - - Error creating MQTT channel. Please check MQTT server settings. - Error setting up thing - - - - Could not connect to Garadget device. - Error setting up thing - - - - - Garadget - - Sonoff-Garadget - The name of the plugin Garadget ({476781af-ad41-423b-b9bb-f308f2aff339}) - - - - Single switch (Sonoff Basic, RF, Touch...) - The name of the ThingClass ({e808b8ae-7608-41ce-8444-892f0648a4d3}) - - - - IP address - The name of the ParamType (ThingClass: sonoff_basic, Type: thing, ID: {54a11a17-fc37-4316-891f-001c55e38220}) - - - - Connected device - The name of the ParamType (ThingClass: sonoff_basic, Type: thing, ID: {f2a79266-1b69-4c50-8397-9533dd2f30cb}) - - - - Connected changed - The name of the EventType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass sonoff_basic - - - - Connected - The name of the ParamType (ThingClass: sonoff_basic, EventType: connected, ID: {a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) ----------- -The name of the StateType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass sonoff_basic - - - - - Power changed - The name of the EventType ({481a7cf8-418b-4774-8fd4-32693ab52299}) of ThingClass sonoff_basic - - - - Power - The name of the ParamType (ThingClass: sonoff_basic, ActionType: power, ID: {481a7cf8-418b-4774-8fd4-32693ab52299}) ----------- -The name of the ParamType (ThingClass: sonoff_basic, EventType: power, ID: {481a7cf8-418b-4774-8fd4-32693ab52299}) ----------- -The name of the StateType ({481a7cf8-418b-4774-8fd4-32693ab52299}) of ThingClass sonoff_basic - - - - - Garadget - The name of the vendor ({22d59bee-79cc-4dea-b742-30ac6bdcf2c9}) - - - - Signal strength - The name of the ParamType (ThingClass: sonoff_basic, EventType: signalStrength, ID: {e276e6ca-4cb5-46d2-9a78-31f92d78ac70}) ----------- -The name of the StateType ({e276e6ca-4cb5-46d2-9a78-31f92d78ac70}) of ThingClass sonoff_basic - - - - Signal strength changed - The name of the EventType ({e276e6ca-4cb5-46d2-9a78-31f92d78ac70}) of ThingClass sonoff_basic - - - - -