mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-07-14 00:12:27 +02:00
Migrate plugin timer
This commit is contained in:
parent
0b1991d50a
commit
2b39765d58
@ -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()) {
|
||||
|
||||
@ -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 ¶ms) override;
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
|
||||
private slots:
|
||||
void onServiceEntryAdded(const AvahiServiceEntry &serviceEntry);
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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();
|
||||
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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
34
debian/control
vendored
@ -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,
|
||||
|
||||
1
debian/guh-plugin-dollhouse.install.in
vendored
1
debian/guh-plugin-dollhouse.install.in
vendored
@ -1 +0,0 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/guh/plugins/libguh_deviceplugindollhouse.so
|
||||
1
debian/guh-plugin-lircd.install.in
vendored
1
debian/guh-plugin-lircd.install.in
vendored
@ -1 +0,0 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/guh/plugins/libguh_devicepluginlircd.so
|
||||
@ -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)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ¶ms)
|
||||
@ -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){
|
||||
|
||||
@ -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 ¶ms) 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);
|
||||
|
||||
@ -62,11 +62,6 @@ DevicePluginGenericElements::DevicePluginGenericElements()
|
||||
{
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginGenericElements::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceNone;
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginGenericElements::setupDevice(Device *device)
|
||||
{
|
||||
// Toggle Button
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -41,7 +41,6 @@ public:
|
||||
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
|
||||
@ -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 \
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ¶ms)
|
||||
{
|
||||
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());
|
||||
|
||||
@ -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 ¶ms) 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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ¶ms)
|
||||
{
|
||||
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 ¶ms, 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 ¶ms, 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());
|
||||
|
||||
@ -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 ¶ms) 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 ¶ms, 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();
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
//}
|
||||
@ -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
|
||||
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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 \
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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 ¶ms) 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;
|
||||
};
|
||||
|
||||
@ -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 ¶ms)
|
||||
@ -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);
|
||||
|
||||
@ -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 ¶ms) 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();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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 ¶ms) 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 ¬ificationNumber, const QByteArray &payload);
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
};
|
||||
|
||||
@ -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 ¶ms)
|
||||
{
|
||||
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 ¶ms, 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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 ¶ms) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
|
||||
void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &upnpDeviceDescriptorList) override;
|
||||
DeviceManager::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, 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
|
||||
|
||||
@ -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 ¶ms)
|
||||
{
|
||||
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)) {
|
||||
|
||||
@ -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 ¶ms) 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 ¬ificationNumber, const QByteArray &payload);
|
||||
};
|
||||
|
||||
@ -26,12 +26,6 @@ DevicePluginTcpCommander::DevicePluginTcpCommander()
|
||||
{
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginTcpCommander::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceNone;
|
||||
}
|
||||
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginTcpCommander::setupDevice(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == tcpOutputDeviceClassId) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -67,11 +67,6 @@ DevicePluginUdpCommander::DevicePluginUdpCommander()
|
||||
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginUdpCommander::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceNone;
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginUdpCommander::setupDevice(Device *device)
|
||||
{
|
||||
// check port
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -35,7 +35,6 @@ class DevicePluginUnitec : public DevicePlugin
|
||||
public:
|
||||
explicit DevicePluginUnitec();
|
||||
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
|
||||
public slots:
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 ¶ms)
|
||||
{
|
||||
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 ¬ifyData)
|
||||
{
|
||||
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 ¬ification)
|
||||
{
|
||||
Q_UNUSED(notification)
|
||||
}
|
||||
|
||||
@ -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 ¶ms) 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 ¬ifyData);
|
||||
|
||||
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 ¬ification);
|
||||
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINWEMO_H
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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 ¶ms) 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 ¬ificationNumber, const QByteArray &payload);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user