mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-10-23 14:43:44 +02:00
added connection layer
This commit is contained in:
parent
3206f285ba
commit
f3e003eae2
513
philipshue/bridgeconnection.cpp
Normal file
513
philipshue/bridgeconnection.cpp
Normal file
@ -0,0 +1,513 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
||||||
|
* Copyright (C) 2015 - 2019 Simon Stürz <simon.stuerz@nymea.io> *
|
||||||
|
* Copyright (C) 2019 Bernhard Trinns <bernhard.trinnes@nymea.io> *
|
||||||
|
* *
|
||||||
|
* This file is part of nymea. *
|
||||||
|
* *
|
||||||
|
* 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 "bridgeconnection.h"
|
||||||
|
#include "devices/device.h"
|
||||||
|
#include "types/param.h"
|
||||||
|
#include "plugininfo.h"
|
||||||
|
#include "network/upnp/upnpdiscovery.h"
|
||||||
|
#include "network/upnp/upnpdiscoveryreply.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
|
||||||
|
BridgeConnection::BridgeConnection(HueBridge *bridge, HardwareManager *hardwareManager, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_hardwareManager(hardwareManager),
|
||||||
|
m_bridge(bridge)
|
||||||
|
{
|
||||||
|
m_bridge = new HueBridge(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BridgeConnection::~BridgeConnection()
|
||||||
|
{
|
||||||
|
m_hardwareManager->pluginTimerManager()->unregisterTimer(m_pluginTimer1Sec);
|
||||||
|
m_hardwareManager->pluginTimerManager()->unregisterTimer(m_pluginTimer5Sec);
|
||||||
|
m_hardwareManager->pluginTimerManager()->unregisterTimer(m_pluginTimer15Sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::init()
|
||||||
|
{
|
||||||
|
m_pluginTimer1Sec = m_hardwareManager->pluginTimerManager()->registerTimer(1);
|
||||||
|
connect(m_pluginTimer1Sec, &PluginTimer::timeout, this, [this]() {
|
||||||
|
// refresh sensors every second
|
||||||
|
if (m_remotes.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refreshSensors();
|
||||||
|
});
|
||||||
|
m_pluginTimer5Sec = m_hardwareManager->pluginTimerManager()->registerTimer(5);
|
||||||
|
connect(m_pluginTimer5Sec, &PluginTimer::timeout, this, [this]() {
|
||||||
|
// refresh lights every 5 seconds
|
||||||
|
refreshLights();
|
||||||
|
|
||||||
|
});
|
||||||
|
m_pluginTimer15Sec = m_hardwareManager->pluginTimerManager()->registerTimer(15);
|
||||||
|
connect(m_pluginTimer15Sec, &PluginTimer::timeout, this, [this]() {
|
||||||
|
// refresh bridges every 15 seconds
|
||||||
|
refreshBridge();
|
||||||
|
// search for new devices connected to the bridge
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::refreshLight(const QString &uuid)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
|
||||||
|
QNetworkRequest request(QUrl("http://" + light->hostAddress().toString() + "/api/" + light->apiKey() + "/lights/" + QString::number(light->id())));
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
|
||||||
|
//m_lightRefreshRequests.insert(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::refreshBridge()
|
||||||
|
{
|
||||||
|
// qCDebug(dcPhilipsHue()) << "refreshing bridge";
|
||||||
|
|
||||||
|
QNetworkRequest request(QUrl("http://" + m_bridge->hostAddress().toString() + "/api/" + m_bridge->apiKey() + "/config"));
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
//TODO abort old request and start new one
|
||||||
|
//m_bridgeRefreshRequests.insert(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::refreshLights()
|
||||||
|
{
|
||||||
|
// qCDebug(dcPhilipsHue()) << "refreshing lights";
|
||||||
|
QNetworkRequest request(QUrl("http://" + m_bridge->hostAddress().toString() + "/api/" + m_bridge->apiKey() + "/lights"));
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
//m_lightsRefreshRequests.insert(reply, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::refreshSensors()
|
||||||
|
{
|
||||||
|
// qCDebug(dcPhilipsHue()) << "refreshing sensors";
|
||||||
|
|
||||||
|
QNetworkRequest request(QUrl("http://" + m_bridge->hostAddress().toString() + "/api/" + m_bridge->apiKey() + "/sensors"));
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
//m_sensorsRefreshRequests.insert(reply, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::discoverBridgeDevices()
|
||||||
|
{
|
||||||
|
qCDebug(dcPhilipsHue) << "Discover bridge devices" << m_bridge->hostAddress();
|
||||||
|
|
||||||
|
QPair<QNetworkRequest, QByteArray> lightsRequest = m_bridge->createDiscoverLightsRequest();
|
||||||
|
QNetworkReply *lightsReply = m_hardwareManager->networkManager()->get(lightsRequest.first);
|
||||||
|
connect(lightsReply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
//m_bridgeLightsDiscoveryRequests.insert(lightsReply, device);
|
||||||
|
|
||||||
|
QPair<QNetworkRequest, QByteArray> sensorsRequest = m_bridge->createSearchSensorsRequest();
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->get(sensorsRequest.first);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
//m_bridgeSensorsDiscoveryRequests.insert(reply, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::searchNewDevices(const QString &serialNumber)
|
||||||
|
{
|
||||||
|
qCDebug(dcPhilipsHue) << "Discover bridge devices" << m_bridge->hostAddress();
|
||||||
|
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = m_bridge->createSearchLightsRequest(serialNumber);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->post(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
//m_bridgeSearchDevicesRequests.insert(reply, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::setPower(const QString &uuid, bool power)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(power);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::setBrightness(const QString &uuid, quint8 percent)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percent);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::setColor(const QString &uuid, QColor color)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = light->createSetColorRequest(color);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::setEffect(const QString &uuid, const QString &effect)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = light->createSetEffectRequest(effect);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::setTemperature(const QString &uuid, quint16 temperature)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = light->createSetTemperatureRequest(temperature);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::setFlash(const QString &uuid, const QString &mode)
|
||||||
|
{
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(mode);
|
||||||
|
QNetworkReply *reply = m_hardwareManager->networkManager()->put(request.first, request.second);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &BridgeConnection::networkManagerReplyReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BridgeConnection::processLightRefreshResponse(QString uuid, const QByteArray &data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
// check JSON error
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check response error
|
||||||
|
if (data.contains("error")) {
|
||||||
|
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||||
|
} else {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light: Invalid error message format";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HueLight *light = m_lights.value(uuid);
|
||||||
|
light->updateStates(jsonDoc.toVariant().toMap().value("state").toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::processBridgeRefreshResponse(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
// check JSON error
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Bridge:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//qCDebug(dcPhilipsHue()) << "Bridge refresh response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
|
||||||
|
|
||||||
|
QVariantMap configMap = jsonDoc.toVariant().toMap();
|
||||||
|
|
||||||
|
// mark bridge as reachable
|
||||||
|
bridgeReachableChanged(true);
|
||||||
|
//device->setStateValue(bridgeApiVersionStateTypeId, configMap.value("apiversion").toString());
|
||||||
|
//device->setStateValue(bridgeSoftwareVersionStateTypeId, configMap.value("swversion").toString());
|
||||||
|
|
||||||
|
int updateStatus = configMap.value("swupdate").toMap().value("updatestate").toInt();
|
||||||
|
switch (updateStatus) {
|
||||||
|
case 0:
|
||||||
|
//device->setStateValue(bridgeUpdateStatusStateTypeId, "Up to date");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
//device->setStateValue(bridgeUpdateStatusStateTypeId, "Downloading updates");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
//device->setStateValue(bridgeUpdateStatusStateTypeId, "Updates ready to install");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
//device->setStateValue(bridgeUpdateStatusStateTypeId, "Installing updates");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::processLightsRefreshResponse(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
// check JSON error
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check response error
|
||||||
|
if (data.contains("error")) {
|
||||||
|
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Lights:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||||
|
} else {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Lights: Invalid error message format";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update light states
|
||||||
|
QVariantMap lightsMap = jsonDoc.toVariant().toMap();
|
||||||
|
foreach (const QString &lightId, lightsMap.keys()) {
|
||||||
|
QVariantMap lightMap = lightsMap.value(lightId).toMap();
|
||||||
|
// get the light of this bridge
|
||||||
|
foreach (HueLight *light, m_lights.values()) {
|
||||||
|
if (light->id() == lightId.toInt()) {
|
||||||
|
light->updateStates(lightMap.value("state").toMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::processSensorsRefreshResponse(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
// check JSON error
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check response error
|
||||||
|
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Sensors:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update sensor states
|
||||||
|
QVariantMap sensorsMap = jsonDoc.toVariant().toMap();
|
||||||
|
foreach (const QString &sensorId, sensorsMap.keys()) {
|
||||||
|
QVariantMap sensorMap = sensorsMap.value(sensorId).toMap();
|
||||||
|
|
||||||
|
// Remotes
|
||||||
|
foreach (HueRemote *remote, m_remotes.values()) {
|
||||||
|
if (remote->id() == sensorId.toInt()) {
|
||||||
|
remote->updateStates(sensorMap.value("state").toMap(), sensorMap.value("config").toMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outdoor sensors
|
||||||
|
foreach (HueMotionSensor *motionSensor, m_motionSensors.values()) {
|
||||||
|
if (motionSensor->hasSensor(sensorId.toInt())) {
|
||||||
|
motionSensor->updateStates(sensorMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::processSetNameResponse(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
// check JSON error
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
||||||
|
//emit deviceSetupFinished(device, Device::DeviceSetupStatusFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check response error
|
||||||
|
if (data.contains("error")) {
|
||||||
|
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to set name of Hue:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
||||||
|
} else {
|
||||||
|
qCWarning(dcPhilipsHue) << "Failed to set name of Hue: Invalid error message format";
|
||||||
|
}
|
||||||
|
//emit setNameFinished(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BridgeConnection::networkManagerReplyReady()
|
||||||
|
{
|
||||||
|
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
// qCDebug(dcPhilipsHue()) << "Hue reply:" << status << reply->error() << reply->errorString();
|
||||||
|
|
||||||
|
// create user finished
|
||||||
|
if (m_pairingRequests.contains(reply)) {
|
||||||
|
PairingInfo *pairingInfo = m_pairingRequests.take(reply);
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Request error:" << status << reply->errorString();
|
||||||
|
pairingInfo->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processPairingResponse(pairingInfo, reply->readAll());
|
||||||
|
|
||||||
|
} else if (m_informationRequests.contains(reply)) {
|
||||||
|
PairingInfo *pairingInfo = m_informationRequests.take(reply);
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Request error:" << status << reply->errorString();
|
||||||
|
pairingInfo->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processInformationResponse(pairingInfo, reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_bridgeLightsDiscoveryRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Bridge light discovery error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processBridgeLightDiscoveryResponse(reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_bridgeSensorsDiscoveryRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Bridge sensor discovery error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processBridgeSensorDiscoveryResponse(reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_bridgeSearchDevicesRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Bridge search new devices error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
discoverBridgeDevices();
|
||||||
|
|
||||||
|
} else if (m_bridgeRefreshRequests == reply) {;
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Refresh Hue Bridge request error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processBridgeRefreshResponse(reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_lightRefreshRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Refresh Hue Light request error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processLightRefreshResponse(reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_lightsRefreshRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Refresh Hue lights request error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processLightsRefreshResponse(reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_sensorsRefreshRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Refresh Hue sensors request error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processSensorsRefreshResponse(reply->readAll());
|
||||||
|
|
||||||
|
} else if (m_asyncActions.contains(reply)) {
|
||||||
|
QPair<Device *, ActionId> actionInfo = m_asyncActions.take(reply);
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Execute Hue Light action request error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
//emit actionExecutionFinished(actionInfo.second, Device::DeviceErrorHardwareNotAvailable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processActionResponse(actionInfo.second, reply->readAll());
|
||||||
|
|
||||||
|
} else if (reply == m_setNameRequests) {
|
||||||
|
|
||||||
|
// check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPhilipsHue) << "Set name of Hue Light request error:" << status << reply->errorString();
|
||||||
|
bridgeReachableChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processSetNameResponse(reply->readAll());
|
||||||
|
} else {
|
||||||
|
qCWarning(dcPhilipsHue()) << "Unhandled bridge reply" << reply->error() << reply->readAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BridgeConnection::brightnessToPercentage(int brightness)
|
||||||
|
{
|
||||||
|
return qRound((100.0 * brightness) / 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BridgeConnection::percentageToBrightness(int percentage)
|
||||||
|
{
|
||||||
|
return qRound((255.0 * percentage) / 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BridgeConnection::abortRequests(QHash<QNetworkReply *, Device *> requestList, Device *device)
|
||||||
|
{
|
||||||
|
foreach (QNetworkReply* reply, requestList.keys()) {
|
||||||
|
if (requestList.value(reply) == device) {
|
||||||
|
reply->abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
135
philipshue/bridgeconnection.h
Normal file
135
philipshue/bridgeconnection.h
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
||||||
|
* Copyright (C) 2015 - 2019 Simon Stürz <simon.stuerz@nymea.io> *
|
||||||
|
* Copyright (C) 2019 Bernhard Trinns <bernhard.trinnes@nymea.io> *
|
||||||
|
* *
|
||||||
|
* This file is part of nymea. *
|
||||||
|
* *
|
||||||
|
* 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 BRIDGECONNECTION_H
|
||||||
|
#define BRIDGECONNECTION_H
|
||||||
|
|
||||||
|
#include "devices/deviceplugin.h"
|
||||||
|
#include "huebridge.h"
|
||||||
|
#include "huelight.h"
|
||||||
|
#include "hueremote.h"
|
||||||
|
#include "pairinginfo.h"
|
||||||
|
#include "huemotionsensor.h"
|
||||||
|
|
||||||
|
#include "plugintimer.h"
|
||||||
|
#include "network/networkaccessmanager.h"
|
||||||
|
#include "network/upnp/upnpdiscovery.h"
|
||||||
|
#include "devices/devicemanager.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class BridgeConnection : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit BridgeConnection(HueBridge *bridge, HardwareManager *hardwaremanager, QObject *parent = nullptr);
|
||||||
|
~BridgeConnection();
|
||||||
|
void init();
|
||||||
|
|
||||||
|
//bridge actions
|
||||||
|
void discoverBridgeDevices();
|
||||||
|
void searchNewDevices(const QString &serialNumber);
|
||||||
|
|
||||||
|
//light actions
|
||||||
|
void setPower(const QString &uuid, bool power);
|
||||||
|
void setBrightness(const QString &uuid, quint8 percent);
|
||||||
|
void setColor(const QString &uuid, QColor percent);
|
||||||
|
void setEffect(const QString &uuid, const QString &effect);
|
||||||
|
void setFlash(const QString &uuid, const QString &flashMode);
|
||||||
|
void setTemperature(const QString &uuid, quint16 temperature);
|
||||||
|
|
||||||
|
void setLightName();
|
||||||
|
void setRemoteName();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void lightStateChanged();
|
||||||
|
void remoteStateChanged();
|
||||||
|
void onRemoteButtonEvent(int buttonCode);
|
||||||
|
|
||||||
|
// Motion sensor
|
||||||
|
void onMotionSensorReachableChanged(bool reachable);
|
||||||
|
void onMotionSensorBatteryLevelChanged(int batteryLevel);
|
||||||
|
void onMotionSensorTemperatureChanged(double temperature);
|
||||||
|
void onMotionSensorPresenceChanged(bool presence);
|
||||||
|
void onMotionSensorLightIntensityChanged(double lightIntensity);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void networkManagerReplyReady();
|
||||||
|
void onDeviceNameChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
HardwareManager *m_hardwareManager = nullptr;
|
||||||
|
|
||||||
|
PluginTimer *m_pluginTimer1Sec = nullptr;
|
||||||
|
PluginTimer *m_pluginTimer5Sec = nullptr;
|
||||||
|
PluginTimer *m_pluginTimer15Sec = nullptr;
|
||||||
|
|
||||||
|
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
|
||||||
|
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
|
||||||
|
|
||||||
|
QNetworkReply *m_lightRefreshRequests;
|
||||||
|
QNetworkReply *m_setNameRequests;
|
||||||
|
QNetworkReply *m_bridgeRefreshRequests;
|
||||||
|
QNetworkReply *m_lightsRefreshRequests;
|
||||||
|
QNetworkReply *m_sensorsRefreshRequests;
|
||||||
|
QNetworkReply *m_bridgeLightsDiscoveryRequests;
|
||||||
|
QNetworkReply *m_bridgeSensorsDiscoveryRequests;
|
||||||
|
QNetworkReply *m_bridgeSearchDevicesRequests;
|
||||||
|
|
||||||
|
QHash<QNetworkReply *, QPair<Device *, ActionId> > m_asyncActions;
|
||||||
|
|
||||||
|
HueBridge *m_bridge;
|
||||||
|
QHash<QString, HueLight *> m_lights;
|
||||||
|
QHash<QString, HueRemote *> m_remotes;
|
||||||
|
QHash<QString, HueMotionSensor *> m_motionSensors;
|
||||||
|
|
||||||
|
void refreshLight(const QString &uuid); //
|
||||||
|
void refreshBridge();
|
||||||
|
void refreshLights();
|
||||||
|
void refreshSensors();
|
||||||
|
|
||||||
|
void processBridgeLightDiscoveryResponse(const QByteArray &data);
|
||||||
|
void processBridgeSensorDiscoveryResponse(const QByteArray &data);
|
||||||
|
void processLightRefreshResponse(const QByteArray &data);
|
||||||
|
void processBridgeRefreshResponse(const QByteArray &data);
|
||||||
|
void processLightsRefreshResponse(const QByteArray &data);
|
||||||
|
void processSensorsRefreshResponse(const QByteArray &data);
|
||||||
|
void processSetNameResponse(const QByteArray &data);
|
||||||
|
void processPairingResponse(PairingInfo *pairingInfo, const QByteArray &data);
|
||||||
|
void processInformationResponse(PairingInfo *pairingInfo, const QByteArray &data);
|
||||||
|
void processActionResponse(const ActionId actionId, const QByteArray &data);
|
||||||
|
|
||||||
|
void bridgeReachableChanged(const bool &reachable);
|
||||||
|
|
||||||
|
bool lightAlreadyAdded(const QString &uuid);
|
||||||
|
bool sensorAlreadyAdded(const QString &uuid);
|
||||||
|
|
||||||
|
int brightnessToPercentage(int brightness);
|
||||||
|
int percentageToBrightness(int percentage);
|
||||||
|
|
||||||
|
void abortRequests(QHash<QNetworkReply *, Device *> requestList);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BRIDGECONNECTION_H
|
||||||
@ -1,8 +1,9 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
||||||
* Copyright (C) 2015 - 2019 Simon Stürz <simon.stuerz@guh.io> *
|
* Copyright (C) 2015 - 2019 Simon Stürz <simon.stuerz@nymea.io> *
|
||||||
* Copyright (C) 2018 Michael Zanetti <michael.zanetti@guh.io> *
|
* Copyright (C) 2018 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
|
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea. *
|
* This file is part of nymea. *
|
||||||
* *
|
* *
|
||||||
@ -41,42 +42,6 @@ DevicePluginPhilipsHue::DevicePluginPhilipsHue()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DevicePluginPhilipsHue::~DevicePluginPhilipsHue()
|
|
||||||
{
|
|
||||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer1Sec);
|
|
||||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer5Sec);
|
|
||||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer15Sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::init()
|
|
||||||
{
|
|
||||||
m_pluginTimer1Sec = hardwareManager()->pluginTimerManager()->registerTimer(1);
|
|
||||||
connect(m_pluginTimer1Sec, &PluginTimer::timeout, this, [this]() {
|
|
||||||
// refresh sensors every second
|
|
||||||
if (m_remotes.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (HueBridge *bridge, m_bridges.keys()) {
|
|
||||||
refreshSensors(bridge);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
m_pluginTimer5Sec = hardwareManager()->pluginTimerManager()->registerTimer(5);
|
|
||||||
connect(m_pluginTimer5Sec, &PluginTimer::timeout, this, [this]() {
|
|
||||||
// refresh lights every 5 seconds
|
|
||||||
foreach (HueBridge *bridge, m_bridges.keys()) {
|
|
||||||
refreshLights(bridge);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
m_pluginTimer15Sec = hardwareManager()->pluginTimerManager()->registerTimer(15);
|
|
||||||
connect(m_pluginTimer15Sec, &PluginTimer::timeout, this, [this]() {
|
|
||||||
// refresh bridges every 15 seconds
|
|
||||||
foreach (Device *device, m_bridges.values()) {
|
|
||||||
refreshBridge(device);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Device::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
Device::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||||
{
|
{
|
||||||
Q_UNUSED(params)
|
Q_UNUSED(params)
|
||||||
@ -117,7 +82,6 @@ Device::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId
|
|||||||
discovery->results.append(descriptor);
|
discovery->results.append(descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finishDiscovery(discovery);
|
finishDiscovery(discovery);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -160,10 +124,8 @@ Device::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceClassId
|
|||||||
qCDebug(dcPhilipsHue()) << "N-UPnP: Found Hue bridge:" << bridgeId;
|
qCDebug(dcPhilipsHue()) << "N-UPnP: Found Hue bridge:" << bridgeId;
|
||||||
discovery->results.append(descriptor);
|
discovery->results.append(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
finishDiscovery(discovery);
|
finishDiscovery(discovery);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +145,7 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
|
|||||||
device->setParamValue(bridgeDeviceApiKeyParamTypeId, b->apiKey());
|
device->setParamValue(bridgeDeviceApiKeyParamTypeId, b->apiKey());
|
||||||
device->setParamValue(bridgeDeviceZigbeeChannelParamTypeId, b->zigbeeChannel());
|
device->setParamValue(bridgeDeviceZigbeeChannelParamTypeId, b->zigbeeChannel());
|
||||||
device->setParamValue(bridgeDeviceMacParamTypeId, b->macAddress());
|
device->setParamValue(bridgeDeviceMacParamTypeId, b->macAddress());
|
||||||
m_bridges.insert(b, device);
|
m_bridgeConnections.insert(device->id(), );
|
||||||
device->setStateValue(bridgeConnectedStateTypeId, true);
|
device->setStateValue(bridgeConnectedStateTypeId, true);
|
||||||
discoverBridgeDevices(b);
|
discoverBridgeDevices(b);
|
||||||
return Device::DeviceSetupStatusSuccess;
|
return Device::DeviceSetupStatusSuccess;
|
||||||
@ -193,15 +155,18 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
|
|||||||
// Loaded bridge
|
// Loaded bridge
|
||||||
qCDebug(dcPhilipsHue) << "Setup Hue Bridge" << device->params();
|
qCDebug(dcPhilipsHue) << "Setup Hue Bridge" << device->params();
|
||||||
|
|
||||||
|
|
||||||
HueBridge *bridge = new HueBridge(this);
|
HueBridge *bridge = new HueBridge(this);
|
||||||
bridge->setId(device->paramValue(bridgeDeviceIdParamTypeId).toString());
|
bridge->setId(device->paramValue(bridgeDeviceIdParamTypeId).toString());
|
||||||
bridge->setApiKey(device->paramValue(bridgeDeviceApiKeyParamTypeId).toString());
|
bridge->setApiKey(device->paramValue(bridgeDeviceApiKeyParamTypeId).toString());
|
||||||
bridge->setHostAddress(QHostAddress(device->paramValue(bridgeDeviceHostParamTypeId).toString()));
|
bridge->setHostAddress(QHostAddress(device->paramValue(bridgeDeviceHostParamTypeId).toString()));
|
||||||
bridge->setMacAddress(device->paramValue(bridgeDeviceMacParamTypeId).toString());
|
bridge->setMacAddress(device->paramValue(bridgeDeviceMacParamTypeId).toString());
|
||||||
bridge->setZigbeeChannel(device->paramValue(bridgeDeviceZigbeeChannelParamTypeId).toInt());
|
bridge->setZigbeeChannel(device->paramValue(bridgeDeviceZigbeeChannelParamTypeId).toInt());
|
||||||
m_bridges.insert(bridge, device);
|
|
||||||
|
|
||||||
discoverBridgeDevices(bridge);
|
BridgeConnection *bridgeConnection = new BridgeConnection(bridge, hardwareManager(), this);
|
||||||
|
m_bridgeConnections.insert(device->id(), bridgeConnection);
|
||||||
|
|
||||||
|
bridgeConnection->discoverBridgeDevices();
|
||||||
return Device::DeviceSetupStatusSuccess;
|
return Device::DeviceSetupStatusSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +174,7 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
|
|||||||
if (device->deviceClassId() == colorLightDeviceClassId) {
|
if (device->deviceClassId() == colorLightDeviceClassId) {
|
||||||
qCDebug(dcPhilipsHue) << "Setup Hue color light" << device->params();
|
qCDebug(dcPhilipsHue) << "Setup Hue color light" << device->params();
|
||||||
|
|
||||||
HueBridge *bridge = m_bridges.key(myDevices().findById(device->parentId()));
|
BridgeConnection *bridge = m_bridgeConnections;
|
||||||
HueLight *hueLight = new HueLight(this);
|
HueLight *hueLight = new HueLight(this);
|
||||||
hueLight->setHostAddress(bridge->hostAddress());
|
hueLight->setHostAddress(bridge->hostAddress());
|
||||||
hueLight->setApiKey(bridge->apiKey());
|
hueLight->setApiKey(bridge->apiKey());
|
||||||
@ -297,7 +262,7 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *device)
|
|||||||
if (device->deviceClassId() == remoteDeviceClassId) {
|
if (device->deviceClassId() == remoteDeviceClassId) {
|
||||||
qCDebug(dcPhilipsHue) << "Setup Hue remote" << device->params() << device->deviceClassId();
|
qCDebug(dcPhilipsHue) << "Setup Hue remote" << device->params() << device->deviceClassId();
|
||||||
|
|
||||||
HueBridge *bridge = m_bridges.key(myDevices().findById(device->parentId()));
|
BridgeConnection *bridge = m_bridgeConnections.value(device->parentId());
|
||||||
HueRemote *hueRemote = new HueRemote(this);
|
HueRemote *hueRemote = new HueRemote(this);
|
||||||
hueRemote->setHostAddress(bridge->hostAddress());
|
hueRemote->setHostAddress(bridge->hostAddress());
|
||||||
hueRemote->setApiKey(bridge->apiKey());
|
hueRemote->setApiKey(bridge->apiKey());
|
||||||
@ -486,148 +451,6 @@ Device::DeviceSetupStatus DevicePluginPhilipsHue::confirmPairing(const PairingTr
|
|||||||
return Device::DeviceSetupStatusAsync;
|
return Device::DeviceSetupStatusAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::networkManagerReplyReady()
|
|
||||||
{
|
|
||||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
|
|
||||||
// qCDebug(dcPhilipsHue()) << "Hue reply:" << status << reply->error() << reply->errorString();
|
|
||||||
|
|
||||||
// create user finished
|
|
||||||
if (m_pairingRequests.contains(reply)) {
|
|
||||||
PairingInfo *pairingInfo = m_pairingRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Request error:" << status << reply->errorString();
|
|
||||||
pairingInfo->deleteLater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processPairingResponse(pairingInfo, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_informationRequests.contains(reply)) {
|
|
||||||
PairingInfo *pairingInfo = m_informationRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Request error:" << status << reply->errorString();
|
|
||||||
pairingInfo->deleteLater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processInformationResponse(pairingInfo, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_bridgeLightsDiscoveryRequests.contains(reply)) {
|
|
||||||
Device *device = m_bridgeLightsDiscoveryRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Bridge light discovery error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processBridgeLightDiscoveryResponse(device, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_bridgeSensorsDiscoveryRequests.contains(reply)) {
|
|
||||||
Device *device = m_bridgeSensorsDiscoveryRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Bridge sensor discovery error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processBridgeSensorDiscoveryResponse(device, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_bridgeSearchDevicesRequests.contains(reply)) {
|
|
||||||
Device *device = m_bridgeSearchDevicesRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Bridge search new devices error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
discoverBridgeDevices(m_bridges.key(device));
|
|
||||||
|
|
||||||
} else if (m_bridgeRefreshRequests.contains(reply)) {
|
|
||||||
Device *device = m_bridgeRefreshRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
if (device->stateValue(bridgeConnectedStateTypeId).toBool()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Refresh Hue Bridge request error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processBridgeRefreshResponse(device, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_lightRefreshRequests.contains(reply)) {
|
|
||||||
Device *device = m_lightRefreshRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Refresh Hue Light request error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processLightRefreshResponse(device, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_lightsRefreshRequests.contains(reply)) {
|
|
||||||
Device *device = m_lightsRefreshRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
if (device->stateValue(bridgeConnectedStateTypeId).toBool()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Refresh Hue lights request error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processLightsRefreshResponse(device, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_sensorsRefreshRequests.contains(reply)) {
|
|
||||||
Device *device = m_sensorsRefreshRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
if (device->stateValue(bridgeConnectedStateTypeId).toBool()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Refresh Hue sensors request error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processSensorsRefreshResponse(device, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_asyncActions.contains(reply)) {
|
|
||||||
QPair<Device *, ActionId> actionInfo = m_asyncActions.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Execute Hue Light action request error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(actionInfo.first, false);
|
|
||||||
emit actionExecutionFinished(actionInfo.second, Device::DeviceErrorHardwareNotAvailable);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processActionResponse(actionInfo.first, actionInfo.second, reply->readAll());
|
|
||||||
|
|
||||||
} else if (m_setNameRequests.contains(reply)) {
|
|
||||||
Device *device = m_setNameRequests.take(reply);
|
|
||||||
|
|
||||||
// check HTTP status code
|
|
||||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Set name of Hue Light request error:" << status << reply->errorString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processSetNameResponse(device, reply->readAll());
|
|
||||||
} else {
|
|
||||||
qCWarning(dcPhilipsHue()) << "Unhandled bridge reply" << reply->error() << reply->readAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::onDeviceNameChanged()
|
void DevicePluginPhilipsHue::onDeviceNameChanged()
|
||||||
{
|
{
|
||||||
Device *device = static_cast<Device*>(sender());
|
Device *device = static_cast<Device*>(sender());
|
||||||
@ -672,48 +495,39 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
|
|||||||
|
|
||||||
// Color light
|
// Color light
|
||||||
if (device->deviceClassId() == colorLightDeviceClassId) {
|
if (device->deviceClassId() == colorLightDeviceClassId) {
|
||||||
HueLight *light = m_lights.key(device);
|
|
||||||
|
|
||||||
if (!light->reachable()) {
|
BridgeConnection* bridge = m_bridgeConnections.value(device->parentId());
|
||||||
|
QString uuid = device->paramValue(colorLightDeviceUuidParamTypeId).toString();
|
||||||
|
|
||||||
|
/*if (!light->reachable()) {
|
||||||
qCWarning(dcPhilipsHue) << "Light" << light->name() << "not reachable";
|
qCWarning(dcPhilipsHue) << "Light" << light->name() << "not reachable";
|
||||||
return Device::DeviceErrorHardwareNotAvailable;
|
return Device::DeviceErrorHardwareNotAvailable;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (action.actionTypeId() == colorLightPowerActionTypeId) {
|
if (action.actionTypeId() == colorLightPowerActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(action.param(colorLightPowerActionPowerParamTypeId).value().toBool());
|
//get bridge
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
bridge->setPower(uuid, action.param(colorLightPowerActionPowerParamTypeId).value().toBool())
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
//m_asyncActions.insert(device, action.id());
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorLightColorActionTypeId) {
|
} else if (action.actionTypeId() == colorLightColorActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetColorRequest(action.param(colorLightColorActionColorParamTypeId).value().value<QColor>());
|
bridge->setColor(uuid, action.param(colorLightColorActionColorParamTypeId).value().value<QColor>());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply,QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply,QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorLightBrightnessActionTypeId) {
|
} else if (action.actionTypeId() == colorLightBrightnessActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percentageToBrightness(action.param(colorLightBrightnessActionBrightnessParamTypeId).value().toInt()));
|
bridge->setBrightness(uuid, action.param(colorLightBrightnessActionBrightnessParamTypeId).value().toInt());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorLightEffectActionTypeId) {
|
} else if (action.actionTypeId() == colorLightEffectActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetEffectRequest(action.param(colorLightEffectActionEffectParamTypeId).value().toString());
|
bridge->setEffect(uuid, action.param(colorLightEffectActionEffectParamTypeId).value().toString());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorLightAlertActionTypeId) {
|
} else if (action.actionTypeId() == colorLightAlertActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(action.param(colorLightAlertActionAlertParamTypeId).value().toString());
|
bridge->setFlash(uuid, action.param(colorLightAlertActionAlertParamTypeId).value().toString());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorLightColorTemperatureActionTypeId) {
|
} else if (action.actionTypeId() == colorLightColorTemperatureActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetTemperatureRequest(action.param(colorLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
|
bridge->setTemperature(uuid, action.param(colorLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorActionTypeNotFound;
|
return Device::DeviceErrorActionTypeNotFound;
|
||||||
@ -721,36 +535,29 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
|
|||||||
|
|
||||||
// Color temperature light
|
// Color temperature light
|
||||||
if (device->deviceClassId() == colorTemperatureLightDeviceClassId) {
|
if (device->deviceClassId() == colorTemperatureLightDeviceClassId) {
|
||||||
HueLight *light = m_lights.key(device);
|
BridgeConnection* bridge = m_bridgeConnections.value(device->parentId());
|
||||||
|
QString uuid = device->paramValue(colorTemperatureLightDeviceUuidParamTypeId).toString();
|
||||||
|
|
||||||
if (!light->reachable()) {
|
/*if (!light->reachable()) {
|
||||||
qCWarning(dcPhilipsHue) << "Light" << light->name() << "not reachable";
|
qCWarning(dcPhilipsHue) << "Light" << light->name() << "not reachable";
|
||||||
return Device::DeviceErrorHardwareNotAvailable;
|
return Device::DeviceErrorHardwareNotAvailable;
|
||||||
}
|
}*/ //TODO
|
||||||
|
|
||||||
if (action.actionTypeId() == colorTemperatureLightPowerActionTypeId) {
|
if (action.actionTypeId() == colorTemperatureLightPowerActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(action.param(colorTemperatureLightPowerActionPowerParamTypeId).value().toBool());
|
bridge->setTemperature(uuid, action.param(colorTemperatureLightPowerActionPowerParamTypeId).value().toBool());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorTemperatureLightBrightnessActionTypeId) {
|
} else if (action.actionTypeId() == colorTemperatureLightBrightnessActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percentageToBrightness(action.param(colorTemperatureLightBrightnessActionBrightnessParamTypeId).value().toInt()));
|
bridge->setBrightness(uuid, action.param(colorTemperatureLightBrightnessActionBrightnessParamTypeId).value().toInt());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorTemperatureLightAlertActionTypeId) {
|
} else if (action.actionTypeId() == colorTemperatureLightAlertActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(action.param(colorTemperatureLightAlertActionAlertParamTypeId).value().toString());
|
bridge->setFlash(uuid, action.param(colorTemperatureLightAlertActionAlertParamTypeId).value().toString());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == colorTemperatureLightColorTemperatureActionTypeId) {
|
} else if (action.actionTypeId() == colorTemperatureLightColorTemperatureActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetTemperatureRequest(action.param(colorTemperatureLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
|
bridge->setTemperature(uuid, action.param(colorTemperatureLightColorTemperatureActionColorTemperatureParamTypeId).value().toInt());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorActionTypeNotFound;
|
return Device::DeviceErrorActionTypeNotFound;
|
||||||
@ -758,30 +565,28 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
|
|||||||
|
|
||||||
// Dimmable light
|
// Dimmable light
|
||||||
if (device->deviceClassId() == dimmableLightDeviceClassId) {
|
if (device->deviceClassId() == dimmableLightDeviceClassId) {
|
||||||
HueLight *light = m_lights.key(device);
|
|
||||||
|
|
||||||
if (!light->reachable()) {
|
BridgeConnection* bridge = m_bridgeConnections.value(device->parentId());
|
||||||
|
QString uuid = device->paramValue(dimmableLightDeviceUuidParamTypeId).toString();
|
||||||
|
|
||||||
|
/*if (!light->reachable()) {
|
||||||
qCWarning(dcPhilipsHue) << "Light" << light->name() << "not reachable";
|
qCWarning(dcPhilipsHue) << "Light" << light->name() << "not reachable";
|
||||||
return Device::DeviceErrorHardwareNotAvailable;
|
return Device::DeviceErrorHardwareNotAvailable;
|
||||||
}
|
}*/ //TODO
|
||||||
|
|
||||||
if (action.actionTypeId() == dimmableLightPowerActionTypeId) {
|
if (action.actionTypeId() == dimmableLightPowerActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetPowerRequest(action.param(dimmableLightPowerActionPowerParamTypeId).value().toBool());
|
bridge->setPower(uuid, action.param(dimmableLightPowerActionPowerParamTypeId).value().toBool());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == dimmableLightBrightnessActionTypeId) {
|
} else if (action.actionTypeId() == dimmableLightBrightnessActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createSetBrightnessRequest(percentageToBrightness(action.param(dimmableLightBrightnessActionBrightnessParamTypeId).value().toInt()));
|
bridge->setBrightness(uuid, action.param(dimmableLightBrightnessActionBrightnessParamTypeId).value().toInt());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
} else if (action.actionTypeId() == dimmableLightAlertActionTypeId) {
|
} else if (action.actionTypeId() == dimmableLightAlertActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = light->createFlashRequest(action.param(dimmableLightAlertActionAlertParamTypeId).value().toString());
|
bridge->setFlash(uuid, action.param(dimmableLightAlertActionAlertParamTypeId).value().toString());
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->put(request.first, request.second);
|
//m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_asyncActions.insert(reply, QPair<Device *, ActionId>(device, action.id()));
|
|
||||||
return Device::DeviceErrorAsync;
|
return Device::DeviceErrorAsync;
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorActionTypeNotFound;
|
return Device::DeviceErrorActionTypeNotFound;
|
||||||
@ -789,14 +594,15 @@ Device::DeviceError DevicePluginPhilipsHue::executeAction(Device *device, const
|
|||||||
|
|
||||||
// Hue bridge
|
// Hue bridge
|
||||||
if (device->deviceClassId() == bridgeDeviceClassId) {
|
if (device->deviceClassId() == bridgeDeviceClassId) {
|
||||||
HueBridge *bridge = m_bridges.key(device);
|
BridgeConnection* bridge = m_bridgeConnections.value(device->id());
|
||||||
|
|
||||||
if (!device->stateValue(bridgeConnectedStateTypeId).toBool()) {
|
if (!device->stateValue(bridgeConnectedStateTypeId).toBool()) {
|
||||||
qCWarning(dcPhilipsHue) << "Bridge" << bridge->hostAddress().toString() << "not reachable";
|
qCWarning(dcPhilipsHue) << "Bridge" << bridge->hostAddress().toString() << "not reachable";
|
||||||
return Device::DeviceErrorHardwareNotAvailable;
|
return Device::DeviceErrorHardwareNotAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == bridgeSearchNewDevicesActionTypeId) {
|
if (action.actionTypeId() == bridgeSearchNewDevicesActionTypeId) {
|
||||||
searchNewDevices(bridge, action.param(bridgeSearchNewDevicesActionSerialParamTypeId).value().toString());
|
bridge->searchNewDevices(action.param(bridgeSearchNewDevicesActionSerialParamTypeId).value().toString());
|
||||||
return Device::DeviceErrorNoError;
|
return Device::DeviceErrorNoError;
|
||||||
} else if (action.actionTypeId() == bridgeCheckForUpdatesActionTypeId) {
|
} else if (action.actionTypeId() == bridgeCheckForUpdatesActionTypeId) {
|
||||||
QPair<QNetworkRequest, QByteArray> request = bridge->createCheckUpdatesRequest();
|
QPair<QNetworkRequest, QByteArray> request = bridge->createCheckUpdatesRequest();
|
||||||
@ -962,79 +768,7 @@ void DevicePluginPhilipsHue::onMotionSensorLightIntensityChanged(double lightInt
|
|||||||
sensorDevice->setStateValue(sensor->lightIntensityStateTypeId(), lightIntensity);
|
sensorDevice->setStateValue(sensor->lightIntensityStateTypeId(), lightIntensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = hardwareManager()->networkManager()->get(request);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_lightRefreshRequests.insert(reply, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::refreshBridge(Device *device)
|
|
||||||
{
|
|
||||||
HueBridge *bridge = m_bridges.key(device);
|
|
||||||
// qCDebug(dcPhilipsHue()) << "refreshing bridge";
|
|
||||||
|
|
||||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/config"));
|
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_bridgeRefreshRequests.insert(reply, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::refreshLights(HueBridge *bridge)
|
|
||||||
{
|
|
||||||
Device *device = m_bridges.value(bridge);
|
|
||||||
// qCDebug(dcPhilipsHue()) << "refreshing lights";
|
|
||||||
|
|
||||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/lights"));
|
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_lightsRefreshRequests.insert(reply, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::refreshSensors(HueBridge *bridge)
|
|
||||||
{
|
|
||||||
Device *device = m_bridges.value(bridge);
|
|
||||||
// qCDebug(dcPhilipsHue()) << "refreshing sensors";
|
|
||||||
|
|
||||||
QNetworkRequest request(QUrl("http://" + bridge->hostAddress().toString() + "/api/" + bridge->apiKey() + "/sensors"));
|
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_sensorsRefreshRequests.insert(reply, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::discoverBridgeDevices(HueBridge *bridge)
|
|
||||||
{
|
|
||||||
Device *device = m_bridges.value(bridge);
|
|
||||||
qCDebug(dcPhilipsHue) << "Discover bridge devices" << bridge->hostAddress();
|
|
||||||
|
|
||||||
QPair<QNetworkRequest, QByteArray> lightsRequest = bridge->createDiscoverLightsRequest();
|
|
||||||
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();
|
|
||||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(sensorsRequest.first);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &DevicePluginPhilipsHue::networkManagerReplyReady);
|
|
||||||
m_bridgeSensorsDiscoveryRequests.insert(reply, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::searchNewDevices(HueBridge *bridge, const QString &serialNumber)
|
|
||||||
{
|
|
||||||
Device *device = m_bridges.value(bridge);
|
|
||||||
qCDebug(dcPhilipsHue) << "Discover bridge devices" << bridge->hostAddress();
|
|
||||||
|
|
||||||
QPair<QNetworkRequest, QByteArray> request = bridge->createSearchLightsRequest(serialNumber);
|
|
||||||
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)
|
void DevicePluginPhilipsHue::setLightName(Device *device)
|
||||||
{
|
{
|
||||||
@ -1321,175 +1055,7 @@ void DevicePluginPhilipsHue::processBridgeSensorDiscoveryResponse(Device *device
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::processLightRefreshResponse(Device *device, const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
// check JSON error
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check response error
|
|
||||||
if (data.contains("error")) {
|
|
||||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
|
||||||
} else {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Light: Invalid error message format";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HueLight *light = m_lights.key(device);
|
|
||||||
light->updateStates(jsonDoc.toVariant().toMap().value("state").toMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::processBridgeRefreshResponse(Device *device, const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
// check JSON error
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Bridge:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
|
||||||
bridgeReachableChanged(device, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qCDebug(dcPhilipsHue()) << "Bridge refresh response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
|
|
||||||
|
|
||||||
QVariantMap configMap = jsonDoc.toVariant().toMap();
|
|
||||||
|
|
||||||
// mark bridge as reachable
|
|
||||||
bridgeReachableChanged(device, true);
|
|
||||||
device->setStateValue(bridgeApiVersionStateTypeId, configMap.value("apiversion").toString());
|
|
||||||
device->setStateValue(bridgeSoftwareVersionStateTypeId, configMap.value("swversion").toString());
|
|
||||||
|
|
||||||
int updateStatus = configMap.value("swupdate").toMap().value("updatestate").toInt();
|
|
||||||
switch (updateStatus) {
|
|
||||||
case 0:
|
|
||||||
device->setStateValue(bridgeUpdateStatusStateTypeId, "Up to date");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
device->setStateValue(bridgeUpdateStatusStateTypeId, "Downloading updates");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
device->setStateValue(bridgeUpdateStatusStateTypeId, "Updates ready to install");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
device->setStateValue(bridgeUpdateStatusStateTypeId, "Installing updates");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::processLightsRefreshResponse(Device *device, const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
// check JSON error
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check response error
|
|
||||||
if (data.contains("error")) {
|
|
||||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Lights:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
|
||||||
} else {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Lights: Invalid error message format";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update light states
|
|
||||||
QVariantMap lightsMap = jsonDoc.toVariant().toMap();
|
|
||||||
foreach (const QString &lightId, lightsMap.keys()) {
|
|
||||||
QVariantMap lightMap = lightsMap.value(lightId).toMap();
|
|
||||||
// get the light of this bridge
|
|
||||||
foreach (HueLight *light, m_lights.keys()) {
|
|
||||||
if (light->id() == lightId.toInt() && m_lights.value(light)->parentId() == device->id()) {
|
|
||||||
light->updateStates(lightMap.value("state").toMap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::processSensorsRefreshResponse(Device *device, const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
// check JSON error
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check response error
|
|
||||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to refresh Hue Sensors:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update sensor states
|
|
||||||
QVariantMap sensorsMap = jsonDoc.toVariant().toMap();
|
|
||||||
foreach (const QString &sensorId, sensorsMap.keys()) {
|
|
||||||
QVariantMap sensorMap = sensorsMap.value(sensorId).toMap();
|
|
||||||
|
|
||||||
// Remotes
|
|
||||||
foreach (HueRemote *remote, m_remotes.keys()) {
|
|
||||||
if (remote->id() == sensorId.toInt() && m_remotes.value(remote)->parentId() == device->id()) {
|
|
||||||
remote->updateStates(sensorMap.value("state").toMap(), sensorMap.value("config").toMap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outdoor sensors
|
|
||||||
foreach (HueMotionSensor *motionSensor, m_motionSensors.keys()) {
|
|
||||||
if (motionSensor->hasSensor(sensorId.toInt()) && m_motionSensors.value(motionSensor)->parentId() == device->id()) {
|
|
||||||
motionSensor->updateStates(sensorMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::processSetNameResponse(Device *device, const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
// check JSON error
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Hue Bridge json error in response" << error.errorString();
|
|
||||||
emit deviceSetupFinished(device, Device::DeviceSetupStatusFailure);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check response error
|
|
||||||
if (data.contains("error")) {
|
|
||||||
if (!jsonDoc.toVariant().toList().isEmpty()) {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to set name of Hue:" << jsonDoc.toVariant().toList().first().toMap().value("error").toMap().value("description").toString();
|
|
||||||
} else {
|
|
||||||
qCWarning(dcPhilipsHue) << "Failed to set name of Hue: Invalid error message format";
|
|
||||||
}
|
|
||||||
emit deviceSetupFinished(device, Device::DeviceSetupStatusFailure);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->deviceClassId() == colorLightDeviceClassId || device->deviceClassId() == dimmableLightDeviceClassId)
|
|
||||||
refreshLight(device);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginPhilipsHue::processPairingResponse(PairingInfo *pairingInfo, const QByteArray &data)
|
void DevicePluginPhilipsHue::processPairingResponse(PairingInfo *pairingInfo, const QByteArray &data)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
|
||||||
* Copyright (C) 2015 - 2019 Simon Stürz <simon.stuerz@guh.io> *
|
* Copyright (C) 2015 - 2019 Simon Stürz <simon.stuerz@nymea.io> *
|
||||||
|
* Copyright (C) 2019 Bernhard Trinns <bernhard.trinnes@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea. *
|
* This file is part of nymea. *
|
||||||
* *
|
* *
|
||||||
@ -25,12 +26,12 @@
|
|||||||
#define DEVICEPLUGINPHILIPSHUE_H
|
#define DEVICEPLUGINPHILIPSHUE_H
|
||||||
|
|
||||||
#include "devices/deviceplugin.h"
|
#include "devices/deviceplugin.h"
|
||||||
|
#include "bridgeconnection.h"
|
||||||
#include "huebridge.h"
|
#include "huebridge.h"
|
||||||
#include "huelight.h"
|
#include "huelight.h"
|
||||||
#include "hueremote.h"
|
#include "hueremote.h"
|
||||||
#include "pairinginfo.h"
|
#include "pairinginfo.h"
|
||||||
#include "huemotionsensor.h"
|
#include "huemotionsensor.h"
|
||||||
#include "huemotionsensor.h"
|
|
||||||
|
|
||||||
#include "plugintimer.h"
|
#include "plugintimer.h"
|
||||||
#include "network/networkaccessmanager.h"
|
#include "network/networkaccessmanager.h"
|
||||||
@ -47,31 +48,28 @@ class DevicePluginPhilipsHue: public DevicePlugin
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DevicePluginPhilipsHue();
|
explicit DevicePluginPhilipsHue();
|
||||||
~DevicePluginPhilipsHue();
|
|
||||||
|
|
||||||
void init() override;
|
|
||||||
Device::DeviceSetupStatus setupDevice(Device *device) override;
|
Device::DeviceSetupStatus setupDevice(Device *device) override;
|
||||||
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||||
void deviceRemoved(Device *device) override;
|
void deviceRemoved(Device *device) override;
|
||||||
Device::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, const QString &secret) override;
|
Device::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, const QString &secret) override;
|
||||||
|
Device::DeviceError executeAction(Device *device, const Action &action) override;
|
||||||
public slots:
|
|
||||||
Device::DeviceError executeAction(Device *device, const Action &action);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void lightStateChanged();
|
// Light Device Events
|
||||||
void remoteStateChanged();
|
void onLightStateChanged();
|
||||||
|
|
||||||
|
// Remote Device Eventes
|
||||||
|
void onRemoteStateChanged();
|
||||||
void onRemoteButtonEvent(int buttonCode);
|
void onRemoteButtonEvent(int buttonCode);
|
||||||
|
|
||||||
// Motion sensor
|
// Motion Sensor Events
|
||||||
void onMotionSensorReachableChanged(bool reachable);
|
void onMotionSensorReachableChanged(bool reachable);
|
||||||
void onMotionSensorBatteryLevelChanged(int batteryLevel);
|
void onMotionSensorBatteryLevelChanged(int batteryLevel);
|
||||||
void onMotionSensorTemperatureChanged(double temperature);
|
void onMotionSensorTemperatureChanged(double temperature);
|
||||||
void onMotionSensorPresenceChanged(bool presence);
|
void onMotionSensorPresenceChanged(bool presence);
|
||||||
void onMotionSensorLightIntensityChanged(double lightIntensity);
|
void onMotionSensorLightIntensityChanged(double lightIntensity);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void networkManagerReplyReady();
|
|
||||||
void onDeviceNameChanged();
|
void onDeviceNameChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -83,66 +81,18 @@ private:
|
|||||||
};
|
};
|
||||||
void finishDiscovery(DiscoveryJob* job);
|
void finishDiscovery(DiscoveryJob* job);
|
||||||
|
|
||||||
PluginTimer *m_pluginTimer1Sec = nullptr;
|
|
||||||
PluginTimer *m_pluginTimer5Sec = nullptr;
|
|
||||||
PluginTimer *m_pluginTimer15Sec = nullptr;
|
|
||||||
|
|
||||||
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
|
QHash<QNetworkReply *, PairingInfo *> m_pairingRequests;
|
||||||
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
|
QHash<QNetworkReply *, PairingInfo *> m_informationRequests;
|
||||||
|
|
||||||
|
QHash<DeviceId, BridgeConnection *> m_bridgeConnections;
|
||||||
|
|
||||||
QList<HueBridge *> m_unconfiguredBridges;
|
QList<HueBridge *> m_unconfiguredBridges;
|
||||||
QList<HueLight *> m_unconfiguredLights;
|
QList<HueLight *> m_unconfiguredLights;
|
||||||
|
|
||||||
QHash<QNetworkReply *, Device *> m_lightRefreshRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_setNameRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_bridgeRefreshRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_lightsRefreshRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_sensorsRefreshRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_bridgeLightsDiscoveryRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_bridgeSensorsDiscoveryRequests;
|
|
||||||
QHash<QNetworkReply *, Device *> m_bridgeSearchDevicesRequests;
|
|
||||||
|
|
||||||
QHash<QNetworkReply *, QPair<Device *, ActionId> > m_asyncActions;
|
QHash<QNetworkReply *, QPair<Device *, ActionId> > m_asyncActions;
|
||||||
|
|
||||||
QHash<HueBridge *, Device *> m_bridges;
|
|
||||||
QHash<HueLight *, Device *> m_lights;
|
|
||||||
QHash<HueRemote *, Device *> m_remotes;
|
|
||||||
QHash<HueMotionSensor *, Device *> m_motionSensors;
|
|
||||||
|
|
||||||
void refreshLight(Device *device);
|
|
||||||
void refreshBridge(Device *device);
|
|
||||||
|
|
||||||
void refreshLights(HueBridge *bridge);
|
|
||||||
void refreshSensors(HueBridge *bridge);
|
|
||||||
|
|
||||||
void discoverBridgeDevices(HueBridge *bridge);
|
|
||||||
void searchNewDevices(HueBridge *bridge, const QString &serialNumber);
|
|
||||||
|
|
||||||
void setLightName(Device *device);
|
|
||||||
void setRemoteName(Device *device);
|
|
||||||
|
|
||||||
void processNUpnpResponse(const QByteArray &data);
|
|
||||||
void processBridgeLightDiscoveryResponse(Device *device, const QByteArray &data);
|
|
||||||
void processBridgeSensorDiscoveryResponse(Device *device, const QByteArray &data);
|
|
||||||
void processLightRefreshResponse(Device *device, const QByteArray &data);
|
|
||||||
void processBridgeRefreshResponse(Device *device, const QByteArray &data);
|
|
||||||
void processLightsRefreshResponse(Device *device, const QByteArray &data);
|
|
||||||
void processSensorsRefreshResponse(Device *device, const QByteArray &data);
|
|
||||||
void processSetNameResponse(Device *device, const QByteArray &data);
|
|
||||||
void processPairingResponse(PairingInfo *pairingInfo, const QByteArray &data);
|
|
||||||
void processInformationResponse(PairingInfo *pairingInfo, const QByteArray &data);
|
|
||||||
void processActionResponse(Device *device, const ActionId actionId, const QByteArray &data);
|
|
||||||
|
|
||||||
void bridgeReachableChanged(Device *device, const bool &reachable);
|
|
||||||
|
|
||||||
Device* bridgeForBridgeId(const QString &id);
|
|
||||||
bool lightAlreadyAdded(const QString &uuid);
|
bool lightAlreadyAdded(const QString &uuid);
|
||||||
bool sensorAlreadyAdded(const QString &uuid);
|
bool sensorAlreadyAdded(const QString &uuid);
|
||||||
|
|
||||||
int brightnessToPercentage(int brightness);
|
|
||||||
int percentageToBrightness(int percentage);
|
|
||||||
|
|
||||||
void abortRequests(QHash<QNetworkReply *, Device *> requestList, Device* device);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICEPLUGINBOBLIGHT_H
|
#endif // DEVICEPLUGINPHILIPSHUE_H
|
||||||
|
|||||||
@ -103,7 +103,6 @@ private:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateChanged();
|
void stateChanged();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HUELIGHT_H
|
#endif // HUELIGHT_H
|
||||||
|
|||||||
@ -13,7 +13,8 @@ SOURCES += \
|
|||||||
huemotionsensor.cpp \
|
huemotionsensor.cpp \
|
||||||
pairinginfo.cpp \
|
pairinginfo.cpp \
|
||||||
hueremote.cpp \
|
hueremote.cpp \
|
||||||
huedevice.cpp
|
huedevice.cpp \
|
||||||
|
bridgeconnection.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
devicepluginphilipshue.h \
|
devicepluginphilipshue.h \
|
||||||
@ -25,7 +26,8 @@ HEADERS += \
|
|||||||
huemotionsensor.h \
|
huemotionsensor.h \
|
||||||
pairinginfo.h \
|
pairinginfo.h \
|
||||||
hueremote.h \
|
hueremote.h \
|
||||||
huedevice.h
|
huedevice.h \
|
||||||
|
bridgeconnection.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user