diff --git a/debian/control b/debian/control index 6efef76e..8c06dd32 100644 --- a/debian/control +++ b/debian/control @@ -215,6 +215,21 @@ Description: nymea.io plugin for dweet.io This package will install the nymea.io plugin for dweet.io +Package: nymea-plugin-dynatrace +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, + nymea-plugins-translations, +Description: nymea.io plugin for dynatrace + 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 dynatrace + + Package: nymea-plugin-elgato Architecture: any Depends: ${shlibs:Depends}, diff --git a/debian/nymea-plugin-dynatrace.install.in b/debian/nymea-plugin-dynatrace.install.in new file mode 100644 index 00000000..80cc26d7 --- /dev/null +++ b/debian/nymea-plugin-dynatrace.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_deviceplugindynatrace.so diff --git a/dynatrace/README.md b/dynatrace/README.md new file mode 100644 index 00000000..14d22069 --- /dev/null +++ b/dynatrace/README.md @@ -0,0 +1,20 @@ +# Dynatrace + +This plug-in enables nymea to control the Dynatrace Ufo. + + +## Device Setup + +An excerpt of the Ufo (Blog Post)[https://www.dynatrace.com/news/blog/using-dynatrace-devops-pipeline-state-ufo/] + +* Plug it in! +* Press the little black dot on the top. The UFO starts blinking blue and now offers a WiFi hotspot with the name “ufo” +* Connect to that hotspot, browse to http://192.168.4.1 +* Through the Web UI connect to your own WiFi. You can also do it via the REST API: http://192.168.4.1/api?ssid=&pwd= +* Remember: WPA2 works well where Enterprise WPA2 is currently not supported +* While it reboots itself it will blink yellow. Once it has its assigned IP Address it will start visualizing its IP Address through a special „blink code“ as explained in the Quick Start Guide! +* Remember: the UFO will also try to register its hostname as „ufo“ with your DHCP server. If that works you can simply browse to http://ufo + +More about the Dynatrace Ufo: +https://github.com/Dynatrace/ufo + diff --git a/dynatrace/deviceplugindynatrace.cpp b/dynatrace/deviceplugindynatrace.cpp new file mode 100644 index 00000000..3f9edb64 --- /dev/null +++ b/dynatrace/deviceplugindynatrace.cpp @@ -0,0 +1,219 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* This project may also contain libraries licensed under the open source software license GNU GPL v.3. +* 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 "deviceplugindynatrace.h" +#include "devices/device.h" +#include "plugininfo.h" +#include "network/networkaccessmanager.h" + +#include +#include +#include +#include + +DevicePluginDynatrace::DevicePluginDynatrace() +{ + +} + +void DevicePluginDynatrace::discoverDevices(DeviceDiscoveryInfo *info) +{ + if (info->deviceClassId() == ufoDeviceClassId) { + + QHostInfo::lookupHost("ufo.home", this, [info, this](const QHostInfo &host){ + if (host.error() != QHostInfo::NoError) { + qCDebug(dcDynatrace()) << "Lookup failed:" << host.errorString(); + } + + foreach (QHostAddress address, host.addresses()) { + qCDebug(dcDynatrace()) << "Found IP address" << address.toString(); + + DeviceDescriptor descriptor(ufoDeviceClassId, "Ufo", address.toString()); + ParamList params; + + /*Device *existingDevice = myDevices().findByParams(ParamList() << Param(ufoDeviceIdParamTypeId, "")); + if (existingDevice) { + //For device re-discovery + descriptor.setDeviceId(existingDevice->id()); + }*/ + params << Param(ufoDeviceHostParamTypeId, address.toString()); + descriptor.setParams(params); + info->addDeviceDescriptor(descriptor); + } + info->finish(Device::DeviceErrorNoError); + }); + } +} + +void DevicePluginDynatrace::setupDevice(DeviceSetupInfo *info) +{ + + if (info->device()->deviceClassId() == ufoDeviceClassId) { + QHostAddress address = QHostAddress(info->device()->paramValue(ufoDeviceHostParamTypeId).toString()); + QString id = info->device()->paramValue(ufoDeviceIdParamTypeId).toString(); + if(id.isEmpty()) { //Probably a manual device setup + QUrl url; + url.setScheme("http"); + url.setHost(address.toString()); + url.setPath("/info", QUrl::ParsingMode::TolerantMode); + QNetworkRequest request; + request.setUrl(url); + QNetworkReply *reply = hardwareManager()->networkManager()->get(request); + connect(reply, &QNetworkReply::finished, this, [info, reply, this] { + reply->deleteLater(); + + QJsonParseError error; + QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) { + info->finish(Device::DeviceErrorSetupFailed, error.errorString()); + } + + QString id = data.toVariant().toMap().value("ufoid").toString(); + info->device()->setParamValue(ufoDeviceIdParamTypeId, id); + info->finish(Device::DeviceErrorNoError); + }); + } else { + // Discovery device setup + info->finish(Device::DeviceErrorNoError); + } + } +} + +void DevicePluginDynatrace::postSetupDevice(Device *device) +{ + if (device->deviceClassId() == ufoDeviceClassId) { + QHostAddress address = QHostAddress(device->paramValue(ufoDeviceHostParamTypeId).toString()); + Ufo *ufo = new Ufo(hardwareManager()->networkManager(), address, this); + m_ufoConnections.insert(device->id(), ufo); + ufo->resetLogo(); + } + + if(!m_pluginTimer) { + m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); + connect(m_pluginTimer, &PluginTimer::timeout, this, [this]() { + //TODO check if device is reachable + }); + } +} + +void DevicePluginDynatrace::executeAction(DeviceActionInfo *info) +{ + Device *device = info->device(); + Action action = info->action(); + + if (device->deviceClassId() == ufoDeviceClassId) { + Ufo *ufo = m_ufoConnections.value(device->id()); + if (!ufo) + return; + if (action.actionTypeId() == ufoLogoActionTypeId) { + bool power = action.param(ufoLogoActionLogoParamTypeId).value().toBool(); + device->setStateValue(ufoLogoStateTypeId, power); + if (power) { + ufo->resetLogo(); + } else { + QColor color; + color.setRgb(0, 0, 0); + ufo->setLogo(color, color, color, color); + } + info->finish(Device::DeviceErrorNoError); + + } else if (action.actionTypeId() == ufoPowerActionTypeId) { + bool power = action.param(ufoPowerActionPowerParamTypeId).value().toBool(); + device->setStateValue(ufoPowerStateTypeId, power); + if (power) { + ufo->setBackgroundColor(true, true, QColor(Qt::white)); //#ffffff + } else { + ufo->setBackgroundColor(true, true, QColor(Qt::black)); //#000000 + } + info->finish(Device::DeviceErrorNoError); + + } else if (action.actionTypeId() == ufoBrightnessActionTypeId) { + int brightness = action.param(ufoBrightnessActionBrightnessParamTypeId).value().toInt(); + QColor color = QColor(device->stateValue(ufoColorStateTypeId).toString()); + color.setHsv(color.hue(), color.saturation(), brightness); + ufo->setBackgroundColor(true, true, color); + info->finish(Device::DeviceErrorNoError); + } else if (action.actionTypeId() == ufoColorActionTypeId) { + QColor color = QColor(action.param(ufoColorActionColorParamTypeId).value().toString()); + int brightness = device->stateValue(ufoBrightnessStateTypeId).toInt(); + device->setStateValue(ufoColorStateTypeId, color); + color.setHsv(color.hue(), color.saturation(), brightness); + ufo->setBackgroundColor(true, true, color); + info->finish(Device::DeviceErrorNoError); + } else { + qCWarning(dcDynatrace()) << "Execute action: Unhandled actionTypeId"; + } + } else { + qCWarning(dcDynatrace()) << "Execute action: Unhandled deviceClass"; + } +} + +void DevicePluginDynatrace::deviceRemoved(Device *device) +{ + if (device->deviceClassId() == ufoDeviceClassId) { + if (m_ufoConnections.contains(device->id())){ + Ufo *ufo = m_ufoConnections.take(device->id()); + ufo->deleteLater(); + } + } + + if (myDevices().isEmpty() && m_pluginTimer) { + m_pluginTimer->deleteLater(); + m_pluginTimer = nullptr; + } +} + +void DevicePluginDynatrace::getId(const QHostAddress &address) +{ + QUrl url; + url.setScheme("http"); + url.setHost(address.toString()); + url.setPath("/info", QUrl::ParsingMode::TolerantMode); + QNetworkRequest request; + request.setUrl(url); + QNetworkReply *reply = hardwareManager()->networkManager()->get(request); + connect(reply, &QNetworkReply::finished, this, [reply, this] { + reply->deleteLater(); + + QJsonParseError error; + QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) + return; + + QString id = data.toVariant().toMap().value("ufoid").toString(); + if (m_asyncSetup.contains(reply->url().host())) { + DeviceSetupInfo *info = m_asyncSetup.value(reply->url().host()); + info->finish(Device::DeviceErrorNoError); + } + }); +} + +void DevicePluginDynatrace::onConnectionChanged(bool connected) +{ + Q_UNUSED(connected) +} diff --git a/dynatrace/deviceplugindynatrace.h b/dynatrace/deviceplugindynatrace.h new file mode 100644 index 00000000..f55f91a4 --- /dev/null +++ b/dynatrace/deviceplugindynatrace.h @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* This project may also contain libraries licensed under the open source software license GNU GPL v.3. +* 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 DEVICEPLUGINDYNATRACE_H +#define DEVICEPLUGINDYNATRACE_H + +#include "plugintimer.h" +#include "devices/deviceplugin.h" +#include "network/oauth2.h" +#include "ufo.h" + +#include +#include + +class DevicePluginDynatrace : public DevicePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "deviceplugindynatrace.json") + Q_INTERFACES(DevicePlugin) + +public: + explicit DevicePluginDynatrace(); + void discoverDevices(DeviceDiscoveryInfo *info) override; + void setupDevice(DeviceSetupInfo *info) override; + void postSetupDevice(Device *device) override; + void executeAction(DeviceActionInfo *info) override; + void deviceRemoved(Device *device) override; + +private: + PluginTimer *m_pluginTimer = nullptr; + QHash m_ufoConnections; + QHash m_asyncActions; + QHash m_asyncSetup; + + void getId(const QHostAddress &address); + +private slots: + void onConnectionChanged(bool connected); +}; + +#endif // DEVICEPLUGINDYNATRACE_H diff --git a/dynatrace/deviceplugindynatrace.json b/dynatrace/deviceplugindynatrace.json new file mode 100644 index 00000000..e2eac5e2 --- /dev/null +++ b/dynatrace/deviceplugindynatrace.json @@ -0,0 +1,139 @@ +{ + "displayName": "Dynatrace", + "name": "dynatrace", + "id": "a8451bd7-69cb-4106-968f-1206a5736368", + "vendors": [ + { + "name": "Dynatrace", + "displayName": "Dynatrace", + "id": "31b402be-1562-4335-aa83-d1c1166db570", + "deviceClasses": [ + { + "id": "6271f010-0b0a-4f29-b894-0611bb5f3dcc", + "name": "ufo", + "displayName": "ufo", + "createMethods": ["user", "discovery"], + "interfaces": ["colorlight", "alert", "connectable"], + "paramTypes": [ + { + "id": "3e14968b-954e-4e85-ae79-3de9ae4fe951", + "name": "host", + "displayName": "Host address", + "type" : "QString", + "inputType": "IPv4Address", + "readOnly": true + }, + { + "id": "142c25c0-03e3-478e-b5c3-3d072f668cc4", + "name": "id", + "displayName": "Id", + "type" : "QString", + "readOnly": true + } + ], + "actionTypes": [ + { + "id": "6efa52d9-527b-4ac7-8885-50f2b1786561", + "name": "alert", + "displayName": "flash", + "paramTypes": [ + { + "id": "e8d854ce-02d0-4ddd-a2bd-0c464cbb9182", + "name": "alert", + "displayName": "alert", + "type": "QString", + "defaultValue": "flash", + "allowedValues": [ + "flash", + "flash 15 [s]" + ] + } + ] + } + ], + "stateTypes": [ + { + "id": "1a439907-e810-4dea-b357-dd32281896e7", + "name": "connected", + "displayName": "Reachable", + "displayNameEvent": "Reachable changed", + "defaultValue": false, + "type": "bool" + }, + { + "id": "a9c123e2-db78-40d3-a422-7e4817d50984", + "name": "logo", + "displayName": "Logo", + "displayNameEvent": "Logo changed", + "displayNameAction": "Set logo", + "defaultValue": false, + "type": "bool", + "writable": true + }, + { + "id": "14ac8d16-72be-4530-a2ce-dd5589ce8dd7", + "name": "power", + "displayName": "Power", + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "type": "bool", + "defaultValue": false, + "writable": true + }, + { + "id": "60fa917b-8702-4ff2-90b8-9c8c616bb21f", + "name": "colorTemperature", + "displayName": "Color temperature", + "displayNameEvent": "Color temperature changed", + "displayNameAction": "Set color temperature", + "type": "int", + "unit": "Mired", + "defaultValue": 170, + "minValue": 153, + "maxValue": 500, + "writable": true + }, + { + "id": "9535fd99-05c6-449f-80a2-8daf61d9b9b0", + "name": "color", + "displayName": "Color", + "displayNameEvent": "Color changed", + "displayNameAction": "Set color", + "type": "QColor", + "defaultValue": "#000000", + "writable": true + }, + { + "id": "1adb2df8-7ba1-48b8-b0da-d67085efe041", + "name": "brightness", + "displayName": "Brightness", + "displayNameEvent": "Brightness changed", + "displayNameAction": "Set brigtness", + "type": "int", + "unit": "Percentage", + "defaultValue": 0, + "minValue": 0, + "maxValue": 100, + "writable": true + }, + { + "id": "53da0021-974a-434a-94ac-3f187aad1480", + "name": "effect", + "displayName": "Effect", + "displayNameEvent": "Effect changed", + "displayNameAction": "Set effect", + "type": "QString", + "defaultValue": "None", + "possibleValues": [ + "None", + "Morph", + "Whirl" + ], + "writable": true + } + ] + } + ] + } + ] +} diff --git a/dynatrace/dynatrace.pro b/dynatrace/dynatrace.pro new file mode 100644 index 00000000..41ab4c98 --- /dev/null +++ b/dynatrace/dynatrace.pro @@ -0,0 +1,13 @@ +include(../plugins.pri) + +QT += network + +TARGET = $$qtLibraryTarget(nymea_deviceplugindynatrace) + +SOURCES += \ + deviceplugindynatrace.cpp \ + ufo.cpp + +HEADERS += \ + deviceplugindynatrace.h \ + ufo.h diff --git a/dynatrace/translations/a8451bd7-69cb-4106-968f-1206a5736368-en_US.ts b/dynatrace/translations/a8451bd7-69cb-4106-968f-1206a5736368-en_US.ts new file mode 100644 index 00000000..2d702e9c --- /dev/null +++ b/dynatrace/translations/a8451bd7-69cb-4106-968f-1206a5736368-en_US.ts @@ -0,0 +1,205 @@ + + + + + dynatrace + + + + + Brightness + The name of the ParamType (DeviceClass: ufo, ActionType: brightness, ID: {1adb2df8-7ba1-48b8-b0da-d67085efe041}) +---------- +The name of the ParamType (DeviceClass: ufo, EventType: brightness, ID: {1adb2df8-7ba1-48b8-b0da-d67085efe041}) +---------- +The name of the StateType ({1adb2df8-7ba1-48b8-b0da-d67085efe041}) of DeviceClass ufo + + + + + Brightness changed + The name of the EventType ({1adb2df8-7ba1-48b8-b0da-d67085efe041}) of DeviceClass ufo + + + + + + + Color + The name of the ParamType (DeviceClass: ufo, ActionType: color, ID: {9535fd99-05c6-449f-80a2-8daf61d9b9b0}) +---------- +The name of the ParamType (DeviceClass: ufo, EventType: color, ID: {9535fd99-05c6-449f-80a2-8daf61d9b9b0}) +---------- +The name of the StateType ({9535fd99-05c6-449f-80a2-8daf61d9b9b0}) of DeviceClass ufo + + + + + Color changed + The name of the EventType ({9535fd99-05c6-449f-80a2-8daf61d9b9b0}) of DeviceClass ufo + + + + + + + Color temperature + The name of the ParamType (DeviceClass: ufo, ActionType: colorTemperature, ID: {60fa917b-8702-4ff2-90b8-9c8c616bb21f}) +---------- +The name of the ParamType (DeviceClass: ufo, EventType: colorTemperature, ID: {60fa917b-8702-4ff2-90b8-9c8c616bb21f}) +---------- +The name of the StateType ({60fa917b-8702-4ff2-90b8-9c8c616bb21f}) of DeviceClass ufo + + + + + Color temperature changed + The name of the EventType ({60fa917b-8702-4ff2-90b8-9c8c616bb21f}) of DeviceClass ufo + + + + + + Dynatrace + The name of the vendor ({31b402be-1562-4335-aa83-d1c1166db570}) +---------- +The name of the plugin dynatrace ({a8451bd7-69cb-4106-968f-1206a5736368}) + + + + + + + Effect + The name of the ParamType (DeviceClass: ufo, ActionType: effect, ID: {53da0021-974a-434a-94ac-3f187aad1480}) +---------- +The name of the ParamType (DeviceClass: ufo, EventType: effect, ID: {53da0021-974a-434a-94ac-3f187aad1480}) +---------- +The name of the StateType ({53da0021-974a-434a-94ac-3f187aad1480}) of DeviceClass ufo + + + + + Effect changed + The name of the EventType ({53da0021-974a-434a-94ac-3f187aad1480}) of DeviceClass ufo + + + + + Host address + The name of the ParamType (DeviceClass: ufo, Type: device, ID: {3e14968b-954e-4e85-ae79-3de9ae4fe951}) + + + + + Id + The name of the ParamType (DeviceClass: ufo, Type: device, ID: {142c25c0-03e3-478e-b5c3-3d072f668cc4}) + + + + + + + Logo + The name of the ParamType (DeviceClass: ufo, ActionType: logo, ID: {a9c123e2-db78-40d3-a422-7e4817d50984}) +---------- +The name of the ParamType (DeviceClass: ufo, EventType: logo, ID: {a9c123e2-db78-40d3-a422-7e4817d50984}) +---------- +The name of the StateType ({a9c123e2-db78-40d3-a422-7e4817d50984}) of DeviceClass ufo + + + + + Logo changed + The name of the EventType ({a9c123e2-db78-40d3-a422-7e4817d50984}) of DeviceClass ufo + + + + + + + Power + The name of the ParamType (DeviceClass: ufo, ActionType: power, ID: {14ac8d16-72be-4530-a2ce-dd5589ce8dd7}) +---------- +The name of the ParamType (DeviceClass: ufo, EventType: power, ID: {14ac8d16-72be-4530-a2ce-dd5589ce8dd7}) +---------- +The name of the StateType ({14ac8d16-72be-4530-a2ce-dd5589ce8dd7}) of DeviceClass ufo + + + + + Power changed + The name of the EventType ({14ac8d16-72be-4530-a2ce-dd5589ce8dd7}) of DeviceClass ufo + + + + + + Reachable + The name of the ParamType (DeviceClass: ufo, EventType: connected, ID: {1a439907-e810-4dea-b357-dd32281896e7}) +---------- +The name of the StateType ({1a439907-e810-4dea-b357-dd32281896e7}) of DeviceClass ufo + + + + + Reachable changed + The name of the EventType ({1a439907-e810-4dea-b357-dd32281896e7}) of DeviceClass ufo + + + + + Set brigtness + The name of the ActionType ({1adb2df8-7ba1-48b8-b0da-d67085efe041}) of DeviceClass ufo + + + + + Set color + The name of the ActionType ({9535fd99-05c6-449f-80a2-8daf61d9b9b0}) of DeviceClass ufo + + + + + Set color temperature + The name of the ActionType ({60fa917b-8702-4ff2-90b8-9c8c616bb21f}) of DeviceClass ufo + + + + + Set effect + The name of the ActionType ({53da0021-974a-434a-94ac-3f187aad1480}) of DeviceClass ufo + + + + + Set logo + The name of the ActionType ({a9c123e2-db78-40d3-a422-7e4817d50984}) of DeviceClass ufo + + + + + Set power + The name of the ActionType ({14ac8d16-72be-4530-a2ce-dd5589ce8dd7}) of DeviceClass ufo + + + + + alert + The name of the ParamType (DeviceClass: ufo, ActionType: alert, ID: {e8d854ce-02d0-4ddd-a2bd-0c464cbb9182}) + + + + + flash + The name of the ActionType ({6efa52d9-527b-4ac7-8885-50f2b1786561}) of DeviceClass ufo + + + + + ufo + The name of the DeviceClass ({6271f010-0b0a-4f29-b894-0611bb5f3dcc}) + + + + diff --git a/dynatrace/ufo.cpp b/dynatrace/ufo.cpp new file mode 100644 index 00000000..ff9232d6 --- /dev/null +++ b/dynatrace/ufo.cpp @@ -0,0 +1,159 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* This project may also contain libraries licensed under the open source software license GNU GPL v.3. +* 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 "ufo.h" +#include "extern-plugininfo.h" +#include + +Ufo::Ufo(NetworkAccessManager *networkManager, const QHostAddress &address, QObject *parent) : + QObject(parent), + m_networkManager(networkManager), + m_address(address) +{ + +} + +void Ufo::resetLogo() +{ + QUrl url; + url.setScheme("http"); + url.setHost(m_address.toString()); + url.setPath("/api"); + url.setQuery("logo_reset"); + QNetworkRequest request; + request.setUrl(url); + qCDebug(dcDynatrace()) << "Sending request" << url; + QNetworkReply *reply = m_networkManager->get(request); + connect(reply, &QNetworkReply::finished, this, [reply, this] { + reply->deleteLater(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + // Check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcDynatrace()) << "Request error:" << status << reply->errorString(); + emit connectionChanged(false); + return; + } + emit connectionChanged(true); + }); + +} + +void Ufo::setLogo(QColor led1, QColor led2, QColor led3, QColor led4) +{ + QUrl url; + url.setScheme("http"); + url.setHost(m_address.toString()); + url.setPath("/api"); + QUrlQuery query; + query.addQueryItem("logo", led1.name().remove(0,1)+"|"+led2.name().remove(0,1)+"|"+led3.name().remove(0,1)+"|"+led4.name().remove(0,1)); + url.setQuery(query); + QNetworkRequest request; + request.setUrl(url); + + qCDebug(dcDynatrace()) << "Sending request" << url; + QNetworkReply *reply = m_networkManager->get(request); + connect(reply, &QNetworkReply::finished, this, [reply, this] { + reply->deleteLater(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + // Check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcDynatrace()) << "Request error:" << status << reply->errorString(); + emit connectionChanged(false); + return; + } + emit connectionChanged(true); + }); +} + +void Ufo::initBackgroundColor(bool top, bool bottom) +{ + QUrl url; + url.setScheme("http"); + url.setHost(m_address.toString()); + url.setPath("/api"); + if (top) { + url.setQuery("top_init"); + } + if (bottom) { + url.setQuery("bottom_init"); + } + QNetworkRequest request; + request.setUrl(url); + + qCDebug(dcDynatrace()) << "Sending request" << url; + QNetworkReply *reply = m_networkManager->get(request); + connect(reply, &QNetworkReply::finished, this, [reply, this] { + reply->deleteLater(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + // Check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcDynatrace()) << "Request error:" << status << reply->errorString(); + emit connectionChanged(false); + return; + } + emit connectionChanged(true); + }); +} + +void Ufo::setBackgroundColor(bool top, bool bottom, QColor color) +{ + QUrl url; + url.setScheme("http"); + url.setHost(m_address.toString()); + url.setPath("/api"); + QUrlQuery query; + if (top){ + query.addQueryItem("top_init", "0"); + query.addQueryItem("top_bg", color.name().remove(0,1)); + } + if (bottom) { + query.addQueryItem("bottom_init", "0"); + query.addQueryItem("bottom_bg", color.name().remove(0,1)); + } + url.setQuery(query); + QNetworkRequest request; + request.setUrl(url); + + qCDebug(dcDynatrace()) << "Sending request" << url; + QNetworkReply *reply = m_networkManager->get(request); + connect(reply, &QNetworkReply::finished, this, [reply, this] { + reply->deleteLater(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + // Check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcDynatrace()) << "Request error:" << status << reply->errorString(); + emit connectionChanged(false); + return; + } + emit connectionChanged(true); + }); +} diff --git a/dynatrace/ufo.h b/dynatrace/ufo.h new file mode 100644 index 00000000..a2e1ebdc --- /dev/null +++ b/dynatrace/ufo.h @@ -0,0 +1,65 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* This project may also contain libraries licensed under the open source software license GNU GPL v.3. +* 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 DYNATRACE_UFO_H +#define DYNATRACE_UFO_H + +#include "network/networkaccessmanager.h" +#include "devices/device.h" + +#include +#include +#include +#include + +class Ufo : public QObject +{ + Q_OBJECT +public: + explicit Ufo(NetworkAccessManager *networkManager, const QHostAddress &address, QObject *parent = nullptr); + + void resetLogo(); + void setLogo(QColor led1, QColor led2, QColor led3, QColor led4); + void initBackgroundColor(bool top, bool bottom); + void setBackgroundColor(bool top, bool bottom, QColor color); + void setLeds(bool top, int ledIndex, int numOfLeds, QColor color); + void startWhirl(bool top, bool bottom, int speed, bool clockwise); + void stopWhirl(bool top, bool bottom); + void startMorph(bool top, bool bottom, int speed, bool time); + void stopMorph(bool top, bool bottom); + + +private: + NetworkAccessManager *m_networkManager; + QHostAddress m_address; + +signals: + void connectionChanged(bool reachable); + +}; +#endif //DYNATRACE_UFO_H diff --git a/nymea-plugins.pro b/nymea-plugins.pro index 23d78cdf..7814a71b 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -13,6 +13,7 @@ PLUGIN_DIRS = \ daylightsensor \ denon \ dweetio \ + dynatrace \ elgato \ elro \ eq-3 \