diff --git a/lifx/integrationpluginlifx.cpp b/lifx/integrationpluginlifx.cpp index 1baacc85..81fb9731 100644 --- a/lifx/integrationpluginlifx.cpp +++ b/lifx/integrationpluginlifx.cpp @@ -234,6 +234,8 @@ void IntegrationPluginLifx::setupThing(ThingSetupInfo *info) connect(lifxCloud, &LifxCloud::lightsListReceived, this, &IntegrationPluginLifx::onLifxCloudLightsListReceived); connect(lifxCloud, &LifxCloud::scenesListReceived, this, &IntegrationPluginLifx::onLifxCloudScenesListReceived); connect(lifxCloud, &LifxCloud::requestExecuted, this, &IntegrationPluginLifx::onLifxCloudRequestExecuted); + connect(lifxCloud, &LifxCloud::connectionChanged, this, &IntegrationPluginLifx::onLifxCloudConnectionChanged); + connect(lifxCloud, &LifxCloud::authenticationChanged, this, &IntegrationPluginLifx::onLifxCloudAuthenticationChanged); lifxCloud->setAuthorizationToken(token); lifxCloud->listLights(); @@ -245,8 +247,6 @@ void IntegrationPluginLifx::setupThing(ThingSetupInfo *info) void IntegrationPluginLifx::postSetupThing(Thing *thing) { - connect(thing, &Thing::nameChanged, this, &IntegrationPluginLifx::onDeviceNameChanged); - if (!m_pluginTimer) { m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); connect(m_pluginTimer, &PluginTimer::timeout, this, [this]() { @@ -336,7 +336,7 @@ void IntegrationPluginLifx::executeAction(ThingActionInfo *info) connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_asyncActions.remove(requestId);}); m_asyncActions.insert(requestId, info); } else { - Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); + Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); } } else if (thing->thingClassId() == dimmableBulbThingClassId) { QByteArray lightId = thing->paramValue(dimmableBulbThingIdParamTypeId).toByteArray(); @@ -412,12 +412,6 @@ void IntegrationPluginLifx::executeBrowserItem(BrowserActionInfo *info) connect(info, &BrowserActionInfo::aborted, this, [requestId, this] {m_asyncBrowserItem.remove(requestId);}); } -void IntegrationPluginLifx::onDeviceNameChanged() -{ - Thing *thing = static_cast(sender()); - Q_UNUSED(thing) -} - void IntegrationPluginLifx::onConnectionChanged(bool connected) { Q_UNUSED(connected) @@ -437,9 +431,7 @@ void IntegrationPluginLifx::onRequestExecuted(int requestId, bool success) } else { info->finish(Thing::ThingErrorHardwareFailure); } - } - - if (m_asyncBrowserItem.contains(requestId)) { + } else if (m_asyncBrowserItem.contains(requestId)) { BrowserActionInfo *info = m_asyncBrowserItem.take(requestId); if (success) { info->finish(Thing::ThingErrorNoError); @@ -463,6 +455,15 @@ void IntegrationPluginLifx::onLifxCloudConnectionChanged(bool connected) } } +void IntegrationPluginLifx::onLifxCloudAuthenticationChanged(bool authenticated) +{ + LifxCloud *lifxCloud = static_cast(sender()); + Thing *accountThing = m_lifxCloudConnections.key(lifxCloud); + if (!accountThing) + return; + accountThing->setStateValue(lifxAccountLoggedInStateTypeId, authenticated); +} + void IntegrationPluginLifx::onLifxCloudLightsListReceived(const QList &lights) { LifxCloud *lifxCloud = static_cast(sender()); @@ -502,6 +503,8 @@ void IntegrationPluginLifx::onLifxCloudLightsListReceived(const QListfinish(Thing::ThingErrorNoError); - } else { - info->finish(Thing::ThingErrorHardwareNotAvailable); + if (m_asyncActions.contains(requestId)) { + ThingActionInfo *info = m_asyncActions.take(requestId); + if (!info) { + return; + } + if (success) { + info->finish(Thing::ThingErrorNoError); + } else { + info->finish(Thing::ThingErrorHardwareNotAvailable); + } + } else if (m_asyncBrowserItem.contains(requestId)) { + BrowserActionInfo *info = m_asyncBrowserItem.value(requestId); + if (!info) { + return; + } + if (success) { + info->finish(Thing::ThingErrorNoError); + } else { + info->finish(Thing::ThingErrorHardwareNotAvailable); + } } } diff --git a/lifx/integrationpluginlifx.h b/lifx/integrationpluginlifx.h index f073486a..788e4b85 100644 --- a/lifx/integrationpluginlifx.h +++ b/lifx/integrationpluginlifx.h @@ -90,11 +90,11 @@ private: QHash m_lifxProducts; private slots: - void onDeviceNameChanged(); void onConnectionChanged(bool connected); void onRequestExecuted(int requestId, bool success); void onLifxCloudConnectionChanged(bool connected); + void onLifxCloudAuthenticationChanged(bool authenticated); void onLifxCloudRequestExecuted(int requestId, bool success); void onLifxCloudLightsListReceived(const QList &lights); void onLifxCloudScenesListReceived(const QList &scenes); diff --git a/lifx/lifx.cpp b/lifx/lifx.cpp index 2fdf6503..1bb4eb73 100644 --- a/lifx/lifx.cpp +++ b/lifx/lifx.cpp @@ -75,7 +75,6 @@ bool Lifx::enable() m_socket = nullptr; return false; } - connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); connect(m_socket, &QUdpSocket::readyRead, this, &Lifx::onReadyRead); return true; } diff --git a/lifx/lifx.h b/lifx/lifx.h index 5af8b849..6ac42447 100644 --- a/lifx/lifx.h +++ b/lifx/lifx.h @@ -152,7 +152,7 @@ private slots: signals: void connectionChanged(bool connected); - //void requestExecuted(int requestId, bool success); + void requestExecuted(int requestId, bool success); //void errorReceived(int code, const QString &message); //void powerNotificationReceived(bool status); diff --git a/lifx/lifxcloud.cpp b/lifx/lifxcloud.cpp index 2fbba9da..4b3d13f9 100644 --- a/lifx/lifxcloud.cpp +++ b/lifx/lifxcloud.cpp @@ -50,6 +50,16 @@ void LifxCloud::setAuthorizationToken(const QByteArray &token) m_authorizationToken = token; } +bool LifxCloud::cloudAuthenticated() +{ + return m_authenticated; +} + +bool LifxCloud::cloudConnected() +{ + return m_connected; +} + void LifxCloud::listLights() { if (m_authorizationToken.isEmpty()) { @@ -67,10 +77,18 @@ void LifxCloud::listLights() int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // check HTTP status code - if (status != 200) { + if (status > 207) { qCWarning(dcLifx()) << "Error get lights list" << status << reply->errorString(); return; } + if (!m_authenticated) { + m_authenticated = true; + emit authenticationChanged(true); + } + if (!m_connected) { + m_connected = true; + emit authenticationChanged(true); + } QByteArray rawData = reply->readAll(); QJsonDocument data; QJsonParseError error; @@ -151,6 +169,14 @@ void LifxCloud::listScenes() qCWarning(dcLifx()) << "Error get scene list" << status << reply->errorString(); return; } + if (!m_authenticated) { + m_authenticated = true; + emit authenticationChanged(true); + } + if (!m_connected) { + m_connected = true; + emit authenticationChanged(true); + } QByteArray rawData = reply->readAll(); qCDebug(dcLifx()) << "Got list scenes reply" << rawData; QJsonDocument data; QJsonParseError error; @@ -166,7 +192,7 @@ void LifxCloud::listScenes() QList scenes; foreach (QJsonValue value, array) { Scene scene; - scene.id = value.toObject().value("id").toString().toUtf8(); + scene.id = value.toObject().value("uuid").toString().toUtf8(); scene.name = value.toObject().value("name").toString(); scenes.append(scene); } @@ -208,23 +234,36 @@ int LifxCloud::activateScene(const QString &sceneId) int requestId = qrand(); QNetworkRequest request; - request.setUrl(QUrl(QString("https://api.lifx.com/v1/scenes/scene_id::%1/activate").arg(sceneId))); + request.setUrl(QUrl(QString("https://api.lifx.com/v1/scenes/scene_id:%1/activate").arg(sceneId))); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json"); request.setRawHeader("Authorization","Bearer "+m_authorizationToken); - QByteArray payload; - payload.append("duration:5"); - QNetworkReply *reply = m_networkManager->put(request, payload); + QNetworkReply *reply = m_networkManager->put(request, ""); connect(reply, &QNetworkReply::finished, &QNetworkReply::deleteLater); - connect(reply, &QNetworkReply::finished, this, [reply, this] { + connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // check HTTP status code - if (status != 200) { - qCWarning(dcLifx()) << "Error get scene list" << status << reply->errorString(); + if (status == 401 || status == 403) { + if (m_authenticated) { + m_authenticated = false; + emit authenticationChanged(false); + } + } + if (status > 207) { + qCWarning(dcLifx()) << "Error activate Scene" << status << reply->errorString(); + emit requestExecuted(requestId, false); return; } + if (!m_authenticated) { + m_authenticated = true; + emit authenticationChanged(true); + } + if (!m_connected) { + m_connected = true; + emit authenticationChanged(true); + } + emit requestExecuted(requestId, true); QByteArray rawData = reply->readAll(); - qCDebug(dcLifx()) << "Got list lights reply" << rawData; - + qCDebug(dcLifx()) << "Got activate scene reply" << rawData; }); return requestId; } @@ -271,11 +310,19 @@ int LifxCloud::setState(const QString &selector, State state, QVariant stateValu connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // check HTTP status code - if (status != 200) { + if (status > 207) { qCWarning(dcLifx()) << "Error get scene list" << status << reply->errorString(); emit requestExecuted(requestId, false); return; } + if (!m_authenticated) { + m_authenticated = true; + emit authenticationChanged(true); + } + if (!m_connected) { + m_connected = true; + emit authenticationChanged(true); + } QByteArray rawData = reply->readAll(); qCDebug(dcLifx()) << "Got set state reply" << rawData; emit requestExecuted(requestId, true); diff --git a/lifx/lifxcloud.h b/lifx/lifxcloud.h index 545768a0..1e0025e1 100644 --- a/lifx/lifxcloud.h +++ b/lifx/lifxcloud.h @@ -96,6 +96,8 @@ public: explicit LifxCloud(NetworkAccessManager *networkManager, QObject *parent = nullptr); void setAuthorizationToken(const QByteArray &token); + bool cloudAuthenticated(); + bool cloudConnected(); void listLights(); void listScenes(); @@ -112,8 +114,11 @@ private: QByteArray m_authorizationToken; int setState(const QString &lightId, State state, QVariant stateValue, int duration); - + bool m_authenticated = false; + bool m_connected = false; signals: + void connectionChanged(bool m_connected); + void authenticationChanged(bool m_authenticated); void lightsListReceived(const QList &lights); void scenesListReceived(const QList &scenes); void requestExecuted(int requestId, bool susccess);