Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Commit 1ee26e8

Browse files
author
Tim Niggemann
committed
State of all lights is saved and restored on switchOff().
1 parent 0686a8d commit 1ee26e8

File tree

2 files changed

+113
-16
lines changed

2 files changed

+113
-16
lines changed

libsrc/leddevice/LedDevicePhilipsHue.cpp

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,51 @@
11
// Local-Hyperion includes
22
#include "LedDevicePhilipsHue.h"
33

4-
#include <iostream>
4+
// jsoncpp includes
5+
#include <json/json.h>
56

7+
// qt includes
68
#include <QtCore/qmath.h>
79
#include <QUrl>
810
#include <QHttpRequestHeader>
9-
#include <QThread>
11+
#include <QEventLoop>
1012

1113
LedDevicePhilipsHue::LedDevicePhilipsHue(const std::string& output) :
12-
host(output.c_str()), username("newdeveloper") {
13-
http = new QHttp(host, 80);
14+
host(output.c_str()), username("newdeveloper") {
15+
http = new QHttp(host);
1416
}
1517

1618
LedDevicePhilipsHue::~LedDevicePhilipsHue() {
1719
delete http;
1820
}
1921

2022
int LedDevicePhilipsHue::write(const std::vector<ColorRgb> & ledValues) {
23+
// Save light states if not done before.
24+
if (!statesSaved()) {
25+
saveStates(ledValues.size());
26+
}
27+
// Iterate through colors and set light states.
2128
unsigned int lightId = 1;
2229
for (const ColorRgb& color : ledValues) {
2330
float x, y, b;
2431
// Scale colors from [0, 255] to [0, 1] and convert to xy space.
2532
rgbToXYBrightness(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, x, y, b);
2633
// Send adjust color command in JSON format.
27-
put(getRoute(lightId), QString("{\"xy\": [%1, %2]}").arg(x).arg(y));
34+
put(getStateRoute(lightId), QString("{\"xy\": [%1, %2]}").arg(x).arg(y));
2835
// Send brightness color command in JSON format.
29-
put(getRoute(lightId), QString("{\"bri\": %1}").arg(qRound(b * 255.0f)));
36+
put(getStateRoute(lightId), QString("{\"bri\": %1}").arg(qRound(b * 255.0f)));
3037
// Next light id.
3138
lightId++;
3239
}
3340
return 0;
3441
}
3542

3643
int LedDevicePhilipsHue::switchOff() {
44+
// If light states have been saved before, ...
45+
if (statesSaved()) {
46+
// ... restore them.
47+
restoreStates();
48+
}
3749
return 0;
3850
}
3951

@@ -47,15 +59,68 @@ void LedDevicePhilipsHue::put(QString route, QString content) {
4759
http->request(header, content.toAscii());
4860
}
4961

50-
QString LedDevicePhilipsHue::getRoute(unsigned int lightId) {
62+
QByteArray LedDevicePhilipsHue::get(QString route) {
63+
QString url = QString("/api/%1/%2").arg(username).arg(route);
64+
// Event loop to block until request finished.
65+
QEventLoop loop;
66+
// Connect requestFinished signal to quit slot of the loop.
67+
loop.connect(http, SIGNAL(requestFinished(int, bool)), SLOT(quit()));
68+
// Perfrom request
69+
http->get(url);
70+
// Go into the loop until the request is finished.
71+
loop.exec();
72+
// Read all data of the response.
73+
return http->readAll();
74+
}
75+
76+
QString LedDevicePhilipsHue::getStateRoute(unsigned int lightId) {
5177
return QString("lights/%1/state").arg(lightId);
5278
}
5379

80+
QString LedDevicePhilipsHue::getRoute(unsigned int lightId) {
81+
return QString("lights/%1").arg(lightId);
82+
}
83+
84+
void LedDevicePhilipsHue::saveStates(unsigned int nLights) {
85+
// Clear saved light states.
86+
states.clear();
87+
// Use json parser to parse reponse.
88+
Json::Reader reader;
89+
Json::FastWriter writer;
90+
// Iterate lights.
91+
for (unsigned int i = 0; i < nLights; i++) {
92+
// Read the response.
93+
QByteArray response = get(getRoute(i + 1));
94+
// Parse JSON.
95+
Json::Value state;
96+
if (!reader.parse(QString(response).toStdString(), state)) {
97+
// Error occured, break loop.
98+
break;
99+
}
100+
// Save state object.
101+
states.push_back(QString(writer.write(state["state"]).c_str()));
102+
}
103+
}
104+
105+
void LedDevicePhilipsHue::restoreStates() {
106+
unsigned int lightId = 1;
107+
for (QString state : states) {
108+
put(getStateRoute(lightId), state);
109+
lightId++;
110+
}
111+
// Clear saved light states.
112+
states.clear();
113+
}
114+
115+
bool LedDevicePhilipsHue::statesSaved() {
116+
return !states.empty();
117+
}
118+
54119
void LedDevicePhilipsHue::rgbToXYBrightness(float red, float green, float blue, float& x, float& y, float& brightness) {
55120
// Apply gamma correction.
56121
red = (red > 0.04045f) ? qPow((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f);
57-
green = (green > 0.04045f) ? qPow ((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f);
58-
blue = (blue > 0.04045f) ? qPow ((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
122+
green = (green > 0.04045f) ? qPow((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f);
123+
blue = (blue > 0.04045f) ? qPow((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
59124
// Convert to XYZ space.
60125
float X = red * 0.649926f + green * 0.103455f + blue * 0.197109f;
61126
float Y = red * 0.234327f + green * 0.743075f + blue * 0.022598f;

libsrc/leddevice/LedDevicePhilipsHue.h

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
// Leddevice includes
1111
#include <leddevice/LedDevice.h>
12-
12+
1313
/**
1414
* Implementation for the Philips Hue system.
1515
*
@@ -18,8 +18,7 @@
1818
* Framegrabber must be limited to 10 Hz / numer of lights to avoid rate limitation by the hue bridge.
1919
* Create a new API user name "newdeveloper" on the bridge (http://developers.meethue.com/gettingstarted.html)
2020
*/
21-
class LedDevicePhilipsHue : public LedDevice
22-
{
21+
class LedDevicePhilipsHue: public LedDevice {
2322
public:
2423
///
2524
/// Constructs the device.
@@ -46,14 +45,26 @@ class LedDevicePhilipsHue : public LedDevice
4645
virtual int switchOff();
4746

4847
private:
48+
/// Array to save the light states.
49+
std::vector<QString> states;
4950
/// Ip address of the bridge
5051
QString host;
5152
/// User name for the API ("newdeveloper")
5253
QString username;
54+
/// Qhttp object for sending requests.
5355
QHttp* http;
5456

5557
///
56-
/// Sends a HTTP PUT request
58+
/// Sends a HTTP GET request (blocking).
59+
///
60+
/// @param route the URI of the request
61+
///
62+
/// @return response of the request
63+
///
64+
QByteArray get(QString route);
65+
66+
///
67+
/// Sends a HTTP PUT request (non-blocking).
5768
///
5869
/// @param route the URI of the request
5970
///
@@ -64,10 +75,32 @@ class LedDevicePhilipsHue : public LedDevice
6475
///
6576
/// @param lightId the id of the hue light (starting from 1)
6677
///
67-
/// @return the URI of the light
78+
/// @return the URI of the light state for PUT requests.
79+
///
80+
QString getStateRoute(unsigned int lightId);
81+
82+
///
83+
/// @param lightId the id of the hue light (starting from 1)
84+
///
85+
/// @return the URI of the light for GET requests.
6886
///
6987
QString getRoute(unsigned int lightId);
7088

89+
///
90+
/// Queries the status of all lights and saves it.
91+
///
92+
/// @param nLights the number of lights
93+
///
94+
void saveStates(unsigned int nLights);
95+
96+
/// Restores the status of all lights.
97+
void restoreStates();
98+
99+
///
100+
/// @return true if light states have been saved.
101+
///
102+
bool statesSaved();
103+
71104
///
72105
/// Converts an RGB color to the Hue xy color space and brightness
73106
/// https://github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/blob/master/ApplicationDesignNotes/RGB%20to%20xy%20Color%20conversion.md
@@ -84,7 +117,6 @@ class LedDevicePhilipsHue : public LedDevice
84117
///
85118
/// @param brightness converted brightness component
86119
///
87-
void rgbToXYBrightness(float red, float green, float blue,
88-
float& x, float& y, float& brightness);
120+
void rgbToXYBrightness(float red, float green, float blue, float& x, float& y, float& brightness);
89121

90122
};

0 commit comments

Comments
 (0)