Migrate plugin timer

This commit is contained in:
Simon Stürz 2017-11-24 22:54:15 +01:00 committed by Michael Zanetti
parent 0b1991d50a
commit 2b39765d58
72 changed files with 1168 additions and 2211 deletions

View File

@ -44,6 +44,7 @@
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "network/avahi/qtavahiservicebrowser.h"
#include <QDebug>
#include <QStringList>
@ -56,8 +57,8 @@ DevicePluginAvahiMonitor::DevicePluginAvahiMonitor()
void DevicePluginAvahiMonitor::init()
{
connect(avahiServiceBrowser(), SIGNAL(serviceEntryAdded(AvahiServiceEntry)), this, SLOT(onServiceEntryAdded(AvahiServiceEntry)));
connect(avahiServiceBrowser(), SIGNAL(serviceEntryRemoved(AvahiServiceEntry)), this, SLOT(onServiceEntryRemoved(AvahiServiceEntry)));
connect(hardwareManager()->avahiBrowser(), &QtAvahiServiceBrowser::serviceEntryAdded, this, &DevicePluginAvahiMonitor::onServiceEntryAdded);
connect(hardwareManager()->avahiBrowser(), &QtAvahiServiceBrowser::serviceEntryRemoved, this, &DevicePluginAvahiMonitor::onServiceEntryRemoved);
}
DeviceManager::DeviceSetupStatus DevicePluginAvahiMonitor::setupDevice(Device *device)
@ -75,7 +76,7 @@ DeviceManager::DeviceError DevicePluginAvahiMonitor::discoverDevices(const Devic
return DeviceManager::DeviceErrorDeviceClassNotFound;
QList<DeviceDescriptor> deviceDescriptors;
foreach (const AvahiServiceEntry &service, avahiServiceBrowser()->serviceEntries()) {
foreach (const AvahiServiceEntry &service, hardwareManager()->avahiBrowser()->serviceEntries()) {
DeviceDescriptor deviceDescriptor(avahiDeviceClassId, service.name(), service.hostAddress().toString());
ParamList params;
params.append(Param(serviceParamTypeId, service.name()));
@ -89,11 +90,6 @@ DeviceManager::DeviceError DevicePluginAvahiMonitor::discoverDevices(const Devic
return DeviceManager::DeviceErrorAsync;
}
DeviceManager::HardwareResources DevicePluginAvahiMonitor::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
void DevicePluginAvahiMonitor::onServiceEntryAdded(const AvahiServiceEntry &serviceEntry)
{
foreach (Device *device, myDevices()) {

View File

@ -25,6 +25,7 @@
#define DEVICEPLUGINAVAHIMONITOR_H
#include "plugin/deviceplugin.h"
#include "network/avahi/avahiserviceentry.h"
#include <QProcess>
@ -42,7 +43,6 @@ public:
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::HardwareResources requiredHardware() const override;
private slots:
void onServiceEntryAdded(const AvahiServiceEntry &serviceEntry);

View File

@ -69,6 +69,8 @@
#include "devicepluginawattar.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "hardwaremanager.h"
#include "network/networkaccessmanager.h"
#include <QDateTime>
#include <QJsonDocument>
@ -78,9 +80,15 @@ DevicePluginAwattar::DevicePluginAwattar()
{
}
DeviceManager::HardwareResources DevicePluginAwattar::requiredHardware() const
DevicePluginAwattar::~DevicePluginAwattar()
{
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginAwattar::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(15);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginAwattar::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginAwattar::setupDevice(Device *device)
@ -119,85 +127,6 @@ void DevicePluginAwattar::deviceRemoved(Device *device)
m_device = 0;
}
void DevicePluginAwattar::networkManagerReplyReady(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (m_updatePrice.contains(reply)) {
m_updatePrice.removeAll(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcAwattar) << "Update reply HTTP error:" << status << reply->errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
// check JSON file
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcAwattar) << "Update reply JSON error:" << error.errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
processPriceData(jsonDoc.toVariant().toMap());
// start user data update
m_updateUserData.append(requestUserData(m_token, m_userUuid));
} else if (m_updateUserData.contains(reply)) {
m_updateUserData.removeAll(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcAwattar) << "Update user data reply HTTP error:" << status << reply->errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
// check JSON file
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcAwattar) << "Update user data reply JSON error:" << error.errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
setOnlineStatus(true);
processUserData(jsonDoc.toVariant().toMap());
} else if (m_searchPumpReplies.contains(reply)) {
m_searchPumpReplies.removeAll(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcAwattar) << "Search pump reply HTTP error:" << status << reply->errorString();
reply->deleteLater();
return;
}
processPumpSearchData(reply->readAll());
}
reply->deleteLater();
}
void DevicePluginAwattar::guhTimer()
{
if (m_device.isNull())
return;
updateData();
searchHeatPumps();
}
DeviceManager::DeviceError DevicePluginAwattar::executeAction(Device *device, const Action &action)
{
if (m_device.isNull() || m_device != device)
@ -244,7 +173,9 @@ QNetworkReply *DevicePluginAwattar::requestPriceData(const QString &token)
QNetworkRequest request(QUrl("https://api.awattar.com/v1/marketdata"));
request.setRawHeader("Authorization", header.toLocal8Bit());
request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
return networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginAwattar::onNetworkReplyFinished);
return reply;
}
QNetworkReply *DevicePluginAwattar::requestUserData(const QString &token, const QString &userId)
@ -255,7 +186,9 @@ QNetworkReply *DevicePluginAwattar::requestUserData(const QString &token, const
QNetworkRequest request(QUrl(QString("https://api.awattar.com/v1/devices/%1/actuators").arg(userId)));
request.setRawHeader("Authorization", header.toLocal8Bit());
request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
return networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginAwattar::onNetworkReplyFinished);
return reply;
}
void DevicePluginAwattar::updateData()
@ -273,8 +206,8 @@ void DevicePluginAwattar::searchHeatPumps()
}
QNetworkRequest request(QUrl(QString("http://[%1]").arg(rplAddress.toString())));
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginAwattar::onNetworkReplyFinished);
m_searchPumpReplies.append(reply);
}
@ -452,6 +385,86 @@ bool DevicePluginAwattar::heatPumpExists(const QHostAddress &pumpAddress)
return false;
}
void DevicePluginAwattar::onPluginTimer()
{
if (m_device.isNull())
return;
updateData();
searchHeatPumps();
}
void DevicePluginAwattar::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (m_updatePrice.contains(reply)) {
m_updatePrice.removeAll(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcAwattar) << "Update reply HTTP error:" << status << reply->errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
// check JSON file
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcAwattar) << "Update reply JSON error:" << error.errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
processPriceData(jsonDoc.toVariant().toMap());
// start user data update
m_updateUserData.append(requestUserData(m_token, m_userUuid));
} else if (m_updateUserData.contains(reply)) {
m_updateUserData.removeAll(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcAwattar) << "Update user data reply HTTP error:" << status << reply->errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
// check JSON file
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcAwattar) << "Update user data reply JSON error:" << error.errorString();
setOnlineStatus(false);
reply->deleteLater();
return;
}
setOnlineStatus(true);
processUserData(jsonDoc.toVariant().toMap());
} else if (m_searchPumpReplies.contains(reply)) {
m_searchPumpReplies.removeAll(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcAwattar) << "Search pump reply HTTP error:" << status << reply->errorString();
reply->deleteLater();
return;
}
processPumpSearchData(reply->readAll());
}
reply->deleteLater();
}
void DevicePluginAwattar::onHeatPumpReachableChanged()
{
HeatPump *pump = static_cast<HeatPump *>(sender());

View File

@ -24,6 +24,8 @@
#define DEVICEPLUGINAWATTAR_H
#include "plugin/deviceplugin.h"
#include "plugintimer.h"
#include "heatpump.h"
#include <QHash>
@ -39,17 +41,16 @@ class DevicePluginAwattar : public DevicePlugin
public:
explicit DevicePluginAwattar();
~DevicePluginAwattar();
DeviceManager::HardwareResources requiredHardware() const override;
void init() 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:
PluginTimer *m_pluginTimer = nullptr;
QPointer<Device> m_device;
QList<QPointer<HeatPump> > m_heatPumps;
@ -63,7 +64,6 @@ private:
int m_autoSgMode;
int m_manualSgMode;
QNetworkReply *requestPriceData(const QString& token);
QNetworkReply *requestUserData(const QString& token, const QString &userId);
@ -79,6 +79,8 @@ private:
bool heatPumpExists(const QHostAddress &pumpAddress);
private slots:
void onPluginTimer();
void onNetworkReplyFinished();
void onHeatPumpReachableChanged();
};

View File

@ -106,6 +106,7 @@
DevicePluginCommandLauncher::DevicePluginCommandLauncher()
{
}
DeviceManager::DeviceSetupStatus DevicePluginCommandLauncher::setupDevice(Device *device)
@ -137,11 +138,6 @@ DeviceManager::DeviceSetupStatus DevicePluginCommandLauncher::setupDevice(Device
return DeviceManager::DeviceSetupStatusFailure;
}
DeviceManager::HardwareResources DevicePluginCommandLauncher::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
DeviceManager::DeviceError DevicePluginCommandLauncher::executeAction(Device *device, const Action &action)
{
// Application

View File

@ -24,6 +24,7 @@
#define DEVICEPLUGINCOMMANDLAUNCHER_H
#include "plugin/deviceplugin.h"
#include <QProcess>
#include <QFileInfo>
@ -38,7 +39,6 @@ public:
explicit DevicePluginCommandLauncher();
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void deviceRemoved(Device *device) override;

View File

@ -46,6 +46,7 @@
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "hardware/radio433/radio433.h"
#include <QDebug>
#include <QStringList>
@ -53,11 +54,7 @@
DevicePluginConrad::DevicePluginConrad()
{
}
DeviceManager::HardwareResources DevicePluginConrad::requiredHardware() const
{
return DeviceManager::HardwareResourceRadio433;
}
DeviceManager::DeviceSetupStatus DevicePluginConrad::setupDevice(Device *device)
@ -71,6 +68,10 @@ DeviceManager::DeviceSetupStatus DevicePluginConrad::setupDevice(Device *device)
DeviceManager::DeviceError DevicePluginConrad::executeAction(Device *device, const Action &action)
{
if (!hardwareManager()->radio433()->available()) {
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
QList<int> rawData;
QByteArray binCode;
@ -119,13 +120,13 @@ DeviceManager::DeviceError DevicePluginConrad::executeAction(Device *device, con
// =======================================
// send data to driver
if(transmitData(delay, rawData, repetitions)){
if(hardwareManager()->radio433()->sendData(delay, rawData, repetitions)){
qCDebug(dcConrad) << "Transmitted successfully" << device->name() << action.actionTypeId();
return DeviceManager::DeviceErrorNoError;
}else{
qCWarning(dcConrad) << "Could not transmitt" << pluginName() << device->name() << action.actionTypeId();
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
return DeviceManager::DeviceErrorNoError;
}
void DevicePluginConrad::radioData(const QList<int> &rawData)

View File

@ -36,9 +36,8 @@ class DevicePluginConrad : public DevicePlugin
public:
explicit DevicePluginConrad();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void radioData(const QList<int> &rawData) override;
void radioData(const QList<int> &rawData);
public slots:

View File

@ -96,6 +96,8 @@
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "hardwaremanager.h"
#include "network/networkaccessmanager.h"
#include <QJsonDocument>
#include <QUrlQuery>
@ -118,11 +120,6 @@ DevicePluginDateTime::DevicePluginDateTime() :
connect(m_timer, &QTimer::timeout, this, &DevicePluginDateTime::onSecondChanged);
}
DeviceManager::HardwareResources DevicePluginDateTime::requiredHardware() const
{
return DeviceManager::HardwareResourceNetworkManager;
}
DeviceManager::DeviceSetupStatus DevicePluginDateTime::setupDevice(Device *device)
{
// check timezone
@ -243,28 +240,6 @@ DeviceManager::DeviceError DevicePluginDateTime::executeAction(Device *device, c
return DeviceManager::DeviceErrorNoError;
}
void DevicePluginDateTime::networkManagerReplyReady(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (m_locationReplies.contains(reply)) {
m_locationReplies.removeAll(reply);
if (status != 200) {
qCWarning(dcDateTime) << "Http error status for location request:" << status << reply->error();
} else {
processGeoLocationData(reply->readAll());
}
} else if (m_timeReplies.contains(reply)) {
m_timeReplies.removeAll(reply);
if (status != 200) {
qCWarning(dcDateTime) << "Http error status for time request:" << status << reply->error();
} else {
processTimesData(reply->readAll());
}
}
reply->deleteLater();
}
void DevicePluginDateTime::startMonitoringAutoDevices()
{
// foreach (Device *device, myDevices()) {
@ -285,9 +260,10 @@ void DevicePluginDateTime::searchGeoLocation()
QNetworkRequest request;
request.setUrl(QUrl("http://ip-api.com/json"));
qCDebug(dcDateTime) << "Requesting geo location.";
qCDebug(dcDateTime()) << "Requesting geo location.";
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginDateTime::onNetworkReplayFinished);
m_locationReplies.append(reply);
}
@ -340,7 +316,9 @@ void DevicePluginDateTime::getTimes(const QString &latitude, const QString &long
QNetworkRequest request;
request.setUrl(url);
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginDateTime::onNetworkReplayFinished);
m_timeReplies.append(reply);
}
@ -385,6 +363,30 @@ void DevicePluginDateTime::processTimesData(const QByteArray &data)
updateTimes();
}
void DevicePluginDateTime::onNetworkReplayFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (m_locationReplies.contains(reply)) {
m_locationReplies.removeAll(reply);
if (status != 200) {
qCWarning(dcDateTime) << "Http error status for location request:" << status << reply->error();
} else {
processGeoLocationData(reply->readAll());
}
} else if (m_timeReplies.contains(reply)) {
m_timeReplies.removeAll(reply);
if (status != 200) {
qCWarning(dcDateTime) << "Http error status for time request:" << status << reply->error();
} else {
processTimesData(reply->readAll());
}
}
reply->deleteLater();
}
void DevicePluginDateTime::onAlarm()
{
Alarm *alarm = static_cast<Alarm *>(sender());

View File

@ -42,13 +42,11 @@ class DevicePluginDateTime : public DevicePlugin
public:
explicit DevicePluginDateTime();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void postSetupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void startMonitoringAutoDevices() override;
@ -84,6 +82,7 @@ signals:
void dawn();
private slots:
void onNetworkReplayFinished();
void onAlarm();
void onCountdownTimeout();
void onCountdownRunningChanged(const bool &running);

34
debian/control vendored
View File

@ -102,21 +102,6 @@ Description: guh.io plugin for denon
This package will install the guh.io plugin for denon
Package: guh-plugin-dollhouse
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
guh-plugins-translations,
Description: guh.io plugin for dollhouse
The guh 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 guh.io plugin for dollhouse
Package: guh-plugin-elgato
Architecture: any
Depends: ${shlibs:Depends},
@ -252,21 +237,6 @@ Description: guh.io plugin for lgsmarttv
This package will install the guh.io plugin for lgsmarttv
Package: guh-plugin-lircd
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
guh-plugins-translations,
Description: guh.io plugin for lircd
The guh 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 guh.io plugin for lircd
Package: guh-plugin-mailnotification
Architecture: any
Depends: ${shlibs:Depends},
@ -536,8 +506,7 @@ Description: Plugins for guh IoT server - the default plugin collection
Package: guh-plugins-maker
Section: libs
Architecture: all
Depends: guh-plugin-lircd,
guh-plugin-commandlauncher,
Depends: guh-plugin-commandlauncher,
guh-plugin-udpcommander,
guh-plugin-tcpcommander,
guh-plugin-genericelements,
@ -557,7 +526,6 @@ Package: guh-plugins-merkurboard
Section: libs
Architecture: all
Depends: guh-plugin-osdomotics,
guh-plugin-dollhouse,
guh-plugin-plantcare,
guh-plugin-ws2812,
guh-plugin-orderbutton,

View File

@ -1 +0,0 @@
usr/lib/@DEB_HOST_MULTIARCH@/guh/plugins/libguh_deviceplugindollhouse.so

View File

@ -1 +0,0 @@
usr/lib/@DEB_HOST_MULTIARCH@/guh/plugins/libguh_devicepluginlircd.so

View File

@ -51,9 +51,15 @@ DevicePluginDenon::DevicePluginDenon()
}
DeviceManager::HardwareResources DevicePluginDenon::requiredHardware() const
DevicePluginDenon::~DevicePluginDenon()
{
return DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginDenon::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(15);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginDenon::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
@ -96,19 +102,6 @@ void DevicePluginDenon::deviceRemoved(Device *device)
m_denonConnection->deleteLater();
}
void DevicePluginDenon::guhTimer()
{
if (m_denonConnection.isNull())
return;
if (!m_denonConnection->connected()) {
m_denonConnection->connectDenon();
} else {
m_denonConnection->sendData("PW?\rSI?\rMV?\r");
}
}
DeviceManager::DeviceError DevicePluginDenon::executeAction(Device *device, const Action &action)
{
qCDebug(dcDenon) << "Execute action" << device->id() << action.id() << action.params();
@ -163,6 +156,18 @@ DeviceManager::DeviceError DevicePluginDenon::executeAction(Device *device, cons
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
void DevicePluginDenon::onPluginTimer()
{
if (m_denonConnection.isNull())
return;
if (!m_denonConnection->connected()) {
m_denonConnection->connectDenon();
} else {
m_denonConnection->sendData("PW?\rSI?\rMV?\r");
}
}
void DevicePluginDenon::onConnectionChanged()
{
if (!m_device)

View File

@ -34,6 +34,7 @@
#include <QHostAddress>
#include <QNetworkReply>
#include "plugintimer.h"
#include "denonconnection.h"
class DevicePluginDenon : public DevicePlugin
@ -45,15 +46,15 @@ class DevicePluginDenon : public DevicePlugin
public:
explicit DevicePluginDenon();
~DevicePluginDenon();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void guhTimer() override;
private:
PluginTimer *m_pluginTimer = nullptr;
QPointer<Device> m_device;
QPointer<DenonConnection> m_denonConnection;
QList<DenonConnection *> m_asyncSetups;
@ -62,6 +63,7 @@ private:
QHash <QNetworkReply *, ActionId> m_asyncActionReplies;
private slots:
void onPluginTimer();
void onConnectionChanged();
void onDataReceived(const QByteArray &data);
void onSocketError();

View File

@ -1,396 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\page dollhouse.html
\title Dollhouse
\brief Plugin for a guh demo booth based on 6LoWPAN networking.
\ingroup plugins
\ingroup guh-plugins-merkur
The plugin for the guh-dollhouse demo booth.
\chapter Plugin properties
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}.
\quotefile plugins/deviceplugins/dollhouse/deviceplugindollhouse.json
*/
#include "deviceplugindollhouse.h"
#include "plugininfo.h"
#include <QUrlQuery>
DevicePluginDollHouse::DevicePluginDollHouse() :
m_houseReachable(false)
{
m_coap = new Coap(this);
connect(m_coap, SIGNAL(replyFinished(CoapReply*)), this, SLOT(coapReplyFinished(CoapReply*)));
}
DeviceManager::HardwareResources DevicePluginDollHouse::requiredHardware() const
{
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
}
DeviceManager::DeviceSetupStatus DevicePluginDollHouse::setupDevice(Device *device)
{
qCDebug(dcDollhouse) << "Setup" << device->name() << device->params();
if (device->deviceClassId() == connectionDeviceClassId) {
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == connectionDeviceClassId) {
qCWarning(dcDollhouse) << "Dollhouse connection allready configured.";
return DeviceManager::DeviceSetupStatusFailure;
}
}
int lookupId = QHostInfo::lookupHost(device->paramValue(rplParamTypeId).toString(), this, SLOT(hostLockupFinished(QHostInfo)));
m_asyncSetup.insert(lookupId, device);
return DeviceManager::DeviceSetupStatusAsync;
} else if (device->deviceClassId() == lightDeviceClassId) {
DollhouseLight *light = new DollhouseLight(this);
light->setName(device->paramValue(nameParamTypeId).toString());
light->setHostAddress(device->paramValue(addressParamTypeId).toString());
light->setConnectionUuid(device->paramValue(connectionUuidParamTypeId).toString());
light->setLightId(device->paramValue(lightIdParamTypeId).toInt());
device->setParentId(DeviceId(light->connectionUuid()));
m_lights.insert(device, light);
return DeviceManager::DeviceSetupStatusSuccess;
}
return DeviceManager::DeviceSetupStatusFailure;
}
void DevicePluginDollHouse::deviceRemoved(Device *device)
{
if (device->deviceClassId() == lightDeviceClassId) {
DollhouseLight *light = m_lights.take(device);
light->deleteLater();
}
m_houseAddress.clear();
m_houseReachable = false;
}
void DevicePluginDollHouse::guhTimer()
{
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == connectionDeviceClassId && m_houseAddress.isNull()) {
scanNodes(device);
}
}
if (!m_houseAddress.isNull()) {
QUrl url;
url.setScheme("coap");
url.setHost(m_houseAddress.toString());
url.setPort(5683);
url.setPath("/a/ws2812");
m_asyncPings.append(m_coap->ping(CoapRequest(url)));
}
}
DeviceManager::DeviceError DevicePluginDollHouse::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() == lightDeviceClassId) {
if (!device->stateValue(reachableStateTypeId).toBool())
return DeviceManager::DeviceErrorHardwareNotAvailable;
DollhouseLight *light = m_lights.value(device);
// Create URL for action
QUrlQuery query;
query.addQueryItem("number", QString::number(light->lightId()));
QUrl url;
url.setScheme("coap");
url.setHost(device->paramValue(addressParamTypeId).toString());
url.setPath("/a/ws2812");
url.setQuery(query);
if (action.actionTypeId() == colorActionTypeId) {
QColor color = action.param(colorStateParamTypeId).value().value<QColor>().toHsv();
QColor newColor = QColor::fromHsv(color.hue(), color.saturation(), 100 * light->brightness() / 255.0);
QByteArray message = "color=" + newColor.toRgb().name().remove("#").toUtf8();
qCDebug(dcDollhouse) << "Sending" << url.toString() << message;
CoapReply *reply = m_coap->post(CoapRequest(url), message);
m_asyncActions.insert(reply, action);
m_asyncActionLights.insert(action.id(), light);
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == powerActionTypeId) {
QByteArray message;
if (action.param(powerStateParamTypeId).value().toBool()) {
QColor color = light->color().toHsv();
QColor newColor = QColor::fromHsv(color.hue(), color.saturation(), 100 * light->brightness() / 255.0);
message = "color=" + newColor.toRgb().name().remove("#").toUtf8();
} else {
message.append("color=000000");
}
qCDebug(dcDollhouse) << "Sending" << url.toString() << message;
CoapReply *reply = m_coap->post(CoapRequest(url), message);
m_asyncActions.insert(reply, action);
m_asyncActionLights.insert(action.id(), light);
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == brightnessActionTypeId) {
int brightness = action.param(brightnessStateParamTypeId).value().toInt();
QColor color = light->color().toHsv();
QColor newColor = QColor::fromHsv(color.hue(), color.saturation(), 100 * brightness / 255.0);
QByteArray message = "color=" + newColor.toRgb().name().remove("#").toUtf8();
qCDebug(dcDollhouse) << "Sending" << url.toString() << message;
CoapReply *reply = m_coap->post(CoapRequest(url), message);
m_asyncActions.insert(reply, action);
m_asyncActionLights.insert(action.id(), light);
return DeviceManager::DeviceErrorAsync;
}
}
return DeviceManager::DeviceErrorNoError;
}
void DevicePluginDollHouse::networkManagerReplyReady(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// create user finished
if (m_asyncNodeScan.contains(reply)) {
Device *device = m_asyncNodeScan.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcDollhouse) << "Node scan reply HTTP error:" << reply->errorString();
reply->deleteLater();
return;
}
parseNode(device, reply->readAll());
}
reply->deleteLater();
}
void DevicePluginDollHouse::scanNodes(Device *device)
{
QUrl url;
url.setScheme("http");
url.setHost(device->paramValue(rplParamTypeId).toString());
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
m_asyncNodeScan.insert(reply, device);
}
void DevicePluginDollHouse::parseNode(Device *device, const QByteArray &data)
{
QList<QByteArray> lines = data.split('\n');
QList<QHostAddress> addresses;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
// remove the '/128' from the address
QHostAddress address(QString(data.left(line.length() - 4)));
if (!address.isNull())
addresses.append(address);
}
// int index = data.indexOf("Routes<pre>") + 11;
// int delta = data.indexOf("/128",index);
// QHostAddress houseAddress = QHostAddress(QString(data.mid(index, delta - index)));
if (addresses.isEmpty())
return;
QHostAddress houseAddress = addresses.first();
if (houseAddress != m_houseAddress && !houseAddress.isNull()) {
m_houseAddress = houseAddress;
qCDebug(dcDollhouse) << "Found house at" << m_houseAddress.toString();
if (!m_lights.isEmpty())
return;
QList<DeviceDescriptor> deviceDescriptorList;
for (int i = 0; i < 5; i++) {
DeviceDescriptor descriptor(lightDeviceClassId, "Light", QString::number(i));
ParamList params;
params.append(Param(addressParamTypeId, m_houseAddress.toString()));
params.append(Param(lightIdParamTypeId, i));
params.append(Param(connectionUuidParamTypeId, device->id()));
switch (i) {
case 0:
params.append(Param(nameParamTypeId, "Living room"));
break;
case 1:
params.append(Param(nameParamTypeId, "Kitchen"));
break;
case 2:
params.append(Param(nameParamTypeId, "Under the bed"));
break;
case 3:
params.append(Param(nameParamTypeId, "Bedroom"));
break;
case 4:
params.append(Param(nameParamTypeId, "Dining room"));
break;
default:
params.append(Param(nameParamTypeId, QString("Light %1").arg(QString::number(i))));
break;
}
descriptor.setParams(params);
deviceDescriptorList.append(descriptor);
}
if (!deviceDescriptorList.isEmpty())
emit autoDevicesAppeared(lightDeviceClassId, deviceDescriptorList);
}
}
void DevicePluginDollHouse::hostLockupFinished(const QHostInfo &info)
{
Device *device = m_asyncSetup.value(info.lookupId());
if (!device)
return;
if (info.error() != QHostInfo::NoError) {
qCWarning(dcDollhouse) << "Could not look up host" << info.hostName() << info.errorString();
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
}
qCDebug(dcDollhouse) << "Looked up successfully" << info.hostName();
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
scanNodes(device);
}
void DevicePluginDollHouse::coapReplyFinished(CoapReply *reply)
{
if (m_asyncPings.contains(reply)) {
m_asyncPings.removeAll(reply);
if (reply->error() != CoapReply::NoError || reply->statusCode() != CoapPdu::Empty) {
if (m_houseReachable) {
qCWarning(dcDollhouse) << "Could not ping Dollhouse:" << reply->errorString();
m_houseReachable = false;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == lightDeviceClassId) {
device->setStateValue(reachableStateTypeId, m_houseReachable);
}
}
}
} else {
if (!m_houseReachable) {
qCDebug(dcDollhouse) << "Dollhouse reachable";
m_houseReachable = true;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == lightDeviceClassId) {
device->setStateValue(reachableStateTypeId, m_houseReachable);
}
}
}
}
} else if (m_asyncActions.contains(reply)) {
Action action = m_asyncActions.take(reply);
DollhouseLight *light = m_asyncActionLights.take(action.id());
if (reply->error() != CoapReply::NoError) {
qCWarning(dcDollhouse) << "Got action response with error" << reply->errorString();
emit actionExecutionFinished(action.id(), DeviceManager::DeviceErrorHardwareFailure);
reply->deleteLater();
return;
}
if (reply->statusCode() != CoapPdu::Content) {
qCWarning(dcDollhouse) << "Got action response with status code" << reply;
emit actionExecutionFinished(action.id(), DeviceManager::DeviceErrorHardwareFailure);
reply->deleteLater();
return;
}
emit actionExecutionFinished(action.id(), DeviceManager::DeviceErrorNoError);
// Set the states
if (action.actionTypeId() == powerActionTypeId) {
bool power = action.param(powerStateParamTypeId).value().toBool();
light->setPower(power);
m_lights.key(light)->setStateValue(powerStateTypeId, power);
} else if (action.actionTypeId() == colorActionTypeId) {
if (!light->power()) {
light->setPower(true);
m_lights.key(light)->setStateValue(powerStateTypeId, true);
}
QColor color = action.param(colorStateParamTypeId).value().value<QColor>();
light->setColor(color);
m_lights.key(light)->setStateValue(colorStateTypeId, color);
} else if (action.actionTypeId() == brightnessActionTypeId) {
if (!light->power()) {
light->setPower(true);
m_lights.key(light)->setStateValue(powerStateTypeId, true);
}
int brightness = action.param(brightnessStateParamTypeId).value().toInt();
light->setBrightness(brightness);
m_lights.key(light)->setStateValue(brightnessStateTypeId, brightness);
}
}
reply->deleteLater();
}

View File

@ -1,76 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DEVICEPLUGINDOLLHOUSE_H
#define DEVICEPLUGINDOLLHOUSE_H
#include "plugin/deviceplugin.h"
#include "devicemanager.h"
#include "coap/coap.h"
#include "dollhouselight.h"
#include <QHash>
class DevicePluginDollHouse : public DevicePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "deviceplugindollhouse.json")
Q_INTERFACES(DevicePlugin)
public:
DevicePluginDollHouse();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void guhTimer() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
private:
Coap *m_coap;
QHash<int, Device *> m_asyncSetup;
QHash<QNetworkReply *, Device *> m_asyncNodeScan;
QHash<CoapReply *, Action> m_asyncActions;
QHash<ActionId, DollhouseLight *> m_asyncActionLights;
QList<CoapReply *> m_asyncPings;
QHostAddress m_houseAddress;
bool m_houseReachable;
QHash<Device *, DollhouseLight *> m_lights;
void scanNodes(Device *device);
void parseNode(Device *device, const QByteArray &data);
private slots:
void hostLockupFinished(const QHostInfo &info);
void coapReplyFinished(CoapReply *reply);
};
#endif // DEVICEPLUGINDOLLHOUSE_H

View File

@ -1,126 +0,0 @@
{
"name": "Smart Dollhouse",
"idName": "Dollhouse",
"id": "ee62716c-64b5-4ec5-a877-9a8d9c1042cb",
"vendors": [
{
"name": "guh",
"idName": "guh",
"id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6",
"deviceClasses": [
{
"name": "Dollhouse Connection",
"idName": "connection",
"id": "44e12a1c-9711-4780-9913-53bb38264e1e",
"createMethods": ["user"],
"interfaces": ["gateway"],
"basicTags": [
"Device",
"Gateway"
],
"paramTypes": [
{
"id": "2015e286-4268-4a12-912f-7d70bf2d0bab",
"idName": "rpl",
"name": "RPL address",
"type": "QString",
"inputType": "TextLine",
"defaultValue": "fdaa:e9b8:d03a::ff:fe00:1"
}
]
},
{
"name": "Dollhouse Light",
"idName": "light",
"id": "b4dd5f10-36d4-4232-867a-6d3b04a08bad",
"createMethods": ["auto"],
"criticalStateTypeId": "93c539b4-50d8-431e-8be4-5ebba89452b7",
"primaryActionTypeId": "f6ac30a0-77b8-4f1f-8c44-4c2e6d542663",
"interfaces": ["colorlight"],
"basicTags": [
"Device",
"Lighting"
],
"paramTypes": [
{
"id": "49d3ae89-d76d-4e4c-b1ad-67f5c8f96e52",
"idName": "name",
"name": "name",
"type": "QString",
"defaultValue": "Dollhouse Light"
},
{
"id": "37d5d2fa-dea2-4007-99b1-a1300025c709",
"idName": "address",
"name": "address",
"type": "QString"
},
{
"id": "c843c179-ab02-4aa8-a228-fdc8d9558f1d",
"idName": "lightId",
"name": "light id",
"type": "int",
"defaultValue": 0,
"readOnly": true
},
{
"id": "2bf1d5d5-1f40-4dca-9acd-2909016e4a2b",
"idName": "connectionUuid",
"name": "connection uuid",
"type": "QString",
"inputType": "TextLine",
"readOnly": true
}
],
"stateTypes": [
{
"id": "e4885a73-9fe1-48ca-b773-aeb93f34cd54",
"idName": "color",
"name": "color",
"eventTypeName": "color changed",
"actionTypeName": "Set color",
"type": "QColor",
"defaultValue": "#fff30a",
"ruleRelevant": false,
"eventRuleRelevant": false,
"writable": true
},
{
"id": "e78c9136-c10a-45c9-b6bc-2d937f09cdec",
"idName": "brightness",
"name": "brightness",
"eventTypeName": "brightness changed",
"actionTypeName": "Set brightness",
"type": "int",
"unit": "Percentage",
"minValue": 0,
"maxValue": 100,
"defaultValue": 100,
"ruleRelevant": false,
"eventRuleRelevant": false,
"writable": true
},
{
"id": "f6ac30a0-77b8-4f1f-8c44-4c2e6d542663",
"idName": "power",
"name": "power",
"eventTypeName": "power changed",
"actionTypeName": "Set power",
"type": "bool",
"defaultValue": false,
"writable": true
},
{
"id": "93c539b4-50d8-431e-8be4-5ebba89452b7",
"idName": "reachable",
"name": "reachable",
"eventTypeName": "reachable changed",
"type": "bool",
"defaultValue": false
}
]
}
]
}
]
}

View File

@ -1,15 +0,0 @@
TRANSLATIONS = translations/en_US.ts \
translations/de_DE.ts
# Note: include after the TRANSLATIONS definition
include(../plugins.pri)
TARGET = $$qtLibraryTarget(guh_deviceplugindollhouse)
SOURCES += \
deviceplugindollhouse.cpp \
dollhouselight.cpp
HEADERS += \
deviceplugindollhouse.h \
dollhouselight.h

View File

@ -1,103 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "dollhouselight.h"
DollhouseLight::DollhouseLight(QObject *parent) :
QObject(parent),
m_color(QColor("#fff30a")),
m_brightness(100),
m_power(false)
{
}
QString DollhouseLight::name() const
{
return m_name;
}
void DollhouseLight::setName(const QString &name)
{
m_name = name;
}
QString DollhouseLight::connectionUuid() const
{
return m_connectionUuid;
}
void DollhouseLight::setConnectionUuid(const QString &connectionUuid)
{
m_connectionUuid = connectionUuid;
}
QString DollhouseLight::hostAddress() const
{
return m_hostAddress;
}
void DollhouseLight::setHostAddress(const QString &address)
{
m_hostAddress = address;
}
int DollhouseLight::lightId() const
{
return m_lightId;
}
void DollhouseLight::setLightId(const int &lightId)
{
m_lightId = lightId;
}
QColor DollhouseLight::color() const
{
return m_color;
}
void DollhouseLight::setColor(const QColor &color)
{
m_color = color;
}
int DollhouseLight::brightness() const
{
return m_brightness;
}
void DollhouseLight::setBrightness(const int &brightness)
{
m_brightness = brightness;
}
bool DollhouseLight::power() const
{
return m_power;
}
void DollhouseLight::setPower(const bool &power)
{
m_power = power;
}

View File

@ -1,69 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DOLLHOUSELIGHT_H
#define DOLLHOUSELIGHT_H
#include <QObject>
#include <QColor>
class DollhouseLight : public QObject
{
Q_OBJECT
public:
explicit DollhouseLight(QObject *parent = 0);
QString name() const;
void setName(const QString &name);
QString connectionUuid() const;
void setConnectionUuid(const QString &connectionUuid);
QString hostAddress() const;
void setHostAddress(const QString &address);
int lightId() const;
void setLightId(const int &lightId);
// properties
QColor color() const;
void setColor(const QColor &color);
int brightness() const;
void setBrightness(const int &brightness);
bool power() const;
void setPower(const bool &power);
private:
QString m_name;
QString m_connectionUuid;
QString m_hostAddress;
int m_lightId;
QColor m_color;
int m_brightness;
bool m_power;
};
#endif // DOLLHOUSELIGHT_H

View File

@ -43,6 +43,8 @@
#include "devicepluginelro.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "hardware/radio433/radio433.h"
#include <QDebug>
#include <QStringList>
@ -51,13 +53,10 @@ DevicePluginElro::DevicePluginElro()
{
}
DeviceManager::HardwareResources DevicePluginElro::requiredHardware() const
{
return DeviceManager::HardwareResourceRadio433;
}
DeviceManager::DeviceError DevicePluginElro::executeAction(Device *device, const Action &action)
{
{
if (!hardwareManager()->isAvailable(HardwareResource::TypeRadio433))
return DeviceManager::DeviceErrorHardwareNotAvailable;
if (action.actionTypeId() != powerActionTypeId)
return DeviceManager::DeviceErrorActionTypeNotFound;
@ -146,13 +145,14 @@ DeviceManager::DeviceError DevicePluginElro::executeAction(Device *device, const
}
// send data to hardware resource
if (transmitData(delay, rawData)) {
if (hardwareManager()->radio433()->sendData(delay, rawData, 10)) {
qCDebug(dcElro) << "Transmitted" << pluginName() << device->name() << "power: " << action.param(powerParamTypeId).value().toBool();
return DeviceManager::DeviceErrorNoError;
} else {
qCWarning(dcElro) << "Could not transmitt" << pluginName() << device->name() << "power: " << action.param(powerParamTypeId).value().toBool();
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
return DeviceManager::DeviceErrorNoError;
}
void DevicePluginElro::radioData(const QList<int> &rawData)

View File

@ -35,8 +35,7 @@ class DevicePluginElro : public DevicePlugin
public:
explicit DevicePluginElro();
DeviceManager::HardwareResources requiredHardware() const override;
void radioData(const QList<int> &rawData) override;
void radioData(const QList<int> &rawData);
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;

View File

@ -73,14 +73,21 @@
DevicePluginEQ3::DevicePluginEQ3()
{
m_cubeDiscovery = new MaxCubeDiscovery(this);
connect(m_cubeDiscovery,SIGNAL(cubesDetected(QList<MaxCube*>)),this,SLOT(discoveryDone(QList<MaxCube*>)));
}
DeviceManager::HardwareResources DevicePluginEQ3::requiredHardware() const
DevicePluginEQ3::~DevicePluginEQ3()
{
return DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginEQ3::init()
{
m_cubeDiscovery = new MaxCubeDiscovery(this);
connect(m_cubeDiscovery, &MaxCubeDiscovery::cubesDetected, this, &DevicePluginEQ3::discoveryDone);
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginEQ3::onPluginTimer);
}
DeviceManager::DeviceError DevicePluginEQ3::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
@ -145,15 +152,6 @@ void DevicePluginEQ3::deviceRemoved(Device *device)
cube->deleteLater();
}
void DevicePluginEQ3::guhTimer()
{
foreach (MaxCube *cube, m_cubes.keys()){
if(cube->isConnected() && cube->isInitialized()){
cube->refresh();
}
}
}
DeviceManager::DeviceError DevicePluginEQ3::executeAction(Device *device, const Action &action)
{
if(device->deviceClassId() == wallThermostateDeviceClassId || device->deviceClassId() == radiatorThermostateDeviceClassId){
@ -182,6 +180,15 @@ DeviceManager::DeviceError DevicePluginEQ3::executeAction(Device *device, const
return DeviceManager::DeviceErrorActionTypeNotFound;
}
void DevicePluginEQ3::onPluginTimer()
{
foreach (MaxCube *cube, m_cubes.keys()){
if(cube->isConnected() && cube->isInitialized()){
cube->refresh();
}
}
}
void DevicePluginEQ3::cubeConnectionStatusChanged(const bool &connected)
{
if(connected){

View File

@ -25,6 +25,7 @@
#include "plugin/deviceplugin.h"
#include "maxcubediscovery.h"
#include "plugintimer.h"
#include <QHostAddress>
@ -39,25 +40,27 @@ class DevicePluginEQ3: public DevicePlugin
public:
explicit DevicePluginEQ3();
~DevicePluginEQ3();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
void startMonitoringAutoDevices() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void guhTimer() override;
private:
PluginTimer *m_pluginTimer = nullptr;
QList<Param> m_config;
MaxCubeDiscovery *m_cubeDiscovery;
QHash<MaxCube*, Device*> m_cubes;
MaxCubeDiscovery *m_cubeDiscovery = nullptr;
QHash<MaxCube *, Device *> m_cubes;
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action);
private slots:
void onPluginTimer();
void cubeConnectionStatusChanged(const bool &connected);
void discoveryDone(const QList<MaxCube *> &cubeList);
void commandActionFinished(const bool &succeeded, const ActionId &actionId);

View File

@ -62,11 +62,6 @@ DevicePluginGenericElements::DevicePluginGenericElements()
{
}
DeviceManager::HardwareResources DevicePluginGenericElements::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
DeviceManager::DeviceSetupStatus DevicePluginGenericElements::setupDevice(Device *device)
{
// Toggle Button

View File

@ -34,11 +34,8 @@ class DevicePluginGenericElements : public DevicePlugin
public:
explicit DevicePluginGenericElements();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;

View File

@ -211,11 +211,6 @@ DeviceManager::DeviceError DevicePluginGpio::discoverDevices(const DeviceClassId
return DeviceManager::DeviceErrorVendorNotFound;
}
DeviceManager::HardwareResources DevicePluginGpio::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
void DevicePluginGpio::deviceRemoved(Device *device)
{
if (m_gpioDevices.values().contains(device)) {

View File

@ -41,7 +41,6 @@ public:
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::HardwareResources requiredHardware() const override;
void deviceRemoved(Device *device) override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;

View File

@ -6,7 +6,6 @@ PLUGIN_DIRS = \
networkdetector \
conrad \
openweathermap \
lircd \
wakeonlan \
mailnotification \
philipshue \
@ -21,17 +20,16 @@ PLUGIN_DIRS = \
udpcommander \
tcpcommander \
kodi \
elgato \
#elgato \
awattar \
netatmo \
dollhouse \
plantcare \
osdomotics \
ws2812 \
orderbutton \
denon \
avahimonitor \
senic \
#senic \
gpio \

View File

@ -44,6 +44,7 @@
#include "plugin/device.h"
#include "devicemanager.h"
#include "hardware/radio433/radio433.h"
#include "plugininfo.h"
#include <QDebug>
@ -51,15 +52,15 @@
DevicePluginIntertechno::DevicePluginIntertechno()
{
}
DeviceManager::HardwareResources DevicePluginIntertechno::requiredHardware() const
{
return DeviceManager::HardwareResourceRadio433;
}
DeviceManager::DeviceError DevicePluginIntertechno::executeAction(Device *device, const Action &action)
{
if (!hardwareManager()->isAvailable(HardwareResource::TypeRadio433))
return DeviceManager::DeviceErrorHardwareNotAvailable;
QList<int> rawData;
QByteArray binCode;
@ -175,13 +176,13 @@ DeviceManager::DeviceError DevicePluginIntertechno::executeAction(Device *device
// =======================================
// send data to hardware resource
if (transmitData(delay, rawData)) {
if (hardwareManager()->radio433()->sendData(delay, rawData, 10)) {
qCDebug(dcIntertechno) << "transmitted" << pluginName() << device->name() << "power: " << action.param(powerParamTypeId).value().toBool();
return DeviceManager::DeviceErrorNoError;
} else {
qCWarning(dcIntertechno) << "could not transmitt" << pluginName() << device->name() << "power: " << action.param(powerParamTypeId).value().toBool();
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
return DeviceManager::DeviceErrorNoError;
}
void DevicePluginIntertechno::radioData(const QList<int> &rawData)

View File

@ -35,8 +35,7 @@ class DevicePluginIntertechno : public DevicePlugin
public:
explicit DevicePluginIntertechno();
DeviceManager::HardwareResources requiredHardware() const override;
void radioData(const QList<int> &rawData) override;
void radioData(const QList<int> &rawData);
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;

View File

@ -64,6 +64,7 @@
#include "devicepluginkodi.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "network/upnp/upnpdiscovery.h"
DevicePluginKodi::DevicePluginKodi()
{
@ -79,12 +80,18 @@ DevicePluginKodi::DevicePluginKodi()
// qCWarning(dcKodi) << "could not read" << file.fileName();
// return;
// }
// m_logo = guhLogoByteArray;
// m_logo = guhLogoByteArray;
}
DeviceManager::HardwareResources DevicePluginKodi::requiredHardware() const
DevicePluginKodi::~DevicePluginKodi()
{
return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceUpnpDisovery;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginKodi::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginKodi::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
@ -117,59 +124,18 @@ void DevicePluginKodi::deviceRemoved(Device *device)
kodi->deleteLater();
}
void DevicePluginKodi::guhTimer()
{
foreach (Kodi *kodi, m_kodis.keys()) {
if (!kodi->connected()) {
kodi->connectKodi();
continue;
} else {
// no need for polling information, notifications do the job
//kodi->update();
}
}
}
DeviceManager::DeviceError DevicePluginKodi::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
Q_UNUSED(deviceClassId)
qCDebug(dcKodi) << "Start UPnP search";
upnpDiscover();
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices();
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginKodi::onUpnpDiscoveryFinished);
return DeviceManager::DeviceErrorAsync;
}
void DevicePluginKodi::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList)
{
QList<DeviceDescriptor> deviceDescriptors;
foreach (const UpnpDeviceDescriptor &upnpDescriptor, upnpDeviceDescriptorList) {
if (upnpDescriptor.modelName().contains("Kodi")) {
// check if we allready found the kodi on this ip
bool alreadyAdded = false;
foreach (const DeviceDescriptor dDescriptor, deviceDescriptors) {
if (dDescriptor.params().paramValue(ipParamTypeId).toString() == upnpDescriptor.hostAddress().toString()) {
alreadyAdded = true;
break;
}
}
if (alreadyAdded)
continue;
qCDebug(dcKodi) << upnpDescriptor;
DeviceDescriptor deviceDescriptor(kodiDeviceClassId, "Kodi - Media Center", upnpDescriptor.hostAddress().toString());
ParamList params;
params.append(Param(nameParamTypeId, upnpDescriptor.friendlyName()));
params.append(Param(ipParamTypeId, upnpDescriptor.hostAddress().toString()));
params.append(Param(portParamTypeId, 9090));
deviceDescriptor.setParams(params);
deviceDescriptors.append(deviceDescriptor);
}
}
emit devicesDiscovered(kodiDeviceClassId, deviceDescriptors);
}
DeviceManager::DeviceError DevicePluginKodi::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() == kodiDeviceClassId) {
@ -207,6 +173,53 @@ DeviceManager::DeviceError DevicePluginKodi::executeAction(Device *device, const
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
void DevicePluginKodi::onPluginTimer()
{
foreach (Kodi *kodi, m_kodis.keys()) {
if (!kodi->connected()) {
kodi->connectKodi();
continue;
}
}
}
void DevicePluginKodi::onUpnpDiscoveryFinished()
{
qCDebug(dcKodi()) << "Upnp discovery finished";
UpnpDiscoveryReply *reply = static_cast<UpnpDiscoveryReply *>(sender());
if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) {
qCWarning(dcKodi()) << "Upnp discovery error" << reply->error();
}
reply->deleteLater();
QList<DeviceDescriptor> deviceDescriptors;
foreach (const UpnpDeviceDescriptor &upnpDescriptor, reply->deviceDescriptors()) {
if (upnpDescriptor.modelName().contains("Kodi")) {
// check if we allready found the kodi on this ip
bool alreadyAdded = false;
foreach (const DeviceDescriptor dDescriptor, deviceDescriptors) {
if (dDescriptor.params().paramValue(ipParamTypeId).toString() == upnpDescriptor.hostAddress().toString()) {
alreadyAdded = true;
break;
}
}
if (alreadyAdded)
continue;
qCDebug(dcKodi) << upnpDescriptor;
DeviceDescriptor deviceDescriptor(kodiDeviceClassId, "Kodi - Media Center", upnpDescriptor.hostAddress().toString());
ParamList params;
params.append(Param(nameParamTypeId, upnpDescriptor.friendlyName()));
params.append(Param(ipParamTypeId, upnpDescriptor.hostAddress().toString()));
params.append(Param(portParamTypeId, 9090));
deviceDescriptor.setParams(params);
deviceDescriptors.append(deviceDescriptor);
}
}
emit devicesDiscovered(kodiDeviceClassId, deviceDescriptors);
}
void DevicePluginKodi::onConnectionChanged()
{
Kodi *kodi = static_cast<Kodi *>(sender());

View File

@ -24,6 +24,7 @@
#define DEVICEPLUGINKODI_H
#include "plugin/deviceplugin.h"
#include "plugintimer.h"
#include "kodi.h"
#include <QHash>
@ -38,23 +39,22 @@ class DevicePluginKodi : public DevicePlugin
public:
explicit DevicePluginKodi();
~DevicePluginKodi();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void guhTimer() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
PluginTimer *m_pluginTimer;
QHash<Kodi *, Device *> m_kodis;
QList<Kodi *> m_asyncSetups;
private slots:
void onPluginTimer();
void onUpnpDiscoveryFinished();
void onConnectionChanged();
void onStateChanged();
void onActionExecuted(const ActionId &actionId, const bool &success);

View File

@ -49,6 +49,7 @@
#include "devicepluginleynew.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "hardware/radio433/radio433.h"
#include <QDebug>
#include <QStringList>
@ -64,13 +65,11 @@ DeviceManager::DeviceSetupStatus DevicePluginLeynew::setupDevice(Device *device)
return DeviceManager::DeviceSetupStatusSuccess;
}
DeviceManager::HardwareResources DevicePluginLeynew::requiredHardware() const
{
return DeviceManager::HardwareResourceRadio433;
}
DeviceManager::DeviceError DevicePluginLeynew::executeAction(Device *device, const Action &action)
{
if (!hardwareManager()->radio433()->available()) {
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
if (device->deviceClassId() != rfControllerDeviceClassId) {
return DeviceManager::DeviceErrorDeviceClassNotFound;
@ -170,11 +169,11 @@ DeviceManager::DeviceError DevicePluginLeynew::executeAction(Device *device, con
// =======================================
// send data to hardware resource
if(transmitData(delay, rawData, repetitions)){
if(hardwareManager()->radio433()->sendData(delay, rawData, repetitions)){
qCDebug(dcLeynew) << "Transmitted" << pluginName() << device->name() << action.id();
return DeviceManager::DeviceErrorNoError;
}else{
qCWarning(dcLeynew) << "Could not transmitt" << pluginName() << device->name() << action.id();
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
return DeviceManager::DeviceErrorNoError;
}

View File

@ -36,7 +36,6 @@ public:
explicit DevicePluginLeynew();
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::HardwareResources requiredHardware() const override;
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;

View File

@ -45,6 +45,9 @@
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
#include "network/upnp/upnpdiscovery.h"
#include "hardwaremanager.h"
#include <QDebug>
@ -52,22 +55,25 @@ DevicePluginLgSmartTv::DevicePluginLgSmartTv()
{
}
DeviceManager::HardwareResources DevicePluginLgSmartTv::requiredHardware() const
DevicePluginLgSmartTv::~DevicePluginLgSmartTv()
{
return DeviceManager::HardwareResourceTimer |
DeviceManager::HardwareResourceUpnpDisovery |
DeviceManager::HardwareResourceNetworkManager;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginLgSmartTv::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(15);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginLgSmartTv::onPluginTimer);
}
DeviceManager::DeviceError DevicePluginLgSmartTv::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
Q_UNUSED(deviceClassId)
if(deviceClassId != lgSmartTvDeviceClassId){
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
qCDebug(dcLgSmartTv) << "Start discovering";
upnpDiscover("udap:rootservice","UDAP/2.0");
qCDebug(dcLgSmartTv()) << "Start discovering";
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices("udap:rootservice","UDAP/2.0");
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginLgSmartTv::onUpnpDiscoveryFinished);
return DeviceManager::DeviceErrorAsync;
}
@ -121,10 +127,206 @@ void DevicePluginLgSmartTv::deviceRemoved(Device *device)
delete tvDevice;
}
void DevicePluginLgSmartTv::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList)
DeviceManager::DeviceError DevicePluginLgSmartTv::executeAction(Device *device, const Action &action)
{
TvDevice * tvDevice = m_tvList.key(device);
if (!tvDevice->reachable()) {
qCWarning(dcLgSmartTv) << "Device not reachable";
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
if (action.actionTypeId() == commandVolumeUpActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::VolUp);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandVolumeDownActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::VolDown);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandMuteActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Mute);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandChannelUpActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ChannelUp);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandChannelDownActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ChannelDown);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandPowerOffActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Power);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowUpActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Up);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowDownActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Down);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowLeftActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Left);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowRightActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Right);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandOkActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Ok);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandBackActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Back);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandHomeActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Home);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandInputSourceActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ExternalInput);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandExitActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Exit);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandInfoActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Info);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandMyAppsActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::MyApps);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandProgramListActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ProgramList);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_asyncActions.insert(reply, action.id());
} else {
return DeviceManager::DeviceErrorActionTypeNotFound;
}
return DeviceManager::DeviceErrorAsync;
}
DeviceManager::DeviceError DevicePluginLgSmartTv::displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor)
{
Q_UNUSED(pairingTransactionId)
QHostAddress host = QHostAddress(deviceDescriptor.params().paramValue(hostAddressParamTypeId).toString());
int port = deviceDescriptor.params().paramValue(portParamTypeId).toInt();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createDisplayKeyRequest(host, port);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_showPinReply.append(reply);
return DeviceManager::DeviceErrorNoError;
}
DeviceManager::DeviceSetupStatus DevicePluginLgSmartTv::confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params, const QString &secret)
{
Q_UNUSED(deviceClassId)
QHostAddress host = QHostAddress(params.paramValue(hostAddressParamTypeId).toString());
int port = params.paramValue(portParamTypeId).toInt();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createPairingRequest(host, port, secret);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_setupPairingTv.insert(reply, pairingTransactionId);
m_tvKeys.insert(params.paramValue(uuidParamTypeId).toString(), secret);
return DeviceManager::DeviceSetupStatusAsync;
}
void DevicePluginLgSmartTv::pairTvDevice(Device *device, const bool &setup)
{
QHostAddress host = QHostAddress(device->paramValue(hostAddressParamTypeId).toString());
int port = device->paramValue(portParamTypeId).toInt();
QString key = device->paramValue(keyParamTypeId).toString();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createPairingRequest(host, port, key);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
if (setup) {
m_asyncSetup.insert(reply, device);
} else {
m_pairRequests.insert(reply, device);
}
}
void DevicePluginLgSmartTv::unpairTvDevice(Device *device)
{
QHostAddress host = QHostAddress(device->paramValue(hostAddressParamTypeId).toString());
int port = device->paramValue(portParamTypeId).toInt();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createEndPairingRequest(host, port);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_deleteTv.append(reply);
}
void DevicePluginLgSmartTv::refreshTv(Device *device)
{
TvDevice *tv = m_tvList.key(device);
// check volume information
QNetworkReply *volumeReply = hardwareManager()->networkManager()->get(tv->createVolumeInformationRequest());
connect(volumeReply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_volumeInfoRequests.insert(volumeReply, device);
// check channel information
QNetworkReply *channelReply = hardwareManager()->networkManager()->get(tv->createChannelInformationRequest());
connect(channelReply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_channelInfoRequests.insert(channelReply, device);
}
void DevicePluginLgSmartTv::onPluginTimer()
{
foreach (Device *device, m_tvList.values()) {
TvDevice *tv = m_tvList.key(device);
if (tv->paired()) {
refreshTv(device);
} else {
pairTvDevice(device);
}
}
}
void DevicePluginLgSmartTv::onUpnpDiscoveryFinished()
{
qCDebug(dcLgSmartTv()) << "Upnp discovery finished";
UpnpDiscoveryReply *reply = static_cast<UpnpDiscoveryReply *>(sender());
if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) {
qCWarning(dcLgSmartTv()) << "Upnp discovery error" << reply->error();
}
reply->deleteLater();
QList<DeviceDescriptor> deviceDescriptors;
foreach (UpnpDeviceDescriptor upnpDeviceDescriptor, upnpDeviceDescriptorList) {
foreach (UpnpDeviceDescriptor upnpDeviceDescriptor, reply->deviceDescriptors()) {
if (!upnpDeviceDescriptor.friendlyName().contains("LG") || !upnpDeviceDescriptor.deviceType().contains("TV"))
continue;
qCDebug(dcLgSmartTv) << upnpDeviceDescriptor;
@ -140,125 +342,13 @@ void DevicePluginLgSmartTv::upnpDiscoveryFinished(const QList<UpnpDeviceDescript
deviceDescriptors.append(descriptor);
}
emit devicesDiscovered(lgSmartTvDeviceClassId, deviceDescriptors);
}
DeviceManager::DeviceError DevicePluginLgSmartTv::executeAction(Device *device, const Action &action)
void DevicePluginLgSmartTv::onNetworkManagerReplyFinished()
{
TvDevice * tvDevice = m_tvList.key(device);
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
if (!tvDevice->reachable()) {
qCWarning(dcLgSmartTv) << "Device not reachable";
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
if (action.actionTypeId() == commandVolumeUpActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::VolUp);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandVolumeDownActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::VolDown);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandMuteActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Mute);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandChannelUpActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ChannelUp);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandChannelDownActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ChannelDown);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandPowerOffActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Power);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowUpActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Up);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowDownActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Down);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowLeftActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Left);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandArrowRightActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Right);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandOkActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Ok);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandBackActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Back);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandHomeActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Home);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandInputSourceActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ExternalInput);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandExitActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Exit);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandInfoActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::Info);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandMyAppsActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::MyApps);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else if(action.actionTypeId() == commandProgramListActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = tvDevice->createPressButtonRequest(TvDevice::ProgramList);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_asyncActions.insert(reply, action.id());
} else {
return DeviceManager::DeviceErrorActionTypeNotFound;
}
return DeviceManager::DeviceErrorAsync;
}
DeviceManager::DeviceError DevicePluginLgSmartTv::displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor)
{
Q_UNUSED(pairingTransactionId)
QHostAddress host = QHostAddress(deviceDescriptor.params().paramValue(hostAddressParamTypeId).toString());
int port = deviceDescriptor.params().paramValue(portParamTypeId).toInt();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createDisplayKeyRequest(host, port);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_showPinReply.append(reply);
return DeviceManager::DeviceErrorNoError;
}
DeviceManager::DeviceSetupStatus DevicePluginLgSmartTv::confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params, const QString &secret)
{
Q_UNUSED(deviceClassId)
QHostAddress host = QHostAddress(params.paramValue(hostAddressParamTypeId).toString());
int port = params.paramValue(portParamTypeId).toInt();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createPairingRequest(host, port, secret);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_setupPairingTv.insert(reply, pairingTransactionId);
m_tvKeys.insert(params.paramValue(uuidParamTypeId).toString(), secret);
return DeviceManager::DeviceSetupStatusAsync;
}
void DevicePluginLgSmartTv::networkManagerReplyReady(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (m_showPinReply.contains(reply)) {
@ -274,7 +364,8 @@ void DevicePluginLgSmartTv::networkManagerReplyReady(QNetworkReply *reply)
} else {
// End pairing before calling setupDevice, which will always try to pair
QPair<QNetworkRequest, QByteArray> request = TvDevice::createEndPairingRequest(reply->request().url());
QNetworkReply *reply = networkManagerPost(request.first, request.second);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginLgSmartTv::onNetworkManagerReplyFinished);
m_setupEndPairingTv.insert(reply, pairingTransactionId);
}
} else if (m_setupEndPairingTv.keys().contains(reply)) {
@ -337,54 +428,6 @@ void DevicePluginLgSmartTv::networkManagerReplyReady(QNetworkReply *reply)
reply->deleteLater();
}
void DevicePluginLgSmartTv::guhTimer()
{
foreach (Device *device, m_tvList.values()) {
TvDevice *tv = m_tvList.key(device);
if (tv->paired()) {
refreshTv(device);
} else {
pairTvDevice(device);
}
}
}
void DevicePluginLgSmartTv::pairTvDevice(Device *device, const bool &setup)
{
QHostAddress host = QHostAddress(device->paramValue(hostAddressParamTypeId).toString());
int port = device->paramValue(portParamTypeId).toInt();
QString key = device->paramValue(keyParamTypeId).toString();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createPairingRequest(host, port, key);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
if (setup) {
m_asyncSetup.insert(reply, device);
} else {
m_pairRequests.insert(reply, device);
}
}
void DevicePluginLgSmartTv::unpairTvDevice(Device *device)
{
QHostAddress host = QHostAddress(device->paramValue(hostAddressParamTypeId).toString());
int port = device->paramValue(portParamTypeId).toInt();
QPair<QNetworkRequest, QByteArray> request = TvDevice::createEndPairingRequest(host, port);
QNetworkReply *reply = networkManagerPost(request.first, request.second);
m_deleteTv.append(reply);
}
void DevicePluginLgSmartTv::refreshTv(Device *device)
{
TvDevice *tv = m_tvList.key(device);
// check volume information
QNetworkReply *volumeReply = networkManagerGet(tv->createVolumeInformationRequest());
m_volumeInfoRequests.insert(volumeReply, device);
// check channel information
QNetworkReply *channelReply = networkManagerGet(tv->createChannelInformationRequest());
m_channelInfoRequests.insert(channelReply, device);
}
void DevicePluginLgSmartTv::stateChanged()
{
TvDevice *tvDevice = static_cast<TvDevice*>(sender());

View File

@ -23,8 +23,9 @@
#ifndef DEVICEPLUGINLGSMARTTV_H
#define DEVICEPLUGINLGSMARTTV_H
#include "plugin/deviceplugin.h"
#include "tvdevice.h"
#include "plugintimer.h"
#include "plugin/deviceplugin.h"
#include "network/upnp/upnpdevicedescriptor.h"
class DevicePluginLgSmartTv : public DevicePlugin
@ -36,23 +37,19 @@ class DevicePluginLgSmartTv : public DevicePlugin
public:
explicit DevicePluginLgSmartTv();
~DevicePluginLgSmartTv();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
DeviceManager::DeviceError displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor) override;
DeviceManager::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params, const QString &secret) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void guhTimer() override;
private:
PluginTimer *m_pluginTimer = nullptr;
QHash<TvDevice *, Device *> m_tvList;
QHash<QString, QString> m_tvKeys;
@ -78,6 +75,9 @@ private:
void refreshTv(Device *device);
private slots:
void onPluginTimer();
void onUpnpDiscoveryFinished();
void onNetworkManagerReplyFinished();
void stateChanged();
};

View File

@ -1,104 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\page lirc.html
\title LIRC
\brief Plugin for the LIRC infrared daemon.
\ingroup plugins
\ingroup guh-plugins-maker
This plugin allows to interact with \l{http://www.lirc.org/}{LIRC} daemon and controll commonly used remote controls.
If lircd (LIRC daemon) is configured on your system, guh will connect to the lirc daemon and all configured remote
controls of lircd will appear in guh.
\chapter Plugin properties
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}.
\quotefile plugins/deviceplugins/lircd/devicepluginlircd.json
*/
#include "devicepluginlircd.h"
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "lircdclient.h"
#include <QDebug>
#include <QStringList>
DeviceClassId lircdDeviceClassId = DeviceClassId("5c2bc4cd-ba6c-4052-b6cd-1db83323ea22");
EventTypeId LircKeypressEventTypeId = EventTypeId("8711471a-fa0e-410b-b174-dfc3d2aeffb1");
DevicePluginLircd::DevicePluginLircd()
{
m_lircClient = new LircClient(this);
//m_lircClient->connect();
connect(m_lircClient, &LircClient::buttonPressed, this, &DevicePluginLircd::buttonPressed);
}
DeviceManager::HardwareResources DevicePluginLircd::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
void DevicePluginLircd::buttonPressed(const QString &remoteName, const QString &buttonName, int repeat)
{
Device *remote = nullptr;
QList<Device*> configuredRemotes = deviceManager()->findConfiguredDevices(lircdDeviceClassId);
foreach (Device *device, configuredRemotes) {
if (device->paramValue(nameParamTypeId).toString() == remoteName) {
remote = device;
break;
}
}
if (!remote) {
qCWarning(dcLircd) << "Unhandled remote" << remoteName << buttonName;
return;
}
qCDebug(dcLircd) << "found remote" << remoteName << supportedDevices().first().eventTypes().count();
ParamList params;
Param buttonParam(buttonParamTypeId, buttonName);
params.append(buttonParam);
Param repeatParam(repeatParamTypeId, repeat);
params.append(repeatParam);
Event event(LircKeypressEventTypeId, remote->id(), params);
emitEvent(event);
}
//QVariantMap DevicePluginLircd::configuration() const
//{
// return m_config;
//}
//void DevicePluginLircd::setConfiguration(const QVariantMap &configuration)
//{
// m_config = configuration;
//}

View File

@ -1,56 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DEVICEPLUGINLIRCD_H
#define DEVICEPLUGINLIRCD_H
#include "plugin/deviceplugin.h"
#include <QProcess>
class LircClient;
class DevicePluginLircd: public DevicePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginlircd.json")
Q_INTERFACES(DevicePlugin)
public:
explicit DevicePluginLircd();
DeviceManager::HardwareResources requiredHardware() const override;
// QVariantMap configuration() const override;
// void setConfiguration(const QVariantMap &configuration) override;
private slots:
void buttonPressed(const QString &remoteName, const QString &buttonName, int repeat);
private:
LircClient *m_lircClient;
// QVariantMap m_config;
};
#endif // DEVICEPLUGINBOLIRCD_H

View File

@ -1,55 +0,0 @@
{
"name": "Lirc receiver",
"idName": "Lircd",
"id": "075f734f-4d76-4ce3-9ef8-34c212285676",
"vendors": [
{
"name": "Lirc",
"idName": "lirc",
"id": "9a53049c-8828-4b87-b3f6-7bc7708196cd",
"deviceClasses": [
{
"id": "5c2bc4cd-ba6c-4052-b6cd-1db83323ea22",
"idName": "irReceiver",
"name": "IR receiver",
"basicTags": [
"Service",
"Actuator",
"Multimedia"
],
"createMethods": ["user"],
"paramTypes": [
{
"id": "06704d73-66d1-486b-bc0b-0346534983a1",
"idName": "name",
"name": "remoteName",
"type": "QString",
"inputType": "TextLine"
}
],
"eventTypes": [
{
"id": "8711471a-fa0e-410b-b174-dfc3d2aeffb1",
"idName": "buttonPressed",
"name": "button pressed",
"paramTypes": [
{
"id": "a6344673-17f5-4a37-b59e-f342a2877909",
"idName": "button",
"name": "button",
"type": "QString"
},
{
"id": "a98d9348-1154-45c6-a163-c9f0477be626",
"idName": "repeat",
"name": "repeat",
"type": "int"
}
]
}
]
}
]
}
]
}

View File

@ -1,20 +0,0 @@
TRANSLATIONS = translations/en_US.ts \
translations/de_DE.ts
# Note: include after the TRANSLATIONS definition
include(../plugins.pri)
TARGET = $$qtLibraryTarget(guh_devicepluginlircd)
QT += network
SOURCES += \
devicepluginlircd.cpp \
lircdclient.cpp \
HEADERS += \
devicepluginlircd.h \
lircdclient.h \

View File

@ -1,95 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "lircdclient.h"
#include "extern-plugininfo.h"
#include <QDebug>
#include <QLocalSocket>
LircClient::LircClient(QObject *parent) :
QObject(parent)
{
m_socket = new QLocalSocket(this);
QObject::connect(m_socket, &QLocalSocket::readyRead, this, &LircClient::readyRead);
}
bool LircClient::connect()
{
m_socket->connectToServer("/var/run/lirc/lircd", QIODevice::ReadWrite);
if (!m_socket->isOpen()) {
qCWarning(dcLircd) << "--> Lirc daemon NOT available.";
return false;
}
m_socket->write("LIST\n");
qCDebug(dcLircd) << "--> Lirc daemon available.";
return true;
}
void LircClient::readyRead()
{
qCDebug(dcLircd) << "got data" << m_socket->readAll();
bool inBlock = false;
while (m_socket->canReadLine()) {
QByteArray line = m_socket->readLine().trimmed();
qCDebug(dcLircd) << "got line:" << line;
if (line == "BEGIN") {
inBlock = true;
continue;
}
if (line == "LIST") {
if (m_socket->readLine().trimmed() == "SUCCESS") {
readRemotes();
} else {
qCWarning(dcLircd) << "Error reading remotes from Lircd";
}
continue;
}
if ( line == "END") {
inBlock = false;
continue;
}
if (!inBlock) {
QList<QByteArray> parts = line.split(' ');
if (parts.count() != 4) {
qCWarning(dcLircd) << "Don't understand IR command. ignoring...";
continue;
}
qCDebug(dcLircd) << "emitting buttonpress";
emit buttonPressed(QString(parts.at(3)), QString(parts.at(2)), parts.at(1).toInt());
}
}
}
void LircClient::readRemotes()
{
m_socket->readLine(); // IGNORE DATA
int remoteCount = m_socket->readLine().trimmed().toInt();
qCDebug(dcLircd) << "found" << remoteCount << "lirc remotes";
for (int i = 0; i < remoteCount; i++) {
QByteArray line = m_socket->readLine().trimmed();
m_remotes.append(line);
}
}

View File

@ -1,53 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
* *
* This file is part of guh. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef LIRCCLIENT_H
#define LIRCCLIENT_H
#include <QObject>
#include <QLocalSocket>
#include <QStringList>
class LircClient : public QObject
{
Q_OBJECT
public:
explicit LircClient(QObject *parent = 0);
bool connect();
signals:
void buttonPressed(const QString &remoteName, const QString &buttonName, int repeat);
private slots:
void readyRead();
private:
void readRemotes();
private:
QLocalSocket *m_socket;
QStringList m_remotes;
};
#endif // LIRCCLIENT_H

View File

@ -164,11 +164,6 @@ DeviceManager::DeviceSetupStatus DevicePluginMailNotification::setupDevice(Devic
return DeviceManager::DeviceSetupStatusFailure;
}
DeviceManager::HardwareResources DevicePluginMailNotification::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
DeviceManager::DeviceError DevicePluginMailNotification::executeAction(Device *device, const Action &action)
{
if(action.actionTypeId() == sendMailActionTypeId) {

View File

@ -38,7 +38,6 @@ public:
~DevicePluginMailNotification();
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void deviceRemoved(Device *device) override;

View File

@ -42,6 +42,7 @@
#include "devicepluginnetatmo.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
#include <QDebug>
#include <QUrlQuery>
@ -52,9 +53,15 @@ DevicePluginNetatmo::DevicePluginNetatmo()
}
DeviceManager::HardwareResources DevicePluginNetatmo::requiredHardware() const
DevicePluginNetatmo::~DevicePluginNetatmo()
{
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginNetatmo::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(30);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginNetatmo::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginNetatmo::setupDevice(Device *device)
@ -119,49 +126,6 @@ void DevicePluginNetatmo::deviceRemoved(Device *device)
}
}
void DevicePluginNetatmo::networkManagerReplyReady(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// update values request
if (m_refreshRequest.keys().contains(reply)) {
Device *device = m_refreshRequest.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcNetatmo) << "Device list reply HTTP error:" << status << reply->errorString();
device->setStateValue(availableStateTypeId, false);
reply->deleteLater();
return;
}
// check JSON file
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcNetatmo) << "Device list reply JSON error:" << error.errorString();
reply->deleteLater();
return;
}
//qCDebug(dcNetatmo) << jsonDoc.toJson();
processRefreshData(jsonDoc.toVariant().toMap(), device->id().toString());
}
reply->deleteLater();
}
void DevicePluginNetatmo::guhTimer()
{
foreach (OAuth2 *authentication, m_authentications.keys()) {
if (authentication->authenticated()) {
refreshData(m_authentications.value(authentication), authentication->token());
} else {
authentication->startAuthentication();
}
}
}
DeviceManager::DeviceError DevicePluginNetatmo::executeAction(Device *device, const Action &action)
{
Q_UNUSED(device)
@ -178,7 +142,9 @@ void DevicePluginNetatmo::refreshData(Device *device, const QString &token)
QUrl url("https://api.netatmo.com/api/devicelist");
url.setQuery(query);
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginNetatmo::onNetworkReplyFinished);
m_refreshRequest.insert(reply, device);
}
@ -267,6 +233,50 @@ Device *DevicePluginNetatmo::findOutdoorDevice(const QString &macAddress)
return 0;
}
void DevicePluginNetatmo::onPluginTimer()
{
foreach (OAuth2 *authentication, m_authentications.keys()) {
if (authentication->authenticated()) {
refreshData(m_authentications.value(authentication), authentication->token());
} else {
authentication->startAuthentication();
}
}
}
void DevicePluginNetatmo::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// update values request
if (m_refreshRequest.keys().contains(reply)) {
Device *device = m_refreshRequest.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcNetatmo) << "Device list reply HTTP error:" << status << reply->errorString();
device->setStateValue(availableStateTypeId, false);
reply->deleteLater();
return;
}
// check JSON file
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcNetatmo) << "Device list reply JSON error:" << error.errorString();
reply->deleteLater();
return;
}
//qCDebug(dcNetatmo) << jsonDoc.toJson();
processRefreshData(jsonDoc.toVariant().toMap(), device->id().toString());
}
reply->deleteLater();
}
void DevicePluginNetatmo::onAuthenticationChanged()
{
OAuth2 *authentication = static_cast<OAuth2 *>(sender());

View File

@ -23,6 +23,7 @@
#ifndef DEVICEPLUGINNETATMO_H
#define DEVICEPLUGINNETATMO_H
#include "plugintimer.h"
#include "plugin/deviceplugin.h"
#include "network/oauth2.h"
#include "netatmobasestation.h"
@ -39,18 +40,17 @@ class DevicePluginNetatmo : public DevicePlugin
public:
explicit DevicePluginNetatmo();
~DevicePluginNetatmo();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void guhTimer() override;
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
PluginTimer *m_pluginTimer;
QList<Device *> m_asyncSetups;
QHash<OAuth2 *, Device *> m_authentications;
@ -66,6 +66,8 @@ private:
Device *findOutdoorDevice(const QString &macAddress);
private slots:
void onPluginTimer();
void onNetworkReplyFinished();
void onAuthenticationChanged();
void onIndoorStatesChanged();
void onOutdoorStatesChanged();

View File

@ -61,11 +61,19 @@ DevicePluginNetworkDetector::DevicePluginNetworkDetector()
DevicePluginNetworkDetector::~DevicePluginNetworkDetector()
{
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
if (m_discovery->isRunning()) {
m_discovery->abort();
}
}
void DevicePluginNetworkDetector::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginNetworkDetector::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginNetworkDetector::setupDevice(Device *device)
{
qCDebug(dcNetworkDetector()) << "Setup" << device->name() << device->params();
@ -81,7 +89,6 @@ DeviceManager::DeviceError DevicePluginNetworkDetector::discoverDevices(const De
{
Q_UNUSED(params)
if (deviceClassId != networkDeviceClassId)
return DeviceManager::DeviceErrorDeviceClassNotFound;
@ -95,11 +102,6 @@ DeviceManager::DeviceError DevicePluginNetworkDetector::discoverDevices(const De
return DeviceManager::DeviceErrorAsync;
}
DeviceManager::HardwareResources DevicePluginNetworkDetector::requiredHardware() const
{
return DeviceManager::HardwareResourceTimer;
}
void DevicePluginNetworkDetector::deviceRemoved(Device *device)
{
DeviceMonitor *monitor = m_monitors.key(device);
@ -107,7 +109,7 @@ void DevicePluginNetworkDetector::deviceRemoved(Device *device)
delete monitor;
}
void DevicePluginNetworkDetector::guhTimer()
void DevicePluginNetworkDetector::onPluginTimer()
{
foreach (DeviceMonitor *monitor, m_monitors.keys()) {
monitor->update();

View File

@ -27,6 +27,7 @@
#include "plugin/deviceplugin.h"
#include "host.h"
#include "discovery.h"
#include "plugintimer.h"
#include "devicemonitor.h"
#include <QProcess>
@ -44,19 +45,23 @@ public:
explicit DevicePluginNetworkDetector();
~DevicePluginNetworkDetector();
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::HardwareResources requiredHardware() const override;
void deviceRemoved(Device *device) override;
void guhTimer() override;
private slots:
void discoveryFinished(const QList<Host> &hosts);
void deviceReachableChanged(bool reachable);
void deviceAddressChanged(const QString &address);
void onPluginTimer();
private:
PluginTimer *m_pluginTimer = nullptr;
Discovery *m_discovery = nullptr;
QHash<DeviceMonitor*, Device*> m_monitors;
};

View File

@ -48,7 +48,6 @@
*/
#include "devicepluginopenweathermap.h"
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
@ -66,12 +65,17 @@ DevicePluginOpenweathermap::DevicePluginOpenweathermap()
// max 50000 calls/day
m_apiKey = "c1b9d5584bb740804871583f6c62744f";
// update every 15 minutes
m_timer = new QTimer(this);
m_timer->setSingleShot(false);
m_timer->setInterval(900000);
}
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
DevicePluginOpenweathermap::~DevicePluginOpenweathermap()
{
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginOpenweathermap::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(900);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginOpenweathermap::onPluginTimer);
}
DeviceManager::DeviceError DevicePluginOpenweathermap::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
@ -96,19 +100,11 @@ DeviceManager::DeviceSetupStatus DevicePluginOpenweathermap::setupDevice(Device
if (device->deviceClassId() != openweathermapDeviceClassId)
return DeviceManager::DeviceSetupStatusFailure;
if (!m_timer->isActive())
m_timer->start();
update(device);
return DeviceManager::DeviceSetupStatusSuccess;
}
DeviceManager::HardwareResources DevicePluginOpenweathermap::requiredHardware() const
{
return DeviceManager::HardwareResourceNetworkManager;
}
DeviceManager::DeviceError DevicePluginOpenweathermap::executeAction(Device *device, const Action &action)
{
if(action.actionTypeId() == refreshWeatherActionTypeId){
@ -128,13 +124,12 @@ void DevicePluginOpenweathermap::deviceRemoved(Device *device)
reply->deleteLater();
}
}
if (myDevices().isEmpty())
m_timer->stop();
}
void DevicePluginOpenweathermap::networkManagerReplyReady(QNetworkReply *reply)
void DevicePluginOpenweathermap::networkManagerReplyReady()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
if (reply->error()) {
qCWarning(dcOpenWeatherMap) << "OpenWeatherMap reply error: " << reply->errorString();
reply->deleteLater();
@ -163,6 +158,7 @@ void DevicePluginOpenweathermap::networkManagerReplyReady(QNetworkReply *reply)
void DevicePluginOpenweathermap::update(Device *device)
{
qCDebug(dcOpenWeatherMap()) << "Refresh data for" << device->name();
QUrl url("http://api.openweathermap.org/data/2.5/weather");
QUrlQuery query;
query.addQueryItem("id", device->paramValue(idParamTypeId).toString());
@ -171,13 +167,15 @@ void DevicePluginOpenweathermap::update(Device *device)
query.addQueryItem("appid", m_apiKey);
url.setQuery(query);
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOpenweathermap::networkManagerReplyReady);
m_weatherReplies.insert(reply, device);
}
void DevicePluginOpenweathermap::searchAutodetect()
{
QNetworkReply *reply = networkManagerGet(QNetworkRequest(QUrl("http://ip-api.com/json")));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(QUrl("http://ip-api.com/json")));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOpenweathermap::networkManagerReplyReady);
m_autodetectionReplies.append(reply);
}
@ -192,7 +190,8 @@ void DevicePluginOpenweathermap::search(QString searchString)
query.addQueryItem("appid", m_apiKey);
url.setQuery(query);
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOpenweathermap::networkManagerReplyReady);
m_searchReplies.append(reply);
}
@ -209,7 +208,8 @@ void DevicePluginOpenweathermap::searchGeoLocation(double lat, double lon)
query.addQueryItem("appid", m_apiKey);
url.setQuery(query);
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOpenweathermap::networkManagerReplyReady);
m_searchGeoReplies.append(reply);
}
@ -392,7 +392,7 @@ void DevicePluginOpenweathermap::processWeatherData(const QByteArray &data, Devi
}
}
void DevicePluginOpenweathermap::onTimeout()
void DevicePluginOpenweathermap::onPluginTimer()
{
foreach (Device *device, myDevices()) {
update(device);

View File

@ -23,9 +23,12 @@
#ifndef DEVICEPLUGINOPENWEATHERMAP_H
#define DEVICEPLUGINOPENWEATHERMAP_H
#include "plugintimer.h"
#include "plugin/deviceplugin.h"
#include "network/networkaccessmanager.h"
#include <QTimer>
#include <QHostAddress>
class DevicePluginOpenweathermap : public DevicePlugin
{
@ -36,17 +39,17 @@ class DevicePluginOpenweathermap : public DevicePlugin
public:
explicit DevicePluginOpenweathermap();
~DevicePluginOpenweathermap();
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
//void guhTimer() override;
private:
PluginTimer *m_pluginTimer = nullptr;
QList<QNetworkReply *> m_autodetectionReplies;
QList<QNetworkReply *> m_searchReplies;
QList<QNetworkReply *> m_searchGeoReplies;
@ -59,7 +62,6 @@ private:
double m_longitude;
double m_latitude;
QTimer *m_timer;
QString m_apiKey;
void update(Device *device);
@ -75,7 +77,8 @@ private:
void processWeatherData(const QByteArray &data, Device *device);
private slots:
void onTimeout();
void networkManagerReplyReady();
void onPluginTimer();
};

View File

@ -42,16 +42,22 @@
#include "devicepluginorderbutton.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
DevicePluginOrderButton::DevicePluginOrderButton()
{
}
DeviceManager::HardwareResources DevicePluginOrderButton::requiredHardware() const
DevicePluginOrderButton::~DevicePluginOrderButton()
{
// We need the NetworkAccessManager for node discovery and the timer for ping requests
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginOrderButton::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginOrderButton::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginOrderButton::setupDevice(Device *device)
@ -96,68 +102,18 @@ DeviceManager::DeviceError DevicePluginOrderButton::discoverDevices(const Device
url.setScheme("http");
url.setHost(address.toString());
m_asyncNodeScans.insert(networkManagerGet(QNetworkRequest(url)), deviceClassId);
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOrderButton::onNetworkReplyFinished);
m_asyncNodeScans.insert(reply, deviceClassId);
return DeviceManager::DeviceErrorAsync;
}
void DevicePluginOrderButton::networkManagerReplyReady(QNetworkReply *reply)
{
if (m_asyncNodeScans.keys().contains(reply)) {
DeviceClassId deviceClassId = m_asyncNodeScans.take(reply);
// Check HTTP status code
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
qCWarning(dcOrderButton) << "Node scan reply HTTP error:" << reply->errorString();
emit devicesDiscovered(deviceClassId, QList<DeviceDescriptor>());
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
qCDebug(dcOrderButton) << "Node discovery finished:" << endl << data;
QList<DeviceDescriptor> deviceDescriptors;
QList<QByteArray> lines = data.split('\n');
qCDebug(dcOrderButton) << lines;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
QHostAddress address(QString(line.left(line.length() - 4)));
if (address.isNull())
continue;
qCDebug(dcOrderButton) << "Found node" << address.toString();
// Create a deviceDescriptor for each found address
DeviceDescriptor descriptor(deviceClassId, "Order Button", address.toString());
ParamList params;
params.append(Param(hostParamTypeId, address.toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
// Inform the user which devices were found
emit devicesDiscovered(deviceClassId, deviceDescriptors);
}
// Delete the HTTP reply
reply->deleteLater();
}
void DevicePluginOrderButton::postSetupDevice(Device *device)
{
// Try to ping the device after a successful setup
pingDevice(device);
}
void DevicePluginOrderButton::guhTimer()
{
// Try to ping each device every 10 seconds to make sure it is still reachable
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == orderbuttonDeviceClassId) {
pingDevice(device);
}
}
}
DeviceManager::DeviceError DevicePluginOrderButton::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() != orderbuttonDeviceClassId)
@ -360,6 +316,60 @@ Device *DevicePluginOrderButton::findDevice(const QHostAddress &address)
return NULL;
}
void DevicePluginOrderButton::onPluginTimer()
{
// Try to ping each device every 10 seconds to make sure it is still reachable
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == orderbuttonDeviceClassId) {
pingDevice(device);
}
}
}
void DevicePluginOrderButton::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
if (m_asyncNodeScans.keys().contains(reply)) {
DeviceClassId deviceClassId = m_asyncNodeScans.take(reply);
// Check HTTP status code
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
qCWarning(dcOrderButton) << "Node scan reply HTTP error:" << reply->errorString();
emit devicesDiscovered(deviceClassId, QList<DeviceDescriptor>());
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
qCDebug(dcOrderButton) << "Node discovery finished:" << endl << data;
QList<DeviceDescriptor> deviceDescriptors;
QList<QByteArray> lines = data.split('\n');
qCDebug(dcOrderButton) << lines;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
QHostAddress address(QString(line.left(line.length() - 4)));
if (address.isNull())
continue;
qCDebug(dcOrderButton) << "Found node" << address.toString();
// Create a deviceDescriptor for each found address
DeviceDescriptor descriptor(deviceClassId, "Order Button", address.toString());
ParamList params;
params.append(Param(hostParamTypeId, address.toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
// Inform the user which devices were found
emit devicesDiscovered(deviceClassId, deviceDescriptors);
}
// Delete the HTTP reply
reply->deleteLater();
}
void DevicePluginOrderButton::coapReplyFinished(CoapReply *reply)
{
if (m_pingReplies.contains(reply)) {

View File

@ -27,6 +27,7 @@
#include "plugin/deviceplugin.h"
#include "types/action.h"
#include "coap/coap.h"
#include "plugintimer.h"
#include <QHash>
@ -38,19 +39,17 @@ class DevicePluginOrderButton : public DevicePlugin
public:
explicit DevicePluginOrderButton();
~DevicePluginOrderButton();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void postSetupDevice(Device *device) override;
void guhTimer() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
PluginTimer *m_pluginTimer = nullptr;
QPointer<Coap> m_coap;
QHash<QNetworkReply *, DeviceClassId> m_asyncNodeScans;
QHash<CoapReply *, Device *> m_enableNotification;
@ -81,6 +80,8 @@ private:
Device *findDevice(const QHostAddress &address);
private slots:
void onPluginTimer();
void onNetworkReplyFinished();
void coapReplyFinished(CoapReply *reply);
void onNotificationReceived(const CoapObserveResource &resource, const int &notificationNumber, const QByteArray &payload);
};

View File

@ -46,21 +46,29 @@
#include "devicepluginosdomotics.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
DevicePluginOsdomotics::DevicePluginOsdomotics()
{
m_coap = new Coap(this);
connect(m_coap, SIGNAL(replyFinished(CoapReply*)), this, SLOT(coapReplyFinished(CoapReply*)));
}
DeviceManager::HardwareResources DevicePluginOsdomotics::requiredHardware() const
DevicePluginOsdomotics::~DevicePluginOsdomotics()
{
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginOsdomotics::init()
{
m_coap = new Coap(this);
connect(m_coap, &Coap::replyFinished, this, &DevicePluginOsdomotics::coapReplyFinished);
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginOsdomotics::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginOsdomotics::setupDevice(Device *device)
{
if (device->deviceClassId() == rplRouterDeviceClassId) {
qCDebug(dcOsdomotics) << "Setup RPL router" << device->paramValue(hostParamTypeId).toString();
QHostAddress address(device->paramValue(hostParamTypeId).toString());
@ -74,7 +82,8 @@ DeviceManager::DeviceSetupStatus DevicePluginOsdomotics::setupDevice(Device *dev
url.setScheme("http");
url.setHost(address.toString());
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOsdomotics::onNetworkReplyFinished);
m_asyncSetup.insert(reply, device);
return DeviceManager::DeviceSetupStatusAsync;
@ -91,59 +100,11 @@ void DevicePluginOsdomotics::deviceRemoved(Device *device)
Q_UNUSED(device)
}
void DevicePluginOsdomotics::networkManagerReplyReady(QNetworkReply *reply)
{
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// create user finished
if (m_asyncSetup.contains(reply)) {
Device *device = m_asyncSetup.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcOsdomotics) << "Setup reply HTTP error:" << reply->errorString();
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
parseNodes(device, data);
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
} else if (m_asyncNodeRescans.contains(reply)) {
Device *device = m_asyncSetup.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcOsdomotics) << "Setup reply HTTP error:" << reply->errorString();
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
parseNodes(device, data);
}
reply->deleteLater();
}
void DevicePluginOsdomotics::postSetupDevice(Device *device)
{
updateNode(device);
}
void DevicePluginOsdomotics::guhTimer()
{
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == merkurNodeDeviceClassId) {
updateNode(device);
} else if(device->deviceClassId() == rplRouterDeviceClassId) {
scanNodes(device);
}
}
}
DeviceManager::DeviceError DevicePluginOsdomotics::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() == merkurNodeDeviceClassId) {
@ -183,7 +144,8 @@ void DevicePluginOsdomotics::scanNodes(Device *device)
url.setScheme("http");
url.setHost(address.toString());
QNetworkReply *reply = networkManagerGet(QNetworkRequest(url));
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginOsdomotics::onNetworkReplyFinished);
m_asyncNodeRescans.insert(reply, device);
}
@ -258,6 +220,55 @@ Device *DevicePluginOsdomotics::findDevice(const QHostAddress &address)
return 0;
}
void DevicePluginOsdomotics::onPluginTimer()
{
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == merkurNodeDeviceClassId) {
updateNode(device);
} else if(device->deviceClassId() == rplRouterDeviceClassId) {
scanNodes(device);
}
}
}
void DevicePluginOsdomotics::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// create user finished
if (m_asyncSetup.contains(reply)) {
Device *device = m_asyncSetup.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcOsdomotics) << "Setup reply HTTP error:" << reply->errorString();
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
parseNodes(device, data);
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
} else if (m_asyncNodeRescans.contains(reply)) {
Device *device = m_asyncSetup.take(reply);
// check HTTP status code
if (status != 200) {
qCWarning(dcOsdomotics) << "Setup reply HTTP error:" << reply->errorString();
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
parseNodes(device, data);
}
reply->deleteLater();
}
void DevicePluginOsdomotics::coapReplyFinished(CoapReply *reply)
{
qCDebug(dcOsdomotics) << "coap reply finished" << reply;

View File

@ -29,6 +29,7 @@
#include <QDebug>
#include "coap/coap.h"
#include "plugintimer.h"
class DevicePluginOsdomotics : public DevicePlugin
{
@ -38,19 +39,17 @@ class DevicePluginOsdomotics : public DevicePlugin
public:
explicit DevicePluginOsdomotics();
~DevicePluginOsdomotics();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void postSetupDevice(Device *device) override;
void guhTimer() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
Coap *m_coap;
PluginTimer *m_pluginTimer = nullptr;
Coap *m_coap = nullptr;
QHash<QNetworkReply *, Device *> m_asyncSetup;
QHash<QNetworkReply *, Device *> m_asyncNodeRescans;
@ -65,6 +64,8 @@ private:
Device *findDevice(const QHostAddress &address);
private slots:
void onPluginTimer();
void onNetworkReplyFinished();
void coapReplyFinished(CoapReply *reply);
};

View File

@ -47,6 +47,8 @@
#include "plugin/device.h"
#include "types/param.h"
#include "plugininfo.h"
#include "network/upnp/upnpdiscovery.h"
#include "network/upnp/upnpdiscoveryreply.h"
#include <QDebug>
#include <QStringList>
@ -55,24 +57,28 @@
DevicePluginPhilipsHue::DevicePluginPhilipsHue()
{
m_timer = new QTimer(this);
m_timer->setSingleShot(false);
m_timer->setInterval(5000);
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
DeviceManager::HardwareResources DevicePluginPhilipsHue::requiredHardware() const
DevicePluginPhilipsHue::~DevicePluginPhilipsHue()
{
return DeviceManager::HardwareResourceUpnpDisovery | DeviceManager::HardwareResourceNetworkManager;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginPhilipsHue::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginPhilipsHue::onPluginTimer);
}
DeviceManager::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(deviceClassId)
Q_UNUSED(params)
Q_UNUSED(deviceClassId)
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices("libhue:idl");
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginPhilipsHue::onUpnpDiscoveryFinished);
upnpDiscover("libhue:idl");
return DeviceManager::DeviceErrorAsync;
}
@ -94,7 +100,6 @@ DeviceManager::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *dev
m_bridges.insert(b, device);
device->setStateValue(bridgeReachableStateTypeId, true);
discoverBridgeDevices(b);
m_timer->start();
return DeviceManager::DeviceSetupStatusSuccess;
}
}
@ -111,7 +116,6 @@ DeviceManager::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *dev
bridge->setZigbeeChannel(device->paramValue(bridgeZigbeeChannelParamTypeId).toInt());
m_bridges.insert(bridge, device);
m_timer->start();
return DeviceManager::DeviceSetupStatusSuccess;
}
@ -213,38 +217,6 @@ void DevicePluginPhilipsHue::deviceRemoved(Device *device)
m_remotes.remove(remote);
remote->deleteLater();
}
if (myDevices().isEmpty())
m_timer->stop();
}
void DevicePluginPhilipsHue::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList)
{
if (upnpDeviceDescriptorList.isEmpty()) {
qCDebug(dcPhilipsHue) << "No UPnP device found. Try N-UPNP discovery.";
QNetworkRequest request(QUrl("https://www.meethue.com/api/nupnp"));
QNetworkReply *reply = networkManagerGet(request);
m_discoveryRequests.append(reply);
return;
}
QList<DeviceDescriptor> deviceDescriptors;
foreach (const UpnpDeviceDescriptor &upnpDevice, upnpDeviceDescriptorList) {
if (upnpDevice.modelDescription().contains("Philips")) {
DeviceDescriptor descriptor(hueBridgeDeviceClassId, "Philips Hue Bridge", upnpDevice.hostAddress().toString());
ParamList params;
params.append(Param(bridgeNameParamTypeId, upnpDevice.friendlyName()));
params.append(Param(bridgeHostParamTypeId, upnpDevice.hostAddress().toString()));
params.append(Param(bridgeApiParamTypeId, QString()));
params.append(Param(bridgeMacParamTypeId, QString()));
params.append(Param(bridgeIdParamTypeId, upnpDevice.serialNumber().toLower()));
params.append(Param(bridgeZigbeeChannelParamTypeId, -1));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
}
emit devicesDiscovered(hueBridgeDeviceClassId, deviceDescriptors);
}
DeviceManager::DeviceSetupStatus DevicePluginPhilipsHue::confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params, const QString &secret)
@ -265,15 +237,17 @@ DeviceManager::DeviceSetupStatus DevicePluginPhilipsHue::confirmPairing(const Pa
QNetworkRequest request(QUrl("http://" + pairingInfo->host().toString() + "/api"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerPost(request, jsonDoc.toJson());
QNetworkReply *reply = hardwareManager()->networkManager()->post(request, jsonDoc.toJson());
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_pairingRequests.insert(reply, pairingInfo);
return DeviceManager::DeviceSetupStatusAsync;
}
void DevicePluginPhilipsHue::networkManagerReplyReady(QNetworkReply *reply)
void DevicePluginPhilipsHue::networkManagerReplyReady()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// create user finished
@ -444,27 +418,39 @@ DeviceManager::DeviceError DevicePluginPhilipsHue::executeAction(Device *device,
if (action.actionTypeId() == huePowerActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(action.param(huePowerStateParamTypeId).value().toBool());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueColorActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetColorRequest(action.param(hueColorStateParamTypeId).value().value<QColor>());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply,QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueBrightnessActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percentageToBrightness(action.param(hueBrightnessStateParamTypeId).value().toInt()));
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueEffectActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetEffectRequest(action.param(hueEffectStateParamTypeId).value().toString());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueAlertActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(action.param(alertParamTypeId).value().toString());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueTemperatureActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetTemperatureRequest(action.param(hueTemperatureStateParamTypeId).value().toInt());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
@ -481,15 +467,21 @@ DeviceManager::DeviceError DevicePluginPhilipsHue::executeAction(Device *device,
if (action.actionTypeId() == huePowerActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(action.param(huePowerStateParamTypeId).value().toBool());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueBrightnessActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percentageToBrightness(action.param(hueBrightnessStateParamTypeId).value().toInt()));
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == hueAlertActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(action.param(alertParamTypeId).value().toString());
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
@ -507,11 +499,15 @@ DeviceManager::DeviceError DevicePluginPhilipsHue::executeAction(Device *device,
return DeviceManager::DeviceErrorNoError;
} else if (action.actionTypeId() == checkForUpdatesActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = bridge->createCheckUpdatesRequest();
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
} else if (action.actionTypeId() == upgradeActionTypeId) {
QPair<QNetworkRequest, QByteArray> request = bridge->createUpgradeRequest();
m_asyncActions.insert(networkManagerPut(request.first, request.second),QPair<Device *, ActionId>(device, action.id()));
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
return DeviceManager::DeviceErrorAsync;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
@ -591,21 +587,58 @@ void DevicePluginPhilipsHue::onRemoteButtonEvent(const int &buttonCode)
}
}
void DevicePluginPhilipsHue::onTimeout()
void DevicePluginPhilipsHue::onPluginTimer()
{
foreach (Device *device, m_bridges.values()) {
refreshBridge(device);
}
}
void DevicePluginPhilipsHue::onUpnpDiscoveryFinished()
{
qCDebug(dcPhilipsHue()) << "Upnp discovery finished";
UpnpDiscoveryReply *reply = static_cast<UpnpDiscoveryReply *>(sender());
if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) {
qCWarning(dcPhilipsHue()) << "Upnp discovery error" << reply->error();
}
reply->deleteLater();
if (reply->deviceDescriptors().isEmpty()) {
qCDebug(dcPhilipsHue) << "No UPnP device found. Try N-UPNP discovery.";
QNetworkRequest request(QUrl("https://www.meethue.com/api/nupnp"));
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_discoveryRequests.append(reply);
return;
}
QList<DeviceDescriptor> deviceDescriptors;
foreach (const UpnpDeviceDescriptor &upnpDevice, reply->deviceDescriptors()) {
if (upnpDevice.modelDescription().contains("Philips")) {
DeviceDescriptor descriptor(hueBridgeDeviceClassId, "Philips Hue Bridge", upnpDevice.hostAddress().toString());
ParamList params;
params.append(Param(bridgeNameParamTypeId, upnpDevice.friendlyName()));
params.append(Param(bridgeHostParamTypeId, upnpDevice.hostAddress().toString()));
params.append(Param(bridgeApiParamTypeId, QString()));
params.append(Param(bridgeMacParamTypeId, QString()));
params.append(Param(bridgeIdParamTypeId, upnpDevice.serialNumber().toLower()));
params.append(Param(bridgeZigbeeChannelParamTypeId, -1));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
}
emit devicesDiscovered(hueBridgeDeviceClassId, deviceDescriptors);
}
void DevicePluginPhilipsHue::refreshLight(Device *device)
{
HueLight *light = m_lights.key(device);
QNetworkRequest request(QUrl("http://" + light->hostAddress().toString() + "/api/" + light->apiKey() + "/lights/" + QString::number(light->id())));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_lightRefreshRequests.insert(reply, device);
}
@ -624,8 +657,8 @@ void DevicePluginPhilipsHue::refreshBridge(Device *device)
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/config"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_bridgeRefreshRequests.insert(reply, device);
}
@ -635,8 +668,8 @@ void DevicePluginPhilipsHue::refreshLights(HueBridge *bridge)
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/lights"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_lightsRefreshRequests.insert(reply, device);
}
@ -646,8 +679,8 @@ void DevicePluginPhilipsHue::refreshSensors(HueBridge *bridge)
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/sensors"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_sensorsRefreshRequests.insert(reply, device);
}
@ -657,10 +690,14 @@ void DevicePluginPhilipsHue::discoverBridgeDevices(HueBridge *bridge)
qCDebug(dcPhilipsHue) << "Discover bridge devices" << bridge->hostAddress();
QPair<QNetworkRequest, QByteArray> lightsRequest = bridge->createDiscoverLightsRequest();
m_bridgeLightsDiscoveryRequests.insert(networkManagerGet(lightsRequest.first), device);
QNetworkReply *lightsReply = hardwareManager()->networkManager()->get(lightsRequest.first);
connect(lightsReply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_bridgeLightsDiscoveryRequests.insert(lightsReply, device);
QPair<QNetworkRequest, QByteArray> sensorsRequest = bridge->createSearchSensorsRequest();
m_bridgeSensorsDiscoveryRequests.insert(networkManagerGet(sensorsRequest.first), device);
QNetworkReply *reply = hardwareManager()->networkManager()->get(sensorsRequest.first);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_bridgeSensorsDiscoveryRequests.insert(reply, device);
}
void DevicePluginPhilipsHue::searchNewDevices(HueBridge *bridge)
@ -669,7 +706,9 @@ void DevicePluginPhilipsHue::searchNewDevices(HueBridge *bridge)
qCDebug(dcPhilipsHue) << "Discover bridge devices" << bridge->hostAddress();
QPair<QNetworkRequest, QByteArray> request = bridge->createSearchLightsRequest();
m_bridgeSearchDevicesRequests.insert(networkManagerPost(request.first, request.second), device);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request.first, request.second);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_bridgeSearchDevicesRequests.insert(reply, device);
}
void DevicePluginPhilipsHue::setLightName(Device *device, const QString &name)
@ -684,7 +723,8 @@ void DevicePluginPhilipsHue::setLightName(Device *device, const QString &name)
"/lights/" + QString::number(light->id())));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerPut(request,jsonDoc.toJson());
QNetworkReply *reply = hardwareManager()->networkManager()->put(request,jsonDoc.toJson());
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_lightSetNameRequests.insert(reply, device);
}
@ -1059,8 +1099,8 @@ void DevicePluginPhilipsHue::processPairingResponse(PairingInfo *pairingInfo, co
// Paired successfully, check bridge information
QNetworkRequest request(QUrl("http://" + pairingInfo->host().toString() + "/api/" + pairingInfo->apiKey() + "/config"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply *reply = networkManagerGet(request);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
m_informationRequests.insert(reply, pairingInfo);
}

View File

@ -29,6 +29,9 @@
#include "huelight.h"
#include "hueremote.h"
#include "pairinginfo.h"
#include "plugintimer.h"
#include "network/networkaccessmanager.h"
#include "network/upnp/upnpdiscovery.h"
class QNetworkReply;
@ -41,19 +44,14 @@ class DevicePluginPhilipsHue: public DevicePlugin
public:
explicit DevicePluginPhilipsHue();
~DevicePluginPhilipsHue();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
void deviceRemoved(Device *device) override;
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
DeviceManager::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params, const QString &secret) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
public slots:
DeviceManager::DeviceError executeAction(Device *device, const Action &action);
@ -61,10 +59,14 @@ private slots:
void lightStateChanged();
void remoteStateChanged();
void onRemoteButtonEvent(const int &buttonCode);
void onTimeout();
void onPluginTimer();
private slots:
void onUpnpDiscoveryFinished();
void networkManagerReplyReady();
private:
QTimer *m_timer;
PluginTimer *m_pluginTimer = nullptr;
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
@ -119,6 +121,7 @@ private:
int brightnessToPercentage(int brightness);
int percentageToBrightness(int percentage);
};
#endif // DEVICEPLUGINBOBLIGHT_H

View File

@ -43,16 +43,22 @@
#include "devicepluginplantcare.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
DevicePluginPlantCare::DevicePluginPlantCare()
{
}
DeviceManager::HardwareResources DevicePluginPlantCare::requiredHardware() const
DevicePluginPlantCare::~DevicePluginPlantCare()
{
// We need the NetworkAccessManager for node discovery and the timer for ping requests
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginPlantCare::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginPlantCare::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginPlantCare::setupDevice(Device *device)
@ -85,6 +91,12 @@ void DevicePluginPlantCare::deviceRemoved(Device *device)
}
}
void DevicePluginPlantCare::postSetupDevice(Device *device)
{
// Try to ping the device after a successful setup
pingDevice(device);
}
DeviceManager::DeviceError DevicePluginPlantCare::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
@ -97,68 +109,12 @@ DeviceManager::DeviceError DevicePluginPlantCare::discoverDevices(const DeviceCl
url.setScheme("http");
url.setHost(address.toString());
m_asyncNodeScans.insert(networkManagerGet(QNetworkRequest(url)), deviceClassId);
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginPlantCare::onNetworkReplyFinished);
m_asyncNodeScans.insert(reply, deviceClassId);
return DeviceManager::DeviceErrorAsync;
}
void DevicePluginPlantCare::networkManagerReplyReady(QNetworkReply *reply)
{
if (m_asyncNodeScans.keys().contains(reply)) {
DeviceClassId deviceClassId = m_asyncNodeScans.take(reply);
// Check HTTP status code
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
qCWarning(dcPlantCare) << "Node scan reply HTTP error:" << reply->errorString();
emit devicesDiscovered(deviceClassId, QList<DeviceDescriptor>());
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
qCDebug(dcPlantCare) << "Node discovery finished:" << endl << data;
QList<DeviceDescriptor> deviceDescriptors;
QList<QByteArray> lines = data.split('\n');
qCDebug(dcPlantCare) << lines;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
QHostAddress address(QString(line.left(line.length() - 4)));
if (address.isNull())
continue;
qCDebug(dcPlantCare) << "Found node" << address.toString();
// Create a deviceDescriptor for each found address
DeviceDescriptor descriptor(deviceClassId, "Plant Care", address.toString());
ParamList params;
params.append(Param(hostParamTypeId, address.toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
// Inform the user which devices were found
emit devicesDiscovered(deviceClassId, deviceDescriptors);
}
// Delete the HTTP reply
reply->deleteLater();
}
void DevicePluginPlantCare::postSetupDevice(Device *device)
{
// Try to ping the device after a successful setup
pingDevice(device);
}
void DevicePluginPlantCare::guhTimer()
{
// Try to ping each device every 10 seconds to make sure it is still reachable
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == plantCareDeviceClassId) {
pingDevice(device);
}
}
}
DeviceManager::DeviceError DevicePluginPlantCare::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() != plantCareDeviceClassId)
@ -404,6 +360,60 @@ Device *DevicePluginPlantCare::findDevice(const QHostAddress &address)
return NULL;
}
void DevicePluginPlantCare::onPluginTimer()
{
// Try to ping each device every 10 seconds to make sure it is still reachable
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == plantCareDeviceClassId) {
pingDevice(device);
}
}
}
void DevicePluginPlantCare::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
if (m_asyncNodeScans.keys().contains(reply)) {
DeviceClassId deviceClassId = m_asyncNodeScans.take(reply);
// Check HTTP status code
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
qCWarning(dcPlantCare) << "Node scan reply HTTP error:" << reply->errorString();
emit devicesDiscovered(deviceClassId, QList<DeviceDescriptor>());
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
qCDebug(dcPlantCare) << "Node discovery finished:" << endl << data;
QList<DeviceDescriptor> deviceDescriptors;
QList<QByteArray> lines = data.split('\n');
qCDebug(dcPlantCare) << lines;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
QHostAddress address(QString(line.left(line.length() - 4)));
if (address.isNull())
continue;
qCDebug(dcPlantCare) << "Found node" << address.toString();
// Create a deviceDescriptor for each found address
DeviceDescriptor descriptor(deviceClassId, "Plant Care", address.toString());
ParamList params;
params.append(Param(hostParamTypeId, address.toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
// Inform the user which devices were found
emit devicesDiscovered(deviceClassId, deviceDescriptors);
}
// Delete the HTTP reply
reply->deleteLater();
}
void DevicePluginPlantCare::coapReplyFinished(CoapReply *reply)
{
if (m_pingReplies.contains(reply)) {

View File

@ -27,6 +27,7 @@
#include "plugin/deviceplugin.h"
#include "types/action.h"
#include "coap/coap.h"
#include "plugintimer.h"
#include <QHash>
@ -38,19 +39,17 @@ class DevicePluginPlantCare : public DevicePlugin
public:
explicit DevicePluginPlantCare();
~DevicePluginPlantCare();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void postSetupDevice(Device *device) override;
void guhTimer() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
PluginTimer *m_pluginTimer = nullptr;
QPointer<Coap> m_coap;
QHash<QNetworkReply *, DeviceClassId> m_asyncNodeScans;
QHash<CoapReply *, Device *> m_enableNotification;
@ -82,6 +81,8 @@ private:
Device *findDevice(const QHostAddress &address);
private slots:
void onPluginTimer();
void onNetworkReplyFinished();
void coapReplyFinished(CoapReply *reply);
void onNotificationReceived(const CoapObserveResource &resource, const int &notificationNumber, const QByteArray &payload);
};

View File

@ -26,12 +26,6 @@ DevicePluginTcpCommander::DevicePluginTcpCommander()
{
}
DeviceManager::HardwareResources DevicePluginTcpCommander::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
DeviceManager::DeviceSetupStatus DevicePluginTcpCommander::setupDevice(Device *device)
{
if (device->deviceClassId() == tcpOutputDeviceClassId) {

View File

@ -35,7 +35,6 @@ class DevicePluginTcpCommander : public DevicePlugin
public:
explicit DevicePluginTcpCommander();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;

View File

@ -67,11 +67,6 @@ DevicePluginUdpCommander::DevicePluginUdpCommander()
}
DeviceManager::HardwareResources DevicePluginUdpCommander::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
DeviceManager::DeviceSetupStatus DevicePluginUdpCommander::setupDevice(Device *device)
{
// check port

View File

@ -38,7 +38,6 @@ class DevicePluginUdpCommander : public DevicePlugin
public:
explicit DevicePluginUdpCommander();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;

View File

@ -49,6 +49,8 @@
#include "devicepluginunitec.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "hardwaremanager.h"
#include "hardware/radio433/radio433.h"
#include <QDebug>
#include <QStringList>
@ -57,11 +59,6 @@ DevicePluginUnitec::DevicePluginUnitec()
{
}
DeviceManager::HardwareResources DevicePluginUnitec::requiredHardware() const
{
return DeviceManager::HardwareResourceRadio433;
}
DeviceManager::DeviceSetupStatus DevicePluginUnitec::setupDevice(Device *device)
{
if (device->deviceClassId() != switchDeviceClassId) {
@ -80,6 +77,9 @@ DeviceManager::DeviceSetupStatus DevicePluginUnitec::setupDevice(Device *device)
DeviceManager::DeviceError DevicePluginUnitec::executeAction(Device *device, const Action &action)
{
if (!hardwareManager()->radio433()->available())
return DeviceManager::DeviceErrorHardwareNotAvailable;
QList<int> rawData;
QByteArray binCode;
@ -127,11 +127,12 @@ DeviceManager::DeviceError DevicePluginUnitec::executeAction(Device *device, con
// =======================================
// send data to hardware resource
if(transmitData(delay, rawData)){
if(hardwareManager()->radio433()->sendData(delay, rawData, 10)){
qCDebug(dcUnitec) << "transmitted" << pluginName() << device->name() << "power: " << action.param(powerParamTypeId).value().toBool();
return DeviceManager::DeviceErrorNoError;
}else{
qCWarning(dcUnitec) << "could not transmitt" << pluginName() << device->name() << "power: " << action.param(powerParamTypeId).value().toBool();
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
return DeviceManager::DeviceErrorNoError;
}

View File

@ -35,7 +35,6 @@ class DevicePluginUnitec : public DevicePlugin
public:
explicit DevicePluginUnitec();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
public slots:

View File

@ -58,11 +58,6 @@ DevicePluginWakeOnLan::DevicePluginWakeOnLan()
{
}
DeviceManager::HardwareResources DevicePluginWakeOnLan::requiredHardware() const
{
return DeviceManager::HardwareResourceNone;
}
DeviceManager::DeviceError DevicePluginWakeOnLan::executeAction(Device *device, const Action &action)
{
if(action.actionTypeId() == wolActionTypeId){

View File

@ -37,11 +37,8 @@ class DevicePluginWakeOnLan : public DevicePlugin
public:
explicit DevicePluginWakeOnLan();
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private slots:
void wakeup(QString mac);

View File

@ -49,6 +49,8 @@
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
#include "network/upnp/upnpdiscovery.h"
#include <QDebug>
#include <QNetworkReply>
@ -61,13 +63,26 @@ DevicePluginWemo::DevicePluginWemo()
{
}
DevicePluginWemo::~DevicePluginWemo()
{
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginWemo::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginWemo::onPluginTimer);
connect(hardwareManager()->upnpDiscovery(), &UpnpDiscovery::upnpNotify, this, &DevicePluginWemo::onUpnpNotifyReceived);
}
DeviceManager::DeviceError DevicePluginWemo::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params);
if (deviceClassId != wemoSwitchDeviceClassId) {
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
upnpDiscover("upnp:rootdevice");
Q_UNUSED(deviceClassId)
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices("upnp:rootdevice");
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginWemo::onUpnpDiscoveryFinished);
return DeviceManager::DeviceErrorAsync;
}
@ -81,11 +96,6 @@ DeviceManager::DeviceSetupStatus DevicePluginWemo::setupDevice(Device *device)
return DeviceManager::DeviceSetupStatusSuccess;
}
DeviceManager::HardwareResources DevicePluginWemo::requiredHardware() const
{
return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceUpnpDisovery | DeviceManager::HardwareResourceNetworkManager;
}
DeviceManager::DeviceError DevicePluginWemo::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() != wemoSwitchDeviceClassId)
@ -128,69 +138,6 @@ void DevicePluginWemo::deviceRemoved(Device *device)
}
}
void DevicePluginWemo::networkManagerReplyReady(QNetworkReply *reply)
{
if (m_refreshReplies.contains(reply)) {
QByteArray data = reply->readAll();
Device *device = m_refreshReplies.take(reply);
if (reply->error()) {
// give only error if we don't already know that is unreachable
if (device->stateValue(reachableStateTypeId).toBool()) {
qCWarning(dcWemo) << "WeMo reply error: " << reply->errorString();
}
device->setStateValue(reachableStateTypeId, false);
} else {
processRefreshData(data, device);
}
} else if (m_setPowerReplies.contains(reply)) {
QByteArray data = reply->readAll();
Device *device = m_setPowerReplies.take(reply);
ActionId actionId = m_runningActionExecutions.take(reply);
if (reply->error()) {
// give only error if we don't already know that is unreachable
if (device->stateValue(reachableStateTypeId).toBool()) {
qCWarning(dcWemo) << "WeMo reply error: " << reply->errorString();
}
device->setStateValue(reachableStateTypeId, false);
} else {
processSetPowerData(data, device, actionId);
}
}
reply->deleteLater();
}
void DevicePluginWemo::guhTimer()
{
foreach (Device* device, myDevices()) {
refresh(device);
}
}
void DevicePluginWemo::upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList)
{
QList<DeviceDescriptor> deviceDescriptors;
foreach (UpnpDeviceDescriptor upnpDeviceDescriptor, upnpDeviceDescriptorList) {
if (upnpDeviceDescriptor.friendlyName() == "WeMo Switch") {
DeviceDescriptor descriptor(wemoSwitchDeviceClassId, "WemoSwitch", upnpDeviceDescriptor.serialNumber());
ParamList params;
params.append(Param(nameParamTypeId, upnpDeviceDescriptor.friendlyName()));
params.append(Param(hostParamTypeId, upnpDeviceDescriptor.hostAddress().toString()));
params.append(Param(portParamTypeId, upnpDeviceDescriptor.port()));
params.append(Param(serialParamTypeId, upnpDeviceDescriptor.serialNumber()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
}
emit devicesDiscovered(wemoSwitchDeviceClassId, deviceDescriptors);
}
void DevicePluginWemo::upnpNotifyReceived(const QByteArray &notifyData)
{
Q_UNUSED(notifyData);
}
void DevicePluginWemo::refresh(Device *device)
{
QByteArray getBinarayStateMessage("<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:GetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"><BinaryState>1</BinaryState></u:GetBinaryState></s:Body></s:Envelope>");
@ -201,7 +148,8 @@ void DevicePluginWemo::refresh(Device *device)
request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("guh"));
request.setRawHeader("SOAPACTION", "\"urn:Belkin:service:basicevent:1#GetBinaryState\"");
QNetworkReply *reply = networkManagerPost(request, getBinarayStateMessage);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request, getBinarayStateMessage);
connect(reply, &QNetworkReply::finished, this, &DevicePluginWemo::onNetworkReplyFinished);
m_refreshReplies.insert(reply, device);
}
@ -220,7 +168,8 @@ bool DevicePluginWemo::setPower(Device *device, const bool &power, const ActionI
request.setHeader(QNetworkRequest::UserAgentHeader,QVariant("guh"));
request.setRawHeader("SOAPACTION", "\"urn:Belkin:service:basicevent:1#SetBinaryState\"");
QNetworkReply *reply = networkManagerPost(request, setPowerMessage);
QNetworkReply *reply = hardwareManager()->networkManager()->post(request, setPowerMessage);
connect(reply, &QNetworkReply::finished, this, &DevicePluginWemo::onNetworkReplyFinished);
m_setPowerReplies.insert(reply, device);
m_runningActionExecutions.insert(reply, actionId);
return true;
@ -251,3 +200,67 @@ void DevicePluginWemo::processSetPowerData(const QByteArray &data, Device *devic
emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorHardwareNotAvailable);
}
}
void DevicePluginWemo::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// check HTTP status code
if (status != 200 || reply->error() != QNetworkReply::NoError) {
qCWarning(dcWemo()) << "Request error:" << status << reply->errorString();
reply->deleteLater();
return;
}
if (m_refreshReplies.contains(reply)) {
QByteArray data = reply->readAll();
Device *device = m_refreshReplies.take(reply);
processRefreshData(data, device);
} else if (m_setPowerReplies.contains(reply)) {
QByteArray data = reply->readAll();
Device *device = m_setPowerReplies.take(reply);
ActionId actionId = m_runningActionExecutions.take(reply);
processSetPowerData(data, device, actionId);
}
reply->deleteLater();
}
void DevicePluginWemo::onPluginTimer()
{
foreach (Device* device, myDevices()) {
refresh(device);
}
}
void DevicePluginWemo::onUpnpDiscoveryFinished()
{
qCDebug(dcWemo()) << "Upnp discovery finished";
UpnpDiscoveryReply *reply = static_cast<UpnpDiscoveryReply *>(sender());
if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) {
qCWarning(dcWemo()) << "Upnp discovery error" << reply->error();
}
reply->deleteLater();
QList<DeviceDescriptor> deviceDescriptors;
foreach (const UpnpDeviceDescriptor &upnpDeviceDescriptor, reply->deviceDescriptors()) {
if (upnpDeviceDescriptor.friendlyName() == "WeMo Switch") {
DeviceDescriptor descriptor(wemoSwitchDeviceClassId, "WeMo Switch", upnpDeviceDescriptor.serialNumber());
ParamList params;
params.append(Param(nameParamTypeId, upnpDeviceDescriptor.friendlyName()));
params.append(Param(hostParamTypeId, upnpDeviceDescriptor.hostAddress().toString()));
params.append(Param(portParamTypeId, upnpDeviceDescriptor.port()));
params.append(Param(serialParamTypeId, upnpDeviceDescriptor.serialNumber()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
}
emit devicesDiscovered(wemoSwitchDeviceClassId, deviceDescriptors);
}
void DevicePluginWemo::onUpnpNotifyReceived(const QByteArray &notification)
{
Q_UNUSED(notification)
}

View File

@ -23,6 +23,7 @@
#ifndef DEVICEPLUGINWEMO_H
#define DEVICEPLUGINWEMO_H
#include "plugintimer.h"
#include "plugin/deviceplugin.h"
class DevicePluginWemo : public DevicePlugin
@ -34,20 +35,16 @@ class DevicePluginWemo : public DevicePlugin
public:
explicit DevicePluginWemo();
~DevicePluginWemo();
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::HardwareResources requiredHardware() const override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void guhTimer() override;
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
void upnpNotifyReceived(const QByteArray &notifyData);
private:
PluginTimer *m_pluginTimer = nullptr;
QHash<QNetworkReply *, Device *> m_refreshReplies;
QHash<QNetworkReply *, Device *> m_setPowerReplies;
QHash<QNetworkReply *, ActionId> m_runningActionExecutions;
@ -58,6 +55,12 @@ private:
void processRefreshData(const QByteArray &data, Device *device);
void processSetPowerData(const QByteArray &data, Device *device, const ActionId &actionId);
private slots:
void onNetworkReplyFinished();
void onPluginTimer();
void onUpnpDiscoveryFinished();
void onUpnpNotifyReceived(const QByteArray &notification);
};
#endif // DEVICEPLUGINWEMO_H

View File

@ -44,7 +44,7 @@
#include "devicepluginws2812.h"
#include "plugin/device.h"
#include "plugininfo.h"
#include "network/networkaccessmanager.h"
#include <QDebug>
#include <QStringList>
@ -55,10 +55,15 @@ DevicePluginWs2812::DevicePluginWs2812()
}
DeviceManager::HardwareResources DevicePluginWs2812::requiredHardware() const
DevicePluginWs2812::~DevicePluginWs2812()
{
// We need the NetworkAccessManager for node discovery and the timer for ping requests
return DeviceManager::HardwareResourceNetworkManager | DeviceManager::HardwareResourceTimer;
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
}
void DevicePluginWs2812::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginWs2812::onPluginTimer);
}
DeviceManager::DeviceSetupStatus DevicePluginWs2812::setupDevice(Device *device)
@ -103,68 +108,18 @@ DeviceManager::DeviceError DevicePluginWs2812::discoverDevices(const DeviceClass
url.setScheme("http");
url.setHost(address.toString());
m_asyncNodeScans.insert(networkManagerGet(QNetworkRequest(url)), deviceClassId);
QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &DevicePluginWs2812::onNetworkReplyFinished);
m_asyncNodeScans.insert(reply, deviceClassId);
return DeviceManager::DeviceErrorAsync;
}
void DevicePluginWs2812::networkManagerReplyReady(QNetworkReply *reply)
{
if (m_asyncNodeScans.keys().contains(reply)) {
DeviceClassId deviceClassId = m_asyncNodeScans.take(reply);
// Check HTTP status code
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
qCWarning(dcWs2812) << "Node scan reply HTTP error:" << reply->errorString();
emit devicesDiscovered(deviceClassId, QList<DeviceDescriptor>());
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
qCDebug(dcWs2812) << "Node discovery finished:" << endl << data;
QList<DeviceDescriptor> deviceDescriptors;
QList<QByteArray> lines = data.split('\n');
qCDebug(dcWs2812) << lines;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
QHostAddress address(QString(line.left(line.length() - 4)));
if (address.isNull())
continue;
qCDebug(dcWs2812) << "Found node" << address.toString();
// Create a deviceDescriptor for each found address
DeviceDescriptor descriptor(deviceClassId, "ws2812", address.toString());
ParamList params;
params.append(Param(hostParamTypeId, address.toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
// Inform the user which devices were found
emit devicesDiscovered(deviceClassId, deviceDescriptors);
}
// Delete the HTTP reply
reply->deleteLater();
}
void DevicePluginWs2812::postSetupDevice(Device *device)
{
// Try to ping the device after a successful setup
pingDevice(device);
}
void DevicePluginWs2812::guhTimer()
{
// Try to ping each device every 10 seconds to make sure it is still reachable
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == ws2812DeviceClassId) {
pingDevice(device);
}
}
}
DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() != ws2812DeviceClassId)
@ -228,7 +183,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
return DeviceManager::DeviceErrorAsync;
}else if(action.actionTypeId() == brightnessActionTypeId) {
} else if(action.actionTypeId() == brightnessActionTypeId) {
QUrl url;
url.setScheme("coap");
@ -255,7 +210,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
return DeviceManager::DeviceErrorAsync;
}else if(action.actionTypeId() == maxPixActionTypeId) {
} else if(action.actionTypeId() == maxPixActionTypeId) {
QUrl url;
url.setScheme("coap");
@ -288,7 +243,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
return DeviceManager::DeviceErrorAsync;
}else if(action.actionTypeId() == effectModeActionTypeId) {
} else if(action.actionTypeId() == effectModeActionTypeId) {
int effectmode = 0;
@ -304,7 +259,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
//TODO switch to enum
if(effectModeString == "Off") {
if (effectModeString == "Off") {
effectmode = 0;
} else if (effectModeString == "Color On") {
effectmode = 1;
@ -312,17 +267,17 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
effectmode = 2;
} else if (effectModeString == "Color Fade") {
effectmode = 3;
}else if (effectModeString == "Color Flash") {
} else if (effectModeString == "Color Flash") {
effectmode = 4;
}else if (effectModeString == "Rainbow Wave") {
} else if (effectModeString == "Rainbow Wave") {
effectmode = 5;
}else if (effectModeString == "Rainbow Flash") {
} else if (effectModeString == "Rainbow Flash") {
effectmode = 6;
}else if (effectModeString == "Knight Rider") {
} else if (effectModeString == "Knight Rider") {
effectmode = 7;
}else if (effectModeString == "Fire") {
} else if (effectModeString == "Fire") {
effectmode = 8;
}else if (effectModeString == "Tricolore") {
} else if (effectModeString == "Tricolore") {
effectmode = 9;
}
@ -330,7 +285,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
qCDebug(dcWs2812()) << "Sending" << payload << url.path();
CoapReply *reply = m_coap->post(CoapRequest(url), payload);
if (reply->isFinished() && reply->error() != CoapReply::NoError) {
if(reply->isFinished() && reply->error() != CoapReply::NoError) {
qCWarning(dcWs2812) << "CoAP reply finished with error" << reply->errorString();
setReachable(device, false);
reply->deleteLater();
@ -341,7 +296,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
m_asyncActions.insert(action.id(), device);
return DeviceManager::DeviceErrorAsync;
}else if(action.actionTypeId() == tcolor1ActionTypeId || action.actionTypeId() == tcolor2ActionTypeId || action.actionTypeId() == tcolor3ActionTypeId) {
} else if(action.actionTypeId() == tcolor1ActionTypeId || action.actionTypeId() == tcolor2ActionTypeId || action.actionTypeId() == tcolor3ActionTypeId) {
QUrl url;
url.setScheme("coap");
@ -356,7 +311,7 @@ DeviceManager::DeviceError DevicePluginWs2812::executeAction(Device *device, con
*
*/
if(action.actionTypeId() == tcolor1ActionTypeId){
if(action.actionTypeId() == tcolor1ActionTypeId) {
tColor1 = action.param(tcolor1StateParamTypeId).value().value<QColor>().toRgb();
} else if(action.actionTypeId() == tcolor2ActionTypeId){
tColor2 = action.param(tcolor2StateParamTypeId).value().value<QColor>().toRgb();
@ -558,6 +513,60 @@ Device *DevicePluginWs2812::findDevice(const QHostAddress &address)
return NULL;
}
void DevicePluginWs2812::onPluginTimer()
{
// Try to ping each device every 10 seconds to make sure it is still reachable
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == ws2812DeviceClassId) {
pingDevice(device);
}
}
}
void DevicePluginWs2812::onNetworkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
if (m_asyncNodeScans.keys().contains(reply)) {
DeviceClassId deviceClassId = m_asyncNodeScans.take(reply);
// Check HTTP status code
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
qCWarning(dcWs2812) << "Node scan reply HTTP error:" << reply->errorString();
emit devicesDiscovered(deviceClassId, QList<DeviceDescriptor>());
reply->deleteLater();
return;
}
QByteArray data = reply->readAll();
qCDebug(dcWs2812) << "Node discovery finished:" << endl << data;
QList<DeviceDescriptor> deviceDescriptors;
QList<QByteArray> lines = data.split('\n');
qCDebug(dcWs2812) << lines;
foreach (const QByteArray &line, lines) {
if (line.isEmpty())
continue;
QHostAddress address(QString(line.left(line.length() - 4)));
if (address.isNull())
continue;
qCDebug(dcWs2812) << "Found node" << address.toString();
// Create a deviceDescriptor for each found address
DeviceDescriptor descriptor(deviceClassId, "ws2812", address.toString());
ParamList params;
params.append(Param(hostParamTypeId, address.toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
// Inform the user which devices were found
emit devicesDiscovered(deviceClassId, deviceDescriptors);
}
// Delete the HTTP reply
reply->deleteLater();
}
void DevicePluginWs2812::coapReplyFinished(CoapReply *reply)
{
if (m_pingReplies.contains(reply)) {

View File

@ -27,6 +27,7 @@
#include "plugin/deviceplugin.h"
#include "types/action.h"
#include "coap/coap.h"
#include "plugintimer.h"
#include <QColor>
#include <QHash>
@ -39,20 +40,17 @@ class DevicePluginWs2812 : public DevicePlugin
public:
explicit DevicePluginWs2812();
~DevicePluginWs2812();
DeviceManager::HardwareResources requiredHardware() const override;
void init() override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void networkManagerReplyReady(QNetworkReply *reply) override;
void postSetupDevice(Device *device) override;
void guhTimer() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
PluginTimer *m_pluginTimer = nullptr;
QPointer<Coap> m_coap;
QHash<QNetworkReply *, DeviceClassId> m_asyncNodeScans;
QHash<CoapReply *, Device *> m_enableNotification;
@ -91,6 +89,8 @@ private:
QColor tColor3;
private slots:
void onPluginTimer();
void onNetworkReplyFinished();
void coapReplyFinished(CoapReply *reply);
void onNotificationReceived(const CoapObserveResource &resource, const int &notificationNumber, const QByteArray &payload);
};