From 9220c346bbd8a0a6c95626edc89771e85420e21b Mon Sep 17 00:00:00 2001 From: ntim Date: Thu, 1 May 2014 00:02:10 +0200 Subject: [PATCH 1/3] Blocking PUT requests. Only save the brightness and [x,y] state of the lights. Former-commit-id: 5887fdf1b350172dcdd52c46bd8da74dab521444 --- libsrc/leddevice/LedDevicePhilipsHue.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libsrc/leddevice/LedDevicePhilipsHue.cpp b/libsrc/leddevice/LedDevicePhilipsHue.cpp index 690a7b94..2cedc8a5 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.cpp +++ b/libsrc/leddevice/LedDevicePhilipsHue.cpp @@ -54,9 +54,15 @@ void LedDevicePhilipsHue::put(QString route, QString content) { QHttpRequestHeader header("PUT", url); header.setValue("Host", host); header.setValue("Accept-Encoding", "identity"); + header.setValue("Connection", "keep-alive"); header.setValue("Content-Length", QString("%1").arg(content.size())); - http->setHost(host); + QEventLoop loop; + // Connect requestFinished signal to quit slot of the loop. + loop.connect(http, SIGNAL(requestFinished(int, bool)), SLOT(quit())); + // Perfrom request http->request(header, content.toAscii()); + // Go into the loop until the request is finished. + loop.exec(); } QByteArray LedDevicePhilipsHue::get(QString route) { @@ -92,13 +98,17 @@ void LedDevicePhilipsHue::saveStates(unsigned int nLights) { // Read the response. QByteArray response = get(getRoute(i + 1)); // Parse JSON. - Json::Value state; - if (!reader.parse(QString(response).toStdString(), state)) { + Json::Value json; + if (!reader.parse(QString(response).toStdString(), json)) { // Error occured, break loop. break; } + // Save state object values which are subject to change. + Json::Value state(Json::objectValue); + state["xy"] = json["state"]["xy"]; + state["bri"] = json["state"]["bri"]; // Save state object. - states.push_back(QString(writer.write(state["state"]).c_str())); + states.push_back(QString(writer.write(state).c_str()).trimmed()); } } From 8cca280fdcc1384567a7162a611c46127e9fa953 Mon Sep 17 00:00:00 2001 From: ntim Date: Sat, 3 May 2014 10:12:41 +0200 Subject: [PATCH 2/3] Implemented timeout for restoring original state. Former-commit-id: 925b063aba1a859b592ead9b75ce67d90fb81e28 --- libsrc/leddevice/CMakeLists.txt | 2 +- libsrc/leddevice/LedDevicePhilipsHue.cpp | 5 +++++ libsrc/leddevice/LedDevicePhilipsHue.h | 14 ++++++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index 098ac38c..5a5d2c12 100755 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -14,6 +14,7 @@ include_directories( # Group the headers that go through the MOC compiler SET(Leddevice_QT_HEADERS ${CURRENT_SOURCE_DIR}/LedDeviceAdalight.h + ${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.h ) SET(Leddevice_HEADERS @@ -29,7 +30,6 @@ SET(Leddevice_HEADERS ${CURRENT_SOURCE_DIR}/LedDeviceSedu.h ${CURRENT_SOURCE_DIR}/LedDeviceTest.h ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h - ${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.h ) SET(Leddevice_SOURCES diff --git a/libsrc/leddevice/LedDevicePhilipsHue.cpp b/libsrc/leddevice/LedDevicePhilipsHue.cpp index 2cedc8a5..35f045f2 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.cpp +++ b/libsrc/leddevice/LedDevicePhilipsHue.cpp @@ -13,6 +13,9 @@ LedDevicePhilipsHue::LedDevicePhilipsHue(const std::string& output) : host(output.c_str()), username("newdeveloper") { http = new QHttp(host); + timer.setInterval(1000); + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), this, SLOT(restoreStates()())); } LedDevicePhilipsHue::~LedDevicePhilipsHue() { @@ -37,10 +40,12 @@ int LedDevicePhilipsHue::write(const std::vector & ledValues) { // Next light id. lightId++; } + timer.start(); return 0; } int LedDevicePhilipsHue::switchOff() { + timer.stop(); // If light states have been saved before, ... if (statesSaved()) { // ... restore them. diff --git a/libsrc/leddevice/LedDevicePhilipsHue.h b/libsrc/leddevice/LedDevicePhilipsHue.h index 0bb71182..7a0e86cd 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.h +++ b/libsrc/leddevice/LedDevicePhilipsHue.h @@ -4,8 +4,10 @@ #include // Qt includes +#include #include #include +#include // Leddevice includes #include @@ -18,7 +20,8 @@ * Framegrabber must be limited to 10 Hz / numer of lights to avoid rate limitation by the hue bridge. * Create a new API user name "newdeveloper" on the bridge (http://developers.meethue.com/gettingstarted.html) */ -class LedDevicePhilipsHue: public LedDevice { +class LedDevicePhilipsHue: public QObject, public LedDevice { +Q_OBJECT public: /// /// Constructs the device. @@ -44,6 +47,10 @@ public: /// Switch the leds off virtual int switchOff(); +private slots: + /// Restores the status of all lights. + void restoreStates(); + private: /// Array to save the light states. std::vector states; @@ -53,6 +60,8 @@ private: QString username; /// Qhttp object for sending requests. QHttp* http; + /// Use timer to reset lights when we got into "GRABBINGMODE_OFF". + QTimer timer; /// /// Sends a HTTP GET request (blocking). @@ -93,9 +102,6 @@ private: /// void saveStates(unsigned int nLights); - /// Restores the status of all lights. - void restoreStates(); - /// /// @return true if light states have been saved. /// From 853d00289425d90e71331005d152400a7ae69156 Mon Sep 17 00:00:00 2001 From: ntim Date: Wed, 7 May 2014 15:22:13 +0200 Subject: [PATCH 3/3] Timer to restore light state properly implemented. Lights are not switched on after state has been saved. Former-commit-id: 04959ea3731eb7de9f59b80a789f03cfeb2d4ba3 --- libsrc/leddevice/LedDevicePhilipsHue.cpp | 18 ++++++++++++++---- libsrc/leddevice/LedDevicePhilipsHue.h | 9 ++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libsrc/leddevice/LedDevicePhilipsHue.cpp b/libsrc/leddevice/LedDevicePhilipsHue.cpp index 35f045f2..f8a9698a 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.cpp +++ b/libsrc/leddevice/LedDevicePhilipsHue.cpp @@ -13,9 +13,9 @@ LedDevicePhilipsHue::LedDevicePhilipsHue(const std::string& output) : host(output.c_str()), username("newdeveloper") { http = new QHttp(host); - timer.setInterval(1000); + timer.setInterval(3000); timer.setSingleShot(true); - connect(&timer, SIGNAL(timeout()), this, SLOT(restoreStates()())); + connect(&timer, SIGNAL(timeout()), this, SLOT(restoreStates())); } LedDevicePhilipsHue::~LedDevicePhilipsHue() { @@ -26,6 +26,7 @@ int LedDevicePhilipsHue::write(const std::vector & ledValues) { // Save light states if not done before. if (!statesSaved()) { saveStates(ledValues.size()); + switchOn(ledValues.size()); } // Iterate through colors and set light states. unsigned int lightId = 1; @@ -110,13 +111,22 @@ void LedDevicePhilipsHue::saveStates(unsigned int nLights) { } // Save state object values which are subject to change. Json::Value state(Json::objectValue); - state["xy"] = json["state"]["xy"]; - state["bri"] = json["state"]["bri"]; + state["on"] = json["state"]["on"]; + if (json["state"]["on"] == true) { + state["xy"] = json["state"]["xy"]; + state["bri"] = json["state"]["bri"]; + } // Save state object. states.push_back(QString(writer.write(state).c_str()).trimmed()); } } +void LedDevicePhilipsHue::switchOn(unsigned int nLights) { + for (unsigned int i = 0; i < nLights; i++) { + put(getStateRoute(i + 1), "{\"on\": true}"); + } +} + void LedDevicePhilipsHue::restoreStates() { unsigned int lightId = 1; for (QString state : states) { diff --git a/libsrc/leddevice/LedDevicePhilipsHue.h b/libsrc/leddevice/LedDevicePhilipsHue.h index 435fc800..84e7bd35 100755 --- a/libsrc/leddevice/LedDevicePhilipsHue.h +++ b/libsrc/leddevice/LedDevicePhilipsHue.h @@ -46,7 +46,7 @@ public: /// virtual int write(const std::vector & ledValues); - /// Switch the leds off + /// Restores the original state of the leds. virtual int switchOff(); private slots: @@ -104,6 +104,13 @@ private: /// void saveStates(unsigned int nLights); + /// + /// Switches the leds on. + /// + /// @param nLights the number of lights + /// + void switchOn(unsigned int nLights); + /// /// @return true if light states have been saved. ///