From 17f5ebc6e040e760114db81dab1c08d99cc50b04 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Mon, 16 Oct 2017 16:51:39 +0200 Subject: [PATCH] added http commander --- httpcommander/devicepluginhttpcommander.cpp | 143 +++++++++++++++++++ httpcommander/devicepluginhttpcommander.h | 50 +++++++ httpcommander/devicepluginhttpcommander.json | 116 +++++++++++++++ httpcommander/httpcommander.pro | 15 ++ nymea-plugins.pro | 1 + 5 files changed, 325 insertions(+) create mode 100644 httpcommander/devicepluginhttpcommander.cpp create mode 100644 httpcommander/devicepluginhttpcommander.h create mode 100644 httpcommander/devicepluginhttpcommander.json create mode 100644 httpcommander/httpcommander.pro diff --git a/httpcommander/devicepluginhttpcommander.cpp b/httpcommander/devicepluginhttpcommander.cpp new file mode 100644 index 00000000..b968ec29 --- /dev/null +++ b/httpcommander/devicepluginhttpcommander.cpp @@ -0,0 +1,143 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2017 Bernhard Trinnes * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "devicepluginhttpcommander.h" +#include "plugininfo.h" + + +DevicePluginHttpCommander::DevicePluginHttpCommander() +{ +} + +DeviceManager::HardwareResources DevicePluginHttpCommander::requiredHardware() const +{ + return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer; +} + + +DeviceManager::DeviceSetupStatus DevicePluginHttpCommander::setupDevice(Device *device) +{ + if (device->deviceClassId() == httpGetDeviceClassId) { + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == httpPostDeviceClassId) { + return DeviceManager::DeviceSetupStatusSuccess; + } + return DeviceManager::DeviceSetupStatusFailure; +} + + +void DevicePluginHttpCommander::postSetupDevice(Device *device) +{ + if (device->deviceClassId() == httpGetDeviceClassId) { + QUrl url = device->paramValue(urlParamTypeId).toUrl(); + url.setPort(device->paramValue(portParamTypeId).toInt()); + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("User-Agent", "guhIO 1.0"); + QNetworkReply *reply = networkManagerGet(request);; + m_httpRequests.insert(reply, device); + } +} + + +DeviceManager::DeviceError DevicePluginHttpCommander::executeAction(Device *device, const Action &action) +{ + if (device->deviceClassId() == httpPostDeviceClassId) { + + // check if this is the "press" action + if (action.actionTypeId() == postActionTypeId) { + + QUrl url = device->paramValue(urlParamTypeId).toUrl(); + url.setPort(device->paramValue(portParamTypeId).toInt()); + QByteArray payload = action.param(postDataParamTypeId).value().toByteArray(); + QNetworkReply *reply = networkManagerPost(QNetworkRequest(url), payload); + m_httpRequests.insert(reply, device); + + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + + } + return DeviceManager::DeviceErrorDeviceClassNotFound; +} + + +void DevicePluginHttpCommander::deviceRemoved(Device *device) +{ + Q_UNUSED(device); +} + + +void DevicePluginHttpCommander::guhTimer() +{ + + foreach (Device *device, myDevices()) { + + if (device->deviceClassId() == httpGetDeviceClassId) { + QUrl url = device->paramValue(urlParamTypeId).toUrl(); + url.setPort(device->paramValue(portParamTypeId).toInt()); + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("User-Agent", "guhIO 1.0"); + QNetworkReply *reply = networkManagerGet(request);; + m_httpRequests.insert(reply, device); + } + } + +} + + +void DevicePluginHttpCommander::networkManagerReplyReady(QNetworkReply *reply) +{ + QByteArray data = reply->readAll(); + qDebug(dcHttpCommander()) << "Reply received"; + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_httpRequests.contains(reply)) { + Device *device = m_httpRequests.take(reply); + + if (device->deviceClassId() == httpGetDeviceClassId) { + device->setStateValue(httpResponseStateTypeId, data); + //device->setStateValue(statusStateTypeId, reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); + // check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcHttpCommander()) << "Request error:" << status << reply->errorString(); + device->setStateValue(reachableStateTypeId, false); + reply->deleteLater(); + return; + } + device->setStateValue(reachableStateTypeId, true); + } else if (device->deviceClassId() == httpPostDeviceClassId) { + + // check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcHttpCommander()) << "Request error:" << status << reply->errorString(); + device->setStateValue(reachableStateTypeId, false); + reply->deleteLater(); + return; + } + device->setStateValue(reachableStateTypeId, true); + } + } + reply->deleteLater(); +} + diff --git a/httpcommander/devicepluginhttpcommander.h b/httpcommander/devicepluginhttpcommander.h new file mode 100644 index 00000000..1cec6299 --- /dev/null +++ b/httpcommander/devicepluginhttpcommander.h @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2017 Bernhard Trinnes * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef DEVICEPLUGINDHTTPCOMMANDER_H +#define DEVICEPLUGINDHTTPCOMMANDER_H + +#include "plugin/deviceplugin.h" +#include "devicemanager.h" + +class DevicePluginHttpCommander : public DevicePlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginhttpcommander.json") + Q_INTERFACES(DevicePlugin) + +public: + explicit DevicePluginHttpCommander(); + + DeviceManager::HardwareResources requiredHardware() const override; + DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; + void postSetupDevice(Device *device) override; + void deviceRemoved(Device *device) override; + void networkManagerReplyReady(QNetworkReply *reply) override; + void guhTimer() override; + + DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; + +private: + QHash m_httpRequests; +}; + +#endif // DEVICEPLUGINHTTPCOMMANDER_H diff --git a/httpcommander/devicepluginhttpcommander.json b/httpcommander/devicepluginhttpcommander.json new file mode 100644 index 00000000..e929820e --- /dev/null +++ b/httpcommander/devicepluginhttpcommander.json @@ -0,0 +1,116 @@ +{ + "name": "http commander", + "idName": "HttpCommander", + "id": "4e62670c-6268-4487-8dff-cccca498731a", + "vendors": [ + { + "name": "http commander", + "idName": "httpCommander", + "id": "45d7c941-7690-43c9-92fc-fab36e1cebd0", + "deviceClasses": [ + { + "id": "b101abdf-86fd-4d2e-a657-ee76044235bd", + "idName": "httpPost", + "name": "http post", + "deviceIcon": "Network", + "createMethods": ["user"], + "basicTags": [ + "Service" + ], + "primaryStateTypeId": "137ec5fc-22f5-4201-8921-2896deda0fe6", + "paramTypes": [ + { + "id": "1a3fcb23-931b-4ba1-b134-c49b656c76f7", + "idName": "url", + "name": "url or ipv4 address", + "type": "QString", + "inputType": "None", + "defaultValue": "http://nymea.io" + }, + { + "id": "bee8b151-815a-4159-9d8a-42b76e99b42c", + "idName": "port", + "name": "port", + "type": "int", + "defaultValue": "80" + } + ], + "stateTypes": [ + { + "id": "8daac0e7-4c2f-4cdf-b528-02cfe04c6b39", + "idName": "reachable", + "name": "reachable", + "type": "bool", + "defaultValue": false, + "eventTypeName": "reachable status changed" + } + ], + "actionTypes": [ + { + "id": "5a97ca56-b334-411b-adba-116496ffe83d", + "idName": "post", + "name": "post", + "paramTypes": [ + { + "id": "363119a3-c02c-4ed5-a915-11706198f3eb", + "idName": "postData", + "name": "post data", + "type": "QString", + "defaultValue": "", + "eventTypeName": "post data sent" + } + ] + } + ] + }, + { + "id": "8f3f6dde-9db3-4237-800b-bb7f804098c9", + "idName": "httpGet", + "name": "http get", + "deviceIcon": "Network", + "createMethods": ["user"], + "basicTags": [ + "Service" + ], + "primaryStateTypeId": "137ec5fc-22f5-4201-8921-2896deda0fe6", + "paramTypes": [ + { + "id": "1a3fcb23-931b-4ba1-b134-c49b656c76f7", + "idName": "url", + "name": "Url or IPv4 Address", + "type": "QString", + "inputType": "None", + "defaultValue": "http://nymea.io" + }, + { + "id": "bee8b151-815a-4159-9d8a-42b76e99b42c", + "idName": "port", + "name": "Port", + "type": "int", + "defaultValue": "80" + } + ], + "stateTypes":[ + { + "id": "137ec5fc-22f5-4201-8921-2896deda0fe6", + "idName": "status", + "name": "status", + "type": "QString", + "defaultValue": "Undefined", + "eventTypeName": "connection status changed" + }, + { + "id": "5a97ca56-b334-411b-adba-116496ffe83d", + "idName": "httpResponse", + "name": "response", + "type": "QString", + "defaultValue": "", + "eventTypeName": "response received" + } + ] + } + ] + } + ] +} + diff --git a/httpcommander/httpcommander.pro b/httpcommander/httpcommander.pro new file mode 100644 index 00000000..b1b2b360 --- /dev/null +++ b/httpcommander/httpcommander.pro @@ -0,0 +1,15 @@ +TRANSLATIONS = translations/en_US.ts \ + translations/de_DE.ts + +# Note: include after the TRANSLATIONS definition +include(../plugins.pri) + +TARGET = $$qtLibraryTarget(guh_devicepluginhttpcommander) + +SOURCES += \ + devicepluginhttpcommander.cpp \ + +HEADERS += \ + devicepluginhttpcommander.h \ + + diff --git a/nymea-plugins.pro b/nymea-plugins.pro index e1d7c09d..054b8cb1 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -19,6 +19,7 @@ PLUGIN_DIRS = \ leynew \ udpcommander \ tcpcommander \ + httpcommander \ kodi \ elgato \ senic \