From c55616bf50392a90cd4dd3fca3709e1341bd41f1 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Sun, 31 Oct 2021 07:11:29 -0400 Subject: [PATCH 01/25] New Plugin: Garadget --- debian/control | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/debian/control b/debian/control index 0bfec247..53cd38a3 100644 --- a/debian/control +++ b/debian/control @@ -344,6 +344,22 @@ Description: nymea.io plugin for eq-3 This package will install the nymea.io plugin for eq-3 +Package: nymea-plugin-garadget +Architecture: any +Multi-Arch: same +Section: libs +Depends: ${shlibs:Depends}, + ${misc:Depends}, +Description: nymea.io plugin for Garadget + 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 Garadget Garage Door Opener + + Package: nymea-plugin-genericelements Architecture: any Depends: ${shlibs:Depends}, From a4259205de8603ed73a65e14444b08105b72b3da Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Sun, 31 Oct 2021 07:14:20 -0400 Subject: [PATCH 02/25] Garadget update to include all files --- debian/nymea-plugin-garadget.install.in | 1 + garadget/README.md | 51 ++++ garadget/garadget.pro | 12 + garadget/garadget.svg | 128 ++++++++++ garadget/integrationplugingaradget.cpp | 216 ++++++++++++++++ garadget/integrationplugingaradget.h | 67 +++++ garadget/integrationplugingaradget.json | 184 ++++++++++++++ garadget/meta.json | 14 ++ ...781af-ad41-423b-b9bb-f308f2aff339-en_US.ts | 235 ++++++++++++++++++ 9 files changed, 908 insertions(+) create mode 100644 debian/nymea-plugin-garadget.install.in create mode 100644 garadget/README.md create mode 100644 garadget/garadget.pro create mode 100644 garadget/garadget.svg create mode 100644 garadget/integrationplugingaradget.cpp create mode 100644 garadget/integrationplugingaradget.h create mode 100644 garadget/integrationplugingaradget.json create mode 100644 garadget/meta.json create mode 100644 garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts diff --git a/debian/nymea-plugin-garadget.install.in b/debian/nymea-plugin-garadget.install.in new file mode 100644 index 00000000..620d438b --- /dev/null +++ b/debian/nymea-plugin-garadget.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationplugingaradget.so diff --git a/garadget/README.md b/garadget/README.md new file mode 100644 index 00000000..593d3680 --- /dev/null +++ b/garadget/README.md @@ -0,0 +1,51 @@ +The nymea plugin for Garadget Garage Door Opener requires Garadget version 1.20 or later +nymea supports the Garadget device via the mqtt only mode using the nymea internal MQTT broker. External MQTT broker is not supported. + Make sure nymeas MQTT broker is enabled in System Settings -> MQTT broker and create a policy (Client ID, username and password) for the garadget device to log in. + +Note: The garadget must be configured with the MQTT mode only! otherwise the Particle operation will probably conflict. + +See the (https://www.garadget.com/setup-instructions/) for garadget general setup and (https://community.garadget.com/t/mqtt-support/3226/5) for MQTT instructions + +Garadget Initial Configuration: + Put your device into listening mode: press and hold “M” button for about 3 seconds until LED starts blinking dark blue. + Connect any WiFi enabled device to PHOTON-XXXX access point. + Open http://192.168.0.1/ in the browser + Confirmed in settings that your Garadget is v1.20 or later. + at a minimum set the following: + select your SSID + enter SSID password + select Only MQTT + enter nymead Broker IP: + enter nymead Broker Port: + enter nymead Broker User ID: (if needed) + enter nymead Broker Password: (if needed) + enter Device Topic ID: (this must be unique across all garadget devices and contain NO /s allowed) + select Save & Connect (The device will reconnect to your WiFi network via dhcp) + +nymea configuration: + assuming you have installed the garadget plugin: + select garadget plugin from the ADD things page or Configure things page. + select Garadget (there will be an Internal MQTT client and MQTT client - Ignore them) + Name the thing with your choice of names + Thing Parameter -> enter the Device Topic ID: you entered in the Garadget device above. + +nymea operation: + on the Garadget window, the up icon, stop icon, and down icon cause the device to activate the garage door. + on the Garadget detail window (uppre righthand corner, you can tune the Garadget configuration for: + Refection Threshold + Button Press Time + Door Moving Time. (you should adjust to the time it takes your door to open) + when changed it takes a couple seconds for Garadget to respond and update the values shown in the nymea window. + +notes: + Publish does not send any messages. + other than the three types shown above and the open, close and stop items, no action is taken by the plugin. + DECKO Garage Door opener requires a ~ 3.3 Volt zener diode in series of the connection between the Garadget and the DECKO + +Issues: Garadget operating a DECKO garage door opener (may not be issue with other garage door openers) + the Garadget can get confused on the correct relay actions to take if you hit "stop" and then either "open" or "close" when operating a DECKO + It is best to be in direct view of the door if you hit "stop" (the plugin image will be halfway up) to be sure you know where the door will go next. + This confusion is an issue of the Garadget and not of nymea-plugin. + + The plugin will show connected as soon as the Garadget connects to the broker. + The plugin does NOT know if the Garadget disconnects and therefore will continue to show connected even if the Garadget is no longer connected. diff --git a/garadget/garadget.pro b/garadget/garadget.pro new file mode 100644 index 00000000..d2f5044e --- /dev/null +++ b/garadget/garadget.pro @@ -0,0 +1,12 @@ +include(../plugins.pri) + +QT += network + +PKGCONFIG += nymea-mqtt + +SOURCES += \ + integrationplugingaradget.cpp + +HEADERS += \ + integrationplugingaradget.h + diff --git a/garadget/garadget.svg b/garadget/garadget.svg new file mode 100644 index 00000000..a5a7e695 --- /dev/null +++ b/garadget/garadget.svg @@ -0,0 +1,128 @@ + + + + + + image/svg+xml + + Zeichenfläche 1 + + + + + + + + + + + Zeichenfläche 1 + + + + + + + + + + diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp new file mode 100644 index 00000000..5cfe443c --- /dev/null +++ b/garadget/integrationplugingaradget.cpp @@ -0,0 +1,216 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 "integrations/thing.h" +#include "plugininfo.h" + +#include + +#include "network/mqtt/mqttprovider.h" +#include + + +void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) +{ + Thing *thing = info->thing(); + + QString device = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); + if (!(device.startsWith( "garadget/"))) { + if (device.contains("/")) { + return info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP(QString ("The given deviceName is not valid - no /s allowed"))); + } + thing->setParamValue(garadgetThingDeviceNameParamTypeId,"garadget/" + device + "/#" ); + } + + qCDebug(dcGaradget) << "entered setupThing" << thing->paramValue(garadgetThingDeviceNameParamTypeId); + MqttClient *client = nullptr; + if (thing->thingClassId() == garadgetThingClassId) { + client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); + } + m_mqttClients.insert(thing, client); + + connect(client, &MqttClient::connected, this, [this, thing](){ + subscribe(thing); + }); + connect(client, &MqttClient::subscribeResult, info, [info](quint16 /*packetId*/, const Mqtt::SubscribeReturnCodes returnCodes){ + info->finish(returnCodes.first() == Mqtt::SubscribeReturnCodeFailure ? Thing::ThingErrorHardwareFailure : Thing::ThingErrorNoError); + }); + connect(client, &MqttClient::publishReceived, this, &IntegrationPluginGaradget::publishReceived); + // In case we're already connected, manually call subscribe now + if (client->isConnected()) { + qCDebug(dcGaradget) << "entered is Connected" << client; + subscribe(thing); + } + +} + +void IntegrationPluginGaradget::thingRemoved(Thing *thing) +{ + qCDebug(dcGaradget) << thing << "Removed"; + m_mqttClients.take(thing)->deleteLater(); +} + +void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) +{ + Thing *thing = info->thing(); + Action action = info->action(); + + QString name = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); + if (name.endsWith("/#")) { + name.chop(2); + } + MqttClient *client = m_mqttClients.value(thing); + if (!client) { + qCWarning(dcGaradget) << "No valid MQTT client for thing" << thing->name(); + return info->finish(Thing::ThingErrorThingNotFound); + } + QString act = ""; + QByteArray actarray; + if (action.actionTypeId() == garadgetOpenActionTypeId) { + act = "open"; + } + if (action.actionTypeId() == garadgetCloseActionTypeId) { + act = "close"; + } + if (action.actionTypeId() == garadgetStopActionTypeId) { + act = "stop"; + } + if (act != "" ) { + name = name + "/command"; + } + QString conftype = ""; + int actint = 0; + if (action.actionTypeId() == garadgetSrtActionTypeId) { + if ( (action.paramValue(garadgetSrtActionSrtParamTypeId).toInt() > -1) and (action.paramValue(garadgetSrtActionSrtParamTypeId).toInt() < 81)) { + actint = action.paramValue( garadgetSrtActionSrtParamTypeId).toInt(); + conftype = "srt"; + } else { + name = name + "/command"; + act = "get-config"; + } + } + if (action.actionTypeId() == garadgetMttActionTypeId) { + if ( (action.paramValue( garadgetMttActionMttParamTypeId).toInt() > 0) and (action.paramValue( garadgetMttActionMttParamTypeId).toInt() < 121) ){ + actint = action.paramValue( garadgetMttActionMttParamTypeId).toInt() * 1000; + conftype = "mtt"; + } else { + name = name + "/command"; + act = "get-config"; + } + } + if (action.actionTypeId() == garadgetRltActionTypeId) { + if ( (action.paramValue( garadgetRltActionRltParamTypeId).toInt() > 9) and (action.paramValue( garadgetRltActionRltParamTypeId).toInt() < 2001) ){ + actint = action.paramValue(garadgetRltActionRltParamTypeId).toInt() * 1000; + conftype = "mtt"; + } else { + name = name + "/command"; + act = "get-config"; + } + } + if (conftype != "") { + qCDebug(dcGaradget) << "Processing config change" << conftype << "to" << action.paramValue( garadgetSrtActionSrtParamTypeId).toInt(); + name = name + "/set-config"; + QJsonObject garadgetobj; + garadgetobj.insert(conftype, actint); + QJsonDocument garadgetdoc(garadgetobj); + QByteArray garadgetdata = garadgetdoc.toJson(QJsonDocument::Compact); + QString jsonDoc(garadgetdata); + act = garadgetdata; + } + if (act != "" ) { + actarray = act.toUtf8(); + qCDebug(dcGaradget) << "Publishing:" << name << act; + quint16 packetId = client->publish(name, actarray, Mqtt::QoS1, false); + connect(client, &MqttClient::published, info, [info, packetId](quint16 packetIdResult){ + if (packetId == packetIdResult) { + info->finish(Thing::ThingErrorNoError); + } + }); + } + return; +} + +void IntegrationPluginGaradget::subscribe(Thing *thing) +{ + MqttClient *client = m_mqttClients.value(thing); + if (!client) { + // Device might have been removed + return; + } + if (thing->thingClassId() == garadgetThingClassId) { + client->subscribe(thing->paramValue(garadgetThingDeviceNameParamTypeId).toString()); + } +} + +void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByteArray &payload, bool retained) +{ + qCDebug(dcGaradget) << "Received message from topic" << topic << "with msg" << payload << "retain flag" << retained; + + + MqttClient* client = static_cast(sender()); + Thing *thing = m_mqttClients.key(client); + if (!thing) { + qCWarning(dcGaradget) << "Received a publish message from a client where de don't have a matching thing"; + return; + } + if (topic.endsWith("/status")) { + thing->setStateValue(garadgetConnectedStateTypeId, true); + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(dcGaradget) << "Cannot parse JSON from Garadget device" << error.errorString(); + return; + } + QJsonObject jo = jsonDoc.object(); + thing->setStateValue(garadgetSignallevelStateTypeId, jo.value(QString("signal")).toInt()); + thing->setStateValue(garadgetSensorlevelStateTypeId, jo.value(QString("sensor")).toInt()); + thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); + if (jo.value(QString("status")).toString().contains(QString("stopped"))) { + thing->setStateValue(garadgetStateStateTypeId, "intermediate"); + qCDebug(dcGaradget) << "Garadget is" << jo.value(QString("status")).toString() ; + } else { + thing->setStateValue(garadgetStateStateTypeId, jo.value(QString("status")).toString()); + } + } + if (topic.endsWith("/config")) { + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(dcGaradget) << "Cannot parse JSON from Garadget device" << error.errorString(); + return; + } + QJsonObject jo = jsonDoc.object(); + thing->setStateValue(garadgetSrtStateTypeId,jo.value(QString("srt")).toInt()); + thing->setStateValue(garadgetRltStateTypeId,jo.value(QString("rlt")).toInt()); + thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()/1000); + qCDebug(dcGaradget) << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() * 1000; + } +} diff --git a/garadget/integrationplugingaradget.h b/garadget/integrationplugingaradget.h new file mode 100644 index 00000000..6220d4df --- /dev/null +++ b/garadget/integrationplugingaradget.h @@ -0,0 +1,67 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef INTEGRATIONPLUGINGARADGET_H +#define INTEGRATIONPLUGINGARADGET_H + +#include "integrations/integrationplugin.h" + +#include +#include +#include + +class MqttClient; + +class IntegrationPluginGaradget: public IntegrationPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationplugingaradget.json") + Q_INTERFACES(IntegrationPlugin) + + +public: + explicit IntegrationPluginGaradget() = default; + ~IntegrationPluginGaradget() = default; + + void setupThing(ThingSetupInfo *info) override; + void thingRemoved(Thing *thing) override; + void executeAction(ThingActionInfo *info) override; + +private slots: + void subscribe(Thing *thing); + + void publishReceived(const QString &topic, const QByteArray &payload, bool retained); + +private: + QHash m_mqttClients; +}; + +#endif // INTEGRATIONPLUGINGARADGET_H diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json new file mode 100644 index 00000000..6efe07f0 --- /dev/null +++ b/garadget/integrationplugingaradget.json @@ -0,0 +1,184 @@ +{ + "name": "garadget", + "displayName": "Garadget", + "id": "476781af-ad41-423b-b9bb-f308f2aff339", + "vendors": [ + { + "name": "Garadget", + "displayName": "Garadget", + "id": "22d59bee-79cc-4dea-b742-30ac6bdcf2c9", + "thingClasses": [ + { + "name": "garadget", + "displayName": "Garadget", + "id": "e808b8ae-7608-41ce-8444-892f0648a4d3", + "setupMethod": "JustAdd", + "createMethods": ["User"], + "interfaces": ["statefulgaragedoor", "inputtrigger", "outputtrigger"], + "paramTypes": [ + { + "id": "54a11a17-fc37-4316-891f-001c55e38220", + "name":"deviceName", + "displayName": "deviceName", + "type": "QString", + "defaultValue": "" + } + + ], + "stateTypes": [ + { + "id": "a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "174509b5-fc3e-4f03-8c93-8e044f0a2ce0" , + "name": "state", + "displayName": "State", + "displayNameEvent": "State changed", + "type": "QString", + "possibleValues": ["open", "closed", "opening", "closing", "intermediate"], + "defaultValue": "closed" + }, + { + "id": "024f178c-a920-42d4-887f-1c90a96d5eb3", + "name": "signallevel", + "displayName": "Signal Level", + "displayNameEvent": "Signal Level changed", + "type": "int", + "defaultValue": 0 + }, + { + "id": "4aaeefbd-46d9-4111-b262-a001a47ecb22", + "name": "sensorlevel", + "displayName": "Sensor Level", + "displayNameEvent": "Sensor Level changed", + "type": "int", + "defaultValue": 0 + }, + { + "id": "bd7fece8-3ff6-421a-bb5e-80323beb8d8d", + "name": "brightlevel", + "displayName": "Ambient Brightness Level", + "displayNameEvent": "Ambient Brightness changed", + "type": "int", + "defaultValue": 0 + }, + + { + "id": "656a181e-5c06-4bb6-8c5d-7921db07bef6" , + "name": "srt", + "displayName": "Reflection Threshold 0-80", + "displayNameEvent": "Reflection Threshold changed", + "displayNameAction": "Set Reflection Threshold value", + "type": "int", + "defaultValue": 25, + "writable": true + }, + { + "id": "c38e89db-b259-4fa0-9f20-03fe3b8a7514" , + "name": "rlt", + "displayName": "Button Press Time in 10-2000 ms", + "displayNameEvent": "Button Press Time changed", + "displayNameAction": "Set Button Press Time value", + "type": "int", + "defaultValue": 300, + "writable": true + }, + { + "id": "acda9268-4663-46d1-a409-231d648e6fc8" , + "name": "mtt", + "displayName": "Door Moving Time in 1-120 Sec", + "displayNameEvent": "Door Moving Time changed", + "displayNameAction": "Set Door Moving Time value", + "type": "int", + "defaultValue": 10, + "writable": true + } + ], + "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" + }, + { + "id": "4cde52f7-78f9-49a4-b4c3-76bd702bc473", + "name": "trigger", + "displayName": "Publish", + "paramTypes": [ + { + "id": "9208d419-82d4-4806-a15d-210991daf0ac", + "name": "topic", + "displayName": "Topic", + "type": "QString", + "defaultValue": "/" + }, + { + "id": "088e7db5-c814-4165-b9ff-a411a4c20f19", + "name": "data", + "displayName": "Payload", + "type": "QString", + "defaultValue": "" + }, + { + "id": "140d859b-87b7-44f0-b54f-a11846e24985", + "name": "qos", + "displayName": "QoS", + "type": "int", + "minValue": 0, + "maxValue": 2, + "defaultValue": 0 + }, + { + "id": "44079c1a-9a0a-426d-9508-5b2dcbe40a90", + "name": "retain", + "displayName": "Retain message", + "type": "bool", + "defaultValue": false + } + ]} + ], + "eventTypes": [ + { + "id": "a42983a9-9194-458d-9e67-fc4d7ce27e40", + "name": "triggered", + "displayName": "Publish received", + "paramTypes": [ + { + "id": "5dfb6ce9-095b-4476-ac94-c7c35653de1f", + "name": "topic", + "displayName": "Topic", + "type": "QString" + }, + { + "id": "7573d3c5-a867-4123-a7f9-65eb35eac233", + "name": "data", + "displayName": "Playload", + "type": "QString" + } + ] + } + ] + } + ] + } + ] +} + + + diff --git a/garadget/meta.json b/garadget/meta.json new file mode 100644 index 00000000..84b7f019 --- /dev/null +++ b/garadget/meta.json @@ -0,0 +1,14 @@ +{ + "title": "Garadget", + "tagline": "Garadget", + "icon": "garadget.svg", + "stability": "community", + "offline": true, + "technologies": [ + "network", + "mqtt" + ], + "categories": [ + "lock" + ] +} diff --git a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts new file mode 100644 index 00000000..3a8a544e --- /dev/null +++ b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts @@ -0,0 +1,235 @@ + + + + + garadget + + + + Ambient Brightness Level + The name of the ParamType (ThingClass: garadget, EventType: brightlevel, ID: {bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) +---------- +The name of the StateType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass garadget + + + + + Ambient Brightness changed + The name of the EventType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass garadget + + + + + Button Press Time changed + The name of the EventType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget + + + + + + + Button Press Time in 10-2000 ms + The name of the ParamType (ThingClass: garadget, ActionType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) +---------- +The name of the ParamType (ThingClass: garadget, EventType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) +---------- +The name of the StateType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget + + + + + Close + The name of the ActionType ({56a9e131-b65e-4622-9a9b-f5b42d0021ef}) of ThingClass garadget + + + + + + Connected + The name of the ParamType (ThingClass: garadget, EventType: connected, ID: {a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) +---------- +The name of the StateType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass garadget + + + + + Connected changed + The name of the EventType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass garadget + + + + + Door Moving Time changed + The name of the EventType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget + + + + + + + Door Moving Time in 1-120 Sec + The name of the ParamType (ThingClass: garadget, ActionType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) +---------- +The name of the ParamType (ThingClass: garadget, EventType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) +---------- +The name of the StateType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget + + + + + + + Garadget + The name of the ThingClass ({e808b8ae-7608-41ce-8444-892f0648a4d3}) +---------- +The name of the vendor ({22d59bee-79cc-4dea-b742-30ac6bdcf2c9}) +---------- +The name of the plugin garadget ({476781af-ad41-423b-b9bb-f308f2aff339}) + + + + + Open + The name of the ActionType ({ae3b1c67-7219-4768-a1c7-55c3b9a610cb}) of ThingClass garadget + + + + + Payload + The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {088e7db5-c814-4165-b9ff-a411a4c20f19}) + + + + + Playload + The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {7573d3c5-a867-4123-a7f9-65eb35eac233}) + + + + + Publish + The name of the ActionType ({4cde52f7-78f9-49a4-b4c3-76bd702bc473}) of ThingClass garadget + + + + + Publish received + The name of the EventType ({a42983a9-9194-458d-9e67-fc4d7ce27e40}) of ThingClass garadget + + + + + QoS + The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {140d859b-87b7-44f0-b54f-a11846e24985}) + + + + + + + Reflection Threshold 0-80 + The name of the ParamType (ThingClass: garadget, ActionType: srt, ID: {656a181e-5c06-4bb6-8c5d-7921db07bef6}) +---------- +The name of the ParamType (ThingClass: garadget, EventType: srt, ID: {656a181e-5c06-4bb6-8c5d-7921db07bef6}) +---------- +The name of the StateType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget + + + + + Reflection Threshold changed + The name of the EventType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget + + + + + Retain message + The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {44079c1a-9a0a-426d-9508-5b2dcbe40a90}) + + + + + + Sensor Level + The name of the ParamType (ThingClass: garadget, EventType: sensorlevel, ID: {4aaeefbd-46d9-4111-b262-a001a47ecb22}) +---------- +The name of the StateType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget + + + + + Sensor Level changed + The name of the EventType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget + + + + + Set Button Press Time value + The name of the ActionType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget + + + + + Set Door Moving Time value + The name of the ActionType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget + + + + + Set Reflection Threshold value + The name of the ActionType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget + + + + + + Signal Level + The name of the ParamType (ThingClass: garadget, EventType: signallevel, ID: {024f178c-a920-42d4-887f-1c90a96d5eb3}) +---------- +The name of the StateType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget + + + + + Signal Level changed + The name of the EventType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget + + + + + + State + The name of the ParamType (ThingClass: garadget, EventType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) +---------- +The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass garadget + + + + + State changed + The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass garadget + + + + + Stop + The name of the ActionType ({12ea84c1-0650-4ac1-a02c-de95965def92}) of ThingClass garadget + + + + + + Topic + The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {9208d419-82d4-4806-a15d-210991daf0ac}) +---------- +The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {5dfb6ce9-095b-4476-ac94-c7c35653de1f}) + + + + + deviceName + The name of the ParamType (ThingClass: garadget, Type: thing, ID: {54a11a17-fc37-4316-891f-001c55e38220}) + + + + From 24b4228b528cc396d1845fe7517946471cc06271 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Mon, 1 Nov 2021 06:11:27 -0400 Subject: [PATCH 03/25] modified displayName for sensorlevel and signallevel --- garadget/integrationplugingaradget.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 6efe07f0..2ca08ce0 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -47,7 +47,7 @@ { "id": "024f178c-a920-42d4-887f-1c90a96d5eb3", "name": "signallevel", - "displayName": "Signal Level", + "displayName": "WIFI Signal Level", "displayNameEvent": "Signal Level changed", "type": "int", "defaultValue": 0 @@ -55,9 +55,10 @@ { "id": "4aaeefbd-46d9-4111-b262-a001a47ecb22", "name": "sensorlevel", - "displayName": "Sensor Level", + "displayName": "Lazer Sensor Level", "displayNameEvent": "Sensor Level changed", "type": "int", + "suggestLogging": true, "defaultValue": 0 }, { @@ -66,6 +67,7 @@ "displayName": "Ambient Brightness Level", "displayNameEvent": "Ambient Brightness changed", "type": "int", + "suggestLogging": true, "defaultValue": 0 }, @@ -168,7 +170,7 @@ { "id": "7573d3c5-a867-4123-a7f9-65eb35eac233", "name": "data", - "displayName": "Playload", + "displayName": "Payload", "type": "QString" } ] From 69f924f13ff50dab0c0e26b54a4e10a7062d1afd Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Mon, 1 Nov 2021 06:16:26 -0400 Subject: [PATCH 04/25] Removed inappropiate outtrigger which was not supported in execute action --- garadget/integrationplugingaradget.json | 70 ++++++------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 2ca08ce0..168faff5 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -14,7 +14,7 @@ "id": "e808b8ae-7608-41ce-8444-892f0648a4d3", "setupMethod": "JustAdd", "createMethods": ["User"], - "interfaces": ["statefulgaragedoor", "inputtrigger", "outputtrigger"], + "interfaces": ["statefulgaragedoor", "inputtrigger"], "paramTypes": [ { "id": "54a11a17-fc37-4316-891f-001c55e38220", @@ -103,58 +103,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" - }, - { - "id": "4cde52f7-78f9-49a4-b4c3-76bd702bc473", - "name": "trigger", - "displayName": "Publish", - "paramTypes": [ - { - "id": "9208d419-82d4-4806-a15d-210991daf0ac", - "name": "topic", - "displayName": "Topic", - "type": "QString", - "defaultValue": "/" - }, - { - "id": "088e7db5-c814-4165-b9ff-a411a4c20f19", - "name": "data", - "displayName": "Payload", - "type": "QString", - "defaultValue": "" - }, - { - "id": "140d859b-87b7-44f0-b54f-a11846e24985", - "name": "qos", - "displayName": "QoS", - "type": "int", - "minValue": 0, - "maxValue": 2, - "defaultValue": 0 - }, - { - "id": "44079c1a-9a0a-426d-9508-5b2dcbe40a90", - "name": "retain", - "displayName": "Retain message", - "type": "bool", - "defaultValue": false - } - ]} - ], + { + "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": [ { "id": "a42983a9-9194-458d-9e67-fc4d7ce27e40", From f342f142cb508ab379cedee9d39009b661ca4c5b Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Mon, 1 Nov 2021 06:43:24 -0400 Subject: [PATCH 05/25] added detection for purposeful change of broker by device --- garadget/integrationplugingaradget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 5cfe443c..dfaf3e82 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -213,4 +213,10 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()/1000); qCDebug(dcGaradget) << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() * 1000; } + if (topic.endsWith("/set-config")){ + if ( (payload.contains("mqip")) or (payload.contains("mqpt")) ) { + thing->setStateValue(garadgetConnectedStateTypeId, false); + qCDebug(dcGaradget) << "set connected to false"; + } + } } From f4913d0826f3f91c46580858c5ba95aaccd61796 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Mon, 1 Nov 2021 10:18:21 -0400 Subject: [PATCH 06/25] added garadget to nymea-plugins.pro --- garadget/README.md | 9 ++++----- garadget/integrationplugingaradget.cpp | 2 +- garadget/integrationplugingaradget.json | 6 +++--- nymea-plugins.pro | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/garadget/README.md b/garadget/README.md index 593d3680..495d88f9 100644 --- a/garadget/README.md +++ b/garadget/README.md @@ -19,7 +19,7 @@ Garadget Initial Configuration: enter nymead Broker Port: enter nymead Broker User ID: (if needed) enter nymead Broker Password: (if needed) - enter Device Topic ID: (this must be unique across all garadget devices and contain NO /s allowed) + enter Device Topic ID: (this must be unique across all garadget devices and contain NO /s) select Save & Connect (The device will reconnect to your WiFi network via dhcp) nymea configuration: @@ -31,15 +31,13 @@ nymea configuration: nymea operation: on the Garadget window, the up icon, stop icon, and down icon cause the device to activate the garage door. - on the Garadget detail window (uppre righthand corner, you can tune the Garadget configuration for: + on the Garadget detail window (uppre righthand corner), you can tune the Garadget configuration for: Refection Threshold Button Press Time Door Moving Time. (you should adjust to the time it takes your door to open) when changed it takes a couple seconds for Garadget to respond and update the values shown in the nymea window. notes: - Publish does not send any messages. - other than the three types shown above and the open, close and stop items, no action is taken by the plugin. DECKO Garage Door opener requires a ~ 3.3 Volt zener diode in series of the connection between the Garadget and the DECKO Issues: Garadget operating a DECKO garage door opener (may not be issue with other garage door openers) @@ -48,4 +46,5 @@ Issues: Garadget operating a DECKO garage door opener (may not be issue with oth This confusion is an issue of the Garadget and not of nymea-plugin. The plugin will show connected as soon as the Garadget connects to the broker. - The plugin does NOT know if the Garadget disconnects and therefore will continue to show connected even if the Garadget is no longer connected. + The plugin will detect if the device is commanded to change broker connection and therefore set state to disconnected. + The plugin does NOT know if the Garadget disconnects (power down or breakage) and therefore will continue to show connected even if the Garadget is no longer connected. diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index dfaf3e82..4f7f892c 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -216,7 +216,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt if (topic.endsWith("/set-config")){ if ( (payload.contains("mqip")) or (payload.contains("mqpt")) ) { thing->setStateValue(garadgetConnectedStateTypeId, false); - qCDebug(dcGaradget) << "set connected to false"; + qCDebug(dcGaradget) << "Detected change of Broker msg - set connected to false"; } } } diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 168faff5..5205f5a1 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -14,7 +14,7 @@ "id": "e808b8ae-7608-41ce-8444-892f0648a4d3", "setupMethod": "JustAdd", "createMethods": ["User"], - "interfaces": ["statefulgaragedoor", "inputtrigger"], + "interfaces": ["statefulgaragedoor", "inputtrigger", "wirelessconnectable"], "paramTypes": [ { "id": "54a11a17-fc37-4316-891f-001c55e38220", @@ -48,7 +48,7 @@ "id": "024f178c-a920-42d4-887f-1c90a96d5eb3", "name": "signallevel", "displayName": "WIFI Signal Level", - "displayNameEvent": "Signal Level changed", + "displayNameEvent": "WIFI Signal Level changed", "type": "int", "defaultValue": 0 }, @@ -56,7 +56,7 @@ "id": "4aaeefbd-46d9-4111-b262-a001a47ecb22", "name": "sensorlevel", "displayName": "Lazer Sensor Level", - "displayNameEvent": "Sensor Level changed", + "displayNameEvent": "Lazer Sensor Level changed", "type": "int", "suggestLogging": true, "defaultValue": 0 diff --git a/nymea-plugins.pro b/nymea-plugins.pro index a8f3990e..40fd2fd6 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -22,6 +22,7 @@ PLUGIN_DIRS = \ fastcom \ flowercare \ fronius \ + garadget \ genericelements \ genericthings \ goecharger \ From 303f877308307f2a1761d5d7403c011300e16466 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Mon, 1 Nov 2021 11:34:59 -0400 Subject: [PATCH 07/25] Change signal parameter to signalStrength --- garadget/integrationplugingaradget.cpp | 3 ++- garadget/integrationplugingaradget.json | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 4f7f892c..e1548f28 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -190,7 +190,8 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt return; } QJsonObject jo = jsonDoc.object(); - thing->setStateValue(garadgetSignallevelStateTypeId, jo.value(QString("signal")).toInt()); + qCDebug(dcGaradget) << "wifi signal" << (100 + jo.value(QString("signal")).toInt()) / 0.5 ; + thing->setStateValue(garadgetSignalStrengthStateTypeId, (100 + jo.value(QString("signal")).toInt()) / 0.5 ); thing->setStateValue(garadgetSensorlevelStateTypeId, jo.value(QString("sensor")).toInt()); thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); if (jo.value(QString("status")).toString().contains(QString("stopped"))) { diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 5205f5a1..93477a22 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -46,10 +46,13 @@ }, { "id": "024f178c-a920-42d4-887f-1c90a96d5eb3", - "name": "signallevel", + "name": "signalStrength", "displayName": "WIFI Signal Level", "displayNameEvent": "WIFI Signal Level changed", - "type": "int", + "type": "uint", + "unit": "Percentage", + "minValue": 0, + "maxValue": 100, "defaultValue": 0 }, { From c7cc9b23504922075b7c7cb9c8551a8af694d245 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Tue, 2 Nov 2021 15:37:06 -0400 Subject: [PATCH 08/25] added detection for Garadget disconnect --- garadget/integrationplugingaradget.cpp | 45 +++++++++++++++++++++++--- garadget/integrationplugingaradget.h | 20 ++++++++---- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index e1548f28..6e30eb9f 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -50,7 +50,7 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) thing->setParamValue(garadgetThingDeviceNameParamTypeId,"garadget/" + device + "/#" ); } - qCDebug(dcGaradget) << "entered setupThing" << thing->paramValue(garadgetThingDeviceNameParamTypeId); + qCDebug(dcGaradget) << "entered setupThing" << thing->paramValue(garadgetThingDeviceNameParamTypeId) ; MqttClient *client = nullptr; if (thing->thingClassId() == garadgetThingClassId) { client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); @@ -69,13 +69,48 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) qCDebug(dcGaradget) << "entered is Connected" << client; subscribe(thing); } - + m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); } + +void IntegrationPluginGaradget::postSetupThing(Thing *thing) +{ + + if (!m_pluginTimer) { + QString name = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); + if (name.endsWith("/#")) { + name.chop(2); + } + name = name + "/command"; + qCDebug(dcGaradget) << "inside m_pluginTimer with" << name ; + uint updatetime = 10; + m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); + connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ + if (m_garadgetconnect == 1) { + foreach (Thing *thing, myThings()) { + m_mqttClients.value(thing)->publish(name, "get-status"); + } + } + uint timesinceupdate = QDateTime::currentDateTime().toTime_t() - m_lastActivityTimeStamps[thing].toTime_t(); + if ((timesinceupdate > updatetime) && (m_garadgetconnect == 1)) { + qCDebug(dcGaradget) << "disconnect garadget" << m_lastActivityTimeStamps[thing] << timesinceupdate ; + thing->setStateValue(garadgetConnectedStateTypeId, false); + m_garadgetconnect = 0; + } + }); + } +} + + + void IntegrationPluginGaradget::thingRemoved(Thing *thing) { qCDebug(dcGaradget) << thing << "Removed"; m_mqttClients.take(thing)->deleteLater(); + if (m_pluginTimer) { + hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); + m_pluginTimer = nullptr; + } } void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) @@ -183,6 +218,8 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt } if (topic.endsWith("/status")) { thing->setStateValue(garadgetConnectedStateTypeId, true); + m_garadgetconnect = 1; + m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); if (error.error != QJsonParseError::NoError) { @@ -190,8 +227,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt return; } QJsonObject jo = jsonDoc.object(); - qCDebug(dcGaradget) << "wifi signal" << (100 + jo.value(QString("signal")).toInt()) / 0.5 ; - thing->setStateValue(garadgetSignalStrengthStateTypeId, (100 + jo.value(QString("signal")).toInt()) / 0.5 ); + thing->setStateValue(garadgetSignalStrengthStateTypeId, (100 + jo.value(QString("signal")).toInt()) * 2 ); thing->setStateValue(garadgetSensorlevelStateTypeId, jo.value(QString("sensor")).toInt()); thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); if (jo.value(QString("status")).toString().contains(QString("stopped"))) { @@ -217,6 +253,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt if (topic.endsWith("/set-config")){ if ( (payload.contains("mqip")) or (payload.contains("mqpt")) ) { thing->setStateValue(garadgetConnectedStateTypeId, false); + m_garadgetconnect = 0; qCDebug(dcGaradget) << "Detected change of Broker msg - set connected to false"; } } diff --git a/garadget/integrationplugingaradget.h b/garadget/integrationplugingaradget.h index 6220d4df..17ebc5be 100644 --- a/garadget/integrationplugingaradget.h +++ b/garadget/integrationplugingaradget.h @@ -31,11 +31,14 @@ #ifndef INTEGRATIONPLUGINGARADGET_H #define INTEGRATIONPLUGINGARADGET_H +#include "plugintimer.h" #include "integrations/integrationplugin.h" +#include "network/networkaccessmanager.h" #include #include -#include + +#include class MqttClient; @@ -54,14 +57,19 @@ public: void setupThing(ThingSetupInfo *info) override; void thingRemoved(Thing *thing) override; void executeAction(ThingActionInfo *info) override; - -private slots: - void subscribe(Thing *thing); - - void publishReceived(const QString &topic, const QByteArray &payload, bool retained); + void postSetupThing(Thing *thing) override; private: QHash m_mqttClients; + PluginTimer *m_pluginTimer = nullptr; + QHash m_lastActivityTimeStamps; + + int m_garadgetconnect = 0; + +private slots: + void subscribe(Thing *thing); + void publishReceived(const QString &topic, const QByteArray &payload, bool retained); + }; #endif // INTEGRATIONPLUGINGARADGET_H From b1a9b955ef3740f9a6f04474844fed090fc05d28 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Wed, 3 Nov 2021 08:05:29 -0400 Subject: [PATCH 09/25] Updated translations for garadget --- garadget/integrationplugingaradget.cpp | 2 +- ...781af-ad41-423b-b9bb-f308f2aff339-en_US.ts | 157 ++++++++---------- 2 files changed, 66 insertions(+), 93 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 6e30eb9f..db8cc0ac 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -83,7 +83,7 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) } name = name + "/command"; qCDebug(dcGaradget) << "inside m_pluginTimer with" << name ; - uint updatetime = 10; + uint updatetime = 30; m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ if (m_garadgetconnect == 1) { diff --git a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts index 3a8a544e..884a8b24 100644 --- a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts +++ b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts @@ -4,8 +4,8 @@ garadget - - + + Ambient Brightness Level The name of the ParamType (ThingClass: garadget, EventType: brightlevel, ID: {bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) ---------- @@ -13,21 +13,21 @@ The name of the StateType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass - + Ambient Brightness changed The name of the EventType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass garadget - + Button Press Time changed The name of the EventType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - - - + + + Button Press Time in 10-2000 ms The name of the ParamType (ThingClass: garadget, ActionType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) ---------- @@ -37,14 +37,14 @@ The name of the StateType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass - + Close The name of the ActionType ({56a9e131-b65e-4622-9a9b-f5b42d0021ef}) of ThingClass garadget - - + + Connected The name of the ParamType (ThingClass: garadget, EventType: connected, ID: {a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) ---------- @@ -52,21 +52,21 @@ The name of the StateType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass - + Connected changed The name of the EventType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass garadget - + Door Moving Time changed The name of the EventType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - - - + + + Door Moving Time in 1-120 Sec The name of the ParamType (ThingClass: garadget, ActionType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) ---------- @@ -76,9 +76,9 @@ The name of the StateType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass - - - + + + Garadget The name of the ThingClass ({e808b8ae-7608-41ce-8444-892f0648a4d3}) ---------- @@ -88,45 +88,42 @@ The name of the plugin garadget ({476781af-ad41-423b-b9bb-f308f2aff339}) - + + + Lazer Sensor Level + The name of the ParamType (ThingClass: garadget, EventType: sensorlevel, ID: {4aaeefbd-46d9-4111-b262-a001a47ecb22}) +---------- +The name of the StateType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget + + + + + Lazer Sensor Level changed + The name of the EventType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget + + + + Open The name of the ActionType ({ae3b1c67-7219-4768-a1c7-55c3b9a610cb}) of ThingClass garadget - + Payload - The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {088e7db5-c814-4165-b9ff-a411a4c20f19}) - - - - - Playload The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {7573d3c5-a867-4123-a7f9-65eb35eac233}) - - Publish - The name of the ActionType ({4cde52f7-78f9-49a4-b4c3-76bd702bc473}) of ThingClass garadget - - - - + Publish received The name of the EventType ({a42983a9-9194-458d-9e67-fc4d7ce27e40}) of ThingClass garadget - - QoS - The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {140d859b-87b7-44f0-b54f-a11846e24985}) - - - - - - + + + Reflection Threshold 0-80 The name of the ParamType (ThingClass: garadget, ActionType: srt, ID: {656a181e-5c06-4bb6-8c5d-7921db07bef6}) ---------- @@ -136,68 +133,32 @@ The name of the StateType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass - + Reflection Threshold changed The name of the EventType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - - Retain message - The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {44079c1a-9a0a-426d-9508-5b2dcbe40a90}) - - - - - - Sensor Level - The name of the ParamType (ThingClass: garadget, EventType: sensorlevel, ID: {4aaeefbd-46d9-4111-b262-a001a47ecb22}) ----------- -The name of the StateType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget - - - - - Sensor Level changed - The name of the EventType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget - - - - + Set Button Press Time value The name of the ActionType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - + Set Door Moving Time value The name of the ActionType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - + Set Reflection Threshold value The name of the ActionType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - - - Signal Level - The name of the ParamType (ThingClass: garadget, EventType: signallevel, ID: {024f178c-a920-42d4-887f-1c90a96d5eb3}) ----------- -The name of the StateType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget - - - - - Signal Level changed - The name of the EventType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget - - - - - + + State The name of the ParamType (ThingClass: garadget, EventType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) ---------- @@ -205,28 +166,40 @@ The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass - + State changed The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass garadget - + Stop The name of the ActionType ({12ea84c1-0650-4ac1-a02c-de95965def92}) of ThingClass garadget - - + Topic - The name of the ParamType (ThingClass: garadget, ActionType: trigger, ID: {9208d419-82d4-4806-a15d-210991daf0ac}) ----------- -The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {5dfb6ce9-095b-4476-ac94-c7c35653de1f}) + The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {5dfb6ce9-095b-4476-ac94-c7c35653de1f}) - + + + WIFI Signal Level + The name of the ParamType (ThingClass: garadget, EventType: signalStrength, ID: {024f178c-a920-42d4-887f-1c90a96d5eb3}) +---------- +The name of the StateType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget + + + + + WIFI Signal Level changed + The name of the EventType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget + + + + deviceName The name of the ParamType (ThingClass: garadget, Type: thing, ID: {54a11a17-fc37-4316-891f-001c55e38220}) From 1992d24cb20254d70c9e73b477528efc9a43f143 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Wed, 3 Nov 2021 11:56:34 -0400 Subject: [PATCH 10/25] removed redundant updates of connected status --- garadget/integrationplugingaradget.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index db8cc0ac..e3af1c59 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -217,8 +217,11 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt return; } if (topic.endsWith("/status")) { - thing->setStateValue(garadgetConnectedStateTypeId, true); - m_garadgetconnect = 1; + if (thing->stateValue(garadgetConnectedStateTypeId) == false) { + qCDebug(dcGaradget) << "Setting Garadget to connected" ; + thing->setStateValue(garadgetConnectedStateTypeId, true); + m_garadgetconnect = 1; + } m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error); From 2538d6bebdc146c48b516ba7a32a8dfd36a08276 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Wed, 3 Nov 2021 12:00:26 -0400 Subject: [PATCH 11/25] updated readme for disconnect dectection --- garadget/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garadget/README.md b/garadget/README.md index 495d88f9..f32edf50 100644 --- a/garadget/README.md +++ b/garadget/README.md @@ -47,4 +47,4 @@ Issues: Garadget operating a DECKO garage door opener (may not be issue with oth The plugin will show connected as soon as the Garadget connects to the broker. The plugin will detect if the device is commanded to change broker connection and therefore set state to disconnected. - The plugin does NOT know if the Garadget disconnects (power down or breakage) and therefore will continue to show connected even if the Garadget is no longer connected. + The plugin may take 1 minute to show disconnects (power down or breakage). From 9070a2b87853eb58e090252eb57886fd1616748c Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Wed, 3 Nov 2021 15:52:51 -0400 Subject: [PATCH 12/25] removed m_garadgetconnect --- garadget/integrationplugingaradget.cpp | 27 +++++++++++--------------- garadget/integrationplugingaradget.h | 1 - 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index e3af1c59..50e1c1eb 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -69,34 +69,31 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) qCDebug(dcGaradget) << "entered is Connected" << client; subscribe(thing); } - m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); } void IntegrationPluginGaradget::postSetupThing(Thing *thing) { - if (!m_pluginTimer) { + if (!m_pluginTimer && !myThings().isEmpty()) { QString name = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); if (name.endsWith("/#")) { name.chop(2); } name = name + "/command"; qCDebug(dcGaradget) << "inside m_pluginTimer with" << name ; - uint updatetime = 30; + uint updatetime = 10; m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ - if (m_garadgetconnect == 1) { - foreach (Thing *thing, myThings()) { + foreach (Thing *thing, myThings()) { + if ((m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 1000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { + qCDebug(dcGaradget) << "disconnect garadget"; + thing->setStateValue(garadgetConnectedStateTypeId, false); + } + if (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) { m_mqttClients.value(thing)->publish(name, "get-status"); } } - uint timesinceupdate = QDateTime::currentDateTime().toTime_t() - m_lastActivityTimeStamps[thing].toTime_t(); - if ((timesinceupdate > updatetime) && (m_garadgetconnect == 1)) { - qCDebug(dcGaradget) << "disconnect garadget" << m_lastActivityTimeStamps[thing] << timesinceupdate ; - thing->setStateValue(garadgetConnectedStateTypeId, false); - m_garadgetconnect = 0; - } }); } } @@ -207,20 +204,19 @@ void IntegrationPluginGaradget::subscribe(Thing *thing) void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByteArray &payload, bool retained) { - qCDebug(dcGaradget) << "Received message from topic" << topic << "with msg" << payload << "retain flag" << retained; +// qCDebug(dcGaradget) << "Received message from topic" << topic << "with msg" << payload << "retain flag" << retained; MqttClient* client = static_cast(sender()); Thing *thing = m_mqttClients.key(client); if (!thing) { - qCWarning(dcGaradget) << "Received a publish message from a client where de don't have a matching thing"; + qCWarning(dcGaradget) << "Received a publish message from a client where de don't have a matching thing" << retained; return; } if (topic.endsWith("/status")) { if (thing->stateValue(garadgetConnectedStateTypeId) == false) { qCDebug(dcGaradget) << "Setting Garadget to connected" ; thing->setStateValue(garadgetConnectedStateTypeId, true); - m_garadgetconnect = 1; } m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); QJsonParseError error; @@ -230,7 +226,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt return; } QJsonObject jo = jsonDoc.object(); - thing->setStateValue(garadgetSignalStrengthStateTypeId, (100 + jo.value(QString("signal")).toInt()) * 2 ); + thing->setStateValue(garadgetSignalStrengthStateTypeId, (99 + jo.value(QString("signal")).toInt()) * 2 ); thing->setStateValue(garadgetSensorlevelStateTypeId, jo.value(QString("sensor")).toInt()); thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); if (jo.value(QString("status")).toString().contains(QString("stopped"))) { @@ -256,7 +252,6 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt if (topic.endsWith("/set-config")){ if ( (payload.contains("mqip")) or (payload.contains("mqpt")) ) { thing->setStateValue(garadgetConnectedStateTypeId, false); - m_garadgetconnect = 0; qCDebug(dcGaradget) << "Detected change of Broker msg - set connected to false"; } } diff --git a/garadget/integrationplugingaradget.h b/garadget/integrationplugingaradget.h index 17ebc5be..393a8bb3 100644 --- a/garadget/integrationplugingaradget.h +++ b/garadget/integrationplugingaradget.h @@ -64,7 +64,6 @@ private: PluginTimer *m_pluginTimer = nullptr; QHash m_lastActivityTimeStamps; - int m_garadgetconnect = 0; private slots: void subscribe(Thing *thing); From 475fde87cfd0971df6390fcea07837ada1ddd2e2 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Wed, 3 Nov 2021 16:39:30 -0400 Subject: [PATCH 13/25] corrected rlt and mtt ranges --- garadget/integrationplugingaradget.cpp | 8 ++++---- garadget/integrationplugingaradget.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 50e1c1eb..8528a2f2 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -82,7 +82,7 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) } name = name + "/command"; qCDebug(dcGaradget) << "inside m_pluginTimer with" << name ; - uint updatetime = 10; + uint updatetime = 30; m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ foreach (Thing *thing, myThings()) { @@ -150,7 +150,7 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } } if (action.actionTypeId() == garadgetMttActionTypeId) { - if ( (action.paramValue( garadgetMttActionMttParamTypeId).toInt() > 0) and (action.paramValue( garadgetMttActionMttParamTypeId).toInt() < 121) ){ + if ( (action.paramValue( garadgetMttActionMttParamTypeId).toInt() > 4) and (action.paramValue( garadgetMttActionMttParamTypeId).toInt() < 61) ){ actint = action.paramValue( garadgetMttActionMttParamTypeId).toInt() * 1000; conftype = "mtt"; } else { @@ -160,8 +160,8 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } if (action.actionTypeId() == garadgetRltActionTypeId) { if ( (action.paramValue( garadgetRltActionRltParamTypeId).toInt() > 9) and (action.paramValue( garadgetRltActionRltParamTypeId).toInt() < 2001) ){ - actint = action.paramValue(garadgetRltActionRltParamTypeId).toInt() * 1000; - conftype = "mtt"; + actint = action.paramValue(garadgetRltActionRltParamTypeId).toInt(); + conftype = "rlt"; } else { name = name + "/command"; act = "get-config"; diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 93477a22..394989b1 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -14,7 +14,7 @@ "id": "e808b8ae-7608-41ce-8444-892f0648a4d3", "setupMethod": "JustAdd", "createMethods": ["User"], - "interfaces": ["statefulgaragedoor", "inputtrigger", "wirelessconnectable"], + "interfaces": ["statefulgaragedoor", "wirelessconnectable"], "paramTypes": [ { "id": "54a11a17-fc37-4316-891f-001c55e38220", @@ -97,7 +97,7 @@ { "id": "acda9268-4663-46d1-a409-231d648e6fc8" , "name": "mtt", - "displayName": "Door Moving Time in 1-120 Sec", + "displayName": "Door Moving Time in 5-60 Sec", "displayNameEvent": "Door Moving Time changed", "displayNameAction": "Set Door Moving Time value", "type": "int", From a7df2462507693d76a8bdb3522583cfe5c8b9d5c Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 4 Nov 2021 05:31:28 -0400 Subject: [PATCH 14/25] removed range checking on rlt and mtt as garadget preforms this check. if garadget should change their range in the future, as they have done between version 1.20 and 1.24, nymea will not limit what the user can enter. --- garadget/integrationplugingaradget.cpp | 10 +++++----- garadget/integrationplugingaradget.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 8528a2f2..386bce8e 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -141,7 +141,7 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) QString conftype = ""; int actint = 0; if (action.actionTypeId() == garadgetSrtActionTypeId) { - if ( (action.paramValue(garadgetSrtActionSrtParamTypeId).toInt() > -1) and (action.paramValue(garadgetSrtActionSrtParamTypeId).toInt() < 81)) { + if (action.paramValue(garadgetSrtActionSrtParamTypeId).toInt() > -1) { actint = action.paramValue( garadgetSrtActionSrtParamTypeId).toInt(); conftype = "srt"; } else { @@ -150,8 +150,8 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } } if (action.actionTypeId() == garadgetMttActionTypeId) { - if ( (action.paramValue( garadgetMttActionMttParamTypeId).toInt() > 4) and (action.paramValue( garadgetMttActionMttParamTypeId).toInt() < 61) ){ - actint = action.paramValue( garadgetMttActionMttParamTypeId).toInt() * 1000; + if (action.paramValue( garadgetMttActionMttParamTypeId).toInt() > 0) { + actint = action.paramValue( garadgetMttActionMttParamTypeId).toInt(); conftype = "mtt"; } else { name = name + "/command"; @@ -159,7 +159,7 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } } if (action.actionTypeId() == garadgetRltActionTypeId) { - if ( (action.paramValue( garadgetRltActionRltParamTypeId).toInt() > 9) and (action.paramValue( garadgetRltActionRltParamTypeId).toInt() < 2001) ){ + if (action.paramValue( garadgetRltActionRltParamTypeId).toInt() > 0) { actint = action.paramValue(garadgetRltActionRltParamTypeId).toInt(); conftype = "rlt"; } else { @@ -246,7 +246,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt QJsonObject jo = jsonDoc.object(); thing->setStateValue(garadgetSrtStateTypeId,jo.value(QString("srt")).toInt()); thing->setStateValue(garadgetRltStateTypeId,jo.value(QString("rlt")).toInt()); - thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()/1000); + thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()); qCDebug(dcGaradget) << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() * 1000; } if (topic.endsWith("/set-config")){ diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 394989b1..f3b09691 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -97,7 +97,7 @@ { "id": "acda9268-4663-46d1-a409-231d648e6fc8" , "name": "mtt", - "displayName": "Door Moving Time in 5-60 Sec", + "displayName": "Door Moving Time 5000-60000 ms", "displayNameEvent": "Door Moving Time changed", "displayNameAction": "Set Door Moving Time value", "type": "int", From ba752dc1307e68cba5867851d331603f8c3cf925 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 4 Nov 2021 16:07:46 -0400 Subject: [PATCH 15/25] added configuration support for rdp and rlp --- garadget/README.md | 10 +++++++--- garadget/integrationplugingaradget.cpp | 26 +++++++++++++++++++++---- garadget/integrationplugingaradget.json | 16 +++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/garadget/README.md b/garadget/README.md index f32edf50..722a3cc9 100644 --- a/garadget/README.md +++ b/garadget/README.md @@ -34,17 +34,21 @@ nymea operation: on the Garadget detail window (uppre righthand corner), you can tune the Garadget configuration for: Refection Threshold Button Press Time - Door Moving Time. (you should adjust to the time it takes your door to open) + Door Moving Time. (you should adjust to the time it takes your door to open to prevent garadget indicating stopped unnecessarily) + on the Configure Things page for Garadget, you can tune the Garadget configuration for: + sensor scan interval + multi button press delay (garadget manual labels this consecutive button presses delay) when changed it takes a couple seconds for Garadget to respond and update the values shown in the nymea window. notes: DECKO Garage Door opener requires a ~ 3.3 Volt zener diode in series of the connection between the Garadget and the DECKO + Garadget manual indicates the range of mtt is 1000 to 12000 ms but testing on v1.24 shows it currently only accepts 5000 to 60000 ms (nymea will request other values but Garadget may reject) Issues: Garadget operating a DECKO garage door opener (may not be issue with other garage door openers) the Garadget can get confused on the correct relay actions to take if you hit "stop" and then either "open" or "close" when operating a DECKO It is best to be in direct view of the door if you hit "stop" (the plugin image will be halfway up) to be sure you know where the door will go next. - This confusion is an issue of the Garadget and not of nymea-plugin. + This confusion is an issue of the Garadget device and not of nymea-plugin. The plugin will show connected as soon as the Garadget connects to the broker. - The plugin will detect if the device is commanded to change broker connection and therefore set state to disconnected. + The plugin will detect if the device is commanded to change broker connection or topic name and therefore set state to disconnected. The plugin may take 1 minute to show disconnects (power down or breakage). diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 386bce8e..46e22dd0 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -80,7 +80,7 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) if (name.endsWith("/#")) { name.chop(2); } - name = name + "/command"; + qCDebug(dcGaradget) << "inside m_pluginTimer with" << name ; uint updatetime = 30; m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); @@ -91,10 +91,26 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) thing->setStateValue(garadgetConnectedStateTypeId, false); } if (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) { - m_mqttClients.value(thing)->publish(name, "get-status"); + m_mqttClients.value(thing)->publish(name + "/command", "get-status"); } } }); + connect(thing, &Thing::settingChanged, this, [=](const ParamTypeId &settingTypeId, const QVariant &value){ + foreach (Thing *thing, myThings()) { + QJsonObject garadgetobj; + + if ((thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) && (settingTypeId == garadgetSettingsRdtParamTypeId)){ + garadgetobj.insert("rdt", value.toInt()); + garadgetobj.insert("rlp", thing->setting(garadgetSettingsRlpParamTypeId).toInt()); + QJsonDocument garadgetdoc(garadgetobj); + QByteArray garadgetdata = garadgetdoc.toJson(QJsonDocument::Compact); + QString jsonDoc(garadgetdata); + qCDebug(dcGaradget()) << "Changing Configuration" << garadgetdata; + m_mqttClients.value(thing)->publish(name + "/set-config", garadgetdata); + } + } + }); + } } @@ -247,10 +263,12 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt thing->setStateValue(garadgetSrtStateTypeId,jo.value(QString("srt")).toInt()); thing->setStateValue(garadgetRltStateTypeId,jo.value(QString("rlt")).toInt()); thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()); - qCDebug(dcGaradget) << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() * 1000; + thing->setSettingValue(garadgetSettingsRdtParamTypeId,jo.value(QString("rdt")).toInt()); + thing->setSettingValue(garadgetSettingsRlpParamTypeId,jo.value(QString("rlp")).toInt()); + qCDebug(dcGaradget) << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() << "rdt =" << thing->setting(garadgetSettingsRdtParamTypeId).toUInt() << "rlp =" << thing->setting(garadgetSettingsRlpParamTypeId).toUInt(); } if (topic.endsWith("/set-config")){ - if ( (payload.contains("mqip")) or (payload.contains("mqpt")) ) { + if ( (payload.contains("mqip")) or (payload.contains("mqpt")) or (payload.contains("nme")) ) { thing->setStateValue(garadgetConnectedStateTypeId, false); qCDebug(dcGaradget) << "Detected change of Broker msg - set connected to false"; } diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index f3b09691..54d35d2b 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -25,6 +25,22 @@ } ], + "settingsTypes": [ + { + "id": "13ad28d6-15e5-4e20-862b-51062344b576", + "name": "rdt", + "displayName": "sensor scan interval in mS 200-60,000", + "type": "uint", + "defaultValue": 1000 + }, + { + "id": "6be83c99-cbf0-4d1d-b838-697e442ebb43", + "name": "rlp", + "displayName": "multi button press delay mS 10-5,000", + "type": "uint", + "defaultValue": 1000 + } + ], "stateTypes": [ { "id": "a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2", From 83711c5a976e695c44042ebe0b702df39eb82780 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 4 Nov 2021 16:09:37 -0400 Subject: [PATCH 16/25] update translations --- ...781af-ad41-423b-b9bb-f308f2aff339-en_US.ts | 104 ++++++++++-------- 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts index 884a8b24..96e81fbd 100644 --- a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts +++ b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts @@ -4,8 +4,8 @@ garadget - - + + Ambient Brightness Level The name of the ParamType (ThingClass: garadget, EventType: brightlevel, ID: {bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) ---------- @@ -13,21 +13,21 @@ The name of the StateType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass - + Ambient Brightness changed The name of the EventType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass garadget - + Button Press Time changed The name of the EventType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - - - + + + Button Press Time in 10-2000 ms The name of the ParamType (ThingClass: garadget, ActionType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) ---------- @@ -37,14 +37,14 @@ The name of the StateType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass - + Close The name of the ActionType ({56a9e131-b65e-4622-9a9b-f5b42d0021ef}) of ThingClass garadget - - + + Connected The name of the ParamType (ThingClass: garadget, EventType: connected, ID: {a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) ---------- @@ -52,22 +52,16 @@ The name of the StateType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass - + Connected changed The name of the EventType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass garadget - - Door Moving Time changed - The name of the EventType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - - - - - - - Door Moving Time in 1-120 Sec + + + + Door Moving Time 5000-60000 ms The name of the ParamType (ThingClass: garadget, ActionType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) ---------- The name of the ParamType (ThingClass: garadget, EventType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) @@ -76,9 +70,15 @@ The name of the StateType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass - - - + + Door Moving Time changed + The name of the EventType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget + + + + + + Garadget The name of the ThingClass ({e808b8ae-7608-41ce-8444-892f0648a4d3}) ---------- @@ -88,8 +88,8 @@ The name of the plugin garadget ({476781af-ad41-423b-b9bb-f308f2aff339}) - - + + Lazer Sensor Level The name of the ParamType (ThingClass: garadget, EventType: sensorlevel, ID: {4aaeefbd-46d9-4111-b262-a001a47ecb22}) ---------- @@ -97,33 +97,33 @@ The name of the StateType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass - + Lazer Sensor Level changed The name of the EventType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget - + Open The name of the ActionType ({ae3b1c67-7219-4768-a1c7-55c3b9a610cb}) of ThingClass garadget - + Payload The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {7573d3c5-a867-4123-a7f9-65eb35eac233}) - + Publish received The name of the EventType ({a42983a9-9194-458d-9e67-fc4d7ce27e40}) of ThingClass garadget - - - + + + Reflection Threshold 0-80 The name of the ParamType (ThingClass: garadget, ActionType: srt, ID: {656a181e-5c06-4bb6-8c5d-7921db07bef6}) ---------- @@ -133,32 +133,32 @@ The name of the StateType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass - + Reflection Threshold changed The name of the EventType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - + Set Button Press Time value The name of the ActionType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - + Set Door Moving Time value The name of the ActionType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - + Set Reflection Threshold value The name of the ActionType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - - + + State The name of the ParamType (ThingClass: garadget, EventType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) ---------- @@ -166,26 +166,26 @@ The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass - + State changed The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass garadget - + Stop The name of the ActionType ({12ea84c1-0650-4ac1-a02c-de95965def92}) of ThingClass garadget - + Topic The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {5dfb6ce9-095b-4476-ac94-c7c35653de1f}) - - + + WIFI Signal Level The name of the ParamType (ThingClass: garadget, EventType: signalStrength, ID: {024f178c-a920-42d4-887f-1c90a96d5eb3}) ---------- @@ -193,16 +193,28 @@ The name of the StateType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass - + WIFI Signal Level changed The name of the EventType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget - + deviceName The name of the ParamType (ThingClass: garadget, Type: thing, ID: {54a11a17-fc37-4316-891f-001c55e38220}) + + + multi button press delay mS 10-5,000 + The name of the ParamType (ThingClass: garadget, Type: settings, ID: {6be83c99-cbf0-4d1d-b838-697e442ebb43}) + + + + + sensor scan interval in mS 200-60,000 + The name of the ParamType (ThingClass: garadget, Type: settings, ID: {13ad28d6-15e5-4e20-862b-51062344b576}) + + From 02e808de2d918512daf09286adf6607413ea5167 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Fri, 5 Nov 2021 16:40:51 -0400 Subject: [PATCH 17/25] Accomodated mzanetti comments and requested re-review of on error. --- garadget/integrationplugingaradget.cpp | 36 +++++++------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 46e22dd0..84f0f79b 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -43,18 +43,10 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) Thing *thing = info->thing(); QString device = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); - if (!(device.startsWith( "garadget/"))) { - if (device.contains("/")) { - return info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP(QString ("The given deviceName is not valid - no /s allowed"))); - } - thing->setParamValue(garadgetThingDeviceNameParamTypeId,"garadget/" + device + "/#" ); - } qCDebug(dcGaradget) << "entered setupThing" << thing->paramValue(garadgetThingDeviceNameParamTypeId) ; MqttClient *client = nullptr; - if (thing->thingClassId() == garadgetThingClassId) { - client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); - } + client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); m_mqttClients.insert(thing, client); connect(client, &MqttClient::connected, this, [this, thing](){ @@ -75,13 +67,7 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) void IntegrationPluginGaradget::postSetupThing(Thing *thing) { - if (!m_pluginTimer && !myThings().isEmpty()) { - QString name = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); - if (name.endsWith("/#")) { - name.chop(2); - } - - qCDebug(dcGaradget) << "inside m_pluginTimer with" << name ; + if (!m_pluginTimer) { uint updatetime = 30; m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ @@ -91,7 +77,7 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) thing->setStateValue(garadgetConnectedStateTypeId, false); } if (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) { - m_mqttClients.value(thing)->publish(name + "/command", "get-status"); + m_mqttClients.value(thing)->publish("garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() + "/command", "get-status"); } } }); @@ -106,7 +92,7 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) QByteArray garadgetdata = garadgetdoc.toJson(QJsonDocument::Compact); QString jsonDoc(garadgetdata); qCDebug(dcGaradget()) << "Changing Configuration" << garadgetdata; - m_mqttClients.value(thing)->publish(name + "/set-config", garadgetdata); + m_mqttClients.value(thing)->publish("garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() + "/set-config", garadgetdata); } } }); @@ -120,7 +106,7 @@ void IntegrationPluginGaradget::thingRemoved(Thing *thing) { qCDebug(dcGaradget) << thing << "Removed"; m_mqttClients.take(thing)->deleteLater(); - if (m_pluginTimer) { + if (m_pluginTimer && !myThings().isEmpty()) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); m_pluginTimer = nullptr; } @@ -131,10 +117,7 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) Thing *thing = info->thing(); Action action = info->action(); - QString name = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); - if (name.endsWith("/#")) { - name.chop(2); - } + QString name = "garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); MqttClient *client = m_mqttClients.value(thing); if (!client) { qCWarning(dcGaradget) << "No valid MQTT client for thing" << thing->name(); @@ -203,6 +186,7 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } }); } + info->finish(Thing::ThingErrorNoError); return; } @@ -213,9 +197,7 @@ void IntegrationPluginGaradget::subscribe(Thing *thing) // Device might have been removed return; } - if (thing->thingClassId() == garadgetThingClassId) { - client->subscribe(thing->paramValue(garadgetThingDeviceNameParamTypeId).toString()); - } + client->subscribe("garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() + "/#"); } void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByteArray &payload, bool retained) @@ -226,7 +208,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt MqttClient* client = static_cast(sender()); Thing *thing = m_mqttClients.key(client); if (!thing) { - qCWarning(dcGaradget) << "Received a publish message from a client where de don't have a matching thing" << retained; + qCWarning(dcGaradget) << "Received a publish message from a client but don't have a matching thing" << retained; return; } if (topic.endsWith("/status")) { From 82c915162543323294132843a64a01cc471be97a Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Fri, 5 Nov 2021 17:10:40 -0400 Subject: [PATCH 18/25] replaced ! in thingRemoved test to reset m_pluginTimer --- garadget/integrationplugingaradget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 84f0f79b..574704f0 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -106,7 +106,7 @@ void IntegrationPluginGaradget::thingRemoved(Thing *thing) { qCDebug(dcGaradget) << thing << "Removed"; m_mqttClients.take(thing)->deleteLater(); - if (m_pluginTimer && !myThings().isEmpty()) { + if (m_pluginTimer && myThings().isEmpty()) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); m_pluginTimer = nullptr; } From 43162149b2d4d5cbb8a22e93830250915a1642ca Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Fri, 5 Nov 2021 18:09:15 -0400 Subject: [PATCH 19/25] corrected db conversion to percentage based on unifi conversion to (90 + signalStrength)*2.5 --- garadget/integrationplugingaradget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 574704f0..2912393d 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -224,7 +224,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt return; } QJsonObject jo = jsonDoc.object(); - thing->setStateValue(garadgetSignalStrengthStateTypeId, (99 + jo.value(QString("signal")).toInt()) * 2 ); + thing->setStateValue(garadgetSignalStrengthStateTypeId, (90 + jo.value(QString("signal")).toInt()) * 2.5 ); thing->setStateValue(garadgetSensorlevelStateTypeId, jo.value(QString("sensor")).toInt()); thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); if (jo.value(QString("status")).toString().contains(QString("stopped"))) { From e219b9a6d8b71f773b8cf26b59484c535429e3f1 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Sat, 6 Nov 2021 21:18:11 -0400 Subject: [PATCH 20/25] conversion from db to percentage, enter * 2.5 rather than 2.4 --- garadget/integrationplugingaradget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 2912393d..5c58a944 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -224,7 +224,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt return; } QJsonObject jo = jsonDoc.object(); - thing->setStateValue(garadgetSignalStrengthStateTypeId, (90 + jo.value(QString("signal")).toInt()) * 2.5 ); + thing->setStateValue(garadgetSignalStrengthStateTypeId, (90 + jo.value(QString("signal")).toInt()) * 2.4 ); thing->setStateValue(garadgetSensorlevelStateTypeId, jo.value(QString("sensor")).toInt()); thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); if (jo.value(QString("status")).toString().contains(QString("stopped"))) { From f5927619b016dfb67173ddde326af03f030a35a9 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Tue, 16 Nov 2021 07:04:45 -0500 Subject: [PATCH 21/25] updated disconnect detection --- garadget/README.md | 7 +++--- garadget/integrationplugingaradget.cpp | 30 +++++++++++++------------- garadget/integrationplugingaradget.h | 3 ++- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/garadget/README.md b/garadget/README.md index 722a3cc9..a6648c0f 100644 --- a/garadget/README.md +++ b/garadget/README.md @@ -43,12 +43,13 @@ nymea operation: notes: DECKO Garage Door opener requires a ~ 3.3 Volt zener diode in series of the connection between the Garadget and the DECKO Garadget manual indicates the range of mtt is 1000 to 12000 ms but testing on v1.24 shows it currently only accepts 5000 to 60000 ms (nymea will request other values but Garadget may reject) + The plugin will show connected as soon as the Garadget connects to the broker. + The plugin will detect if the device is commanded to change broker connection or topic name and therefore set state to disconnected. + The plugin may take 1 minute to show disconnects (power down or breakage). Issues: Garadget operating a DECKO garage door opener (may not be issue with other garage door openers) the Garadget can get confused on the correct relay actions to take if you hit "stop" and then either "open" or "close" when operating a DECKO It is best to be in direct view of the door if you hit "stop" (the plugin image will be halfway up) to be sure you know where the door will go next. This confusion is an issue of the Garadget device and not of nymea-plugin. - The plugin will show connected as soon as the Garadget connects to the broker. - The plugin will detect if the device is commanded to change broker connection or topic name and therefore set state to disconnected. - The plugin may take 1 minute to show disconnects (power down or breakage). + If nymead reboots rapidly, Garadget may not detect and show disconnected. In this case You may need to push the reset button on the Garadget diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 5c58a944..ab0533b1 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -44,7 +44,6 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) QString device = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); - qCDebug(dcGaradget) << "entered setupThing" << thing->paramValue(garadgetThingDeviceNameParamTypeId) ; MqttClient *client = nullptr; client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); m_mqttClients.insert(thing, client); @@ -58,7 +57,6 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) connect(client, &MqttClient::publishReceived, this, &IntegrationPluginGaradget::publishReceived); // In case we're already connected, manually call subscribe now if (client->isConnected()) { - qCDebug(dcGaradget) << "entered is Connected" << client; subscribe(thing); } } @@ -68,18 +66,24 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) { if (!m_pluginTimer) { - uint updatetime = 30; + int updatetime = 30; + int lwtupdatetime = 300 / updatetime; m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(updatetime); connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ + m_statuscounter[thing] += 1; foreach (Thing *thing, myThings()) { - if ((m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 1000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { - qCDebug(dcGaradget) << "disconnect garadget"; + if ((m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 2000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { + qCDebug(dcGaradget) << "disconnect device" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); thing->setStateValue(garadgetConnectedStateTypeId, false); } - if (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) { + if ( (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) || m_statuscounter[thing] > lwtupdatetime) { m_mqttClients.value(thing)->publish("garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() + "/command", "get-status"); } } + if (m_statuscounter[thing] > lwtupdatetime) { + qCDebug(dcGaradget) << "reset statusCounter" << m_statuscounter; + m_statuscounter[thing] = 1; + } }); connect(thing, &Thing::settingChanged, this, [=](const ParamTypeId &settingTypeId, const QVariant &value){ foreach (Thing *thing, myThings()) { @@ -104,7 +108,7 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) void IntegrationPluginGaradget::thingRemoved(Thing *thing) { - qCDebug(dcGaradget) << thing << "Removed"; + qCDebug(dcGaradget) << "device " << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "Removed"; m_mqttClients.take(thing)->deleteLater(); if (m_pluginTimer && myThings().isEmpty()) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); @@ -167,7 +171,6 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) } } if (conftype != "") { - qCDebug(dcGaradget) << "Processing config change" << conftype << "to" << action.paramValue( garadgetSrtActionSrtParamTypeId).toInt(); name = name + "/set-config"; QJsonObject garadgetobj; garadgetobj.insert(conftype, actint); @@ -202,9 +205,6 @@ void IntegrationPluginGaradget::subscribe(Thing *thing) void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByteArray &payload, bool retained) { -// qCDebug(dcGaradget) << "Received message from topic" << topic << "with msg" << payload << "retain flag" << retained; - - MqttClient* client = static_cast(sender()); Thing *thing = m_mqttClients.key(client); if (!thing) { @@ -213,7 +213,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt } if (topic.endsWith("/status")) { if (thing->stateValue(garadgetConnectedStateTypeId) == false) { - qCDebug(dcGaradget) << "Setting Garadget to connected" ; + qCDebug(dcGaradget) << "Setting" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "to connected" ; thing->setStateValue(garadgetConnectedStateTypeId, true); } m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); @@ -229,7 +229,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt thing->setStateValue(garadgetBrightlevelStateTypeId, jo.value(QString("bright")).toInt()); if (jo.value(QString("status")).toString().contains(QString("stopped"))) { thing->setStateValue(garadgetStateStateTypeId, "intermediate"); - qCDebug(dcGaradget) << "Garadget is" << jo.value(QString("status")).toString() ; + qCDebug(dcGaradget) << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "is" << jo.value(QString("status")).toString() ; } else { thing->setStateValue(garadgetStateStateTypeId, jo.value(QString("status")).toString()); } @@ -247,12 +247,12 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()); thing->setSettingValue(garadgetSettingsRdtParamTypeId,jo.value(QString("rdt")).toInt()); thing->setSettingValue(garadgetSettingsRlpParamTypeId,jo.value(QString("rlp")).toInt()); - qCDebug(dcGaradget) << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() << "rdt =" << thing->setting(garadgetSettingsRdtParamTypeId).toUInt() << "rlp =" << thing->setting(garadgetSettingsRlpParamTypeId).toUInt(); + qCDebug(dcGaradget) << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() << "rdt =" << thing->setting(garadgetSettingsRdtParamTypeId).toUInt() << "rlp =" << thing->setting(garadgetSettingsRlpParamTypeId).toUInt(); } if (topic.endsWith("/set-config")){ if ( (payload.contains("mqip")) or (payload.contains("mqpt")) or (payload.contains("nme")) ) { thing->setStateValue(garadgetConnectedStateTypeId, false); - qCDebug(dcGaradget) << "Detected change of Broker msg - set connected to false"; + qCDebug(dcGaradget) << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "Detected change of Broker msg - set connected to false"; } } } diff --git a/garadget/integrationplugingaradget.h b/garadget/integrationplugingaradget.h index 393a8bb3..7e0daa39 100644 --- a/garadget/integrationplugingaradget.h +++ b/garadget/integrationplugingaradget.h @@ -43,6 +43,7 @@ class MqttClient; class IntegrationPluginGaradget: public IntegrationPlugin + { Q_OBJECT @@ -63,7 +64,7 @@ private: QHash m_mqttClients; PluginTimer *m_pluginTimer = nullptr; QHash m_lastActivityTimeStamps; - + QHash m_statuscounter; private slots: void subscribe(Thing *thing); From 05d8179a554c7bc7765b057844c5b8e710f40b8c Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 18 Nov 2021 08:43:13 -0500 Subject: [PATCH 22/25] LWT detection and support --- garadget/integrationplugingaradget.cpp | 28 +++++++++++++++++++------ garadget/integrationplugingaradget.json | 9 ++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index ab0533b1..3105cdda 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -42,8 +42,7 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - QString device = thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); - + thing->setStateValue(garadgetLWTStateTypeId,false); MqttClient *client = nullptr; client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); m_mqttClients.insert(thing, client); @@ -72,16 +71,15 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ m_statuscounter[thing] += 1; foreach (Thing *thing, myThings()) { - if ((m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 2000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { + if ((thing->stateValue(garadgetLWTStateTypeId) == false) && (m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 2000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { qCDebug(dcGaradget) << "disconnect device" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); thing->setStateValue(garadgetConnectedStateTypeId, false); } - if ( (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) || m_statuscounter[thing] > lwtupdatetime) { + if ( ((thing->stateValue(garadgetLWTStateTypeId) == false) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) || m_statuscounter[thing] > lwtupdatetime) { m_mqttClients.value(thing)->publish("garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() + "/command", "get-status"); } } if (m_statuscounter[thing] > lwtupdatetime) { - qCDebug(dcGaradget) << "reset statusCounter" << m_statuscounter; m_statuscounter[thing] = 1; } }); @@ -213,7 +211,7 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt } if (topic.endsWith("/status")) { if (thing->stateValue(garadgetConnectedStateTypeId) == false) { - qCDebug(dcGaradget) << "Setting" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "to connected" ; + qCDebug(dcGaradget) << "Setting" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "to Online" ; thing->setStateValue(garadgetConnectedStateTypeId, true); } m_lastActivityTimeStamps[thing] = QDateTime::currentDateTime(); @@ -255,4 +253,22 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt qCDebug(dcGaradget) << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "Detected change of Broker msg - set connected to false"; } } + if (topic.endsWith("/LWT")){ + if (payload.contains("Online") or payload.contains("Offline")) { + thing->setStateValue(garadgetLWTStateTypeId,true); + qCDebug(dcGaradget()) << "enabling LWT functionality" << thing->stateValue(garadgetLWTStateTypeId); + } + if (payload.contains("Online")) { + if (thing->stateValue(garadgetConnectedStateTypeId) == false) { + qCDebug(dcGaradget) << "Setting" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "to Online" ; + thing->setStateValue(garadgetConnectedStateTypeId, true); + } + } + if (payload.contains("Offline")) { + if (thing->stateValue(garadgetConnectedStateTypeId) == true) { + qCDebug(dcGaradget) << "Setting" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "to Offline" ; + thing->setStateValue(garadgetConnectedStateTypeId, false); + } + } + } } diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 54d35d2b..04589fec 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -42,6 +42,15 @@ } ], "stateTypes": [ + { + "id": "3338c7af-89a0-4db3-aaa4-a01a276396d0", + "name": "LWT", + "displayName": "LWT Support", + "displayNameEvent": "LWT Support", + "type": "bool", + "defaultValue": false, + "writable": false + }, { "id": "a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2", "name": "connected", From 46f194a83a864f6008bb9d48dd558a7973f566ca Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 18 Nov 2021 09:34:02 -0500 Subject: [PATCH 23/25] translations update --- ...781af-ad41-423b-b9bb-f308f2aff339-en_US.ts | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts index 96e81fbd..c0f8a39f 100644 --- a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts +++ b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts @@ -4,8 +4,8 @@ garadget - + Ambient Brightness Level The name of the ParamType (ThingClass: garadget, EventType: brightlevel, ID: {bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) ---------- @@ -13,21 +13,21 @@ The name of the StateType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass - + Ambient Brightness changed The name of the EventType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass garadget - + Button Press Time changed The name of the EventType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - + Button Press Time in 10-2000 ms The name of the ParamType (ThingClass: garadget, ActionType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) ---------- @@ -37,14 +37,14 @@ The name of the StateType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass - + Close The name of the ActionType ({56a9e131-b65e-4622-9a9b-f5b42d0021ef}) of ThingClass garadget - + Connected The name of the ParamType (ThingClass: garadget, EventType: connected, ID: {a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) ---------- @@ -52,15 +52,15 @@ The name of the StateType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass - + Connected changed The name of the EventType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass garadget - + Door Moving Time 5000-60000 ms The name of the ParamType (ThingClass: garadget, ActionType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) ---------- @@ -70,15 +70,15 @@ The name of the StateType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass - + Door Moving Time changed The name of the EventType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - + Garadget The name of the ThingClass ({e808b8ae-7608-41ce-8444-892f0648a4d3}) ---------- @@ -88,8 +88,20 @@ The name of the plugin garadget ({476781af-ad41-423b-b9bb-f308f2aff339}) - + + + LWT Support + The name of the ParamType (ThingClass: garadget, EventType: LWT, ID: {3338c7af-89a0-4db3-aaa4-a01a276396d0}) +---------- +The name of the EventType ({3338c7af-89a0-4db3-aaa4-a01a276396d0}) of ThingClass garadget +---------- +The name of the StateType ({3338c7af-89a0-4db3-aaa4-a01a276396d0}) of ThingClass garadget + + + + + Lazer Sensor Level The name of the ParamType (ThingClass: garadget, EventType: sensorlevel, ID: {4aaeefbd-46d9-4111-b262-a001a47ecb22}) ---------- @@ -97,33 +109,33 @@ The name of the StateType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass - + Lazer Sensor Level changed The name of the EventType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget - + Open The name of the ActionType ({ae3b1c67-7219-4768-a1c7-55c3b9a610cb}) of ThingClass garadget - + Payload The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {7573d3c5-a867-4123-a7f9-65eb35eac233}) - + Publish received The name of the EventType ({a42983a9-9194-458d-9e67-fc4d7ce27e40}) of ThingClass garadget - - - + + + Reflection Threshold 0-80 The name of the ParamType (ThingClass: garadget, ActionType: srt, ID: {656a181e-5c06-4bb6-8c5d-7921db07bef6}) ---------- @@ -133,32 +145,32 @@ The name of the StateType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass - + Reflection Threshold changed The name of the EventType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - + Set Button Press Time value The name of the ActionType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - + Set Door Moving Time value The name of the ActionType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - + Set Reflection Threshold value The name of the ActionType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - - + + State The name of the ParamType (ThingClass: garadget, EventType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) ---------- @@ -166,26 +178,26 @@ The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass - + State changed The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass garadget - + Stop The name of the ActionType ({12ea84c1-0650-4ac1-a02c-de95965def92}) of ThingClass garadget - + Topic The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {5dfb6ce9-095b-4476-ac94-c7c35653de1f}) - - + + WIFI Signal Level The name of the ParamType (ThingClass: garadget, EventType: signalStrength, ID: {024f178c-a920-42d4-887f-1c90a96d5eb3}) ---------- @@ -193,25 +205,25 @@ The name of the StateType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass - + WIFI Signal Level changed The name of the EventType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget - + deviceName The name of the ParamType (ThingClass: garadget, Type: thing, ID: {54a11a17-fc37-4316-891f-001c55e38220}) - + multi button press delay mS 10-5,000 The name of the ParamType (ThingClass: garadget, Type: settings, ID: {6be83c99-cbf0-4d1d-b838-697e442ebb43}) - + sensor scan interval in mS 200-60,000 The name of the ParamType (ThingClass: garadget, Type: settings, ID: {13ad28d6-15e5-4e20-862b-51062344b576}) From 0bbf57ecc31f51b8905c41d7a300d293625726fb Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 18 Nov 2021 16:49:00 -0500 Subject: [PATCH 24/25] Changed lastwill to internal parameter, mtt and rlt moved to settingType page. --- garadget/integrationplugingaradget.cpp | 48 +++++++++++-------------- garadget/integrationplugingaradget.json | 43 ++++++++-------------- 2 files changed, 34 insertions(+), 57 deletions(-) diff --git a/garadget/integrationplugingaradget.cpp b/garadget/integrationplugingaradget.cpp index 3105cdda..001d2d9d 100644 --- a/garadget/integrationplugingaradget.cpp +++ b/garadget/integrationplugingaradget.cpp @@ -42,7 +42,10 @@ void IntegrationPluginGaradget::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - thing->setStateValue(garadgetLWTStateTypeId,false); + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("lastWillAvailable", false); + pluginStorage()->endGroup(); + MqttClient *client = nullptr; client = hardwareManager()->mqttProvider()->createInternalClient(thing->id().toString()); m_mqttClients.insert(thing, client); @@ -71,11 +74,14 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) connect(m_pluginTimer, &PluginTimer::timeout, this, [=](){ m_statuscounter[thing] += 1; foreach (Thing *thing, myThings()) { - if ((thing->stateValue(garadgetLWTStateTypeId) == false) && (m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 2000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { + pluginStorage()->beginGroup(thing->id().toString()); + bool lastWillAvailable = pluginStorage()->value("lastWillAvailable").toBool(); + pluginStorage()->endGroup(); + if ((lastWillAvailable == false) && (m_lastActivityTimeStamps[thing].msecsTo(QDateTime::currentDateTime()) > 2000 * updatetime) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) { qCDebug(dcGaradget) << "disconnect device" << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString(); thing->setStateValue(garadgetConnectedStateTypeId, false); } - if ( ((thing->stateValue(garadgetLWTStateTypeId) == false) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) || m_statuscounter[thing] > lwtupdatetime) { + if ( ((lastWillAvailable == false) && (thing->stateValue(garadgetConnectedStateTypeId).toBool() == true)) || m_statuscounter[thing] > lwtupdatetime) { m_mqttClients.value(thing)->publish("garadget/" + thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() + "/command", "get-status"); } } @@ -83,13 +89,15 @@ void IntegrationPluginGaradget::postSetupThing(Thing *thing) m_statuscounter[thing] = 1; } }); - connect(thing, &Thing::settingChanged, this, [=](const ParamTypeId &settingTypeId, const QVariant &value){ + connect(thing, &Thing::settingChanged, this, [=](const ParamTypeId &settingTypeId){ foreach (Thing *thing, myThings()) { QJsonObject garadgetobj; if ((thing->stateValue(garadgetConnectedStateTypeId).toBool() == true) && (settingTypeId == garadgetSettingsRdtParamTypeId)){ - garadgetobj.insert("rdt", value.toInt()); + garadgetobj.insert("rdt", thing->setting(garadgetSettingsRdtParamTypeId).toInt()); garadgetobj.insert("rlp", thing->setting(garadgetSettingsRlpParamTypeId).toInt()); + garadgetobj.insert("rlt",thing->setting(garadgetSettingsRltParamTypeId).toInt()); + garadgetobj.insert("mtt", thing->setting(garadgetSettingsMttParamTypeId).toInt()); QJsonDocument garadgetdoc(garadgetobj); QByteArray garadgetdata = garadgetdoc.toJson(QJsonDocument::Compact); QString jsonDoc(garadgetdata); @@ -150,24 +158,6 @@ void IntegrationPluginGaradget::executeAction(ThingActionInfo *info) act = "get-config"; } } - if (action.actionTypeId() == garadgetMttActionTypeId) { - if (action.paramValue( garadgetMttActionMttParamTypeId).toInt() > 0) { - actint = action.paramValue( garadgetMttActionMttParamTypeId).toInt(); - conftype = "mtt"; - } else { - name = name + "/command"; - act = "get-config"; - } - } - if (action.actionTypeId() == garadgetRltActionTypeId) { - if (action.paramValue( garadgetRltActionRltParamTypeId).toInt() > 0) { - actint = action.paramValue(garadgetRltActionRltParamTypeId).toInt(); - conftype = "rlt"; - } else { - name = name + "/command"; - act = "get-config"; - } - } if (conftype != "") { name = name + "/set-config"; QJsonObject garadgetobj; @@ -241,11 +231,11 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt } QJsonObject jo = jsonDoc.object(); thing->setStateValue(garadgetSrtStateTypeId,jo.value(QString("srt")).toInt()); - thing->setStateValue(garadgetRltStateTypeId,jo.value(QString("rlt")).toInt()); - thing->setStateValue(garadgetMttStateTypeId,jo.value(QString("mtt")).toInt()); + thing->setSettingValue(garadgetSettingsRltParamTypeId,jo.value(QString("rlt")).toInt()); + thing->setSettingValue(garadgetSettingsMttParamTypeId,jo.value(QString("mtt")).toInt()); thing->setSettingValue(garadgetSettingsRdtParamTypeId,jo.value(QString("rdt")).toInt()); thing->setSettingValue(garadgetSettingsRlpParamTypeId,jo.value(QString("rlp")).toInt()); - qCDebug(dcGaradget) << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->stateValue(garadgetRltStateTypeId).toInt()<< "mtt =" << thing->stateValue(garadgetMttStateTypeId).toInt() << "rdt =" << thing->setting(garadgetSettingsRdtParamTypeId).toUInt() << "rlp =" << thing->setting(garadgetSettingsRlpParamTypeId).toUInt(); + qCDebug(dcGaradget) << thing->paramValue(garadgetThingDeviceNameParamTypeId).toString() << "System Configuration" << "srt =" << thing->stateValue(garadgetSrtStateTypeId).toInt() << "rlt =" << thing->setting(garadgetSettingsRltParamTypeId).toInt()<< "mtt =" << thing->setting(garadgetSettingsMttParamTypeId).toInt() << "rdt =" << thing->setting(garadgetSettingsRdtParamTypeId).toUInt() << "rlp =" << thing->setting(garadgetSettingsRlpParamTypeId).toUInt(); } if (topic.endsWith("/set-config")){ if ( (payload.contains("mqip")) or (payload.contains("mqpt")) or (payload.contains("nme")) ) { @@ -255,8 +245,10 @@ void IntegrationPluginGaradget::publishReceived(const QString &topic, const QByt } if (topic.endsWith("/LWT")){ if (payload.contains("Online") or payload.contains("Offline")) { - thing->setStateValue(garadgetLWTStateTypeId,true); - qCDebug(dcGaradget()) << "enabling LWT functionality" << thing->stateValue(garadgetLWTStateTypeId); + qCDebug(dcGaradget()) << "Setting support for LWT"; + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("lastWillAvailable", true); + pluginStorage()->endGroup(); } if (payload.contains("Online")) { if (thing->stateValue(garadgetConnectedStateTypeId) == false) { diff --git a/garadget/integrationplugingaradget.json b/garadget/integrationplugingaradget.json index 04589fec..7ccf3c37 100644 --- a/garadget/integrationplugingaradget.json +++ b/garadget/integrationplugingaradget.json @@ -39,18 +39,23 @@ "displayName": "multi button press delay mS 10-5,000", "type": "uint", "defaultValue": 1000 + }, + { + "id": "c38e89db-b259-4fa0-9f20-03fe3b8a7514" , + "name": "rlt", + "displayName": "Button Press Time in 10-2000 ms", + "type": "int", + "defaultValue": 300 + }, + { + "id": "acda9268-4663-46d1-a409-231d648e6fc8" , + "name": "mtt", + "displayName": "Door Moving Time 5000-60000 ms", + "type": "int", + "defaultValue": 10 } ], "stateTypes": [ - { - "id": "3338c7af-89a0-4db3-aaa4-a01a276396d0", - "name": "LWT", - "displayName": "LWT Support", - "displayNameEvent": "LWT Support", - "type": "bool", - "defaultValue": false, - "writable": false - }, { "id": "a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2", "name": "connected", @@ -108,26 +113,6 @@ "type": "int", "defaultValue": 25, "writable": true - }, - { - "id": "c38e89db-b259-4fa0-9f20-03fe3b8a7514" , - "name": "rlt", - "displayName": "Button Press Time in 10-2000 ms", - "displayNameEvent": "Button Press Time changed", - "displayNameAction": "Set Button Press Time value", - "type": "int", - "defaultValue": 300, - "writable": true - }, - { - "id": "acda9268-4663-46d1-a409-231d648e6fc8" , - "name": "mtt", - "displayName": "Door Moving Time 5000-60000 ms", - "displayNameEvent": "Door Moving Time changed", - "displayNameAction": "Set Door Moving Time value", - "type": "int", - "defaultValue": 10, - "writable": true } ], "actionTypes": [ From d01986f2a0257a245302958f33e63cf1e2389593 Mon Sep 17 00:00:00 2001 From: Bruce Eckstein Date: Thu, 18 Nov 2021 17:02:46 -0500 Subject: [PATCH 25/25] updated translation --- ...781af-ad41-423b-b9bb-f308f2aff339-en_US.ts | 120 ++++++------------ 1 file changed, 36 insertions(+), 84 deletions(-) diff --git a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts index c0f8a39f..724f04e3 100644 --- a/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts +++ b/garadget/translations/476781af-ad41-423b-b9bb-f308f2aff339-en_US.ts @@ -4,8 +4,8 @@ garadget - - + + Ambient Brightness Level The name of the ParamType (ThingClass: garadget, EventType: brightlevel, ID: {bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) ---------- @@ -13,38 +13,26 @@ The name of the StateType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass - + Ambient Brightness changed The name of the EventType ({bd7fece8-3ff6-421a-bb5e-80323beb8d8d}) of ThingClass garadget - - Button Press Time changed - The name of the EventType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - - - - - - + Button Press Time in 10-2000 ms - The name of the ParamType (ThingClass: garadget, ActionType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) ----------- -The name of the ParamType (ThingClass: garadget, EventType: rlt, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) ----------- -The name of the StateType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget + The name of the ParamType (ThingClass: garadget, Type: settings, ID: {c38e89db-b259-4fa0-9f20-03fe3b8a7514}) - + Close The name of the ActionType ({56a9e131-b65e-4622-9a9b-f5b42d0021ef}) of ThingClass garadget - - + + Connected The name of the ParamType (ThingClass: garadget, EventType: connected, ID: {a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) ---------- @@ -52,33 +40,21 @@ The name of the StateType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass - + Connected changed The name of the EventType ({a3d7e6eb-82d0-47ee-b95f-4dde931eb7e2}) of ThingClass garadget - - - + Door Moving Time 5000-60000 ms - The name of the ParamType (ThingClass: garadget, ActionType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) ----------- -The name of the ParamType (ThingClass: garadget, EventType: mtt, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) ----------- -The name of the StateType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget + The name of the ParamType (ThingClass: garadget, Type: settings, ID: {acda9268-4663-46d1-a409-231d648e6fc8}) - - Door Moving Time changed - The name of the EventType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - - - - - - + + + Garadget The name of the ThingClass ({e808b8ae-7608-41ce-8444-892f0648a4d3}) ---------- @@ -88,20 +64,8 @@ The name of the plugin garadget ({476781af-ad41-423b-b9bb-f308f2aff339}) - - - - LWT Support - The name of the ParamType (ThingClass: garadget, EventType: LWT, ID: {3338c7af-89a0-4db3-aaa4-a01a276396d0}) ----------- -The name of the EventType ({3338c7af-89a0-4db3-aaa4-a01a276396d0}) of ThingClass garadget ----------- -The name of the StateType ({3338c7af-89a0-4db3-aaa4-a01a276396d0}) of ThingClass garadget - - - - - + + Lazer Sensor Level The name of the ParamType (ThingClass: garadget, EventType: sensorlevel, ID: {4aaeefbd-46d9-4111-b262-a001a47ecb22}) ---------- @@ -109,33 +73,33 @@ The name of the StateType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass - + Lazer Sensor Level changed The name of the EventType ({4aaeefbd-46d9-4111-b262-a001a47ecb22}) of ThingClass garadget - + Open The name of the ActionType ({ae3b1c67-7219-4768-a1c7-55c3b9a610cb}) of ThingClass garadget - + Payload The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {7573d3c5-a867-4123-a7f9-65eb35eac233}) - + Publish received The name of the EventType ({a42983a9-9194-458d-9e67-fc4d7ce27e40}) of ThingClass garadget - - - + + + Reflection Threshold 0-80 The name of the ParamType (ThingClass: garadget, ActionType: srt, ID: {656a181e-5c06-4bb6-8c5d-7921db07bef6}) ---------- @@ -145,32 +109,20 @@ The name of the StateType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass - + Reflection Threshold changed The name of the EventType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - - Set Button Press Time value - The name of the ActionType ({c38e89db-b259-4fa0-9f20-03fe3b8a7514}) of ThingClass garadget - - - - - Set Door Moving Time value - The name of the ActionType ({acda9268-4663-46d1-a409-231d648e6fc8}) of ThingClass garadget - - - - + Set Reflection Threshold value The name of the ActionType ({656a181e-5c06-4bb6-8c5d-7921db07bef6}) of ThingClass garadget - - + + State The name of the ParamType (ThingClass: garadget, EventType: state, ID: {174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) ---------- @@ -178,26 +130,26 @@ The name of the StateType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass - + State changed The name of the EventType ({174509b5-fc3e-4f03-8c93-8e044f0a2ce0}) of ThingClass garadget - + Stop The name of the ActionType ({12ea84c1-0650-4ac1-a02c-de95965def92}) of ThingClass garadget - + Topic The name of the ParamType (ThingClass: garadget, EventType: triggered, ID: {5dfb6ce9-095b-4476-ac94-c7c35653de1f}) - - + + WIFI Signal Level The name of the ParamType (ThingClass: garadget, EventType: signalStrength, ID: {024f178c-a920-42d4-887f-1c90a96d5eb3}) ---------- @@ -205,25 +157,25 @@ The name of the StateType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass - + WIFI Signal Level changed The name of the EventType ({024f178c-a920-42d4-887f-1c90a96d5eb3}) of ThingClass garadget - + deviceName The name of the ParamType (ThingClass: garadget, Type: thing, ID: {54a11a17-fc37-4316-891f-001c55e38220}) - + multi button press delay mS 10-5,000 The name of the ParamType (ThingClass: garadget, Type: settings, ID: {6be83c99-cbf0-4d1d-b838-697e442ebb43}) - + sensor scan interval in mS 200-60,000 The name of the ParamType (ThingClass: garadget, Type: settings, ID: {13ad28d6-15e5-4e20-862b-51062344b576})