1
1
// Local-Hyperion includes
2
2
#include " LedDevicePhilipsHue.h"
3
3
4
- #include < iostream>
4
+ // jsoncpp includes
5
+ #include < json/json.h>
5
6
7
+ // qt includes
6
8
#include < QtCore/qmath.h>
7
9
#include < QUrl>
8
10
#include < QHttpRequestHeader>
9
- #include < QThread >
11
+ #include < QEventLoop >
10
12
11
13
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);
14
16
}
15
17
16
18
LedDevicePhilipsHue::~LedDevicePhilipsHue () {
17
19
delete http;
18
20
}
19
21
20
22
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.
21
28
unsigned int lightId = 1 ;
22
29
for (const ColorRgb& color : ledValues) {
23
30
float x, y, b;
24
31
// Scale colors from [0, 255] to [0, 1] and convert to xy space.
25
32
rgbToXYBrightness (color.red / 255 .0f , color.green / 255 .0f , color.blue / 255 .0f , x, y, b);
26
33
// 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));
28
35
// 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 )));
30
37
// Next light id.
31
38
lightId++;
32
39
}
33
40
return 0 ;
34
41
}
35
42
36
43
int LedDevicePhilipsHue::switchOff () {
44
+ // If light states have been saved before, ...
45
+ if (statesSaved ()) {
46
+ // ... restore them.
47
+ restoreStates ();
48
+ }
37
49
return 0 ;
38
50
}
39
51
@@ -47,15 +59,68 @@ void LedDevicePhilipsHue::put(QString route, QString content) {
47
59
http->request (header, content.toAscii ());
48
60
}
49
61
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) {
51
77
return QString (" lights/%1/state" ).arg (lightId);
52
78
}
53
79
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
+
54
119
void LedDevicePhilipsHue::rgbToXYBrightness (float red, float green, float blue, float & x, float & y, float & brightness) {
55
120
// Apply gamma correction.
56
121
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 );
59
124
// Convert to XYZ space.
60
125
float X = red * 0 .649926f + green * 0 .103455f + blue * 0 .197109f ;
61
126
float Y = red * 0 .234327f + green * 0 .743075f + blue * 0 .022598f ;
0 commit comments