Commit 77722d5b2e0c0588245262a1b7f47bc330adc56a

Authored by Moritz Wirger
1 parent e872b212

Fix unittests and add new utility function to reduce duplicate code

Showing 49 changed files with 6874 additions and 6997 deletions
.clang-format 0 → 100644
  1 +---
  2 +# Based on Webkit style
  3 +BasedOnStyle: Webkit
  4 +IndentWidth: 4
  5 +ColumnLimit: 120
  6 +---
  7 +Language: Cpp
  8 +Standard: Cpp11
  9 +# Pointers aligned to the left
  10 +DerivePointerAlignment: false
  11 +PointerAlignment: Left
  12 +AccessModifierOffset: -4
  13 +AllowShortFunctionsOnASingleLine: Inline
  14 +AlwaysBreakTemplateDeclarations: true
  15 +BreakBeforeBraces: Custom
  16 +BraceWrapping:
  17 + AfterClass: true
  18 + AfterControlStatement: true
  19 + AfterEnum: true
  20 + AfterFunction: true
  21 + AfterNamespace: true
  22 + AfterStruct: true
  23 + AfterUnion: true
  24 + AfterExternBlock: true
  25 + BeforeCatch: true
  26 + BeforeElse: true
  27 + SplitEmptyFunction: false
  28 + SplitEmptyRecord: false
  29 + SplitEmptyNamespace: false
  30 +BreakConstructorInitializers: BeforeColon
  31 +CompactNamespaces: false
  32 +ConstructorInitializerAllOnOneLineOrOnePerLine: true
  33 +ConstructorInitializerIndentWidth: 4
  34 +Cpp11BracedListStyle: true
  35 +FixNamespaceComments: true
  36 +IncludeBlocks: Regroup
  37 +IncludeCategories:
  38 + # C++ standard headers (no .h)
  39 + - Regex: '<[[:alnum:]_-]+>'
  40 + Priority: 1
  41 + # Extenal libraries (with .h)
  42 + - Regex: '<[[:alnum:]_./-]+>'
  43 + Priority: 2
  44 + # Headers from same folder
  45 + - Regex: '"[[:alnum:]_.-]+"'
  46 + Priority: 3
  47 + # Headers from other folders
  48 + - Regex: '"[[:alnum:]_/.-]+"'
  49 + Priority: 4
  50 +IndentCaseLabels: false
  51 +NamespaceIndentation: All
  52 +SortIncludes: true
  53 +SortUsingDeclarations: true
  54 +SpaceAfterTemplateKeyword: true
  55 +SpacesInAngles: false
  56 +SpacesInParentheses: false
  57 +SpacesInSquareBrackets: false
  58 +UseTab: Never
0 59 \ No newline at end of file
... ...
hueplusplus/CMakeLists.txt
... ... @@ -9,6 +9,7 @@ set(hueplusplus_SOURCES
9 9 ${CMAKE_CURRENT_SOURCE_DIR}/SimpleColorHueStrategy.cpp
10 10 ${CMAKE_CURRENT_SOURCE_DIR}/SimpleColorTemperatureStrategy.cpp
11 11 ${CMAKE_CURRENT_SOURCE_DIR}/UPnP.cpp
  12 + ${CMAKE_CURRENT_SOURCE_DIR}/Utils.cpp
12 13 )
13 14  
14 15 # on windows we want to compile the WinHttpHandler
... ...
hueplusplus/ExtendedColorHueStrategy.cpp
1 1 /**
2   - \file ExtendedColorHueStrategy.cpp
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file ExtendedColorHueStrategy.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #include "include/ExtendedColorHueStrategy.h"
21   -#include "include/HueConfig.h"
22 21  
23 22 #include <cmath>
24 23 #include <iostream>
25 24 #include <thread>
26 25  
27   -bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat,
28   - HueLight &light) const {
29   - light.refreshState();
30   - std::string cType = light.state["state"]["colormode"];
31   - bool on = light.state["state"]["on"];
32   - if (cType == "hs") {
33   - uint16_t oldHue = light.state["state"]["hue"];
34   - uint8_t oldSat = light.state["state"]["sat"];
35   - if (!light.setColorHueSaturation(hue, sat, 1)) {
36   - return false;
37   - }
38   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
39   - if (!light.alert()) {
40   - return false;
41   - }
42   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
43   - if (!on) {
44   - light.setColorHueSaturation(oldHue, oldSat, 1);
45   - return light.OffNoRefresh(1);
46   - } else {
47   - return light.setColorHueSaturation(oldHue, oldSat, 1);
48   - }
49   - } else if (cType == "xy") {
50   - float oldX = light.state["state"]["xy"][0];
51   - float oldY = light.state["state"]["xy"][1];
52   - if (!light.setColorHueSaturation(hue, sat, 1)) {
53   - return false;
54   - }
55   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
56   - if (!light.alert()) {
57   - return false;
58   - }
59   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
60   - if (!on) {
61   - light.setColorXY(oldX, oldY, 1);
62   - return light.OffNoRefresh(1);
63   - } else {
64   - return light.setColorXY(oldX, oldY, 1);
  26 +#include "include/HueConfig.h"
  27 +
  28 +bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const
  29 +{
  30 + light.refreshState();
  31 + std::string cType = light.state["state"]["colormode"];
  32 + bool on = light.state["state"]["on"];
  33 + if (cType == "hs")
  34 + {
  35 + uint16_t oldHue = light.state["state"]["hue"];
  36 + uint8_t oldSat = light.state["state"]["sat"];
  37 + if (!light.setColorHueSaturation(hue, sat, 1))
  38 + {
  39 + return false;
  40 + }
  41 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  42 + if (!light.alert())
  43 + {
  44 + return false;
  45 + }
  46 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  47 + if (!on)
  48 + {
  49 + light.setColorHueSaturation(oldHue, oldSat, 1);
  50 + return light.OffNoRefresh(1);
  51 + }
  52 + else
  53 + {
  54 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  55 + }
65 56 }
66   - } else if (cType == "ct") {
67   - uint16_t oldCT = light.state["state"]["ct"];
68   - if (!light.setColorHueSaturation(hue, sat, 1)) {
69   - return false;
  57 + else if (cType == "xy")
  58 + {
  59 + float oldX = light.state["state"]["xy"][0];
  60 + float oldY = light.state["state"]["xy"][1];
  61 + if (!light.setColorHueSaturation(hue, sat, 1))
  62 + {
  63 + return false;
  64 + }
  65 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  66 + if (!light.alert())
  67 + {
  68 + return false;
  69 + }
  70 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  71 + if (!on)
  72 + {
  73 + light.setColorXY(oldX, oldY, 1);
  74 + return light.OffNoRefresh(1);
  75 + }
  76 + else
  77 + {
  78 + return light.setColorXY(oldX, oldY, 1);
  79 + }
70 80 }
71   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
72   - if (!light.alert()) {
73   - return false;
  81 + else if (cType == "ct")
  82 + {
  83 + uint16_t oldCT = light.state["state"]["ct"];
  84 + if (!light.setColorHueSaturation(hue, sat, 1))
  85 + {
  86 + return false;
  87 + }
  88 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  89 + if (!light.alert())
  90 + {
  91 + return false;
  92 + }
  93 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  94 + if (!on)
  95 + {
  96 + light.setColorTemperature(oldCT, 1);
  97 + return light.OffNoRefresh(1);
  98 + }
  99 + else
  100 + {
  101 + return light.setColorTemperature(oldCT, 1);
  102 + }
74 103 }
75   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
76   - if (!on) {
77   - light.setColorTemperature(oldCT, 1);
78   - return light.OffNoRefresh(1);
79   - } else {
80   - return light.setColorTemperature(oldCT, 1);
  104 + else
  105 + {
  106 + return false;
81 107 }
82   - } else {
83   - return false;
84   - }
85 108 }
86 109  
87   -bool ExtendedColorHueStrategy::alertXY(float x, float y,
88   - HueLight &light) const {
89   - light.refreshState();
90   - std::string cType = light.state["state"]["colormode"];
91   - bool on = light.state["state"]["on"];
92   - if (cType == "hs") {
93   - uint16_t oldHue = light.state["state"]["hue"];
94   - uint8_t oldSat = light.state["state"]["sat"];
95   - if (!light.setColorXY(x, y, 1)) {
96   - return false;
97   - }
98   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
99   - if (!light.alert()) {
100   - return false;
  110 +bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const
  111 +{
  112 + light.refreshState();
  113 + std::string cType = light.state["state"]["colormode"];
  114 + bool on = light.state["state"]["on"];
  115 + if (cType == "hs")
  116 + {
  117 + uint16_t oldHue = light.state["state"]["hue"];
  118 + uint8_t oldSat = light.state["state"]["sat"];
  119 + if (!light.setColorXY(x, y, 1))
  120 + {
  121 + return false;
  122 + }
  123 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  124 + if (!light.alert())
  125 + {
  126 + return false;
  127 + }
  128 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  129 + if (!on)
  130 + {
  131 + light.setColorHueSaturation(oldHue, oldSat, 1);
  132 + return light.OffNoRefresh(1);
  133 + }
  134 + else
  135 + {
  136 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  137 + }
101 138 }
102   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
103   - if (!on) {
104   - light.setColorHueSaturation(oldHue, oldSat, 1);
105   - return light.OffNoRefresh(1);
106   - } else {
107   - return light.setColorHueSaturation(oldHue, oldSat, 1);
  139 + else if (cType == "xy")
  140 + {
  141 + float oldX = light.state["state"]["xy"][0];
  142 + float oldY = light.state["state"]["xy"][1];
  143 + if (!light.setColorXY(x, y, 1))
  144 + {
  145 + return false;
  146 + }
  147 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  148 + if (!light.alert())
  149 + {
  150 + return false;
  151 + }
  152 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  153 + if (!on)
  154 + {
  155 + light.setColorXY(oldX, oldY, 1);
  156 + return light.OffNoRefresh(1);
  157 + }
  158 + else
  159 + {
  160 + return light.setColorXY(oldX, oldY, 1);
  161 + }
108 162 }
109   - } else if (cType == "xy") {
110   - float oldX = light.state["state"]["xy"][0];
111   - float oldY = light.state["state"]["xy"][1];
112   - if (!light.setColorXY(x, y, 1)) {
113   - return false;
  163 + else if (cType == "ct")
  164 + {
  165 + uint16_t oldCT = light.state["state"]["ct"];
  166 + if (!light.setColorXY(x, y, 1))
  167 + {
  168 + return false;
  169 + }
  170 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  171 + if (!light.alert())
  172 + {
  173 + return false;
  174 + }
  175 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  176 + if (!on)
  177 + {
  178 + light.setColorTemperature(oldCT, 1);
  179 + return light.OffNoRefresh(1);
  180 + }
  181 + else
  182 + {
  183 + return light.setColorTemperature(oldCT, 1);
  184 + }
114 185 }
115   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
116   - if (!light.alert()) {
117   - return false;
  186 + else
  187 + {
  188 + return false;
118 189 }
119   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
120   - if (!on) {
121   - light.setColorXY(oldX, oldY, 1);
122   - return light.OffNoRefresh(1);
123   - } else {
124   - return light.setColorXY(oldX, oldY, 1);
125   - }
126   - } else if (cType == "ct") {
127   - uint16_t oldCT = light.state["state"]["ct"];
128   - if (!light.setColorXY(x, y, 1)) {
129   - return false;
130   - }
131   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
132   - if (!light.alert()) {
133   - return false;
134   - }
135   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
136   - if (!on) {
137   - light.setColorTemperature(oldCT, 1);
138   - return light.OffNoRefresh(1);
139   - } else {
140   - return light.setColorTemperature(oldCT, 1);
141   - }
142   - } else {
143   - return false;
144   - }
145 190 }
146 191  
147   -bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b,
148   - HueLight &light) const {
149   - light.refreshState();
150   - std::string cType = light.state["state"]["colormode"];
151   - bool on = light.state["state"]["on"];
152   - if (cType == "hs") {
153   - uint16_t oldHue = light.state["state"]["hue"];
154   - uint8_t oldSat = light.state["state"]["sat"];
155   - if (!light.setColorRGB(r, g, b, 1)) {
156   - return false;
157   - }
158   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
159   - if (!light.alert()) {
160   - return false;
161   - }
162   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
163   - if (!on) {
164   - light.setColorHueSaturation(oldHue, oldSat, 1);
165   - return light.OffNoRefresh(1);
166   - } else {
167   - return light.setColorHueSaturation(oldHue, oldSat, 1);
168   - }
169   - } else if (cType == "xy") {
170   - float oldX = light.state["state"]["xy"][0];
171   - float oldY = light.state["state"]["xy"][1];
172   - if (!light.setColorRGB(r, g, b, 1)) {
173   - return false;
174   - }
175   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
176   - if (!light.alert()) {
177   - return false;
178   - }
179   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
180   - if (!on) {
181   - light.setColorXY(oldX, oldY, 1);
182   - return light.OffNoRefresh(1);
183   - } else {
184   - return light.setColorXY(oldX, oldY, 1);
  192 +bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const
  193 +{
  194 + light.refreshState();
  195 + std::string cType = light.state["state"]["colormode"];
  196 + bool on = light.state["state"]["on"];
  197 + if (cType == "hs")
  198 + {
  199 + uint16_t oldHue = light.state["state"]["hue"];
  200 + uint8_t oldSat = light.state["state"]["sat"];
  201 + if (!light.setColorRGB(r, g, b, 1))
  202 + {
  203 + return false;
  204 + }
  205 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  206 + if (!light.alert())
  207 + {
  208 + return false;
  209 + }
  210 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  211 + if (!on)
  212 + {
  213 + light.setColorHueSaturation(oldHue, oldSat, 1);
  214 + return light.OffNoRefresh(1);
  215 + }
  216 + else
  217 + {
  218 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  219 + }
185 220 }
186   - } else if (cType == "ct") {
187   - uint16_t oldCT = light.state["state"]["ct"];
188   - if (!light.setColorRGB(r, g, b, 1)) {
189   - return false;
  221 + else if (cType == "xy")
  222 + {
  223 + float oldX = light.state["state"]["xy"][0];
  224 + float oldY = light.state["state"]["xy"][1];
  225 + if (!light.setColorRGB(r, g, b, 1))
  226 + {
  227 + return false;
  228 + }
  229 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  230 + if (!light.alert())
  231 + {
  232 + return false;
  233 + }
  234 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  235 + if (!on)
  236 + {
  237 + light.setColorXY(oldX, oldY, 1);
  238 + return light.OffNoRefresh(1);
  239 + }
  240 + else
  241 + {
  242 + return light.setColorXY(oldX, oldY, 1);
  243 + }
190 244 }
191   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
192   - if (!light.alert()) {
193   - return false;
  245 + else if (cType == "ct")
  246 + {
  247 + uint16_t oldCT = light.state["state"]["ct"];
  248 + if (!light.setColorRGB(r, g, b, 1))
  249 + {
  250 + return false;
  251 + }
  252 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  253 + if (!light.alert())
  254 + {
  255 + return false;
  256 + }
  257 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  258 + if (!on)
  259 + {
  260 + light.setColorTemperature(oldCT, 1);
  261 + return light.OffNoRefresh(1);
  262 + }
  263 + else
  264 + {
  265 + return light.setColorTemperature(oldCT, 1);
  266 + }
194 267 }
195   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
196   - if (!on) {
197   - light.setColorTemperature(oldCT, 1);
198   - return light.OffNoRefresh(1);
199   - } else {
200   - return light.setColorTemperature(oldCT, 1);
  268 + else
  269 + {
  270 + return false;
201 271 }
202   - } else {
203   - return false;
204   - }
205 272 }
... ...
hueplusplus/ExtendedColorTemperatureStrategy.cpp
1 1 /**
2   - \file ExtendedColorTemperatureStrategy.cpp
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file ExtendedColorTemperatureStrategy.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #include "include/ExtendedColorTemperatureStrategy.h"
21   -#include "include/HueConfig.h"
22 21  
23 22 #include <cmath>
24 23 #include <iostream>
25 24 #include <thread>
26 25  
  26 +#include "include/HueConfig.h"
  27 +#include "include/Utils.h"
  28 +
27 29 bool ExtendedColorTemperatureStrategy::setColorTemperature(
28   - unsigned int mired, uint8_t transition, HueLight &light) const {
29   - light.refreshState();
30   - nlohmann::json request({});
31   - if (transition != 4) {
32   - request["transitiontime"] = transition;
33   - }
34   - if (light.state["state"]["on"] != true) {
35   - request["on"] = true;
36   - }
37   - if (light.state["state"]["ct"] != mired ||
38   - light.state["state"]["colormode"] != "ct") {
39   - if (mired > 500) {
40   - mired = 500;
  30 + unsigned int mired, uint8_t transition, HueLight& light) const
  31 +{
  32 + light.refreshState();
  33 + nlohmann::json request = nlohmann::json::object();
  34 + if (transition != 4)
  35 + {
  36 + request["transitiontime"] = transition;
41 37 }
42   - if (mired < 153) {
43   - mired = 153;
  38 + if (light.state["state"]["on"] != true)
  39 + {
  40 + request["on"] = true;
  41 + }
  42 + if (light.state["state"]["ct"] != mired || light.state["state"]["colormode"] != "ct")
  43 + {
  44 + if (mired > 500)
  45 + {
  46 + mired = 500;
  47 + }
  48 + if (mired < 153)
  49 + {
  50 + mired = 153;
  51 + }
  52 + request["ct"] = mired;
44 53 }
45   - request["ct"] = mired;
46   - }
47 54  
48   - if (!request.count("on") && !request.count("ct")) {
49   - // Nothing needs to be changed
50   - return true;
51   - }
  55 + if (!request.count("on") && !request.count("ct"))
  56 + {
  57 + // Nothing needs to be changed
  58 + return true;
  59 + }
52 60  
53   - nlohmann::json reply = light.SendPutRequest(request, "/state");
  61 + nlohmann::json reply = light.SendPutRequest(request, "/state");
54 62  
55   - // Check whether request was successful
56   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
57   - bool success = true;
58   - int i = 0;
59   - if (success && request.count("transitiontime")) {
60   - // Check if success was sent and the value was changed
61   - success = reply.size() > i && reply[i].count("success") &&
62   - reply[i]["success"][path + "transitiontime"] ==
63   - request["transitiontime"];
64   - ++i;
65   - }
66   - if (success && request.count("on")) {
67   - // Check if success was sent and the value was changed
68   - success = reply.size() > i && reply[i].count("success") &&
69   - reply[i]["success"][path + "on"] == request["on"];
70   - ++i;
71   - }
72   - if (success && request.count("ct")) {
73   - // Check if success was sent and the value was changed
74   - success = reply.size() > i && reply[i].count("success") &&
75   - reply[i]["success"][path + "ct"] == request["ct"];
76   - }
77   - return success;
  63 + // Check whether request was successful
  64 + return utils::validateReplyForLight(request, reply, light.id);
78 65 }
79 66  
80   -bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired,
81   - HueLight &light) const {
82   - light.refreshState();
83   - std::string cType = light.state["state"]["colormode"];
84   - bool on = light.state["state"]["on"];
85   - if (cType == "hs") {
86   - uint16_t oldHue = light.state["state"]["hue"];
87   - uint8_t oldSat = light.state["state"]["sat"];
88   - if (!light.setColorTemperature(mired, 1)) {
89   - return false;
90   - }
91   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
92   - if (!light.alert()) {
93   - return false;
94   - }
95   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
96   - if (!on) {
97   - light.setColorHueSaturation(oldHue, oldSat, 1);
98   - return light.OffNoRefresh(1);
99   - } else {
100   - return light.setColorHueSaturation(oldHue, oldSat, 1);
101   - }
102   - } else if (cType == "xy") {
103   - float oldX = light.state["state"]["xy"][0];
104   - float oldY = light.state["state"]["xy"][1];
105   - if (!light.setColorTemperature(mired, 1)) {
106   - return false;
107   - }
108   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
109   - if (!light.alert()) {
110   - return false;
111   - }
112   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
113   - if (!on) {
114   - light.setColorXY(oldX, oldY, 1);
115   - return light.OffNoRefresh(1);
116   - } else {
117   - return light.setColorXY(oldX, oldY, 1);
  67 +bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const
  68 +{
  69 + light.refreshState();
  70 + std::string cType = light.state["state"]["colormode"];
  71 + bool on = light.state["state"]["on"];
  72 + if (cType == "hs")
  73 + {
  74 + uint16_t oldHue = light.state["state"]["hue"];
  75 + uint8_t oldSat = light.state["state"]["sat"];
  76 + if (!light.setColorTemperature(mired, 1))
  77 + {
  78 + return false;
  79 + }
  80 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  81 + if (!light.alert())
  82 + {
  83 + return false;
  84 + }
  85 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  86 + if (!on)
  87 + {
  88 + light.setColorHueSaturation(oldHue, oldSat, 1);
  89 + return light.OffNoRefresh(1);
  90 + }
  91 + else
  92 + {
  93 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  94 + }
118 95 }
119   - } else if (cType == "ct") {
120   - uint16_t oldCT = light.state["state"]["ct"];
121   - if (!light.setColorTemperature(mired, 1)) {
122   - return false;
  96 + else if (cType == "xy")
  97 + {
  98 + float oldX = light.state["state"]["xy"][0];
  99 + float oldY = light.state["state"]["xy"][1];
  100 + if (!light.setColorTemperature(mired, 1))
  101 + {
  102 + return false;
  103 + }
  104 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  105 + if (!light.alert())
  106 + {
  107 + return false;
  108 + }
  109 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  110 + if (!on)
  111 + {
  112 + light.setColorXY(oldX, oldY, 1);
  113 + return light.OffNoRefresh(1);
  114 + }
  115 + else
  116 + {
  117 + return light.setColorXY(oldX, oldY, 1);
  118 + }
123 119 }
124   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
125   - if (!light.alert()) {
126   - return false;
  120 + else if (cType == "ct")
  121 + {
  122 + uint16_t oldCT = light.state["state"]["ct"];
  123 + if (!light.setColorTemperature(mired, 1))
  124 + {
  125 + return false;
  126 + }
  127 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  128 + if (!light.alert())
  129 + {
  130 + return false;
  131 + }
  132 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  133 + if (!on)
  134 + {
  135 + light.setColorTemperature(oldCT, 1);
  136 + return light.OffNoRefresh(1);
  137 + }
  138 + else
  139 + {
  140 + return light.setColorTemperature(oldCT, 1);
  141 + }
127 142 }
128   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
129   - if (!on) {
130   - light.setColorTemperature(oldCT, 1);
131   - return light.OffNoRefresh(1);
132   - } else {
133   - return light.setColorTemperature(oldCT, 1);
  143 + else
  144 + {
  145 + return false;
134 146 }
135   - } else {
136   - return false;
137   - }
138 147 }
... ...
hueplusplus/Hue.cpp
... ... @@ -33,379 +33,464 @@
33 33 #include "include/SimpleBrightnessStrategy.h"
34 34 #include "include/SimpleColorHueStrategy.h"
35 35 #include "include/SimpleColorTemperatureStrategy.h"
36   -
37 36 #include "include/UPnP.h"
38 37  
39   -HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler)
40   - : http_handler(std::move(handler)) {}
41   -
42   -std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const {
43   - UPnP uplug;
44   - std::vector<std::pair<std::string, std::string>> foundDevices =
45   - uplug.getDevices(http_handler);
46   -
47   - std::vector<HueIdentification> foundBridges;
48   - for (const std::pair<std::string, std::string> &p : foundDevices) {
49   - size_t found = p.second.find("IpBridge");
50   - if (found != std::string::npos) {
51   - HueIdentification bridge;
52   - size_t start = p.first.find("//") + 2;
53   - size_t length = p.first.find(":", start) - start;
54   - bridge.ip = p.first.substr(start, length);
55   - auto portLength = p.first.find("/", start + length) - (start + length + 1);
56   - auto port = p.first.substr(start + length + 1, portLength);
57   - bridge.port = std::stoi(port);
58   - std::string desc = http_handler->GETString(
59   - "/description.xml", "application/xml", "", bridge.ip, bridge.port);
60   - std::string mac = ParseDescription(desc);
61   - if (!mac.empty()) {
62   - bridge.mac = NormalizeMac(mac);
63   - foundBridges.push_back(std::move(bridge));
64   - }
65   - }
66   - }
67   - return foundBridges;
  38 +HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler(std::move(handler)) {}
  39 +
  40 +std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const
  41 +{
  42 + UPnP uplug;
  43 + std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(http_handler);
  44 +
  45 + std::vector<HueIdentification> foundBridges;
  46 + for (const std::pair<std::string, std::string>& p : foundDevices)
  47 + {
  48 + size_t found = p.second.find("IpBridge");
  49 + if (found != std::string::npos)
  50 + {
  51 + HueIdentification bridge;
  52 + size_t start = p.first.find("//") + 2;
  53 + size_t length = p.first.find(":", start) - start;
  54 + bridge.ip = p.first.substr(start, length);
  55 + std::string desc
  56 + = http_handler->GETString("/description.xml", "application/xml", "", bridge.ip, bridge.port);
  57 + std::string mac = ParseDescription(desc);
  58 + if (!mac.empty())
  59 + {
  60 + bridge.mac = NormalizeMac(mac);
  61 + foundBridges.push_back(std::move(bridge));
  62 + }
  63 + }
  64 + }
  65 + return foundBridges;
68 66 }
69 67  
70   -Hue HueFinder::GetBridge(const HueIdentification &identification) {
71   - std::string normalizedMac = NormalizeMac(identification.mac);
72   - auto pos = usernames.find(normalizedMac);
73   - if (pos != usernames.end()) {
74   - return Hue(identification.ip, identification.port,
75   - pos->second, http_handler);
76   - }
77   - Hue bridge(identification.ip, identification.port, "", http_handler);
78   - bridge.requestUsername(identification.ip);
79   - if (bridge.getUsername().empty()) {
80   - std::cerr << "Failed to request username for ip " << identification.ip
81   - << std::endl;
82   - throw std::runtime_error("Failed to request username!");
83   - }
84   - AddUsername(normalizedMac, bridge.getUsername());
  68 +Hue HueFinder::GetBridge(const HueIdentification& identification)
  69 +{
  70 + std::string normalizedMac = NormalizeMac(identification.mac);
  71 + auto pos = usernames.find(normalizedMac);
  72 + if (pos != usernames.end())
  73 + {
  74 + return Hue(identification.ip, identification.port, pos->second, http_handler);
  75 + }
  76 + Hue bridge(identification.ip, identification.port, "", http_handler);
  77 + bridge.requestUsername(identification.ip);
  78 + if (bridge.getUsername().empty())
  79 + {
  80 + std::cerr << "Failed to request username for ip " << identification.ip << std::endl;
  81 + throw std::runtime_error("Failed to request username!");
  82 + }
  83 + AddUsername(normalizedMac, bridge.getUsername());
85 84  
86   - return bridge;
  85 + return bridge;
87 86 }
88 87  
89   -void HueFinder::AddUsername(const std::string &mac,
90   - const std::string &username) {
91   - usernames[NormalizeMac(mac)] = username;
  88 +void HueFinder::AddUsername(const std::string& mac, const std::string& username)
  89 +{
  90 + usernames[NormalizeMac(mac)] = username;
92 91 }
93 92  
94   -const std::map<std::string, std::string> &HueFinder::GetAllUsernames() const {
95   - return usernames;
  93 +const std::map<std::string, std::string>& HueFinder::GetAllUsernames() const
  94 +{
  95 + return usernames;
96 96 }
97 97  
98   -std::string HueFinder::NormalizeMac(std::string input) {
99   - // Remove any non alphanumeric characters (e.g. ':' and whitespace)
100   - input.erase(
101   - std::remove_if(input.begin(), input.end(),
102   - [](char c) { return !std::isalnum(c, std::locale()); }),
103   - input.end());
104   - // Convert to lower case
105   - std::transform(input.begin(), input.end(), input.begin(),
106   - [](char c) { return std::tolower(c, std::locale()); });
107   - return input;
  98 +std::string HueFinder::NormalizeMac(std::string input)
  99 +{
  100 + // Remove any non alphanumeric characters (e.g. ':' and whitespace)
  101 + input.erase(std::remove_if(input.begin(), input.end(), [](char c) { return !std::isalnum(c, std::locale()); }),
  102 + input.end());
  103 + // Convert to lower case
  104 + std::transform(input.begin(), input.end(), input.begin(), [](char c) { return std::tolower(c, std::locale()); });
  105 + return input;
108 106 }
109 107  
110   -std::string HueFinder::ParseDescription(const std::string &description) {
111   - const char *model = "<modelName>Philips hue bridge";
112   - const char *serialBegin = "<serialNumber>";
113   - const char *serialEnd = "</serialNumber>";
114   - if (description.find(model) != std::string::npos) {
115   - std::size_t begin = description.find(serialBegin);
116   - std::size_t end = description.find(serialEnd, begin);
117   - if (begin != std::string::npos && end != std::string::npos) {
118   - begin += std::strlen(serialBegin);
119   - if (begin < description.size()) {
120   - std::string result = description.substr(begin, end - begin);
121   - return result;
122   - }
123   - }
124   - }
125   - return std::string();
  108 +std::string HueFinder::ParseDescription(const std::string& description)
  109 +{
  110 + const char* model = "<modelName>Philips hue bridge";
  111 + const char* serialBegin = "<serialNumber>";
  112 + const char* serialEnd = "</serialNumber>";
  113 + if (description.find(model) != std::string::npos)
  114 + {
  115 + std::size_t begin = description.find(serialBegin);
  116 + std::size_t end = description.find(serialEnd, begin);
  117 + if (begin != std::string::npos && end != std::string::npos)
  118 + {
  119 + begin += std::strlen(serialBegin);
  120 + if (begin < description.size())
  121 + {
  122 + std::string result = description.substr(begin, end - begin);
  123 + return result;
  124 + }
  125 + }
  126 + }
  127 + return std::string();
126 128 }
127 129  
128   -Hue::Hue(const std::string &ip, const int port, const std::string &username,
129   - std::shared_ptr<const IHttpHandler> handler)
130   - : ip(ip), port(port), username(username),
  130 +Hue::Hue(
  131 + const std::string& ip, const int port, const std::string& username, std::shared_ptr<const IHttpHandler> handler)
  132 + : ip(ip),
  133 + port(port),
  134 + username(username),
131 135 simpleBrightnessStrategy(std::make_shared<SimpleBrightnessStrategy>()),
132 136 simpleColorHueStrategy(std::make_shared<SimpleColorHueStrategy>()),
133 137 extendedColorHueStrategy(std::make_shared<ExtendedColorHueStrategy>()),
134   - simpleColorTemperatureStrategy(
135   - std::make_shared<SimpleColorTemperatureStrategy>()),
136   - extendedColorTemperatureStrategy(
137   - std::make_shared<ExtendedColorTemperatureStrategy>()),
138   - http_handler(std::move(handler)), commands(ip, port, username,
139   - http_handler) {}
140   -
141   -std::string Hue::getBridgeIP() { return ip; }
142   -
143   -int Hue::getBridgePort() { return port; }
144   -
145   -std::string Hue::requestUsername(const std::string &ip) {
146   - std::cout
147   - << "Please press the link Button! You've got 35 secs!\n"; // when the link
148   - // button was
149   - // pressed we
150   - // got 30
151   - // seconds to
152   - // get our
153   - // username for
154   - // control
155   -
156   - nlohmann::json request;
157   - request["devicetype"] = "HuePlusPlus#User";
  138 + simpleColorTemperatureStrategy(std::make_shared<SimpleColorTemperatureStrategy>()),
  139 + extendedColorTemperatureStrategy(std::make_shared<ExtendedColorTemperatureStrategy>()),
  140 + http_handler(std::move(handler)),
  141 + commands(ip, port, username, http_handler)
  142 +{}
  143 +
  144 +std::string Hue::getBridgeIP()
  145 +{
  146 + return ip;
  147 +}
158 148  
159   - nlohmann::json answer;
160   - std::chrono::steady_clock::time_point start =
161   - std::chrono::steady_clock::now();
162   - std::chrono::steady_clock::time_point lastCheck;
163   - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35)) {
164   - if (std::chrono::steady_clock::now() - lastCheck >
165   - std::chrono::seconds(1)) {
166   - lastCheck = std::chrono::steady_clock::now();
167   - answer = http_handler->POSTJson("/api", request, ip, port);
  149 +int Hue::getBridgePort()
  150 +{
  151 + return port;
  152 +}
168 153  
169   - if (answer.size() > 0) {
170   - if (answer[0].count("success")) {
171   - // [{"success":{"username": "<username>"}}]
172   - username = answer[0]["success"]["username"];
173   - this->ip = ip;
174   - // Update commands with new username and ip
175   - commands = HueCommandAPI(ip, port, username, http_handler);
176   - std::cout << "Success! Link button was pressed!\n";
177   - std::cout << "Username is \"" << username << "\"\n";
178   - break;
179   - } else if (answer[0].count("error")) {
180   - std::cout << "Link button not pressed!\n";
  154 +std::string Hue::requestUsername(const std::string& ip)
  155 +{
  156 + std::cout << "Please press the link Button! You've got 35 secs!\n"; // when the link
  157 + // button was
  158 + // pressed we
  159 + // got 30
  160 + // seconds to
  161 + // get our
  162 + // username for
  163 + // control
  164 +
  165 + nlohmann::json request;
  166 + request["devicetype"] = "HuePlusPlus#User";
  167 +
  168 + nlohmann::json answer;
  169 + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
  170 + std::chrono::steady_clock::time_point lastCheck;
  171 + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35))
  172 + {
  173 + if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1))
  174 + {
  175 + lastCheck = std::chrono::steady_clock::now();
  176 + answer = http_handler->POSTJson("/api", request, ip, port);
  177 +
  178 + if (answer.size() > 0)
  179 + {
  180 + if (answer[0].count("success"))
  181 + {
  182 + // [{"success":{"username": "<username>"}}]
  183 + username = answer[0]["success"]["username"];
  184 + this->ip = ip;
  185 + // Update commands with new username and ip
  186 + commands = HueCommandAPI(ip, port, username, http_handler);
  187 + std::cout << "Success! Link button was pressed!\n";
  188 + std::cout << "Username is \"" << username << "\"\n";
  189 + break;
  190 + }
  191 + else if (answer[0].count("error"))
  192 + {
  193 + std::cout << "Link button not pressed!\n";
  194 + }
  195 + }
181 196 }
182   - }
183 197 }
184   - }
185   - return username;
  198 + return username;
186 199 }
187 200  
188   -std::string Hue::getUsername() { return username; }
  201 +std::string Hue::getUsername()
  202 +{
  203 + return username;
  204 +}
189 205  
190   -void Hue::setIP(const std::string &ip) { this->ip = ip; }
  206 +void Hue::setIP(const std::string& ip)
  207 +{
  208 + this->ip = ip;
  209 +}
191 210  
192   -void Hue::setPort(const int port) { this->port = port; }
  211 +void Hue::setPort(const int port)
  212 +{
  213 + this->port = port;
  214 +}
193 215  
194   -HueLight &Hue::getLight(int id) {
195   - auto pos = lights.find(id);
196   - if (pos != lights.end()) {
197   - pos->second.refreshState();
198   - return pos->second;
199   - }
200   - refreshState();
201   - if (!state["lights"].count(std::to_string(id))) {
202   - std::cerr << "Error in Hue getLight(): light with id " << id
203   - << " is not valid\n";
204   - throw(std::runtime_error("Error in Hue getLight(): light id is not valid"));
205   - }
206   - // std::cout << state["lights"][std::to_string(id)] << std::endl;
207   - std::string type = state["lights"][std::to_string(id)]["modelid"];
208   - // std::cout << type << std::endl;
209   - if (type == "LCT001" || type == "LCT002" || type == "LCT003" ||
210   - type == "LCT007" || type == "LLM001") {
211   - // HueExtendedColorLight Gamut B
212   - HueLight light =
213   - HueLight(id, commands, simpleBrightnessStrategy,
214   - extendedColorTemperatureStrategy, extendedColorHueStrategy);
215   - light.colorType = ColorType::GAMUT_B;
216   - lights.emplace(id, light);
217   - return lights.find(id)->second;
218   - } else if (type == "LCT010" || type == "LCT011" || type == "LCT012" ||
219   - type == "LCT014" || type == "LCT015" || type == "LCT016" ||
220   - type == "LLC020" || type == "LST002") {
221   - // HueExtendedColorLight Gamut C
222   - HueLight light =
223   - HueLight(id, commands, simpleBrightnessStrategy,
224   - extendedColorTemperatureStrategy, extendedColorHueStrategy);
225   - light.colorType = ColorType::GAMUT_C;
226   - lights.emplace(id, light);
227   - return lights.find(id)->second;
228   - } else if (type == "LST001" || type == "LLC005" || type == "LLC006" ||
229   - type == "LLC007" || type == "LLC010" || type == "LLC011" ||
230   - type == "LLC012" || type == "LLC013" || type == "LLC014") {
231   - // HueColorLight Gamut A
232   - HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr,
233   - simpleColorHueStrategy);
234   - light.colorType = ColorType::GAMUT_A;
235   - lights.emplace(id, light);
236   - return lights.find(id)->second;
237   - } else if (type == "LWB004" || type == "LWB006" || type == "LWB007" ||
238   - type == "LWB010" || type == "LWB014" || type == "LDF001" ||
239   - type == "LDF002" || type == "LDD001" || type == "LDD002" ||
240   - type == "MWM001") {
241   - // HueDimmableLight No Color Type
242   - HueLight light =
243   - HueLight(id, commands, simpleBrightnessStrategy, nullptr, nullptr);
244   - light.colorType = ColorType::NONE;
245   - lights.emplace(id, light);
246   - return lights.find(id)->second;
247   - } else if (type == "LLM010" || type == "LLM011" || type == "LLM012" ||
248   - type == "LTW001" || type == "LTW004" || type == "LTW010" ||
249   - type == "LTW011" || type == "LTW012" || type == "LTW013" ||
250   - type == "LTW014" || type == "LTW015" || type == "LTP001" ||
251   - type == "LTP002" || type == "LTP003" || type == "LTP004" ||
252   - type == "LTP005" || type == "LTD003" || type == "LTF001" ||
253   - type == "LTF002" || type == "LTC001" || type == "LTC002" ||
254   - type == "LTC003" || type == "LTC004" || type == "LTC011" ||
255   - type == "LTC012" || type == "LTD001" || type == "LTD002" ||
256   - type == "LFF001" || type == "LTT001" || type == "LDT001") {
257   - // HueTemperatureLight
258   - HueLight light = HueLight(id, commands, simpleBrightnessStrategy,
259   - simpleColorTemperatureStrategy, nullptr);
260   - light.colorType = ColorType::TEMPERATURE;
261   - lights.emplace(id, light);
262   - return lights.find(id)->second;
263   - }
264   - std::cerr << "Could not determine HueLight type:" << type << "!\n";
265   - throw(std::runtime_error("Could not determine HueLight type!"));
  216 +HueLight& Hue::getLight(int id)
  217 +{
  218 + auto pos = lights.find(id);
  219 + if (pos != lights.end())
  220 + {
  221 + pos->second.refreshState();
  222 + return pos->second;
  223 + }
  224 + refreshState();
  225 + if (!state["lights"].count(std::to_string(id)))
  226 + {
  227 + std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n";
  228 + throw(std::runtime_error("Error in Hue getLight(): light id is not valid"));
  229 + }
  230 + // std::cout << state["lights"][std::to_string(id)] << std::endl;
  231 + std::string type = state["lights"][std::to_string(id)]["modelid"];
  232 + // std::cout << type << std::endl;
  233 + if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001")
  234 + {
  235 + // HueExtendedColorLight Gamut B
  236 + HueLight light = HueLight(
  237 + id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy);
  238 + light.colorType = ColorType::GAMUT_B;
  239 + lights.emplace(id, light);
  240 + return lights.find(id)->second;
  241 + }
  242 + else if (type == "LCT010" || type == "LCT011" || type == "LCT012" || type == "LCT014" || type == "LCT015"
  243 + || type == "LCT016" || type == "LLC020" || type == "LST002")
  244 + {
  245 + // HueExtendedColorLight Gamut C
  246 + HueLight light = HueLight(
  247 + id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy);
  248 + light.colorType = ColorType::GAMUT_C;
  249 + lights.emplace(id, light);
  250 + return lights.find(id)->second;
  251 + }
  252 + else if (type == "LST001" || type == "LLC005" || type == "LLC006" || type == "LLC007" || type == "LLC010"
  253 + || type == "LLC011" || type == "LLC012" || type == "LLC013" || type == "LLC014")
  254 + {
  255 + // HueColorLight Gamut A
  256 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, simpleColorHueStrategy);
  257 + light.colorType = ColorType::GAMUT_A;
  258 + lights.emplace(id, light);
  259 + return lights.find(id)->second;
  260 + }
  261 + else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014"
  262 + || type == "LDF001" || type == "LDF002" || type == "LDD001" || type == "LDD002" || type == "MWM001")
  263 + {
  264 + // HueDimmableLight No Color Type
  265 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, nullptr);
  266 + light.colorType = ColorType::NONE;
  267 + lights.emplace(id, light);
  268 + return lights.find(id)->second;
  269 + }
  270 + else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004"
  271 + || type == "LTW010" || type == "LTW011" || type == "LTW012" || type == "LTW013" || type == "LTW014"
  272 + || type == "LTW015" || type == "LTP001" || type == "LTP002" || type == "LTP003" || type == "LTP004"
  273 + || type == "LTP005" || type == "LTD003" || type == "LTF001" || type == "LTF002" || type == "LTC001"
  274 + || type == "LTC002" || type == "LTC003" || type == "LTC004" || type == "LTC011" || type == "LTC012"
  275 + || type == "LTD001" || type == "LTD002" || type == "LFF001" || type == "LTT001" || type == "LDT001")
  276 + {
  277 + // HueTemperatureLight
  278 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr);
  279 + light.colorType = ColorType::TEMPERATURE;
  280 + lights.emplace(id, light);
  281 + return lights.find(id)->second;
  282 + }
  283 + std::cerr << "Could not determine HueLight type:" << type << "!\n";
  284 + throw(std::runtime_error("Could not determine HueLight type!"));
266 285 }
267 286  
268   -bool Hue::removeLight(int id) {
269   - nlohmann::json result =
270   - commands.DELETERequest("/lights/" + std::to_string(id), {});
271   - bool success =
272   - result.is_array() && result.size() > 0 && result[0].count("success") &&
273   - result[0]["success"] == "/lights/" + std::to_string(id) + " deleted";
274   - if (success && lights.count(id) != 0) {
275   - lights.erase(id);
276   - }
277   - return success;
  287 +bool Hue::removeLight(int id)
  288 +{
  289 + nlohmann::json result = commands.DELETERequest("/lights/" + std::to_string(id), nlohmann::json::object());
  290 + bool success = result.is_array() && result.size() > 0 && result[0].count("success")
  291 + && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted";
  292 + if (success && lights.count(id) != 0)
  293 + {
  294 + lights.erase(id);
  295 + }
  296 + return success;
278 297 }
279 298  
280   -std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights() {
281   - refreshState();
282   - for (const auto &id : state["lights"].items()) {
283   - getLight(std::stoi(id.key()));
284   - }
285   - std::vector<std::reference_wrapper<HueLight>> result;
286   - for (auto &entry : lights) {
287   - result.emplace_back(entry.second);
288   - }
289   - return result;
  299 +std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights()
  300 +{
  301 + refreshState();
  302 + nlohmann::json lightsState = state["lights"];
  303 + for (nlohmann::json::iterator it = lightsState.begin(); it != lightsState.end(); ++it)
  304 + {
  305 + getLight(std::stoi(it.key()));
  306 + }
  307 + std::vector<std::reference_wrapper<HueLight>> result;
  308 + for (auto& entry : lights)
  309 + {
  310 + result.emplace_back(entry.second);
  311 + }
  312 + return result;
290 313 }
291 314  
292   -bool Hue::lightExists(int id) {
293   - refreshState();
294   - auto pos = lights.find(id);
295   - if (pos != lights.end()) {
296   - return true;
297   - }
298   - if (state["lights"].count(std::to_string(id))) {
299   - return true;
300   - }
301   - return false;
  315 +bool Hue::lightExists(int id)
  316 +{
  317 + refreshState();
  318 + auto pos = lights.find(id);
  319 + if (pos != lights.end())
  320 + {
  321 + return true;
  322 + }
  323 + if (state["lights"].count(std::to_string(id)))
  324 + {
  325 + return true;
  326 + }
  327 + return false;
302 328 }
303 329  
304   -bool Hue::lightExists(int id) const {
305   - auto pos = lights.find(id);
306   - if (pos != lights.end()) {
307   - return true;
308   - }
309   - if (state["lights"].count(std::to_string(id))) {
310   - return true;
311   - }
312   - return false;
  330 +bool Hue::lightExists(int id) const
  331 +{
  332 + auto pos = lights.find(id);
  333 + if (pos != lights.end())
  334 + {
  335 + return true;
  336 + }
  337 + if (state["lights"].count(std::to_string(id)))
  338 + {
  339 + return true;
  340 + }
  341 + return false;
313 342 }
314 343  
315   -std::string Hue::getPictureOfLight(int id) const {
316   - std::string ret = "";
317   - auto pos = lights.find(id);
318   - if (pos != lights.end()) {
319   - ret = getPictureOfModel(pos->second.getModelId());
320   - }
321   - return ret;
  344 +std::string Hue::getPictureOfLight(int id) const
  345 +{
  346 + std::string ret = "";
  347 + auto pos = lights.find(id);
  348 + if (pos != lights.end())
  349 + {
  350 + ret = getPictureOfModel(pos->second.getModelId());
  351 + }
  352 + return ret;
322 353 }
323 354  
324   -std::string Hue::getPictureOfModel(const std::string &model_id) const {
325   - std::string ret = "";
326   - if (model_id == "LCT001" || model_id == "LCT007" || model_id == "LCT010" ||
327   - model_id == "LCT014" || model_id == "LTW010" || model_id == "LTW001" ||
328   - model_id == "LTW004" || model_id == "LTW015" || model_id == "LWB004" ||
329   - model_id == "LWB006") {
330   - ret.append("e27_waca");
331   - } else if (model_id == "LWB010" || model_id == "LWB014") {
332   - ret.append("e27_white");
333   - } else if (model_id == "LCT012" || model_id == "LTW012") {
334   - ret.append("e14");
335   - } else if (model_id == "LCT002") {
336   - ret.append("br30");
337   - } else if (model_id == "LCT011" || model_id == "LTW011") {
338   - ret.append("br30_slim");
339   - } else if (model_id == "LCT003") {
340   - ret.append("gu10");
341   - } else if (model_id == "LTW013") {
342   - ret.append("gu10_perfectfit");
343   - } else if (model_id == "LST001" || model_id == "LST002") {
344   - ret.append("lightstrip");
345   - } else if (model_id == "LLC006 " || model_id == "LLC010") {
346   - ret.append("iris");
347   - } else if (model_id == "LLC005" || model_id == "LLC011" ||
348   - model_id == "LLC012" || model_id == "LLC007") {
349   - ret.append("bloom");
350   - } else if (model_id == "LLC014") {
351   - ret.append("aura");
352   - } else if (model_id == "LLC013") {
353   - ret.append("storylight");
354   - } else if (model_id == "LLC020") {
355   - ret.append("go");
356   - } else if (model_id == "HBL001" || model_id == "HBL002" ||
357   - model_id == "HBL003") {
358   - ret.append("beyond_ceiling_pendant_table");
359   - } else if (model_id == "HIL001 " || model_id == "HIL002") {
360   - ret.append("impulse");
361   - } else if (model_id == "HEL001 " || model_id == "HEL002") {
362   - ret.append("entity");
363   - } else if (model_id == "HML001" || model_id == "HML002" ||
364   - model_id == "HML003" || model_id == "HML004" ||
365   - model_id == "HML005") {
366   - ret.append("phoenix_ceiling_pendant_table_wall");
367   - } else if (model_id == "HML006") {
368   - ret.append("phoenix_down");
369   - } else if (model_id == "LTP001" || model_id == "LTP002" ||
370   - model_id == "LTP003" || model_id == "LTP004" ||
371   - model_id == "LTP005" || model_id == "LTD003") {
372   - ret.append("pendant");
373   - } else if (model_id == "LDF002" || model_id == "LTF001" ||
374   - model_id == "LTF002" || model_id == "LTC001" ||
375   - model_id == "LTC002" || model_id == "LTC003" ||
376   - model_id == "LTC004" || model_id == "LTD001" ||
377   - model_id == "LTD002" || model_id == "LDF001") {
378   - ret.append("ceiling");
379   - } else if (model_id == "LDD002 " || model_id == "LFF001") {
380   - ret.append("floor");
381   - } else if (model_id == "LDD001 " || model_id == "LTT001") {
382   - ret.append("table");
383   - } else if (model_id == "LDT001 " || model_id == "MWM001") {
384   - ret.append("recessed");
385   - } else if (model_id == "BSB001") {
386   - ret.append("bridge_v1");
387   - } else if (model_id == "BSB002") {
388   - ret.append("bridge_v2");
389   - } else if (model_id == "SWT001") {
390   - ret.append("tap");
391   - } else if (model_id == "RWL021") {
392   - ret.append("hds");
393   - } else if (model_id == "SML001") {
394   - ret.append("motion_sensor");
395   - }
396   - return ret;
  355 +std::string Hue::getPictureOfModel(const std::string& model_id) const
  356 +{
  357 + std::string ret = "";
  358 + if (model_id == "LCT001" || model_id == "LCT007" || model_id == "LCT010" || model_id == "LCT014"
  359 + || model_id == "LTW010" || model_id == "LTW001" || model_id == "LTW004" || model_id == "LTW015"
  360 + || model_id == "LWB004" || model_id == "LWB006")
  361 + {
  362 + ret.append("e27_waca");
  363 + }
  364 + else if (model_id == "LWB010" || model_id == "LWB014")
  365 + {
  366 + ret.append("e27_white");
  367 + }
  368 + else if (model_id == "LCT012" || model_id == "LTW012")
  369 + {
  370 + ret.append("e14");
  371 + }
  372 + else if (model_id == "LCT002")
  373 + {
  374 + ret.append("br30");
  375 + }
  376 + else if (model_id == "LCT011" || model_id == "LTW011")
  377 + {
  378 + ret.append("br30_slim");
  379 + }
  380 + else if (model_id == "LCT003")
  381 + {
  382 + ret.append("gu10");
  383 + }
  384 + else if (model_id == "LTW013")
  385 + {
  386 + ret.append("gu10_perfectfit");
  387 + }
  388 + else if (model_id == "LST001" || model_id == "LST002")
  389 + {
  390 + ret.append("lightstrip");
  391 + }
  392 + else if (model_id == "LLC006 " || model_id == "LLC010")
  393 + {
  394 + ret.append("iris");
  395 + }
  396 + else if (model_id == "LLC005" || model_id == "LLC011" || model_id == "LLC012" || model_id == "LLC007")
  397 + {
  398 + ret.append("bloom");
  399 + }
  400 + else if (model_id == "LLC014")
  401 + {
  402 + ret.append("aura");
  403 + }
  404 + else if (model_id == "LLC013")
  405 + {
  406 + ret.append("storylight");
  407 + }
  408 + else if (model_id == "LLC020")
  409 + {
  410 + ret.append("go");
  411 + }
  412 + else if (model_id == "HBL001" || model_id == "HBL002" || model_id == "HBL003")
  413 + {
  414 + ret.append("beyond_ceiling_pendant_table");
  415 + }
  416 + else if (model_id == "HIL001 " || model_id == "HIL002")
  417 + {
  418 + ret.append("impulse");
  419 + }
  420 + else if (model_id == "HEL001 " || model_id == "HEL002")
  421 + {
  422 + ret.append("entity");
  423 + }
  424 + else if (model_id == "HML001" || model_id == "HML002" || model_id == "HML003" || model_id == "HML004"
  425 + || model_id == "HML005")
  426 + {
  427 + ret.append("phoenix_ceiling_pendant_table_wall");
  428 + }
  429 + else if (model_id == "HML006")
  430 + {
  431 + ret.append("phoenix_down");
  432 + }
  433 + else if (model_id == "LTP001" || model_id == "LTP002" || model_id == "LTP003" || model_id == "LTP004"
  434 + || model_id == "LTP005" || model_id == "LTD003")
  435 + {
  436 + ret.append("pendant");
  437 + }
  438 + else if (model_id == "LDF002" || model_id == "LTF001" || model_id == "LTF002" || model_id == "LTC001"
  439 + || model_id == "LTC002" || model_id == "LTC003" || model_id == "LTC004" || model_id == "LTD001"
  440 + || model_id == "LTD002" || model_id == "LDF001")
  441 + {
  442 + ret.append("ceiling");
  443 + }
  444 + else if (model_id == "LDD002 " || model_id == "LFF001")
  445 + {
  446 + ret.append("floor");
  447 + }
  448 + else if (model_id == "LDD001 " || model_id == "LTT001")
  449 + {
  450 + ret.append("table");
  451 + }
  452 + else if (model_id == "LDT001 " || model_id == "MWM001")
  453 + {
  454 + ret.append("recessed");
  455 + }
  456 + else if (model_id == "BSB001")
  457 + {
  458 + ret.append("bridge_v1");
  459 + }
  460 + else if (model_id == "BSB002")
  461 + {
  462 + ret.append("bridge_v2");
  463 + }
  464 + else if (model_id == "SWT001")
  465 + {
  466 + ret.append("tap");
  467 + }
  468 + else if (model_id == "RWL021")
  469 + {
  470 + ret.append("hds");
  471 + }
  472 + else if (model_id == "SML001")
  473 + {
  474 + ret.append("motion_sensor");
  475 + }
  476 + return ret;
397 477 }
398 478  
399   -void Hue::refreshState() {
400   - if (username.empty()) {
401   - return;
402   - }
403   - nlohmann::json answer = commands.GETRequest("", {});
404   - if (answer.is_object() && answer.count("lights")) {
405   - state = answer;
406   - } else {
407   - std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is "
408   - "not expected!\nAnswer:\n\t"
409   - << answer.dump() << std::endl;
410   - }
  479 +void Hue::refreshState()
  480 +{
  481 + if (username.empty())
  482 + {
  483 + return;
  484 + }
  485 + nlohmann::json answer = commands.GETRequest("", nlohmann::json::object());
  486 + if (answer.is_object() && answer.count("lights"))
  487 + {
  488 + state = answer;
  489 + }
  490 + else
  491 + {
  492 + std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is "
  493 + "not expected!\nAnswer:\n\t"
  494 + << answer.dump() << std::endl;
  495 + }
411 496 }
... ...
hueplusplus/HueCommandAPI.cpp
... ... @@ -23,96 +23,100 @@
23 23  
24 24 constexpr std::chrono::steady_clock::duration HueCommandAPI::minDelay;
25 25  
26   -HueCommandAPI::HueCommandAPI(const std::string &ip, const int port,
27   - const std::string &username,
28   - std::shared_ptr<const IHttpHandler> httpHandler)
29   - : ip(ip), port(port), username(username), httpHandler(std::move(httpHandler)),
30   - timeout(new TimeoutData{std::chrono::steady_clock::now()}) {}
  26 +HueCommandAPI::HueCommandAPI(const std::string &ip, const int port, const std::string &username, std::shared_ptr<const IHttpHandler> httpHandler)
  27 + : ip(ip),
  28 + port(port),
  29 + username(username),
  30 + httpHandler(std::move(httpHandler)),
  31 + timeout(new TimeoutData{ std::chrono::steady_clock::now() }) {}
31 32  
32 33 nlohmann::json HueCommandAPI::PUTRequest(const std::string &path,
33   - const nlohmann::json &request) const {
34   - auto now = std::chrono::steady_clock::now();
35   - std::lock_guard<std::mutex> lock(timeout->mutex);
36   - if (timeout->timeout > now) {
37   - std::this_thread::sleep_until(timeout->timeout);
38   - }
39   - // If path does not begin with '/', insert it unless path is empty
40   - const std::string combinedPath =
41   - "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") +
42   - path;
43   - try {
44   - nlohmann::json v = httpHandler->PUTJson(combinedPath, request, ip, port);
45   - timeout->timeout = now + minDelay;
46   - return v;
47   - } catch (const std::system_error &e) {
48   - if (e.code() == std::errc::connection_reset ||
49   - e.code() == std::errc::timed_out) {
50   - // Happens when hue is too busy, wait and try again (once)
51   - std::this_thread::sleep_for(minDelay);
52   - nlohmann::json v = httpHandler->PUTJson(combinedPath, request, ip);
53   - timeout->timeout = std::chrono::steady_clock::now() + minDelay;
54   - return v;
  34 + const nlohmann::json &request) const {
  35 + auto now = std::chrono::steady_clock::now();
  36 + std::lock_guard<std::mutex> lock(timeout->mutex);
  37 + if (timeout->timeout > now) {
  38 + std::this_thread::sleep_until(timeout->timeout);
  39 + }
  40 + // If path does not begin with '/', insert it unless path is empty
  41 + const std::string combinedPath =
  42 + "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") +
  43 + path;
  44 + try {
  45 + nlohmann::json v = httpHandler->PUTJson(combinedPath, request, ip);
  46 + timeout->timeout = now + minDelay;
  47 + return v;
  48 + }
  49 + catch (const std::system_error &e) {
  50 + if (e.code() == std::errc::connection_reset ||
  51 + e.code() == std::errc::timed_out) {
  52 + // Happens when hue is too busy, wait and try again (once)
  53 + std::this_thread::sleep_for(minDelay);
  54 + nlohmann::json v = httpHandler->PUTJson(combinedPath, request, ip);
  55 + timeout->timeout = std::chrono::steady_clock::now() + minDelay;
  56 + return v;
  57 + }
  58 + // Cannot recover from other types of errors
  59 + throw;
55 60 }
56   - // Cannot recover from other types of errors
57   - throw;
58   - }
59 61 }
60 62  
61 63 nlohmann::json HueCommandAPI::GETRequest(const std::string &path,
62   - const nlohmann::json &request) const {
63   - auto now = std::chrono::steady_clock::now();
64   - std::lock_guard<std::mutex> lock(timeout->mutex);
65   - if (timeout->timeout > now) {
66   - std::this_thread::sleep_until(timeout->timeout);
67   - }
68   - // If path does not begin with '/', insert it unless path is empty
69   - const std::string combinedPath =
70   - "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") +
71   - path;
72   - try {
73   - nlohmann::json v = httpHandler->GETJson(combinedPath, request, ip, port);
74   - timeout->timeout = now + minDelay;
75   - return v;
76   - } catch (const std::system_error &e) {
77   - if (e.code() == std::errc::connection_reset ||
78   - e.code() == std::errc::timed_out) {
79   - // Happens when hue is too busy, wait and try again (once)
80   - std::this_thread::sleep_for(minDelay);
81   - nlohmann::json v = httpHandler->GETJson(combinedPath, request, ip, port);
82   - timeout->timeout = std::chrono::steady_clock::now() + minDelay;
83   - return v;
  64 + const nlohmann::json &request) const {
  65 + auto now = std::chrono::steady_clock::now();
  66 + std::lock_guard<std::mutex> lock(timeout->mutex);
  67 + if (timeout->timeout > now) {
  68 + std::this_thread::sleep_until(timeout->timeout);
  69 + }
  70 + // If path does not begin with '/', insert it unless path is empty
  71 + const std::string combinedPath =
  72 + "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") +
  73 + path;
  74 + try {
  75 + nlohmann::json v = httpHandler->GETJson(combinedPath, request, ip);
  76 + timeout->timeout = now + minDelay;
  77 + return v;
  78 + }
  79 + catch (const std::system_error &e) {
  80 + if (e.code() == std::errc::connection_reset ||
  81 + e.code() == std::errc::timed_out) {
  82 + // Happens when hue is too busy, wait and try again (once)
  83 + std::this_thread::sleep_for(minDelay);
  84 + nlohmann::json v = httpHandler->GETJson(combinedPath, request, ip);
  85 + timeout->timeout = std::chrono::steady_clock::now() + minDelay;
  86 + return v;
  87 + }
  88 + // Cannot recover from other types of errors
  89 + throw;
84 90 }
85   - // Cannot recover from other types of errors
86   - throw;
87   - }
88 91 }
89 92  
90 93 nlohmann::json
91 94 HueCommandAPI::DELETERequest(const std::string &path,
92   - const nlohmann::json &request) const {
93   - auto now = std::chrono::steady_clock::now();
94   - std::lock_guard<std::mutex> lock(timeout->mutex);
95   - if (timeout->timeout > now) {
96   - std::this_thread::sleep_until(timeout->timeout);
97   - }
98   - // If path does not begin with '/', insert it unless path is empty
99   - const std::string combinedPath =
100   - "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") +
101   - path;
102   - try {
103   - nlohmann::json v = httpHandler->DELETEJson(combinedPath, request, ip, port);
104   - timeout->timeout = now + minDelay;
105   - return v;
106   - } catch (const std::system_error &e) {
107   - if (e.code() == std::errc::connection_reset ||
108   - e.code() == std::errc::timed_out) {
109   - // Happens when hue is too busy, wait and try again (once)
110   - std::this_thread::sleep_for(minDelay);
111   - nlohmann::json v = httpHandler->DELETEJson(combinedPath, request, ip, port);
112   - timeout->timeout = std::chrono::steady_clock::now() + minDelay;
113   - return v;
  95 + const nlohmann::json &request) const {
  96 + auto now = std::chrono::steady_clock::now();
  97 + std::lock_guard<std::mutex> lock(timeout->mutex);
  98 + if (timeout->timeout > now) {
  99 + std::this_thread::sleep_until(timeout->timeout);
  100 + }
  101 + // If path does not begin with '/', insert it unless path is empty
  102 + const std::string combinedPath =
  103 + "/api/" + username + (path.empty() || path.front() == '/' ? "" : "/") +
  104 + path;
  105 + try {
  106 + nlohmann::json v = httpHandler->DELETEJson(combinedPath, request, ip);
  107 + timeout->timeout = now + minDelay;
  108 + return v;
  109 + }
  110 + catch (const std::system_error &e) {
  111 + if (e.code() == std::errc::connection_reset ||
  112 + e.code() == std::errc::timed_out) {
  113 + // Happens when hue is too busy, wait and try again (once)
  114 + std::this_thread::sleep_for(minDelay);
  115 + nlohmann::json v = httpHandler->DELETEJson(combinedPath, request, ip);
  116 + timeout->timeout = std::chrono::steady_clock::now() + minDelay;
  117 + return v;
  118 + }
  119 + // Cannot recover from other types of errors
  120 + throw;
114 121 }
115   - // Cannot recover from other types of errors
116   - throw;
117   - }
118 122 }
... ...
hueplusplus/HueLight.cpp
... ... @@ -23,213 +23,226 @@
23 23 #include <iostream>
24 24 #include <thread>
25 25  
  26 +#include "include/Utils.h"
26 27 #include "include/json/json.hpp"
27 28  
28   -bool HueLight::On(uint8_t transition) {
29   - refreshState();
30   - return OnNoRefresh(transition);
  29 +bool HueLight::On(uint8_t transition)
  30 +{
  31 + refreshState();
  32 + return OnNoRefresh(transition);
31 33 }
32 34  
33   -bool HueLight::Off(uint8_t transition) {
34   - refreshState();
35   - return OffNoRefresh(transition);
  35 +bool HueLight::Off(uint8_t transition)
  36 +{
  37 + refreshState();
  38 + return OffNoRefresh(transition);
36 39 }
37 40  
38   -bool HueLight::isOn() {
39   - refreshState();
40   - return state["state"]["on"];
  41 +bool HueLight::isOn()
  42 +{
  43 + refreshState();
  44 + return state["state"]["on"];
41 45 }
42 46  
43   -bool HueLight::isOn() const { return state["state"]["on"]; }
  47 +bool HueLight::isOn() const
  48 +{
  49 + return state["state"]["on"];
  50 +}
44 51  
45   -int HueLight::getId() const { return id; }
  52 +int HueLight::getId() const
  53 +{
  54 + return id;
  55 +}
46 56  
47   -std::string HueLight::getType() const { return state["type"]; }
  57 +std::string HueLight::getType() const
  58 +{
  59 + return state["type"];
  60 +}
48 61  
49   -std::string HueLight::getName() {
50   - refreshState();
51   - return state["name"];
  62 +std::string HueLight::getName()
  63 +{
  64 + refreshState();
  65 + return state["name"];
52 66 }
53 67  
54   -std::string HueLight::getName() const { return state["name"]; }
  68 +std::string HueLight::getName() const
  69 +{
  70 + return state["name"];
  71 +}
55 72  
56   -std::string HueLight::getModelId() const { return state["modelid"]; }
  73 +std::string HueLight::getModelId() const
  74 +{
  75 + return state["modelid"];
  76 +}
57 77  
58   -std::string HueLight::getUId() const {
59   - if (state.count("uniqueid")) {
60   - return state["uniqueid"];
61   - }
62   - return std::string();
  78 +std::string HueLight::getUId() const
  79 +{
  80 + if (state.count("uniqueid"))
  81 + {
  82 + return state["uniqueid"];
  83 + }
  84 + return std::string();
63 85 }
64 86  
65   -std::string HueLight::getManufacturername() const {
66   - if (state.count("manufacturername")) {
67   - return state["manufacturername"];
68   - }
69   - return std::string();
  87 +std::string HueLight::getManufacturername() const
  88 +{
  89 + if (state.count("manufacturername"))
  90 + {
  91 + return state["manufacturername"];
  92 + }
  93 + return std::string();
70 94 }
71 95  
72   -std::string HueLight::getProductname() const {
73   - if (state.count("productname")) {
74   - return state["productname"];
75   - }
76   - return std::string();
  96 +std::string HueLight::getProductname() const
  97 +{
  98 + if (state.count("productname"))
  99 + {
  100 + return state["productname"];
  101 + }
  102 + return std::string();
77 103 }
78 104  
79   -std::string HueLight::getLuminaireUId() const {
80   - if (state.count("luminaireuniqueid")) {
81   - return state["luminaireuniqueid"];
82   - }
83   - return std::string();
  105 +std::string HueLight::getLuminaireUId() const
  106 +{
  107 + if (state.count("luminaireuniqueid"))
  108 + {
  109 + return state["luminaireuniqueid"];
  110 + }
  111 + return std::string();
84 112 }
85 113  
86   -std::string HueLight::getSwVersion() {
87   - refreshState();
88   - return state["swversion"];
  114 +std::string HueLight::getSwVersion()
  115 +{
  116 + refreshState();
  117 + return state["swversion"];
89 118 }
90 119  
91   -std::string HueLight::getSwVersion() const { return state["swversion"]; }
  120 +std::string HueLight::getSwVersion() const
  121 +{
  122 + return state["swversion"];
  123 +}
92 124  
93   -bool HueLight::setName(const std::string &name) {
94   - nlohmann::json request({});
95   - request["name"] = name;
96   - nlohmann::json reply = SendPutRequest(request, "/name");
  125 +bool HueLight::setName(const std::string& name)
  126 +{
  127 + nlohmann::json request = nlohmann::json::object();
  128 + request["name"] = name;
  129 + nlohmann::json reply = SendPutRequest(request, "/name");
97 130  
98   - // Check whether request was successful
99   - return reply.size() > 0 && reply[0].count("success") &&
100   - reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name;
  131 + // Check whether request was successful
  132 + return reply.size() > 0 && reply[0].count("success")
  133 + && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name;
101 134 }
102 135  
103   -ColorType HueLight::getColorType() const { return colorType; }
104   -
105   -unsigned int HueLight::KelvinToMired(unsigned int kelvin) const {
106   - return int(0.5f + (1000000 / kelvin));
  136 +ColorType HueLight::getColorType() const
  137 +{
  138 + return colorType;
107 139 }
108 140  
109   -unsigned int HueLight::MiredToKelvin(unsigned int mired) const {
110   - return int(0.5f + (1000000 / mired));
  141 +unsigned int HueLight::KelvinToMired(unsigned int kelvin) const
  142 +{
  143 + return int(0.5f + (1000000 / kelvin));
111 144 }
112 145  
113   -bool HueLight::alert() {
114   - nlohmann::json request;
115   - request["alert"] = "select";
  146 +unsigned int HueLight::MiredToKelvin(unsigned int mired) const
  147 +{
  148 + return int(0.5f + (1000000 / mired));
  149 +}
116 150  
117   - nlohmann::json reply = SendPutRequest(request, "/state");
  151 +bool HueLight::alert()
  152 +{
  153 + nlohmann::json request;
  154 + request["alert"] = "select";
118 155  
119   - if (reply[0]["success"]["/lights/" + std::to_string(id) + "/state/alert"] ==
120   - "select") {
121   - return true;
122   - }
  156 + nlohmann::json reply = SendPutRequest(request, "/state");
123 157  
124   - return false;
  158 + return utils::validateReplyForLight(request, reply, id);
125 159 }
126 160  
127   -HueLight::HueLight(int id, const HueCommandAPI &commands)
128   - : HueLight(id, commands, nullptr, nullptr, nullptr) {}
  161 +HueLight::HueLight(int id, const HueCommandAPI& commands) : HueLight(id, commands, nullptr, nullptr, nullptr) {}
129 162  
130   -HueLight::HueLight(
131   - int id, const HueCommandAPI &commands,
132   - std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
  163 +HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
133 164 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
134 165 std::shared_ptr<const ColorHueStrategy> colorHueStrategy)
135   - : id(id), brightnessStrategy(std::move(brightnessStrategy)),
  166 + : id(id),
  167 + brightnessStrategy(std::move(brightnessStrategy)),
136 168 colorTemperatureStrategy(std::move(colorTempStrategy)),
137   - colorHueStrategy(std::move(colorHueStrategy)), commands(commands)
138   -
139   -{
140   - refreshState();
141   -}
142   -
143   -bool HueLight::OnNoRefresh(uint8_t transition) {
144   - nlohmann::json request({});
145   - if (transition != 4) {
146   - request["transitiontime"] = transition;
147   - }
148   - if (state["state"]["on"] != true) {
149   - request["on"] = true;
150   - }
151   -
152   - if (!request.count("on")) {
153   - // Nothing needs to be changed
154   - return true;
155   - }
156   -
157   - nlohmann::json reply = SendPutRequest(request, "/state");
158   -
159   - // Check whether request was successful
160   - std::string path = "/lights/" + std::to_string(id) + "/state/";
161   - bool success = true;
162   - int i = 0;
163   - if (success && request.count("transitiontime")) {
164   - // Check if success was sent and the value was changed
165   - success = reply.size() > i && reply[i].count("success") &&
166   - reply[i]["success"][path + "transitiontime"] ==
167   - request["transitiontime"];
168   - ++i;
169   - }
170   - if (success && request.count("on")) {
171   - // Check if success was sent and the value was changed
172   - success = reply.size() > i && reply[i].count("success") &&
173   - reply[i]["success"][path + "on"] == request["on"];
174   - }
175   - return success;
176   -}
177   -
178   -bool HueLight::OffNoRefresh(uint8_t transition) {
179   - nlohmann::json request({});
180   - if (transition != 4) {
181   - request["transitiontime"] = transition;
182   - }
183   - if (state["state"]["on"] != false) {
184   - request["on"] = false;
185   - }
186   -
187   - if (!request.count("on")) {
188   - // Nothing needs to be changed
189   - return true;
190   - }
191   -
192   - nlohmann::json reply = SendPutRequest(request, "/state");
193   -
194   - // Check whether request was successful
195   - std::string path = "/lights/" + std::to_string(id) + "/state/";
196   - bool success = true;
197   - int i = 0;
198   - if (success && request.count("transitiontime")) {
199   - // Check if success was sent and the value was changed
200   - success = reply.size() > i && reply[i].count("success") &&
201   - reply[i]["success"][path + "transitiontime"] ==
202   - request["transitiontime"];
203   - ++i;
204   - }
205   - if (success && request.count("on")) {
206   - // Check if success was sent and the value was changed
207   - success = reply.size() > i && reply[i].count("success") &&
208   - reply[i]["success"][path + "on"] == request["on"];
209   - }
210   - return success;
211   -}
212   -
213   -nlohmann::json HueLight::SendPutRequest(const nlohmann::json &request,
214   - const std::string &subPath) {
215   - return commands.PUTRequest("/lights/" + std::to_string(id) + subPath,
216   - request);
217   -}
218   -
219   -void HueLight::refreshState() {
220   - // std::chrono::steady_clock::time_point start =
221   - // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of
222   - // lamp with id: " << id << ", ip: " << ip << "\n";
223   - nlohmann::json answer =
224   - commands.GETRequest("/lights/" + std::to_string(id), {});
225   - if (answer.is_object() && answer.count("state")) {
226   - state = answer;
227   - } else {
228   - std::cout << "Answer in HueLight::refreshState of "
229   - "http_handler->GETJson(...) is not expected!\nAnswer:\n\t"
230   - << answer.dump() << std::endl;
231   - }
232   - // std::cout << "\tRefresh state took: " <<
233   - // std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()
234   - // - start).count() << "ms" << std::endl;
  169 + colorHueStrategy(std::move(colorHueStrategy)),
  170 + commands(commands)
  171 +
  172 +{
  173 + refreshState();
  174 +}
  175 +
  176 +bool HueLight::OnNoRefresh(uint8_t transition)
  177 +{
  178 + nlohmann::json request = nlohmann::json::object();
  179 + if (transition != 4)
  180 + {
  181 + request["transitiontime"] = transition;
  182 + }
  183 + if (state["state"]["on"] != true)
  184 + {
  185 + request["on"] = true;
  186 + }
  187 +
  188 + if (!request.count("on"))
  189 + {
  190 + // Nothing needs to be changed
  191 + return true;
  192 + }
  193 +
  194 + nlohmann::json reply = SendPutRequest(request, "/state");
  195 +
  196 + // Check whether request was successful
  197 + return utils::validateReplyForLight(request, reply, id);
  198 +}
  199 +
  200 +bool HueLight::OffNoRefresh(uint8_t transition)
  201 +{
  202 + nlohmann::json request = nlohmann::json::object();
  203 + if (transition != 4)
  204 + {
  205 + request["transitiontime"] = transition;
  206 + }
  207 + if (state["state"]["on"] != false)
  208 + {
  209 + request["on"] = false;
  210 + }
  211 +
  212 + if (!request.count("on"))
  213 + {
  214 + // Nothing needs to be changed
  215 + return true;
  216 + }
  217 +
  218 + nlohmann::json reply = SendPutRequest(request, "/state");
  219 +
  220 + // Check whether request was successful
  221 + return utils::validateReplyForLight(request, reply, id);
  222 +}
  223 +
  224 +nlohmann::json HueLight::SendPutRequest(const nlohmann::json& request, const std::string& subPath)
  225 +{
  226 + return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request);
  227 +}
  228 +
  229 +void HueLight::refreshState()
  230 +{
  231 + // std::chrono::steady_clock::time_point start =
  232 + // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of
  233 + // lamp with id: " << id << ", ip: " << ip << "\n";
  234 + nlohmann::json answer = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object());
  235 + if (answer.is_object() && answer.count("state"))
  236 + {
  237 + state = answer;
  238 + }
  239 + else
  240 + {
  241 + std::cout << "Answer in HueLight::refreshState of "
  242 + "http_handler->GETJson(...) is not expected!\nAnswer:\n\t"
  243 + << answer.dump() << std::endl;
  244 + }
  245 + // std::cout << "\tRefresh state took: " <<
  246 + // std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()
  247 + // - start).count() << "ms" << std::endl;
235 248 }
... ...
hueplusplus/LinHttpHandler.cpp
... ... @@ -19,211 +19,211 @@
19 19  
20 20 #include "include/LinHttpHandler.h"
21 21  
22   -#include <arpa/inet.h>
23 22 #include <chrono>
24 23 #include <cstring>
25 24 #include <iostream>
26 25 #include <memory>
27   -#include <netdb.h> // struct hostent, gethostbyname
28   -#include <netinet/in.h> // struct sockaddr_in, struct sockaddr
29 26 #include <stdexcept>
30   -#include <stdio.h> // printf, sprintf
31   -#include <stdlib.h> // exit
32   -#include <string.h> // functions for C style null-terminated strings
33   -#include <sys/socket.h> // socket, connect
34 27 #include <system_error>
  28 +
  29 +#include <arpa/inet.h>
  30 +#include <netdb.h> // struct hostent, gethostbyname
  31 +#include <netinet/in.h> // struct sockaddr_in, struct sockaddr
  32 +#include <stdio.h> // printf, sprintf
  33 +#include <stdlib.h> // exit
  34 +#include <string.h> // functions for C style null-terminated strings
  35 +#include <sys/socket.h> // socket, connect
35 36 #include <unistd.h> // read, write, close
36 37  
37   -class SocketCloser {
  38 +class SocketCloser
  39 +{
38 40 public:
39   - explicit SocketCloser(int sockFd) : s(sockFd) {}
40   - ~SocketCloser() { close(s); }
  41 + explicit SocketCloser(int sockFd) : s(sockFd) {}
  42 + ~SocketCloser() { close(s); }
41 43  
42 44 private:
43   - int s;
  45 + int s;
44 46 };
45 47  
46   -std::string LinHttpHandler::send(const std::string &msg, const std::string &adr,
47   - int port) const {
48   - // create socket
49   - int socketFD = socket(AF_INET, SOCK_STREAM, 0);
50   -
51   - SocketCloser closeMySocket(socketFD);
52   - if (socketFD < 0) {
53   - int errCode = errno;
54   - std::cerr << "LinHttpHandler: Failed to open socket: "
55   - << std::strerror(errCode) << "\n";
56   - throw(std::system_error(errCode, std::generic_category(),
57   - "LinHttpHandler: Failed to open socket"));
58   - }
59   -
60   - // lookup ip address
61   - hostent *server;
62   - server = gethostbyname(adr.c_str());
63   - if (server == NULL) {
64   - int errCode = errno;
65   - std::cerr << "LinHttpHandler: Failed to find host with address " << adr
66   - << ": " << std::strerror(errCode) << "\n";
67   - throw(std::system_error(errCode, std::generic_category(),
68   - "LinHttpHandler: gethostbyname"));
69   - }
70   -
71   - // fill in the structure
72   - sockaddr_in server_addr;
73   - memset(&server_addr, 0, sizeof(server_addr));
74   - server_addr.sin_family = AF_INET;
75   - server_addr.sin_port = htons(port);
76   - memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length);
77   -
78   - // connect the socket
79   - if (connect(socketFD, (struct sockaddr *)&server_addr, sizeof(server_addr)) <
80   - 0) {
81   - int errCode = errno;
82   - std::cerr << "LinHttpHandler: Failed to connect socket: "
83   - << std::strerror(errCode) << "\n";
84   - throw(std::system_error(errCode, std::generic_category(),
85   - "LinHttpHandler: Failed to connect socket"));
86   - }
87   -
88   - // send the request
89   - size_t total = msg.length();
90   - ssize_t sent = 0;
91   - do {
92   - ssize_t bytes = write(socketFD, msg.c_str() + sent, total - sent);
93   - if (bytes < 0) {
94   - int errCode = errno;
95   - std::cerr << "LinHttpHandler: Failed to write message to socket: "
96   - << std::strerror(errCode) << "\n";
97   - throw(std::system_error(
98   - errCode, std::generic_category(),
99   - "LinHttpHandler: Failed to write message to socket"));
100   - }
101   - if (bytes == 0) {
102   - break;
103   - }
104   - if (bytes) {
105   - sent += bytes;
106   - }
107   - } while (sent < total);
108   -
109   - // receive the response
110   - std::string response;
111   - total = sizeof(response) - 1;
112   - int received = 0;
113   - char buffer[128] = {};
114   - do {
115   - ssize_t bytes = read(socketFD, buffer, 127);
116   - if (bytes < 0) {
117   - int errCode = errno;
118   - std::cerr << "LinHttpHandler: Failed to read response from socket: "
119   - << std::strerror(errCode) << std::endl;
120   - throw(std::system_error(
121   - errCode, std::generic_category(),
122   - "LinHttpHandler: Failed to read response from socket"));
  48 +std::string LinHttpHandler::send(const std::string& msg, const std::string& adr, int port) const
  49 +{
  50 + // create socket
  51 + int socketFD = socket(AF_INET, SOCK_STREAM, 0);
  52 +
  53 + SocketCloser closeMySocket(socketFD);
  54 + if (socketFD < 0)
  55 + {
  56 + int errCode = errno;
  57 + std::cerr << "LinHttpHandler: Failed to open socket: " << std::strerror(errCode) << "\n";
  58 + throw(std::system_error(errCode, std::generic_category(), "LinHttpHandler: Failed to open socket"));
123 59 }
124   - if (bytes == 0) {
125   - break;
  60 +
  61 + // lookup ip address
  62 + hostent* server;
  63 + server = gethostbyname(adr.c_str());
  64 + if (server == NULL)
  65 + {
  66 + int errCode = errno;
  67 + std::cerr << "LinHttpHandler: Failed to find host with address " << adr << ": " << std::strerror(errCode)
  68 + << "\n";
  69 + throw(std::system_error(errCode, std::generic_category(), "LinHttpHandler: gethostbyname"));
126 70 }
127   - if (bytes) {
128   - received += bytes;
129   - response.append(buffer, bytes);
  71 +
  72 + // fill in the structure
  73 + sockaddr_in server_addr;
  74 + memset(&server_addr, 0, sizeof(server_addr));
  75 + server_addr.sin_family = AF_INET;
  76 + server_addr.sin_port = htons(port);
  77 + memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length);
  78 +
  79 + // connect the socket
  80 + if (connect(socketFD, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
  81 + {
  82 + int errCode = errno;
  83 + std::cerr << "LinHttpHandler: Failed to connect socket: " << std::strerror(errCode) << "\n";
  84 + throw(std::system_error(errCode, std::generic_category(), "LinHttpHandler: Failed to connect socket"));
130 85 }
131   - } while (true);
132 86  
133   - if (received == total) {
134   - std::cerr
135   - << "LinHttpHandler: Failed to store complete response from socket\n";
136   - throw(std::runtime_error(
137   - "LinHttpHandler: Failed to store complete response from socket"));
138   - }
  87 + // send the request
  88 + size_t total = msg.length();
  89 + ssize_t sent = 0;
  90 + do
  91 + {
  92 + ssize_t bytes = write(socketFD, msg.c_str() + sent, total - sent);
  93 + if (bytes < 0)
  94 + {
  95 + int errCode = errno;
  96 + std::cerr << "LinHttpHandler: Failed to write message to socket: " << std::strerror(errCode) << "\n";
  97 + throw(std::system_error(
  98 + errCode, std::generic_category(), "LinHttpHandler: Failed to write message to socket"));
  99 + }
  100 + if (bytes == 0)
  101 + {
  102 + break;
  103 + }
  104 + if (bytes)
  105 + {
  106 + sent += bytes;
  107 + }
  108 + } while (sent < total);
  109 +
  110 + // receive the response
  111 + std::string response;
  112 + total = sizeof(response) - 1;
  113 + int received = 0;
  114 + char buffer[128] = {};
  115 + do
  116 + {
  117 + ssize_t bytes = read(socketFD, buffer, 127);
  118 + if (bytes < 0)
  119 + {
  120 + int errCode = errno;
  121 + std::cerr << "LinHttpHandler: Failed to read response from socket: " << std::strerror(errCode) << std::endl;
  122 + throw(std::system_error(
  123 + errCode, std::generic_category(), "LinHttpHandler: Failed to read response from socket"));
  124 + }
  125 + if (bytes == 0)
  126 + {
  127 + break;
  128 + }
  129 + if (bytes)
  130 + {
  131 + received += bytes;
  132 + response.append(buffer, bytes);
  133 + }
  134 + } while (true);
  135 +
  136 + if (received == total)
  137 + {
  138 + std::cerr << "LinHttpHandler: Failed to store complete response from socket\n";
  139 + throw(std::runtime_error("LinHttpHandler: Failed to store complete response from socket"));
  140 + }
139 141  
140   - return response;
  142 + return response;
141 143 }
142 144  
143   -std::vector<std::string> LinHttpHandler::sendMulticast(const std::string &msg,
144   - const std::string &adr,
145   - int port,
146   - int timeout) const {
147   - hostent *server; // host information
148   - sockaddr_in server_addr; // server address
149   -
150   - // fill in the server's address and data
151   - memset((char *)&server_addr, 0, sizeof(server_addr));
152   - server_addr.sin_family = AF_INET;
153   - server_addr.sin_port = htons(port);
154   -
155   - // look up the address of the server given its name
156   - server = gethostbyname(adr.c_str());
157   - if (!server) {
158   - int errCode = errno;
159   - std::cerr << "LinHttpHandler: sendMulticast: Failed to obtain address of "
160   - << msg << ": " << std::strerror(errCode) << "\n";
161   - throw(std::system_error(
162   - errCode, std::generic_category(),
163   - "LinHttpHandler: sendMulticast: Failed to obtain address of host"));
164   - }
165   -
166   - // put the host's address into the server address structure
167   - memcpy((void *)&server_addr.sin_addr, server->h_addr_list[0],
168   - server->h_length);
169   -
170   - // create the socket
171   - int socketFD = socket(AF_INET, SOCK_DGRAM, 0);
172   - SocketCloser closeMySendSocket(socketFD);
173   - if (socketFD < 0) {
174   - int errCode = errno;
175   - std::cerr << "LinHttpHandler: sendMulticast: Failed to open socket: "
176   - << std::strerror(errCode) << "\n";
177   - throw(std::system_error(
178   - errCode, std::generic_category(),
179   - "LinHttpHandler: sendMulticast: Failed to open socket"));
180   - }
181   -
182   - // send a message to the server
183   - if (sendto(socketFD, msg.c_str(), strlen(msg.c_str()), 0,
184   - (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
185   - int errCode = errno;
186   - std::cerr << "LinHttpHandler: sendMulticast: Failed to send message: "
187   - << std::strerror(errCode) << "\n";
188   - throw(std::system_error(
189   - errCode, std::generic_category(),
190   - "LinHttpHandler: sendMulticast: Failed to send message"));
191   - }
192   -
193   - std::string response;
194   - char buffer[2048] = {}; // receive buffer
195   -
196   - std::chrono::steady_clock::time_point start =
197   - std::chrono::steady_clock::now();
198   - while (std::chrono::steady_clock::now() - start <
199   - std::chrono::seconds(timeout)) {
200   - ssize_t bytesReceived = recv(socketFD, &buffer, 2048, MSG_DONTWAIT);
201   - if (bytesReceived < 0) {
202   - int errCode = errno;
203   - if (errCode != EAGAIN && errCode != EWOULDBLOCK) {
204   - std::cerr << "LinHttpHandler: sendMulticast: Failed to read response "
205   - "from socket: "
  145 +std::vector<std::string> LinHttpHandler::sendMulticast(
  146 + const std::string& msg, const std::string& adr, int port, int timeout) const
  147 +{
  148 + hostent* server; // host information
  149 + sockaddr_in server_addr; // server address
  150 +
  151 + // fill in the server's address and data
  152 + memset((char*)&server_addr, 0, sizeof(server_addr));
  153 + server_addr.sin_family = AF_INET;
  154 + server_addr.sin_port = htons(port);
  155 +
  156 + // look up the address of the server given its name
  157 + server = gethostbyname(adr.c_str());
  158 + if (!server)
  159 + {
  160 + int errCode = errno;
  161 + std::cerr << "LinHttpHandler: sendMulticast: Failed to obtain address of " << msg << ": "
206 162 << std::strerror(errCode) << "\n";
207   - throw(std::system_error(errCode, std::generic_category(),
208   - "LinHttpHandler: sendMulticast: Failed to read "
209   - "response from socket"));
210   - }
211   - continue;
  163 + throw(std::system_error(
  164 + errCode, std::generic_category(), "LinHttpHandler: sendMulticast: Failed to obtain address of host"));
  165 + }
  166 +
  167 + // put the host's address into the server address structure
  168 + memcpy((void*)&server_addr.sin_addr, server->h_addr_list[0], server->h_length);
  169 +
  170 + // create the socket
  171 + int socketFD = socket(AF_INET, SOCK_DGRAM, 0);
  172 + SocketCloser closeMySendSocket(socketFD);
  173 + if (socketFD < 0)
  174 + {
  175 + int errCode = errno;
  176 + std::cerr << "LinHttpHandler: sendMulticast: Failed to open socket: " << std::strerror(errCode) << "\n";
  177 + throw(std::system_error(
  178 + errCode, std::generic_category(), "LinHttpHandler: sendMulticast: Failed to open socket"));
212 179 }
213   - if (bytesReceived) {
214   - response.append(buffer, bytesReceived);
  180 +
  181 + // send a message to the server
  182 + if (sendto(socketFD, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
  183 + {
  184 + int errCode = errno;
  185 + std::cerr << "LinHttpHandler: sendMulticast: Failed to send message: " << std::strerror(errCode) << "\n";
  186 + throw(std::system_error(
  187 + errCode, std::generic_category(), "LinHttpHandler: sendMulticast: Failed to send message"));
  188 + }
  189 +
  190 + std::string response;
  191 + char buffer[2048] = {}; // receive buffer
  192 +
  193 + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
  194 + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(timeout))
  195 + {
  196 + ssize_t bytesReceived = recv(socketFD, &buffer, 2048, MSG_DONTWAIT);
  197 + if (bytesReceived < 0)
  198 + {
  199 + int errCode = errno;
  200 + if (errCode != EAGAIN && errCode != EWOULDBLOCK)
  201 + {
  202 + std::cerr << "LinHttpHandler: sendMulticast: Failed to read response "
  203 + "from socket: "
  204 + << std::strerror(errCode) << "\n";
  205 + throw(std::system_error(errCode, std::generic_category(),
  206 + "LinHttpHandler: sendMulticast: Failed to read "
  207 + "response from socket"));
  208 + }
  209 + continue;
  210 + }
  211 + if (bytesReceived)
  212 + {
  213 + response.append(buffer, bytesReceived);
  214 + }
  215 + }
  216 +
  217 + // construct return vector
  218 + std::vector<std::string> returnString;
  219 + size_t pos = response.find("\r\n\r\n");
  220 + size_t prevpos = 0;
  221 + while (pos != std::string::npos)
  222 + {
  223 + returnString.push_back(response.substr(prevpos, pos - prevpos));
  224 + pos += 4;
  225 + prevpos = pos;
  226 + pos = response.find("\r\n\r\n", pos);
215 227 }
216   - }
217   -
218   - // construct return vector
219   - std::vector<std::string> returnString;
220   - size_t pos = response.find("\r\n\r\n");
221   - size_t prevpos = 0;
222   - while (pos != std::string::npos) {
223   - returnString.push_back(response.substr(prevpos, pos - prevpos));
224   - pos += 4;
225   - prevpos = pos;
226   - pos = response.find("\r\n\r\n", pos);
227   - }
228   - return returnString;
  228 + return returnString;
229 229 }
... ...
hueplusplus/SimpleBrightnessStrategy.cpp
1 1 /**
2   - \file SimpleBrightnessStrategy.cpp
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file SimpleBrightnessStrategy.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #include "include/SimpleBrightnessStrategy.h"
... ... @@ -23,70 +23,62 @@
23 23 #include <iostream>
24 24 #include <thread>
25 25  
26   -bool SimpleBrightnessStrategy::setBrightness(unsigned int bri,
27   - uint8_t transition,
28   - HueLight &light) const {
29   - light.refreshState();
30   - if (bri == 0) {
31   - if (light.state["state"]["on"] == true) {
32   - return light.OffNoRefresh(transition);
33   - } else {
34   - return true;
35   - }
36   - } else {
37   - nlohmann::json request({});
38   - if (transition != 4) {
39   - request["transitiontime"] = transition;
40   - }
41   - if (light.state["state"]["on"] != true) {
42   - request["on"] = true;
43   - }
44   - if (light.state["state"]["bri"] != bri) {
45   - if (bri > 254) {
46   - bri = 254;
47   - }
48   - request["bri"] = bri;
49   - }
  26 +#include "include/Utils.h"
50 27  
51   - if (!request.count("on") && !request.count("bri")) {
52   - // Nothing needs to be changed
53   - return true;
  28 +bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const
  29 +{
  30 + light.refreshState();
  31 + if (bri == 0)
  32 + {
  33 + if (light.state["state"]["on"] == true)
  34 + {
  35 + return light.OffNoRefresh(transition);
  36 + }
  37 + else
  38 + {
  39 + return true;
  40 + }
54 41 }
  42 + else
  43 + {
  44 + nlohmann::json request = nlohmann::json::object();
  45 + if (transition != 4)
  46 + {
  47 + request["transitiontime"] = transition;
  48 + }
  49 + if (light.state["state"]["on"] != true)
  50 + {
  51 + request["on"] = true;
  52 + }
  53 + if (light.state["state"]["bri"] != bri)
  54 + {
  55 + if (bri > 254)
  56 + {
  57 + bri = 254;
  58 + }
  59 + request["bri"] = bri;
  60 + }
55 61  
56   - nlohmann::json reply = light.SendPutRequest(request, "/state");
  62 + if (!request.count("on") && !request.count("bri"))
  63 + {
  64 + // Nothing needs to be changed
  65 + return true;
  66 + }
57 67  
58   - // Check whether request was successful
59   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
60   - bool success = true;
61   - int i = 0;
62   - if (success && request.count("transitiontime")) {
63   - // Check if success was sent and the value was changed
64   - success = reply[i].size() > i && reply[i].count("success") &&
65   - reply[i]["success"][path + "transitiontime"] ==
66   - request["transitiontime"];
67   - ++i;
68   - }
69   - if (success && request.count("on")) {
70   - // Check if success was sent and the value was changed
71   - success = reply[i].size() > i && reply[i].count("success") &&
72   - reply[i]["success"][path + "on"] == request["on"];
73   - ++i;
74   - }
75   - if (success && request.count("bri")) {
76   - // Check if success was sent and the value was changed
77   - success = reply[i].size() > i && reply[i].count("success") &&
78   - reply[i]["success"][path + "bri"] == request["bri"];
  68 + nlohmann::json reply = light.SendPutRequest(request, "/state");
  69 +
  70 + // Check whether request was successful
  71 + return utils::validateReplyForLight(request, reply, light.id);
79 72 }
80   - return success;
81   - }
82 73 }
83 74  
84   -unsigned int SimpleBrightnessStrategy::getBrightness(HueLight &light) const {
85   - light.refreshState();
86   - return light.state["state"]["bri"];
  75 +unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const
  76 +{
  77 + light.refreshState();
  78 + return light.state["state"]["bri"];
87 79 }
88 80  
89   -unsigned int
90   -SimpleBrightnessStrategy::getBrightness(const HueLight &light) const {
91   - return light.state["state"]["bri"];
  81 +unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const
  82 +{
  83 + return light.state["state"]["bri"];
92 84 }
... ...
hueplusplus/SimpleColorHueStrategy.cpp
1 1 /**
2   - \file SimpleColorHueStrategy.cpp
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
6   -
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  2 + \file SimpleColorHueStrategy.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #include "include/SimpleColorHueStrategy.h"
21   -#include "include/HueConfig.h"
22 21  
23 22 #include <cmath>
24 23 #include <iostream>
25 24 #include <thread>
26 25  
27   -bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition,
28   - HueLight &light) const {
29   - light.refreshState();
30   - nlohmann::json request({});
31   - if (transition != 4) {
32   - request["transitiontime"] = transition;
33   - }
34   - if (light.state["state"]["on"] != true) {
35   - request["on"] = true;
36   - }
37   - if (light.state["state"]["hue"] != hue ||
38   - light.state["state"]["colormode"] != "hs") {
39   - hue = hue % 65535;
40   - request["hue"] = hue;
41   - }
42   -
43   - if (!request.count("on") && !request.count("hue")) {
44   - // Nothing needs to be changed
45   - return true;
46   - }
47   -
48   - nlohmann::json reply = light.SendPutRequest(request, "/state");
49   -
50   - // Check whether request was successful
51   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
52   - bool success = true;
53   - int i = 0;
54   - if (success && request.count("transitiontime")) {
55   - // Check if success was sent and the value was changed
56   - success = reply.size() > i && reply[i].count("success") &&
57   - reply[i]["success"][path + "transitiontime"] ==
58   - request["transitiontime"];
59   - ++i;
60   - }
61   - if (success && request.count("on")) {
62   - // Check if success was sent and the value was changed
63   - success = reply.size() > i && reply[i].count("success") &&
64   - reply[i]["success"][path + "on"] == request["on"];
65   - ++i;
66   - }
67   - if (success && request.count("hue")) {
68   - // Check if success was sent and the value was changed
69   - success = reply[i].size() > i && reply[i].count("success") &&
70   - reply[i]["success"][path + "hue"] == request["hue"];
71   - }
72   - return success;
73   -}
  26 +#include "include/HueConfig.h"
  27 +#include "include/Utils.h"
74 28  
75   -bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition,
76   - HueLight &light) const {
77   - light.refreshState();
78   - nlohmann::json request({});
79   - if (transition != 4) {
80   - request["transitiontime"] = transition;
81   - }
82   - if (light.state["state"]["on"] != true) {
83   - request["on"] = true;
84   - }
85   - if (light.state["state"]["sat"] != sat) {
86   - if (sat > 254) {
87   - sat = 254;
  29 +bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const
  30 +{
  31 + light.refreshState();
  32 + nlohmann::json request = nlohmann::json::object();
  33 + if (transition != 4)
  34 + {
  35 + request["transitiontime"] = transition;
  36 + }
  37 + if (light.state["state"]["on"] != true)
  38 + {
  39 + request["on"] = true;
  40 + }
  41 + if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs")
  42 + {
  43 + hue = hue % 65535;
  44 + request["hue"] = hue;
88 45 }
89   - request["sat"] = sat;
90   - }
91   -
92   - if (!request.count("on") && !request.count("sat")) {
93   - // Nothing needs to be changed
94   - return true;
95   - }
96   -
97   - nlohmann::json reply = light.SendPutRequest(request, "/state");
98   -
99   - // Check whether request was successful
100   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
101   - bool success = true;
102   - int i = 0;
103   - if (success && request.count("transitiontime")) {
104   - // Check if success was sent and the value was changed
105   - success = reply[i].size() > i && reply[i].count("success") &&
106   - reply[i]["success"][path + "transitiontime"] ==
107   - request["transitiontime"];
108   - ++i;
109   - }
110   - if (success && request.count("on")) {
111   - // Check if success was sent and the value was changed
112   - success = reply[i].size() > i && reply[i].count("success") &&
113   - reply[i]["success"][path + "on"] == request["on"];
114   - ++i;
115   - }
116   - if (success && request.count("sat")) {
117   - // Check if success was sent and the value was changed
118   - success = reply[i].size() > i && reply[i].count("success") &&
119   - reply[i]["success"][path + "sat"] == request["sat"];
120   - }
121   - return success;
122   -}
123 46  
124   -bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat,
125   - uint8_t transition,
126   - HueLight &light) const {
127   - light.refreshState();
128   - nlohmann::json request({});
129   -
130   - if (transition != 4) {
131   - request["transitiontime"] = transition;
132   - }
133   - if (light.state["state"]["on"] != true) {
134   - request["on"] = true;
135   - }
136   - if (light.state["state"]["hue"] != hue ||
137   - light.state["state"]["colormode"] != "hs") {
138   - hue = hue % 65535;
139   - request["hue"] = hue;
140   - }
141   - if (light.state["state"]["sat"] != sat ||
142   - light.state["state"]["colormode"] != "hs") {
143   - if (sat > 254) {
144   - sat = 254;
  47 + if (!request.count("on") && !request.count("hue"))
  48 + {
  49 + // Nothing needs to be changed
  50 + return true;
145 51 }
146   - request["sat"] = sat;
147   - }
148   -
149   - if (!request.count("on") && !request.count("hue") && !request.count("sat")) {
150   - // Nothing needs to be changed
151   - return true;
152   - }
153   -
154   - nlohmann::json reply = light.SendPutRequest(request, "/state");
155   -
156   - // Check whether request was successful
157   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
158   - bool success = true;
159   - int i = 0;
160   - if (success && request.count("transitiontime")) {
161   - // Check if success was sent and the value was changed
162   - success = reply[i].size() > i && reply[i].count("success") &&
163   - reply[i]["success"][path + "transitiontime"] ==
164   - request["transitiontime"];
165   - ++i;
166   - }
167   - if (success && request.count("on")) {
168   - // Check if success was sent and the value was changed
169   - success = reply[i].size() > i && reply[i].count("success") &&
170   - reply[i]["success"][path + "on"] == request["on"];
171   - ++i;
172   - }
173   - if (success && request.count("hue")) {
174   - // Check if success was sent and the value was changed
175   - success = reply[i].size() > i && reply[i].count("success") &&
176   - reply[i]["success"][path + "hue"] == request["hue"];
177   - ++i;
178   - }
179   - if (success && request.count("sat")) {
180   - // Check if success was sent and the value was changed
181   - success = reply[i].size() > i && reply[i].count("success") &&
182   - reply[i]["success"][path + "sat"] == request["sat"];
183   - }
184   - return success;
  52 +
  53 + nlohmann::json reply = light.SendPutRequest(request, "/state");
  54 +
  55 + // Check whether request was successful
  56 + return utils::validateReplyForLight(request, reply, light.id);
185 57 }
186 58  
187   -bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition,
188   - HueLight &light) const {
189   - light.refreshState();
190   - nlohmann::json request({});
191   -
192   - if (transition != 4) {
193   - request["transitiontime"] = transition;
194   - }
195   - if (light.state["state"]["on"] != true) {
196   - request["on"] = true;
197   - }
198   - if (light.state["state"]["xy"][0] != x ||
199   - light.state["state"]["xy"][1] != y ||
200   - light.state["state"]["colormode"] != "xy") {
201   - request["xy"][0] = x;
202   - request["xy"][1] = y;
203   - }
204   -
205   - if (!request.count("on") && !request.count("xy")) {
206   - // Nothing needs to be changed
207   - return true;
208   - }
209   -
210   - nlohmann::json reply = light.SendPutRequest(request, "/state");
211   -
212   - // Check whether request was successful
213   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
214   - bool success = true;
215   - int i = 0;
216   - if (success && request.count("transitiontime")) {
217   - // Check if success was sent and the value was changed
218   - success = reply[i].size() > i && reply[i].count("success") &&
219   - reply[i]["success"][path + "transitiontime"] ==
220   - request["transitiontime"];
221   - ++i;
222   - }
223   - if (success && request.count("on")) {
224   - // Check if success was sent and the value was changed
225   - success = reply[i].size() > i && reply[i].count("success") &&
226   - reply[i]["success"][path + "on"] == request["on"];
227   - ++i;
228   - }
229   - if (success && request.count("xy")) {
230   - // Check if success was sent and the value was changed
231   - success =
232   - reply[i].size() > i && reply[i].count("success") &&
233   - static_cast<int>(
234   - reply[i]["success"][path + "xy"][0].get<float>() * 10000 + 0.5) ==
235   - static_cast<int>(request["xy"][0].get<float>() * 10000 + 0.5);
236   - if (success) {
237   - success =
238   - reply[i].size() > i && reply[i].count("success") &&
239   - static_cast<int>(
240   - reply[i]["success"][path + "xy"][1].get<float>() * 10000 + 0.5) ==
241   - static_cast<int>(request["xy"][1].get<float>() * 10000 + 0.5);
  59 +bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const
  60 +{
  61 + light.refreshState();
  62 + nlohmann::json request = nlohmann::json::object();
  63 + if (transition != 4)
  64 + {
  65 + request["transitiontime"] = transition;
  66 + }
  67 + if (light.state["state"]["on"] != true)
  68 + {
  69 + request["on"] = true;
  70 + }
  71 + if (light.state["state"]["sat"] != sat)
  72 + {
  73 + if (sat > 254)
  74 + {
  75 + sat = 254;
  76 + }
  77 + request["sat"] = sat;
242 78 }
243   - }
244   - return success;
245   -}
246 79  
247   -bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b,
248   - uint8_t transition,
249   - HueLight &light) const {
250   - if ((r == 0) && (g == 0) && (b == 0)) {
251   - return light.OffNoRefresh();
252   - }
253   -
254   - const float red = float(r) / 255;
255   - const float green = float(g) / 255;
256   - const float blue = float(b) / 255;
257   -
258   - // gamma correction
259   - const float redCorrected = (red > 0.04045f)
260   - ? pow((red + 0.055f) / (1.0f + 0.055f), 2.4f)
261   - : (red / 12.92f);
262   - const float greenCorrected =
263   - (green > 0.04045f) ? pow((green + 0.055f) / (1.0f + 0.055f), 2.4f)
264   - : (green / 12.92f);
265   - const float blueCorrected = (blue > 0.04045f)
266   - ? pow((blue + 0.055f) / (1.0f + 0.055f), 2.4f)
267   - : (blue / 12.92f);
268   -
269   - const float X = redCorrected * 0.664511f + greenCorrected * 0.154324f +
270   - blueCorrected * 0.162028f;
271   - const float Y = redCorrected * 0.283881f + greenCorrected * 0.668433f +
272   - blueCorrected * 0.047685f;
273   - const float Z = redCorrected * 0.000088f + greenCorrected * 0.072310f +
274   - blueCorrected * 0.986039f;
275   -
276   - const float x = X / (X + Y + Z);
277   - const float y = Y / (X + Y + Z);
278   -
279   - return light.setColorXY(x, y, transition);
280   -}
  80 + if (!request.count("on") && !request.count("sat"))
  81 + {
  82 + // Nothing needs to be changed
  83 + return true;
  84 + }
  85 +
  86 + nlohmann::json reply = light.SendPutRequest(request, "/state");
281 87  
282   -bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight &light) const {
283   - // colorloop
284   - light.refreshState();
285   - nlohmann::json request({});
286   -
287   - if (light.state["state"]["on"] != true) {
288   - request["on"] = true;
289   - }
290   - std::string effect;
291   - if ((effect = on ? "colorloop" : "none") != light.state["state"]["effect"]) {
292   - request["effect"] = effect;
293   - }
294   - if (!request.count("on") && !request.count("effect")) {
295   - // Nothing needs to be changed
296   - return true;
297   - }
298   -
299   - nlohmann::json reply = light.SendPutRequest(request, "/state");
300   -
301   - // Check whether request was successful
302   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
303   - bool success = true;
304   - int i = 0;
305   - if (success && request.count("on")) {
306   - // Check if success was sent and the value was changed
307   - success = reply[i].size() > i && reply[i].count("success") &&
308   - reply[i]["success"][path + "on"] == request["on"];
309   - ++i;
310   - }
311   - if (success && request.count("effect")) {
312   - // Check if success was sent and the value was changed
313   - success = reply[i].size() > i && reply[i].count("success") &&
314   - reply[i]["success"][path + "effect"] == request["effect"];
315   - }
316   - return success;
  88 + // Check whether request was successful
  89 + return utils::validateReplyForLight(request, reply, light.id);
317 90 }
318 91  
319   -bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat,
320   - HueLight &light) const {
321   - light.refreshState();
322   - std::string cType = light.state["state"]["colormode"];
323   - bool on = light.state["state"]["on"];
324   - if (cType == "hs") {
325   - uint16_t oldHue = light.state["state"]["hue"];
326   - uint8_t oldSat = light.state["state"]["sat"];
327   - if (!light.setColorHueSaturation(hue, sat, 1)) {
328   - return false;
  92 +bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const
  93 +{
  94 + light.refreshState();
  95 + nlohmann::json request = nlohmann::json::object();
  96 +
  97 + if (transition != 4)
  98 + {
  99 + request["transitiontime"] = transition;
329 100 }
330   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
331   - if (!light.alert()) {
332   - return false;
  101 + if (light.state["state"]["on"] != true)
  102 + {
  103 + request["on"] = true;
333 104 }
334   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
335   - if (!on) {
336   - light.setColorHueSaturation(oldHue, oldSat, 1);
337   - return light.OffNoRefresh(1);
338   - } else {
339   - return light.setColorHueSaturation(oldHue, oldSat, 1);
  105 + if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs")
  106 + {
  107 + hue = hue % 65535;
  108 + request["hue"] = hue;
  109 + }
  110 + if (light.state["state"]["sat"] != sat || light.state["state"]["colormode"] != "hs")
  111 + {
  112 + if (sat > 254)
  113 + {
  114 + sat = 254;
  115 + }
  116 + request["sat"] = sat;
  117 + }
  118 +
  119 + if (!request.count("on") && !request.count("hue") && !request.count("sat"))
  120 + {
  121 + // Nothing needs to be changed
  122 + return true;
340 123 }
341   - } else if (cType == "xy") {
342   - float oldX = light.state["state"]["xy"][0];
343   - float oldY = light.state["state"]["xy"][1];
344   - if (!light.setColorHueSaturation(hue, sat, 1)) {
345   - return false;
  124 +
  125 + nlohmann::json reply = light.SendPutRequest(request, "/state");
  126 +
  127 + // Check whether request was successful
  128 + return utils::validateReplyForLight(request, reply, light.id);
  129 +}
  130 +
  131 +bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition, HueLight& light) const
  132 +{
  133 + light.refreshState();
  134 + nlohmann::json request = nlohmann::json::object();
  135 +
  136 + if (transition != 4)
  137 + {
  138 + request["transitiontime"] = transition;
346 139 }
347   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
348   - if (!light.alert()) {
349   - return false;
  140 + if (light.state["state"]["on"] != true)
  141 + {
  142 + request["on"] = true;
350 143 }
351   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
352   - if (!on) {
353   - light.setColorXY(oldX, oldY, 1);
354   - return light.OffNoRefresh(1);
355   - } else {
356   - return light.setColorXY(oldX, oldY, 1);
  144 + if (std::abs(light.state["state"]["xy"][0].get<float>() - x) > 1E-4f
  145 + || std::abs(light.state["state"]["xy"][1].get<float>() - y) > 1E-4f
  146 + || light.state["state"]["colormode"] != "xy")
  147 + {
  148 + request["xy"][0] = x;
  149 + request["xy"][1] = y;
357 150 }
358   - } else {
359   - return false;
360   - }
  151 +
  152 + if (!request.count("on") && !request.count("xy"))
  153 + {
  154 + // Nothing needs to be changed
  155 + return true;
  156 + }
  157 +
  158 + nlohmann::json reply = light.SendPutRequest(request, "/state");
  159 +
  160 + // Check whether request was successful
  161 + return utils::validateReplyForLight(request, reply, light.id);
361 162 }
362 163  
363   -bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight &light) const {
364   - light.refreshState();
365   - std::string cType = light.state["state"]["colormode"];
366   - bool on = light.state["state"]["on"];
367   - if (cType == "hs") {
368   - uint16_t oldHue = light.state["state"]["hue"];
369   - uint8_t oldSat = light.state["state"]["sat"];
370   - if (!light.setColorXY(x, y, 1)) {
371   - return false;
  164 +bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, HueLight& light) const
  165 +{
  166 + if ((r == 0) && (g == 0) && (b == 0))
  167 + {
  168 + return light.OffNoRefresh();
372 169 }
373   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
374   - if (!light.alert()) {
375   - return false;
  170 +
  171 + const float red = float(r) / 255;
  172 + const float green = float(g) / 255;
  173 + const float blue = float(b) / 255;
  174 +
  175 + // gamma correction
  176 + const float redCorrected = (red > 0.04045f) ? pow((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f);
  177 + const float greenCorrected = (green > 0.04045f) ? pow((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f);
  178 + const float blueCorrected = (blue > 0.04045f) ? pow((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
  179 +
  180 + const float X = redCorrected * 0.664511f + greenCorrected * 0.154324f + blueCorrected * 0.162028f;
  181 + const float Y = redCorrected * 0.283881f + greenCorrected * 0.668433f + blueCorrected * 0.047685f;
  182 + const float Z = redCorrected * 0.000088f + greenCorrected * 0.072310f + blueCorrected * 0.986039f;
  183 +
  184 + const float x = X / (X + Y + Z);
  185 + const float y = Y / (X + Y + Z);
  186 +
  187 + return light.setColorXY(x, y, transition);
  188 +}
  189 +
  190 +bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight& light) const
  191 +{
  192 + // colorloop
  193 + light.refreshState();
  194 + nlohmann::json request = nlohmann::json::object();
  195 +
  196 + if (light.state["state"]["on"] != true)
  197 + {
  198 + request["on"] = true;
376 199 }
377   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
378   - if (!on) {
379   - light.setColorHueSaturation(oldHue, oldSat, 1);
380   - return light.OffNoRefresh(1);
381   - } else {
382   - return light.setColorHueSaturation(oldHue, oldSat, 1);
  200 + std::string effect;
  201 + if ((effect = on ? "colorloop" : "none") != light.state["state"]["effect"])
  202 + {
  203 + request["effect"] = effect;
383 204 }
384   - } else if (cType == "xy") {
385   - float oldX = light.state["state"]["xy"][0];
386   - float oldY = light.state["state"]["xy"][1];
387   - if (!light.setColorXY(x, y, 1)) {
388   - return false;
  205 + if (!request.count("on") && !request.count("effect"))
  206 + {
  207 + // Nothing needs to be changed
  208 + return true;
389 209 }
390   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
391   - if (!light.alert()) {
392   - return false;
  210 +
  211 + nlohmann::json reply = light.SendPutRequest(request, "/state");
  212 +
  213 + // Check whether request was successful
  214 + return utils::validateReplyForLight(request, reply, light.id);
  215 +}
  216 +
  217 +bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const
  218 +{
  219 + light.refreshState();
  220 + std::string cType = light.state["state"]["colormode"];
  221 + bool on = light.state["state"]["on"];
  222 + if (cType == "hs")
  223 + {
  224 + uint16_t oldHue = light.state["state"]["hue"];
  225 + uint8_t oldSat = light.state["state"]["sat"];
  226 + if (!light.setColorHueSaturation(hue, sat, 1))
  227 + {
  228 + return false;
  229 + }
  230 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  231 + if (!light.alert())
  232 + {
  233 + return false;
  234 + }
  235 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  236 + if (!on)
  237 + {
  238 + light.setColorHueSaturation(oldHue, oldSat, 1);
  239 + return light.OffNoRefresh(1);
  240 + }
  241 + else
  242 + {
  243 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  244 + }
393 245 }
394   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
395   - if (!on) {
396   - light.setColorXY(oldX, oldY, 1);
397   - return light.OffNoRefresh(1);
398   - } else {
399   - return light.setColorXY(oldX, oldY, 1);
  246 + else if (cType == "xy")
  247 + {
  248 + float oldX = light.state["state"]["xy"][0];
  249 + float oldY = light.state["state"]["xy"][1];
  250 + if (!light.setColorHueSaturation(hue, sat, 1))
  251 + {
  252 + return false;
  253 + }
  254 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  255 + if (!light.alert())
  256 + {
  257 + return false;
  258 + }
  259 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  260 + if (!on)
  261 + {
  262 + light.setColorXY(oldX, oldY, 1);
  263 + return light.OffNoRefresh(1);
  264 + }
  265 + else
  266 + {
  267 + return light.setColorXY(oldX, oldY, 1);
  268 + }
  269 + }
  270 + else
  271 + {
  272 + return false;
400 273 }
401   - } else {
402   - return false;
403   - }
404 274 }
405 275  
406   -bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b,
407   - HueLight &light) const {
408   - light.refreshState();
409   - std::string cType = light.state["state"]["colormode"];
410   - bool on = light.state["state"]["on"];
411   - if (cType == "hs") {
412   - uint16_t oldHue = light.state["state"]["hue"];
413   - uint8_t oldSat = light.state["state"]["sat"];
414   - if (!light.setColorRGB(r, g, b, 1)) {
415   - return false;
  276 +bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const
  277 +{
  278 + light.refreshState();
  279 + std::string cType = light.state["state"]["colormode"];
  280 + bool on = light.state["state"]["on"];
  281 + if (cType == "hs")
  282 + {
  283 + uint16_t oldHue = light.state["state"]["hue"];
  284 + uint8_t oldSat = light.state["state"]["sat"];
  285 + if (!light.setColorXY(x, y, 1))
  286 + {
  287 + return false;
  288 + }
  289 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  290 + if (!light.alert())
  291 + {
  292 + return false;
  293 + }
  294 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  295 + if (!on)
  296 + {
  297 + light.setColorHueSaturation(oldHue, oldSat, 1);
  298 + return light.OffNoRefresh(1);
  299 + }
  300 + else
  301 + {
  302 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  303 + }
416 304 }
417   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
418   - if (!light.alert()) {
419   - return false;
  305 + else if (cType == "xy")
  306 + {
  307 + float oldX = light.state["state"]["xy"][0];
  308 + float oldY = light.state["state"]["xy"][1];
  309 + if (!light.setColorXY(x, y, 1))
  310 + {
  311 + return false;
  312 + }
  313 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  314 + if (!light.alert())
  315 + {
  316 + return false;
  317 + }
  318 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  319 + if (!on)
  320 + {
  321 + light.setColorXY(oldX, oldY, 1);
  322 + return light.OffNoRefresh(1);
  323 + }
  324 + else
  325 + {
  326 + return light.setColorXY(oldX, oldY, 1);
  327 + }
420 328 }
421   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
422   - if (!on) {
423   - light.setColorHueSaturation(oldHue, oldSat, 1);
424   - return light.OffNoRefresh(1);
425   - } else {
426   - return light.setColorHueSaturation(oldHue, oldSat, 1);
  329 + else
  330 + {
  331 + return false;
427 332 }
428   - } else if (cType == "xy") {
429   - float oldX = light.state["state"]["xy"][0];
430   - float oldY = light.state["state"]["xy"][1];
431   - if (!light.setColorRGB(r, g, b, 1)) {
432   - return false;
  333 +}
  334 +
  335 +bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const
  336 +{
  337 + light.refreshState();
  338 + std::string cType = light.state["state"]["colormode"];
  339 + bool on = light.state["state"]["on"];
  340 + if (cType == "hs")
  341 + {
  342 + uint16_t oldHue = light.state["state"]["hue"];
  343 + uint8_t oldSat = light.state["state"]["sat"];
  344 + if (!light.setColorRGB(r, g, b, 1))
  345 + {
  346 + return false;
  347 + }
  348 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  349 + if (!light.alert())
  350 + {
  351 + return false;
  352 + }
  353 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  354 + if (!on)
  355 + {
  356 + light.setColorHueSaturation(oldHue, oldSat, 1);
  357 + return light.OffNoRefresh(1);
  358 + }
  359 + else
  360 + {
  361 + return light.setColorHueSaturation(oldHue, oldSat, 1);
  362 + }
433 363 }
434   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
435   - if (!light.alert()) {
436   - return false;
  364 + else if (cType == "xy")
  365 + {
  366 + float oldX = light.state["state"]["xy"][0];
  367 + float oldY = light.state["state"]["xy"][1];
  368 + if (!light.setColorRGB(r, g, b, 1))
  369 + {
  370 + return false;
  371 + }
  372 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  373 + if (!light.alert())
  374 + {
  375 + return false;
  376 + }
  377 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  378 + if (!on)
  379 + {
  380 + light.setColorXY(oldX, oldY, 1);
  381 + return light.OffNoRefresh(1);
  382 + }
  383 + else
  384 + {
  385 + return light.setColorXY(oldX, oldY, 1);
  386 + }
437 387 }
438   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
439   - if (!on) {
440   - light.setColorXY(oldX, oldY, 1);
441   - return light.OffNoRefresh(1);
442   - } else {
443   - return light.setColorXY(oldX, oldY, 1);
  388 + else
  389 + {
  390 + return false;
444 391 }
445   - } else {
446   - return false;
447   - }
448 392 }
449 393  
450   -std::pair<uint16_t, uint8_t>
451   -SimpleColorHueStrategy::getColorHueSaturation(HueLight &light) const {
452   - light.refreshState();
453   - return std::pair<uint16_t, uint8_t>(
454   - static_cast<uint16_t>(light.state["state"]["hue"]),
455   - static_cast<uint8_t>(light.state["state"]["sat"]));
  394 +std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const
  395 +{
  396 + light.refreshState();
  397 + return std::pair<uint16_t, uint8_t>(
  398 + static_cast<uint16_t>(light.state["state"]["hue"]), static_cast<uint8_t>(light.state["state"]["sat"]));
456 399 }
457 400  
458   -std::pair<uint16_t, uint8_t>
459   -SimpleColorHueStrategy::getColorHueSaturation(const HueLight &light) const {
460   - return std::pair<uint16_t, uint8_t>(
461   - static_cast<uint16_t>(light.state["state"]["hue"]),
462   - static_cast<uint8_t>(light.state["state"]["sat"]));
  401 +std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const
  402 +{
  403 + return std::pair<uint16_t, uint8_t>(
  404 + static_cast<uint16_t>(light.state["state"]["hue"]), static_cast<uint8_t>(light.state["state"]["sat"]));
463 405 }
464 406  
465   -std::pair<float, float>
466   -SimpleColorHueStrategy::getColorXY(HueLight &light) const {
467   - light.refreshState();
468   - return std::pair<float, float>(light.state["state"]["xy"][0],
469   - light.state["state"]["xy"][1]);
  407 +std::pair<float, float> SimpleColorHueStrategy::getColorXY(HueLight& light) const
  408 +{
  409 + light.refreshState();
  410 + return std::pair<float, float>(light.state["state"]["xy"][0], light.state["state"]["xy"][1]);
470 411 }
471 412  
472   -std::pair<float, float>
473   -SimpleColorHueStrategy::getColorXY(const HueLight &light) const {
474   - return std::pair<float, float>(light.state["state"]["xy"][0],
475   - light.state["state"]["xy"][1]);
  413 +std::pair<float, float> SimpleColorHueStrategy::getColorXY(const HueLight& light) const
  414 +{
  415 + return std::pair<float, float>(light.state["state"]["xy"][0], light.state["state"]["xy"][1]);
476 416 }
477 417 /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float
478 418 x0, float y0, float x1, float y1, float x2, float y2)
... ...
hueplusplus/SimpleColorTemperatureStrategy.cpp
1 1 /**
2   - \file SimpleColorTemperatureStrategy.cpp
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file SimpleColorTemperatureStrategy.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #include "include/SimpleColorTemperatureStrategy.h"
21   -#include "include/HueConfig.h"
22 21  
23 22 #include <cmath>
24 23 #include <iostream>
25 24 #include <thread>
26 25  
27   -bool SimpleColorTemperatureStrategy::setColorTemperature(
28   - unsigned int mired, uint8_t transition, HueLight &light) const {
29   - light.refreshState();
30   - nlohmann::json request({});
31   - if (transition != 4) {
32   - request["transitiontime"] = transition;
33   - }
34   - if (light.state["state"]["on"] != true) {
35   - request["on"] = true;
36   - }
37   - if (light.state["state"]["ct"] != mired) {
38   - if (mired > 500) {
39   - mired = 500;
  26 +#include "include/HueConfig.h"
  27 +#include "include/Utils.h"
  28 +
  29 +bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const
  30 +{
  31 + light.refreshState();
  32 + nlohmann::json request = nlohmann::json::object();
  33 + if (transition != 4)
  34 + {
  35 + request["transitiontime"] = transition;
40 36 }
41   - if (mired < 153) {
42   - mired = 153;
  37 + if (light.state["state"]["on"] != true)
  38 + {
  39 + request["on"] = true;
  40 + }
  41 + if (light.state["state"]["ct"] != mired)
  42 + {
  43 + if (mired > 500)
  44 + {
  45 + mired = 500;
  46 + }
  47 + if (mired < 153)
  48 + {
  49 + mired = 153;
  50 + }
  51 + request["ct"] = mired;
43 52 }
44   - request["ct"] = mired;
45   - }
46 53  
47   - if (!request.count("on") && !request.count("ct")) {
48   - // Nothing needs to be changed
49   - return true;
50   - }
  54 + if (!request.count("on") && !request.count("ct"))
  55 + {
  56 + // Nothing needs to be changed
  57 + return true;
  58 + }
51 59  
52   - nlohmann::json reply = light.SendPutRequest(request, "/state");
  60 + nlohmann::json reply = light.SendPutRequest(request, "/state");
53 61  
54   - // Check whether request was successful
55   - std::string path = "/lights/" + std::to_string(light.id) + "/state/";
56   - bool success = true;
57   - int i = 0;
58   - if (success && request.count("transitiontime")) {
59   - // Check if success was sent and the value was changed
60   - success = reply.size() > i && reply[i].count("success") &&
61   - reply[i]["success"][path + "transitiontime"] ==
62   - request["transitiontime"];
63   - ++i;
64   - }
65   - if (success && request.count("on")) {
66   - // Check if success was sent and the value was changed
67   - success = reply.size() > i && reply[i].count("success") &&
68   - reply[i]["success"][path + "on"] == request["on"];
69   - ++i;
70   - }
71   - if (success && request.count("ct")) {
72   - // Check if success was sent and the value was changed
73   - success = reply[i].size() > i && reply[i].count("success") &&
74   - reply[i]["success"][path + "ct"] == request["ct"];
75   - }
76   - return success;
  62 + // Check whether request was successful
  63 + return utils::validateReplyForLight(request, reply, light.id);
77 64 }
78 65  
79   -bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired,
80   - HueLight &light) const {
81   - light.refreshState();
82   - std::string cType = light.state["state"]["colormode"];
83   - bool on = light.state["state"]["on"];
84   - if (cType == "ct") {
85   - uint16_t oldCT = light.state["state"]["ct"];
86   - if (!light.setColorTemperature(mired, 1)) {
87   - return false;
88   - }
89   - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
90   - if (!light.alert()) {
91   - return false;
  66 +bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const
  67 +{
  68 + light.refreshState();
  69 + std::string cType = light.state["state"]["colormode"];
  70 + bool on = light.state["state"]["on"];
  71 + if (cType == "ct")
  72 + {
  73 + uint16_t oldCT = light.state["state"]["ct"];
  74 + if (!light.setColorTemperature(mired, 1))
  75 + {
  76 + return false;
  77 + }
  78 + std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY));
  79 + if (!light.alert())
  80 + {
  81 + return false;
  82 + }
  83 + std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
  84 + if (!on)
  85 + {
  86 + light.setColorTemperature(oldCT, 1);
  87 + return light.OffNoRefresh(1);
  88 + }
  89 + else
  90 + {
  91 + return light.setColorTemperature(oldCT, 1);
  92 + }
92 93 }
93   - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY));
94   - if (!on) {
95   - light.setColorTemperature(oldCT, 1);
96   - return light.OffNoRefresh(1);
97   - } else {
98   - return light.setColorTemperature(oldCT, 1);
  94 + else
  95 + {
  96 + return false;
99 97 }
100   - } else {
101   - return false;
102   - }
103 98 }
104 99  
105   -unsigned int
106   -SimpleColorTemperatureStrategy::getColorTemperature(HueLight &light) const {
107   - light.refreshState();
108   - return light.state["state"]["ct"];
  100 +unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const
  101 +{
  102 + light.refreshState();
  103 + return light.state["state"]["ct"];
109 104 }
110 105  
111   -unsigned int SimpleColorTemperatureStrategy::getColorTemperature(
112   - const HueLight &light) const {
113   - return light.state["state"]["ct"];
  106 +unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const
  107 +{
  108 + return light.state["state"]["ct"];
114 109 }
... ...
hueplusplus/UPnP.cpp
1 1 /**
2   - \file UPnP.cpp
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file UPnP.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #include "include/UPnP.h"
... ... @@ -22,32 +22,33 @@
22 22 #include <algorithm>
23 23 #include <iostream>
24 24  
25   -std::vector<std::pair<std::string, std::string>>
26   -UPnP::getDevices(std::shared_ptr<const IHttpHandler> handler) {
27   - // send UPnP M-Search request
28   - std::vector<std::string> foundDevices = handler->sendMulticast(
29   - "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
30   - "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
31   - "239.255.255.250", 1900, 5);
  25 +std::vector<std::pair<std::string, std::string>> UPnP::getDevices(std::shared_ptr<const IHttpHandler> handler)
  26 +{
  27 + // send UPnP M-Search request
  28 + std::vector<std::string> foundDevices
  29 + = handler->sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
  30 + "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
  31 + "239.255.255.250", 1900, 5);
32 32  
33   - std::vector<std::pair<std::string, std::string>> devices;
  33 + std::vector<std::pair<std::string, std::string>> devices;
34 34  
35   - // filter out devices
36   - for (const std::string &s : foundDevices) {
37   - std::pair<std::string, std::string> device;
38   - int start = s.find("LOCATION:") + 10;
39   - device.first = s.substr(start, s.find("\r\n", start) - start);
40   - start = s.find("SERVER:") + 8;
41   - device.second = s.substr(start, s.find("\r\n", start) - start);
42   - if (std::find_if(devices.begin(), devices.end(),
43   - [&](const std::pair<std::string, std::string> &item) {
44   - return item.first == device.first;
45   - }) == devices.end()) {
46   - devices.push_back(device);
  35 + // filter out devices
  36 + for (const std::string& s : foundDevices)
  37 + {
  38 + std::pair<std::string, std::string> device;
  39 + int start = s.find("LOCATION:") + 10;
  40 + device.first = s.substr(start, s.find("\r\n", start) - start);
  41 + start = s.find("SERVER:") + 8;
  42 + device.second = s.substr(start, s.find("\r\n", start) - start);
  43 + if (std::find_if(devices.begin(), devices.end(),
  44 + [&](const std::pair<std::string, std::string>& item) { return item.first == device.first; })
  45 + == devices.end())
  46 + {
  47 + devices.push_back(device);
47 48  
48   - // std::cout << "Device: \t" << device.first << std::endl;
49   - // std::cout << " \t" << device.second << std::endl;
  49 + // std::cout << "Device: \t" << device.first << std::endl;
  50 + // std::cout << " \t" << device.second << std::endl;
  51 + }
50 52 }
51   - }
52   - return devices;
  53 + return devices;
53 54 }
... ...
hueplusplus/Utils.cpp 0 → 100644
  1 +/**
  2 + \file Utils.cpp
  3 + Copyright Notice\n
  4 + Copyright (C) 2020 Jan Rogall - developer\n
  5 + Copyright (C) 2020 Moritz Wirger - developer\n
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18 +**/
  19 +
  20 +#include "include/Utils.h"
  21 +
  22 +#include <iostream>
  23 +
  24 +namespace utils
  25 +{
  26 + bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId)
  27 + {
  28 + bool success = false;
  29 + std::string path = "/lights/" + std::to_string(lightId) + "/state/";
  30 + for (nlohmann::json::iterator it = reply.begin(); it != reply.end(); ++it)
  31 + {
  32 + success = it.value().count("success");
  33 + if (success)
  34 + {
  35 + // Traverse through first object
  36 + nlohmann::json successObject = it.value()["success"];
  37 + for (nlohmann::json::iterator successIt = successObject.begin(); successIt != successObject.end();
  38 + ++successIt)
  39 + {
  40 + const std::string successPath = successIt.key();
  41 + if (successPath.find(path) == 0)
  42 + {
  43 + const std::string valueKey = successPath.substr(path.size());
  44 + nlohmann::json::iterator requestIt = request.find(valueKey);
  45 + success = requestIt != request.end();
  46 + if (success)
  47 + {
  48 + if (valueKey == "xy")
  49 + {
  50 + success
  51 + = std::abs(requestIt.value()[0].get<float>() - successIt.value()[0].get<float>())
  52 + <= 1E-4f
  53 + && std::abs(requestIt.value()[1].get<float>() - successIt.value()[1].get<float>())
  54 + <= 1E-4f;
  55 + }
  56 + else
  57 + {
  58 + success = requestIt.value() == successIt.value();
  59 + }
  60 + if (!success)
  61 + {
  62 + std::cout << "Value " << requestIt.value() << " does not match reply "
  63 + << successIt.value() << std::endl;
  64 + }
  65 + }
  66 + }
  67 + else
  68 + {
  69 + success = false;
  70 + }
  71 + }
  72 + }
  73 + if (!success) // Fail fast
  74 + {
  75 + break;
  76 + }
  77 + }
  78 + return success;
  79 + }
  80 +} // namespace utils
0 81 \ No newline at end of file
... ...
hueplusplus/WinHttpHandler.cpp
... ... @@ -22,271 +22,272 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 22 #include <chrono>
23 23 #include <iostream>
24 24 #include <memory>
25   -#include <stdio.h>
26 25 #include <system_error>
  26 +
  27 +#include <stdio.h>
27 28 #include <ws2tcpip.h>
28 29  
29 30 #pragma comment(lib, "Ws2_32.lib")
30 31  
31   -namespace {
32   -class AddrInfoFreer {
33   -public:
34   - explicit AddrInfoFreer(addrinfo *p) : p(p) {}
35   - ~AddrInfoFreer() { freeaddrinfo(p); }
36   -
37   -private:
38   - addrinfo *p;
39   -};
40   -class SocketCloser {
41   -public:
42   - explicit SocketCloser(SOCKET s) : s(s) {}
43   - ~SocketCloser() { closesocket(s); }
44   -
45   -private:
46   - SOCKET s;
47   -};
  32 +namespace
  33 +{
  34 + class AddrInfoFreer
  35 + {
  36 + public:
  37 + explicit AddrInfoFreer(addrinfo* p) : p(p) {}
  38 + ~AddrInfoFreer() { freeaddrinfo(p); }
  39 +
  40 + private:
  41 + addrinfo* p;
  42 + };
  43 + class SocketCloser
  44 + {
  45 + public:
  46 + explicit SocketCloser(SOCKET s) : s(s) {}
  47 + ~SocketCloser() { closesocket(s); }
  48 +
  49 + private:
  50 + SOCKET s;
  51 + };
48 52 } // namespace
49 53  
50   -WinHttpHandler::WinHttpHandler() {
51   - // Initialize Winsock
52   - int return_code = WSAStartup(MAKEWORD(2, 2), &wsaData);
53   - if (return_code != 0) {
54   - std::cerr << "WinHttpHandler: Failed to open socket: " << return_code
55   - << std::endl;
56   - throw(std::system_error(return_code, std::system_category(),
57   - "WinHttpHandler: Failed to open socket"));
58   - }
  54 +WinHttpHandler::WinHttpHandler()
  55 +{
  56 + // Initialize Winsock
  57 + int return_code = WSAStartup(MAKEWORD(2, 2), &wsaData);
  58 + if (return_code != 0)
  59 + {
  60 + std::cerr << "WinHttpHandler: Failed to open socket: " << return_code << std::endl;
  61 + throw(std::system_error(return_code, std::system_category(), "WinHttpHandler: Failed to open socket"));
  62 + }
  63 +}
  64 +
  65 +WinHttpHandler::~WinHttpHandler()
  66 +{
  67 + WSACleanup();
  68 +}
  69 +
  70 +std::string WinHttpHandler::send(const std::string& msg, const std::string& adr, int port) const
  71 +{
  72 + struct addrinfo hints = {};
  73 + hints.ai_family = AF_INET;
  74 + hints.ai_socktype = SOCK_STREAM;
  75 + hints.ai_protocol = IPPROTO_TCP;
  76 +
  77 + // Resolve the server address and port
  78 + struct addrinfo* result = nullptr;
  79 + if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) != 0)
  80 + {
  81 + int err = WSAGetLastError();
  82 + std::cerr << "WinHttpHandler: getaddrinfo failed: " << err << std::endl;
  83 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: getaddrinfo failed"));
  84 + }
  85 + SOCKET connect_socket = INVALID_SOCKET;
  86 + {
  87 + AddrInfoFreer freeResult(result);
  88 +
  89 + // Attempt to connect to the first address returned by
  90 + // the call to getaddrinfo
  91 + struct addrinfo* ptr = result;
  92 +
  93 + // Create a SOCKET for connecting to server
  94 + connect_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
  95 +
  96 + if (connect_socket == INVALID_SOCKET)
  97 + {
  98 + int err = WSAGetLastError();
  99 + std::cerr << "WinHttpHandler: Error at socket(): " << err << std::endl;
  100 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: Error at socket()"));
  101 + }
  102 +
  103 + // Connect to server.
  104 + if (connect(connect_socket, ptr->ai_addr, (int)ptr->ai_addrlen) == SOCKET_ERROR)
  105 + {
  106 + closesocket(connect_socket);
  107 + connect_socket = INVALID_SOCKET;
  108 + }
  109 +
  110 + // Should really try the next address returned by getaddrinfo
  111 + // if the connect call failed
  112 + // But for this simple example we just free the resources
  113 + // returned by getaddrinfo and print an error message
  114 + }
  115 +
  116 + if (connect_socket == INVALID_SOCKET)
  117 + {
  118 + std::cerr << "WinHttpHandler: Unable to connect to server!" << std::endl;
  119 + throw(std::runtime_error("WinHttpHandler: Unable to connect to server!"));
  120 + }
  121 + SocketCloser closeSocket(connect_socket);
  122 +
  123 + // Send an initial buffer
  124 + if (::send(connect_socket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR)
  125 + {
  126 + int err = WSAGetLastError();
  127 + std::cerr << "WinHttpHandler: send failed: " << err << std::endl;
  128 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: send failed"));
  129 + }
  130 +
  131 + // shutdown the connection for sending since no more data will be sent
  132 + // the client can still use the ConnectSocket for receiving data
  133 + if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR)
  134 + {
  135 + int err = WSAGetLastError();
  136 + std::cerr << "WinHttpHandler: shutdown failed: " << err << std::endl;
  137 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: shutdown failed"));
  138 + }
  139 +
  140 + const int recvbuflen = 128;
  141 + char recvbuf[recvbuflen];
  142 +
  143 + // Receive data until the server closes the connection
  144 + std::string response;
  145 + int res;
  146 + do
  147 + {
  148 + res = recv(connect_socket, recvbuf, recvbuflen, 0);
  149 + if (res > 0)
  150 + {
  151 + // std::cout << "WinHttpHandler: Bytes received: " << res << std::endl;
  152 + response.append(recvbuf, res);
  153 + }
  154 + else if (res == 0)
  155 + {
  156 + // std::cout << "WinHttpHandler: Connection closed " << std::endl;
  157 + }
  158 + else
  159 + {
  160 + int err = WSAGetLastError();
  161 + std::cerr << "WinHttpHandler: recv failed: " << err << std::endl;
  162 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: recv failed"));
  163 + }
  164 + } while (res > 0);
  165 +
  166 + return response;
59 167 }
60 168  
61   -WinHttpHandler::~WinHttpHandler() { WSACleanup(); }
62   -
63   -std::string WinHttpHandler::send(const std::string &msg, const std::string &adr,
64   - int port) const {
65   - struct addrinfo hints = {};
66   - hints.ai_family = AF_INET;
67   - hints.ai_socktype = SOCK_STREAM;
68   - hints.ai_protocol = IPPROTO_TCP;
69   -
70   - // Resolve the server address and port
71   - struct addrinfo *result = nullptr;
72   - if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) !=
73   - 0) {
74   - int err = WSAGetLastError();
75   - std::cerr << "WinHttpHandler: getaddrinfo failed: " << err << std::endl;
76   - throw(std::system_error(err, std::system_category(),
77   - "WinHttpHandler: getaddrinfo failed"));
78   - }
79   - SOCKET connect_socket = INVALID_SOCKET;
80   - {
  169 +std::vector<std::string> WinHttpHandler::sendMulticast(
  170 + const std::string& msg, const std::string& adr, int port, int timeout) const
  171 +{
  172 + struct addrinfo hints = {};
  173 + hints.ai_family = AF_INET;
  174 + hints.ai_socktype = SOCK_DGRAM;
  175 + hints.ai_protocol = IPPROTO_TCP;
  176 +
  177 + // Resolve the server address and port
  178 + struct addrinfo* result = nullptr;
  179 + if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) != 0)
  180 + {
  181 + int err = WSAGetLastError();
  182 + std::cerr << "WinHttpHandler: sendMulticast: getaddrinfo failed: " << err << std::endl;
  183 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: getaddrinfo failed"));
  184 + }
81 185 AddrInfoFreer freeResult(result);
82 186  
83 187 // Attempt to connect to the first address returned by
84 188 // the call to getaddrinfo
85   - struct addrinfo *ptr = result;
  189 + struct addrinfo* ptr = result;
86 190  
87 191 // Create a SOCKET for connecting to server
88   - connect_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
  192 + SOCKET connect_socket = socket(ptr->ai_family, ptr->ai_socktype, 0);
  193 + if (connect_socket == INVALID_SOCKET)
  194 + {
  195 + int err = WSAGetLastError();
  196 + std::cerr << "WinHttpHandler: sendMulticast: Error at socket(): " << err << std::endl;
  197 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: Error at socket()"));
  198 + }
  199 + SocketCloser closeSocket(connect_socket);
  200 +
  201 + // Fill out source socket's address information.
  202 + SOCKADDR_IN source_sin;
  203 + source_sin.sin_family = AF_INET;
  204 + source_sin.sin_port = htons(0);
  205 + source_sin.sin_addr.s_addr = htonl(INADDR_ANY);
  206 +
  207 + // Associate the source socket's address with the socket, Sock.
  208 + if (bind(connect_socket, (struct sockaddr FAR*)&source_sin, sizeof(source_sin)) == SOCKET_ERROR)
  209 + {
  210 + int err = WSAGetLastError();
  211 + std::cerr << "WinHttpHandler: sendMulticast: Binding socket failed: " << err << std::endl;
  212 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: Binding socket failed"));
  213 + }
  214 +
  215 + u_long sock_mode = 1;
  216 + ioctlsocket(connect_socket, FIONBIO, &sock_mode);
  217 +
  218 + BOOL bOptVal = TRUE;
  219 + setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, sizeof(bOptVal));
89 220  
90   - if (connect_socket == INVALID_SOCKET) {
91   - int err = WSAGetLastError();
92   - std::cerr << "WinHttpHandler: Error at socket(): " << err << std::endl;
93   - throw(std::system_error(err, std::system_category(),
94   - "WinHttpHandler: Error at socket()"));
  221 + // Set the Time-to-Live of the multicast.
  222 + int iOptVal = 1; // for same subnet, but might be increased to 16
  223 + if (setsockopt(connect_socket, IPPROTO_IP, IP_MULTICAST_TTL, (char FAR*)&iOptVal, sizeof(int)) == SOCKET_ERROR)
  224 + {
  225 + int err = WSAGetLastError();
  226 + std::cerr << "WinHttpHandler: sendMulticast: setsockopt failed: " << err << std::endl;
  227 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: setsockopt failed"));
95 228 }
96 229  
97   - // Connect to server.
98   - if (connect(connect_socket, ptr->ai_addr, (int)ptr->ai_addrlen) ==
99   - SOCKET_ERROR) {
100   - closesocket(connect_socket);
101   - connect_socket = INVALID_SOCKET;
  230 + // Fill out the desination socket's address information.
  231 + SOCKADDR_IN dest_sin;
  232 + dest_sin.sin_family = AF_INET;
  233 + dest_sin.sin_port = htons(port);
  234 + dest_sin.sin_addr.s_addr = inet_addr((const char*)ptr->ai_addr);
  235 +
  236 + // Send a message to the multicasting address.
  237 + if (sendto(connect_socket, msg.c_str(), msg.size(), 0, (struct sockaddr FAR*)&dest_sin, sizeof(dest_sin))
  238 + == SOCKET_ERROR)
  239 + {
  240 + int err = WSAGetLastError();
  241 + std::cerr << "WinHttpHandler: sendMulticast: sendto failed: " << WSAGetLastError() << std::endl;
  242 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: sendto failed"));
102 243 }
103 244  
104   - // Should really try the next address returned by getaddrinfo
105   - // if the connect call failed
106   - // But for this simple example we just free the resources
107   - // returned by getaddrinfo and print an error message
108   - }
109   -
110   - if (connect_socket == INVALID_SOCKET) {
111   - std::cerr << "WinHttpHandler: Unable to connect to server!" << std::endl;
112   - throw(std::runtime_error("WinHttpHandler: Unable to connect to server!"));
113   - }
114   - SocketCloser closeSocket(connect_socket);
115   -
116   - // Send an initial buffer
117   - if (::send(connect_socket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) {
118   - int err = WSAGetLastError();
119   - std::cerr << "WinHttpHandler: send failed: " << err << std::endl;
120   - throw(std::system_error(err, std::system_category(),
121   - "WinHttpHandler: send failed"));
122   - }
123   -
124   - // shutdown the connection for sending since no more data will be sent
125   - // the client can still use the ConnectSocket for receiving data
126   - if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR) {
127   - int err = WSAGetLastError();
128   - std::cerr << "WinHttpHandler: shutdown failed: " << err << std::endl;
129   - throw(std::system_error(err, std::system_category(),
130   - "WinHttpHandler: shutdown failed"));
131   - }
132   -
133   - const int recvbuflen = 128;
134   - char recvbuf[recvbuflen];
135   -
136   - // Receive data until the server closes the connection
137   - std::string response;
138   - int res;
139   - do {
140   - res = recv(connect_socket, recvbuf, recvbuflen, 0);
141   - if (res > 0) {
142   - // std::cout << "WinHttpHandler: Bytes received: " << res << std::endl;
143   - response.append(recvbuf, res);
144   - } else if (res == 0) {
145   - // std::cout << "WinHttpHandler: Connection closed " << std::endl;
146   - } else {
147   - int err = WSAGetLastError();
148   - std::cerr << "WinHttpHandler: recv failed: " << err << std::endl;
149   - throw(std::system_error(err, std::system_category(),
150   - "WinHttpHandler: recv failed"));
  245 + // shutdown the connection for sending since no more data will be sent
  246 + // the client can still use the ConnectSocket for receiving data
  247 + if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR)
  248 + {
  249 + int err = WSAGetLastError();
  250 + std::cerr << "WinHttpHandler: sendMulticast: shutdown failed: " << err << std::endl;
  251 + throw(std::system_error(err, std::system_category(), "WinHttpHandler: sendMulticast: shutdown failed"));
151 252 }
152   - } while (res > 0);
153 253  
154   - return response;
155   -}
  254 + std::string response;
  255 + const int recvbuflen = 2048;
  256 + char recvbuf[recvbuflen] = {};
  257 + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
  258 + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(timeout))
  259 + {
  260 + int res = recv(connect_socket, recvbuf, recvbuflen, 0);
  261 + if (res > 0)
  262 + {
  263 + // std::cout << "WinHttpHandler: sendMulticast: Bytes received: " << res
  264 + // << std::endl;
  265 + response.append(recvbuf, res);
  266 + }
  267 + else if (res == 0)
  268 + {
  269 + // std::cout << "WinHttpHandler: sendMulticast: Connection closed " <<
  270 + // std::endl;
  271 + }
  272 + else
  273 + {
  274 + // No exception here due to non blocking socket
  275 + // std::cerr << "sendMulticast: recv failed: " << WSAGetLastError() <<
  276 + // std::endl; throw(std::runtime_error("recv failed"));
  277 + }
  278 + }
156 279  
157   -std::vector<std::string> WinHttpHandler::sendMulticast(const std::string &msg,
158   - const std::string &adr,
159   - int port,
160   - int timeout) const {
161   - struct addrinfo hints = {};
162   - hints.ai_family = AF_INET;
163   - hints.ai_socktype = SOCK_DGRAM;
164   - hints.ai_protocol = IPPROTO_TCP;
165   -
166   - // Resolve the server address and port
167   - struct addrinfo *result = nullptr;
168   - if (getaddrinfo(adr.c_str(), std::to_string(port).c_str(), &hints, &result) !=
169   - 0) {
170   - int err = WSAGetLastError();
171   - std::cerr << "WinHttpHandler: sendMulticast: getaddrinfo failed: " << err
172   - << std::endl;
173   - throw(
174   - std::system_error(err, std::system_category(),
175   - "WinHttpHandler: sendMulticast: getaddrinfo failed"));
176   - }
177   - AddrInfoFreer freeResult(result);
178   -
179   - // Attempt to connect to the first address returned by
180   - // the call to getaddrinfo
181   - struct addrinfo *ptr = result;
182   -
183   - // Create a SOCKET for connecting to server
184   - SOCKET connect_socket = socket(ptr->ai_family, ptr->ai_socktype, 0);
185   - if (connect_socket == INVALID_SOCKET) {
186   - int err = WSAGetLastError();
187   - std::cerr << "WinHttpHandler: sendMulticast: Error at socket(): " << err
188   - << std::endl;
189   - throw(
190   - std::system_error(err, std::system_category(),
191   - "WinHttpHandler: sendMulticast: Error at socket()"));
192   - }
193   - SocketCloser closeSocket(connect_socket);
194   -
195   - // Fill out source socket's address information.
196   - SOCKADDR_IN source_sin;
197   - source_sin.sin_family = AF_INET;
198   - source_sin.sin_port = htons(0);
199   - source_sin.sin_addr.s_addr = htonl(INADDR_ANY);
200   -
201   - // Associate the source socket's address with the socket, Sock.
202   - if (bind(connect_socket, (struct sockaddr FAR *)&source_sin,
203   - sizeof(source_sin)) == SOCKET_ERROR) {
204   - int err = WSAGetLastError();
205   - std::cerr << "WinHttpHandler: sendMulticast: Binding socket failed: " << err
206   - << std::endl;
207   - throw(std::system_error(
208   - err, std::system_category(),
209   - "WinHttpHandler: sendMulticast: Binding socket failed"));
210   - }
211   -
212   - u_long sock_mode = 1;
213   - ioctlsocket(connect_socket, FIONBIO, &sock_mode);
214   -
215   - BOOL bOptVal = TRUE;
216   - setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char *)&bOptVal,
217   - sizeof(bOptVal));
218   -
219   - // Set the Time-to-Live of the multicast.
220   - int iOptVal = 1; // for same subnet, but might be increased to 16
221   - if (setsockopt(connect_socket, IPPROTO_IP, IP_MULTICAST_TTL,
222   - (char FAR *)&iOptVal, sizeof(int)) == SOCKET_ERROR) {
223   - int err = WSAGetLastError();
224   - std::cerr << "WinHttpHandler: sendMulticast: setsockopt failed: " << err
225   - << std::endl;
226   - throw(
227   - std::system_error(err, std::system_category(),
228   - "WinHttpHandler: sendMulticast: setsockopt failed"));
229   - }
230   -
231   - // Fill out the desination socket's address information.
232   - SOCKADDR_IN dest_sin;
233   - dest_sin.sin_family = AF_INET;
234   - dest_sin.sin_port = htons(port);
235   - dest_sin.sin_addr.s_addr = inet_addr((const char *)ptr->ai_addr);
236   -
237   - // Send a message to the multicasting address.
238   - if (sendto(connect_socket, msg.c_str(), msg.size(), 0,
239   - (struct sockaddr FAR *)&dest_sin,
240   - sizeof(dest_sin)) == SOCKET_ERROR) {
241   - int err = WSAGetLastError();
242   - std::cerr << "WinHttpHandler: sendMulticast: sendto failed: "
243   - << WSAGetLastError() << std::endl;
244   - throw(std::system_error(err, std::system_category(),
245   - "WinHttpHandler: sendMulticast: sendto failed"));
246   - }
247   -
248   - // shutdown the connection for sending since no more data will be sent
249   - // the client can still use the ConnectSocket for receiving data
250   - if (shutdown(connect_socket, SD_SEND) == SOCKET_ERROR) {
251   - int err = WSAGetLastError();
252   - std::cerr << "WinHttpHandler: sendMulticast: shutdown failed: " << err
253   - << std::endl;
254   - throw(std::system_error(err, std::system_category(),
255   - "WinHttpHandler: sendMulticast: shutdown failed"));
256   - }
257   -
258   - std::string response;
259   - const int recvbuflen = 2048;
260   - char recvbuf[recvbuflen] = {};
261   - std::chrono::steady_clock::time_point start =
262   - std::chrono::steady_clock::now();
263   - while (std::chrono::steady_clock::now() - start <
264   - std::chrono::seconds(timeout)) {
265   - int res = recv(connect_socket, recvbuf, recvbuflen, 0);
266   - if (res > 0) {
267   - // std::cout << "WinHttpHandler: sendMulticast: Bytes received: " << res
268   - // << std::endl;
269   - response.append(recvbuf, res);
270   - } else if (res == 0) {
271   - // std::cout << "WinHttpHandler: sendMulticast: Connection closed " <<
272   - // std::endl;
273   - } else {
274   - // No exception here due to non blocking socket
275   - // std::cerr << "sendMulticast: recv failed: " << WSAGetLastError() <<
276   - // std::endl; throw(std::runtime_error("recv failed"));
  280 + // construct return vector
  281 + std::vector<std::string> returnString;
  282 + size_t pos = response.find("\r\n\r\n");
  283 + size_t prevpos = 0;
  284 + while (pos != std::string::npos)
  285 + {
  286 + returnString.push_back(response.substr(prevpos, pos - prevpos));
  287 + pos += 4;
  288 + prevpos = pos;
  289 + pos = response.find("\r\n\r\n", pos);
277 290 }
278   - }
279   -
280   - // construct return vector
281   - std::vector<std::string> returnString;
282   - size_t pos = response.find("\r\n\r\n");
283   - size_t prevpos = 0;
284   - while (pos != std::string::npos) {
285   - returnString.push_back(response.substr(prevpos, pos - prevpos));
286   - pos += 4;
287   - prevpos = pos;
288   - pos = response.find("\r\n\r\n", pos);
289   - }
290   -
291   - return returnString;
  291 +
  292 + return returnString;
292 293 }
... ...
hueplusplus/include/BaseHttpHandler.h
1 1 /**
2   - \file BaseHttpHandler.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file BaseHttpHandler.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _BASE_HTTPHANDLER_H
... ... @@ -26,249 +26,243 @@
26 26 #include <vector>
27 27  
28 28 #include "IHttpHandler.h"
  29 +
29 30 #include "json/json.hpp"
30 31  
31 32 //! Base class for classes that handle http requests and multicast requests
32   -class BaseHttpHandler : public IHttpHandler {
  33 +class BaseHttpHandler : public IHttpHandler
  34 +{
33 35 public:
34   - //! \brief Virtual dtor
35   - virtual ~BaseHttpHandler() = default;
  36 + //! \brief Virtual dtor
  37 + virtual ~BaseHttpHandler() = default;
36 38  
37   - //! \brief Virtual function that should send a given message to a specified
38   - //! host and return the response.
39   - //!
40   - //! \param msg String that contains the message that should be sent to the
41   - //! specified address \param adr String that contains an ip or hostname in
42   - //! dotted decimal notation like "192.168.2.1" \param port Optional integer
43   - //! that specifies the port to which the request should be sent to. Default is
44   - //! 80 \return String containing the response of the host
45   - virtual std::string send(const std::string &msg, const std::string &adr,
46   - int port = 80) const = 0;
  39 + //! \brief Virtual function that should send a given message to a specified
  40 + //! host and return the response.
  41 + //!
  42 + //! \param msg String that contains the message that should be sent to the
  43 + //! specified address \param adr String that contains an ip or hostname in
  44 + //! dotted decimal notation like "192.168.2.1" \param port Optional integer
  45 + //! that specifies the port to which the request should be sent to. Default is
  46 + //! 80 \return String containing the response of the host
  47 + virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const = 0;
47 48  
48   - //! \brief Virtual function that should given message to a specified host and
49   - //! return the body of the response.
50   - //!
51   - //! Note if no body is found a runtime error is thrown!
52   - //! \param msg String that contains the message that should sent to the
53   - //! specified address \param adr String that contains an ip or hostname in
54   - //! dotted decimal notation like "192.168.2.1" \param port Optional integer
55   - //! that specifies the port to which the request should be sent. Default is 80
56   - //! \return String containing the body of the response of the host
57   - virtual std::string sendGetHTTPBody(const std::string &msg,
58   - const std::string &adr,
59   - int port = 80) const {
60   - std::string response = send(msg, adr, port);
61   - size_t start = response.find("\r\n\r\n");
62   - if (start == std::string::npos) {
63   - std::cerr << "BaseHttpHandler: Failed to find body in response\n";
64   - std::cerr << "Request:\n";
65   - std::cerr << "\"" << msg << "\"\n";
66   - std::cerr << "Response:\n";
67   - std::cerr << "\"" << response << "\"\n";
68   - throw(std::runtime_error(
69   - "BaseHttpHandler: Failed to find body in response"));
70   - }
71   - response.erase(0, start + 4);
72   - return response;
73   - };
  49 + //! \brief Virtual function that should given message to a specified host and
  50 + //! return the body of the response.
  51 + //!
  52 + //! Note if no body is found a runtime error is thrown!
  53 + //! \param msg String that contains the message that should sent to the
  54 + //! specified address \param adr String that contains an ip or hostname in
  55 + //! dotted decimal notation like "192.168.2.1" \param port Optional integer
  56 + //! that specifies the port to which the request should be sent. Default is 80
  57 + //! \return String containing the body of the response of the host
  58 + virtual std::string sendGetHTTPBody(const std::string& msg, const std::string& adr, int port = 80) const
  59 + {
  60 + std::string response = send(msg, adr, port);
  61 + size_t start = response.find("\r\n\r\n");
  62 + if (start == std::string::npos)
  63 + {
  64 + std::cerr << "BaseHttpHandler: Failed to find body in response\n";
  65 + std::cerr << "Request:\n";
  66 + std::cerr << "\"" << msg << "\"\n";
  67 + std::cerr << "Response:\n";
  68 + std::cerr << "\"" << response << "\"\n";
  69 + throw(std::runtime_error("BaseHttpHandler: Failed to find body in response"));
  70 + }
  71 + response.erase(0, start + 4);
  72 + return response;
  73 + };
74 74  
75   - //! \brief Virtual function that should send a multicast request with a
76   - //! specified message.
77   - //!
78   - //! \param msg String that contains the request that should be sent to the
79   - //! specified address \param adr Optional String that contains an ip or
80   - //! hostname in dotted decimal notation, default is "239.255.255.250" \param
81   - //! port Optional integer that specifies the port to which the request should
82   - //! be sent. Default is 1900 \param timeout Optional Integer that specifies
83   - //! the timeout of the request in seconds. Default is 5 \return Vector
84   - //! containing strings of each answer received
85   - virtual std::vector<std::string>
86   - sendMulticast(const std::string &msg,
87   - const std::string &adr = "239.255.255.250", int port = 1900,
88   - int timeout = 5) const = 0;
  75 + //! \brief Virtual function that should send a multicast request with a
  76 + //! specified message.
  77 + //!
  78 + //! \param msg String that contains the request that should be sent to the
  79 + //! specified address \param adr Optional String that contains an ip or
  80 + //! hostname in dotted decimal notation, default is "239.255.255.250" \param
  81 + //! port Optional integer that specifies the port to which the request should
  82 + //! be sent. Default is 1900 \param timeout Optional Integer that specifies
  83 + //! the timeout of the request in seconds. Default is 5 \return Vector
  84 + //! containing strings of each answer received
  85 + virtual std::vector<std::string> sendMulticast(
  86 + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const = 0;
89 87  
90   - //! \brief Virtual function that should send a HTTP request with the given
91   - //! method to the specified host and return the body of the response.
92   - //!
93   - //! Note body can also be left empty!
94   - //! \param method String that contains the HTTP method type e.g. GET, HEAD,
95   - //! POST, PUT, DELETE, ... \param uri String that contains the uniform
96   - //! resource identifier \param content_type String that contains the
97   - //! type(MIME) of the body data e.g. "text/html", "application/json", ...
98   - //! \param body String that contains the data of the request
99   - //! \param adr String that contains an ip or hostname in dotted decimal
100   - //! notation like "192.168.2.1" \param port Optional integer that specifies
101   - //! the port to which the request is sent to. Default is 80 \return String
102   - //! containing the body of the response of the host
103   - virtual std::string sendHTTPRequest(std::string method, std::string uri,
104   - std::string content_type,
105   - std::string body, const std::string &adr,
106   - int port = 80) const {
107   - std::string request;
108   - // Protocol reference:
109   - // https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html Request-Line
110   - request.append(method); // Method
111   - request.append(" "); // Separation
112   - request.append(uri); // Request-URI
113   - request.append(" "); // Separation
114   - request.append("HTTP/1.0"); // HTTP-Version
115   - request.append("\r\n"); // Ending
116   - // Entities
117   - request.append("Content-Type:"); // entity-header
118   - request.append(" "); // Separation
119   - request.append(content_type); // media-type
120   - request.append("\r\n"); // Entity ending
121   - request.append("Content-Length:"); // entity-header
122   - request.append(" "); // Separation
123   - request.append(std::to_string(body.size())); // length
124   - request.append("\r\n\r\n"); // Entity ending & Request-Line ending
125   - request.append(body); // message-body
126   - request.append("\r\n\r\n"); // Ending
  88 + //! \brief Virtual function that should send a HTTP request with the given
  89 + //! method to the specified host and return the body of the response.
  90 + //!
  91 + //! Note body can also be left empty!
  92 + //! \param method String that contains the HTTP method type e.g. GET, HEAD,
  93 + //! POST, PUT, DELETE, ... \param uri String that contains the uniform
  94 + //! resource identifier \param content_type String that contains the
  95 + //! type(MIME) of the body data e.g. "text/html", "application/json", ...
  96 + //! \param body String that contains the data of the request
  97 + //! \param adr String that contains an ip or hostname in dotted decimal
  98 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  99 + //! the port to which the request is sent to. Default is 80 \return String
  100 + //! containing the body of the response of the host
  101 + virtual std::string sendHTTPRequest(std::string method, std::string uri, std::string content_type, std::string body,
  102 + const std::string& adr, int port = 80) const
  103 + {
  104 + std::string request;
  105 + // Protocol reference:
  106 + // https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html Request-Line
  107 + request.append(method); // Method
  108 + request.append(" "); // Separation
  109 + request.append(uri); // Request-URI
  110 + request.append(" "); // Separation
  111 + request.append("HTTP/1.0"); // HTTP-Version
  112 + request.append("\r\n"); // Ending
  113 + // Entities
  114 + request.append("Content-Type:"); // entity-header
  115 + request.append(" "); // Separation
  116 + request.append(content_type); // media-type
  117 + request.append("\r\n"); // Entity ending
  118 + request.append("Content-Length:"); // entity-header
  119 + request.append(" "); // Separation
  120 + request.append(std::to_string(body.size())); // length
  121 + request.append("\r\n\r\n"); // Entity ending & Request-Line ending
  122 + request.append(body); // message-body
  123 + request.append("\r\n\r\n"); // Ending
127 124  
128   - return sendGetHTTPBody(request.c_str(), adr, port);
129   - };
  125 + return sendGetHTTPBody(request.c_str(), adr, port);
  126 + };
130 127  
131   - //! \brief Virtual function that should send a HTTP GET request to the
132   - //! specified host and return the body of the response.
133   - //!
134   - //! Note body can also be left empty!
135   - //! \param uri String that contains the uniform resource identifier
136   - //! \param content_type String that contains the type(MIME) of the body data
137   - //! e.g. "text/html", "application/json", ... \param body String that contains
138   - //! the data of the request \param adr String that contains an ip or hostname
139   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
140   - //! that specifies the port to which the request is sent to. Default is 80
141   - //! \return String containing the body of the response of the host
142   - virtual std::string GETString(std::string uri, std::string content_type,
143   - std::string body, const std::string &adr,
144   - int port = 80) const {
145   - return sendHTTPRequest("GET", uri, content_type, body, adr, port);
146   - };
  128 + //! \brief Virtual function that should send a HTTP GET request to the
  129 + //! specified host and return the body of the response.
  130 + //!
  131 + //! Note body can also be left empty!
  132 + //! \param uri String that contains the uniform resource identifier
  133 + //! \param content_type String that contains the type(MIME) of the body data
  134 + //! e.g. "text/html", "application/json", ... \param body String that contains
  135 + //! the data of the request \param adr String that contains an ip or hostname
  136 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  137 + //! that specifies the port to which the request is sent to. Default is 80
  138 + //! \return String containing the body of the response of the host
  139 + virtual std::string GETString(
  140 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const
  141 + {
  142 + return sendHTTPRequest("GET", uri, content_type, body, adr, port);
  143 + };
147 144  
148   - //! \brief Virtual function that should send a HTTP POST request to the
149   - //! specified host and returns the body of the response.
150   - //!
151   - //! Note body can also be left empty!
152   - //! \param uri String that contains the uniform resource identifier
153   - //! \param content_type String that contains the type(MIME) of the body data
154   - //! e.g. "text/html", "application/json", ... \param body String that contains
155   - //! the data of the request \param adr String that contains an ip or hostname
156   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
157   - //! that specifies the port to which the request is sent to. Default is 80
158   - //! \return String containing the body of the response of the host
159   - virtual std::string POSTString(std::string uri, std::string content_type,
160   - std::string body, const std::string &adr,
161   - int port = 80) const {
162   - return sendHTTPRequest("POST", uri, content_type, body, adr, port);
163   - };
  145 + //! \brief Virtual function that should send a HTTP POST request to the
  146 + //! specified host and returns the body of the response.
  147 + //!
  148 + //! Note body can also be left empty!
  149 + //! \param uri String that contains the uniform resource identifier
  150 + //! \param content_type String that contains the type(MIME) of the body data
  151 + //! e.g. "text/html", "application/json", ... \param body String that contains
  152 + //! the data of the request \param adr String that contains an ip or hostname
  153 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  154 + //! that specifies the port to which the request is sent to. Default is 80
  155 + //! \return String containing the body of the response of the host
  156 + virtual std::string POSTString(
  157 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const
  158 + {
  159 + return sendHTTPRequest("POST", uri, content_type, body, adr, port);
  160 + };
164 161  
165   - //! \brief Virtual function that should send a HTTP PUT request to the
166   - //! specified host and return the body of the response.
167   - //!
168   - //! Note body can also be left empty!
169   - //! \param uri String that contains the uniform resource identifier
170   - //! \param content_type String that contains the type(MIME) of the body data
171   - //! e.g. "text/html", "application/json", ... \param body String that contains
172   - //! the data of the request \param adr String that contains an ip or hostname
173   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
174   - //! that specifies the port to which the request is sent to. Default is 80
175   - //! \return String containing the body of the response of the host
176   - virtual std::string PUTString(std::string uri, std::string content_type,
177   - std::string body, const std::string &adr,
178   - int port = 80) const {
179   - return sendHTTPRequest("PUT", uri, content_type, body, adr, port);
180   - };
  162 + //! \brief Virtual function that should send a HTTP PUT request to the
  163 + //! specified host and return the body of the response.
  164 + //!
  165 + //! Note body can also be left empty!
  166 + //! \param uri String that contains the uniform resource identifier
  167 + //! \param content_type String that contains the type(MIME) of the body data
  168 + //! e.g. "text/html", "application/json", ... \param body String that contains
  169 + //! the data of the request \param adr String that contains an ip or hostname
  170 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  171 + //! that specifies the port to which the request is sent to. Default is 80
  172 + //! \return String containing the body of the response of the host
  173 + virtual std::string PUTString(
  174 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const
  175 + {
  176 + return sendHTTPRequest("PUT", uri, content_type, body, adr, port);
  177 + };
181 178  
182   - //! \brief Virtual function that should send a HTTP DELETE request to the
183   - //! specified host and return the body of the response.
184   - //!
185   - //! Note body can also be left empty!
186   - //! \param uri String that contains the uniform resource identifier
187   - //! \param content_type String that contains the type(MIME) of the body data
188   - //! e.g. "text/html", "application/json", ... \param body String that contains
189   - //! the data of the request \param adr String that contains an ip or hostname
190   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
191   - //! that specifies the port to which the request is sent to. Default is 80
192   - //! \return String containing the body of the response of the host
193   - virtual std::string DELETEString(std::string uri, std::string content_type,
194   - std::string body, const std::string &adr,
195   - int port = 80) const {
196   - return sendHTTPRequest("DELETE", uri, content_type, body, adr, port);
197   - };
  179 + //! \brief Virtual function that should send a HTTP DELETE request to the
  180 + //! specified host and return the body of the response.
  181 + //!
  182 + //! Note body can also be left empty!
  183 + //! \param uri String that contains the uniform resource identifier
  184 + //! \param content_type String that contains the type(MIME) of the body data
  185 + //! e.g. "text/html", "application/json", ... \param body String that contains
  186 + //! the data of the request \param adr String that contains an ip or hostname
  187 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  188 + //! that specifies the port to which the request is sent to. Default is 80
  189 + //! \return String containing the body of the response of the host
  190 + virtual std::string DELETEString(
  191 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const
  192 + {
  193 + return sendHTTPRequest("DELETE", uri, content_type, body, adr, port);
  194 + };
198 195  
199   - //! \brief Virtual function that should send a HTTP GET request to the
200   - //! specified host and return the body of the response.
201   - //!
202   - //! Note body can also be left empty!
203   - //! \param uri String that contains the uniform resource identifier
204   - //! \param body nlohmann::json that contains the data of the request
205   - //! \param adr String that contains an ip or hostname in dotted decimal
206   - //! notation like "192.168.2.1" \param port Optional integer that specifies
207   - //! the port to which the request is sent to. Default is 80 \return
208   - //! nlohmann::json containing the parsed body of the response of the host
209   - virtual nlohmann::json GETJson(std::string uri, const nlohmann::json &body,
210   - const std::string &adr, int port = 80) const {
211   - return strToJsonValue(
212   - GETString(uri, "application/json", body.dump(), adr, port));
213   - };
  196 + //! \brief Virtual function that should send a HTTP GET request to the
  197 + //! specified host and return the body of the response.
  198 + //!
  199 + //! Note body can also be left empty!
  200 + //! \param uri String that contains the uniform resource identifier
  201 + //! \param body nlohmann::json that contains the data of the request
  202 + //! \param adr String that contains an ip or hostname in dotted decimal
  203 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  204 + //! the port to which the request is sent to. Default is 80 \return
  205 + //! nlohmann::json containing the parsed body of the response of the host
  206 + virtual nlohmann::json GETJson(
  207 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const
  208 + {
  209 + return strToJsonValue(GETString(uri, "application/json", body.dump(), adr, port));
  210 + };
214 211  
215   - //! \brief Virtual function that should send a HTTP POST request to the
216   - //! specified host and return the body of the response.
217   - //!
218   - //! Note body can also be left empty!
219   - //! \param uri String that contains the uniform resource identifier
220   - //! \param body nlohmann::json that contains the data of the request
221   - //! \param adr String that contains an ip or hostname in dotted decimal
222   - //! notation like "192.168.2.1" \param port Optional integer that specifies
223   - //! the port to which the request is sent to. Default is 80 \return
224   - //! nlohmann::json containing the parsed body of the response of the host
225   - virtual nlohmann::json POSTJson(std::string uri, const nlohmann::json &body,
226   - const std::string &adr, int port = 80) const {
227   - return strToJsonValue(
228   - POSTString(uri, "application/json", body.dump(), adr, port));
229   - }
  212 + //! \brief Virtual function that should send a HTTP POST request to the
  213 + //! specified host and return the body of the response.
  214 + //!
  215 + //! Note body can also be left empty!
  216 + //! \param uri String that contains the uniform resource identifier
  217 + //! \param body nlohmann::json that contains the data of the request
  218 + //! \param adr String that contains an ip or hostname in dotted decimal
  219 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  220 + //! the port to which the request is sent to. Default is 80 \return
  221 + //! nlohmann::json containing the parsed body of the response of the host
  222 + virtual nlohmann::json POSTJson(
  223 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const
  224 + {
  225 + return strToJsonValue(POSTString(uri, "application/json", body.dump(), adr, port));
  226 + }
230 227  
231   - //! \brief Virtual function that should send a HTTP PUT request to the
232   - //! specified host and return the body of the response.
233   - //!
234   - //! Note body can also be left empty!
235   - //! \param uri String that contains the uniform resource identifier
236   - //! \param body nlohmann::json that contains the data of the request
237   - //! \param adr String that contains an ip or hostname in dotted decimal
238   - //! notation like "192.168.2.1" \param port Optional integer that specifies
239   - //! the port to which the request is sent to. Default is 80 \return
240   - //! nlohmann::json containing the parsed body of the response of the host
241   - virtual nlohmann::json PUTJson(std::string uri, const nlohmann::json &body,
242   - const std::string &adr, int port = 80) const {
243   - return strToJsonValue(
244   - PUTString(uri, "application/json", body.dump(), adr, port));
245   - };
  228 + //! \brief Virtual function that should send a HTTP PUT request to the
  229 + //! specified host and return the body of the response.
  230 + //!
  231 + //! Note body can also be left empty!
  232 + //! \param uri String that contains the uniform resource identifier
  233 + //! \param body nlohmann::json that contains the data of the request
  234 + //! \param adr String that contains an ip or hostname in dotted decimal
  235 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  236 + //! the port to which the request is sent to. Default is 80 \return
  237 + //! nlohmann::json containing the parsed body of the response of the host
  238 + virtual nlohmann::json PUTJson(
  239 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const
  240 + {
  241 + return strToJsonValue(PUTString(uri, "application/json", body.dump(), adr, port));
  242 + };
246 243  
247   - //! \brief Virtual function that should send a HTTP DELETE request to the
248   - //! specified host and return the body of the response.
249   - //!
250   - //! Note body can also be left empty!
251   - //! \param uri String that contains the uniform resource identifier
252   - //! \param body nlohmann::json that contains the data of the request
253   - //! \param adr String that contains an ip or hostname in dotted decimal
254   - //! notation like "192.168.2.1" \param port Optional integer that specifies
255   - //! the port to which the request is sent to. Default is 80 \return
256   - //! nlohmann::json containing the parsed body of the response of the host
257   - virtual nlohmann::json DELETEJson(std::string uri, const nlohmann::json &body,
258   - const std::string &adr,
259   - int port = 80) const {
260   - return strToJsonValue(
261   - DELETEString(uri, "application/json", body.dump(), adr, port));
262   - };
  244 + //! \brief Virtual function that should send a HTTP DELETE request to the
  245 + //! specified host and return the body of the response.
  246 + //!
  247 + //! Note body can also be left empty!
  248 + //! \param uri String that contains the uniform resource identifier
  249 + //! \param body nlohmann::json that contains the data of the request
  250 + //! \param adr String that contains an ip or hostname in dotted decimal
  251 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  252 + //! the port to which the request is sent to. Default is 80 \return
  253 + //! nlohmann::json containing the parsed body of the response of the host
  254 + virtual nlohmann::json DELETEJson(
  255 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const
  256 + {
  257 + return strToJsonValue(DELETEString(uri, "application/json", body.dump(), adr, port));
  258 + };
263 259  
264 260 private:
265   - //! \brief Function that converts a given string to a nlohmann::json
266   - //!
267   - //! \param str String that gets converted
268   - //! \return nlohmann::json containing parsed string
269   - nlohmann::json strToJsonValue(std::string str) const {
270   - return nlohmann::json::parse(str);
271   - }
  261 + //! \brief Function that converts a given string to a nlohmann::json
  262 + //!
  263 + //! \param str String that gets converted
  264 + //! \return nlohmann::json containing parsed string
  265 + nlohmann::json strToJsonValue(std::string str) const { return nlohmann::json::parse(str); }
272 266 };
273 267  
274 268 #endif
... ...
hueplusplus/include/BrightnessStrategy.h
1 1 /**
2   - \file BrightnessStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file BrightnessStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _BRIGHTNESS_STRATEGY_H
... ... @@ -25,31 +25,31 @@
25 25 class HueLight;
26 26  
27 27 //! Virtual base class for all BrightnessStrategies
28   -class BrightnessStrategy {
  28 +class BrightnessStrategy
  29 +{
29 30 public:
30   - //! \brief Virtual function for changing a lights brightness with a specified
31   - //! transition.
32   - //!
33   - //! \param bri The brightness raning from 0 = off to 255 = fully lit
34   - //! \param transition The time it takes to fade to the new brightness in
35   - //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
36   - //! light A reference of the light
37   - virtual bool setBrightness(unsigned int bri, uint8_t transition,
38   - HueLight &light) const = 0;
39   - //! \brief Virtual function that returns the current brightnessof the light
40   - //!
41   - //! Should update the lights state by calling refreshState()
42   - //! \param light A reference of the light
43   - //! \return Unsigned int representing the brightness
44   - virtual unsigned int getBrightness(HueLight &light) const = 0;
45   - //! \brief Virtual function that returns the current brightness of the light
46   - //!
47   - //! \note This should not update the lights state
48   - //! \param light A const reference of the light
49   - //! \return Unsigned int representing the brightness
50   - virtual unsigned int getBrightness(const HueLight &light) const = 0;
51   - //! \brief Virtual dtor
52   - virtual ~BrightnessStrategy() = default;
  31 + //! \brief Virtual function for changing a lights brightness with a specified
  32 + //! transition.
  33 + //!
  34 + //! \param bri The brightness raning from 0 = off to 255 = fully lit
  35 + //! \param transition The time it takes to fade to the new brightness in
  36 + //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
  37 + //! light A reference of the light
  38 + virtual bool setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const = 0;
  39 + //! \brief Virtual function that returns the current brightnessof the light
  40 + //!
  41 + //! Should update the lights state by calling refreshState()
  42 + //! \param light A reference of the light
  43 + //! \return Unsigned int representing the brightness
  44 + virtual unsigned int getBrightness(HueLight& light) const = 0;
  45 + //! \brief Virtual function that returns the current brightness of the light
  46 + //!
  47 + //! \note This should not update the lights state
  48 + //! \param light A const reference of the light
  49 + //! \return Unsigned int representing the brightness
  50 + virtual unsigned int getBrightness(const HueLight& light) const = 0;
  51 + //! \brief Virtual dtor
  52 + virtual ~BrightnessStrategy() = default;
53 53 };
54 54  
55 55 #endif
... ...
hueplusplus/include/ColorHueStrategy.h
1 1 /**
2   - \file ColorHueStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file ColorHueStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _COLOR_HUE_STRATEGY_H
21 21 #define _COLOR_HUE_STRATEGY_H
22 22  
23 23 #include <memory>
  24 +
24 25 #include <stdint.h>
25 26  
26 27 class HueLight;
27 28  
28 29 //! Virtual base class for all ColorHueStrategies
29   -class ColorHueStrategy {
  30 +class ColorHueStrategy
  31 +{
30 32 public:
31   - //! \brief Virtual function for changing a lights color in hue with a
32   - //! specified transition.
33   - //!
34   - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
35   - //! green and 46920 is blue. \param hue The hue of the color \param transition
36   - //! The time it takes to fade to the new color in multiples of 100ms, 4 =
37   - //! 400ms and should be seen as the default \param light A reference of the
38   - //! light
39   - virtual bool setColorHue(uint16_t hue, uint8_t transition,
40   - HueLight &light) const = 0;
41   - //! \brief Virtual function for changing a lights color in saturation with a
42   - //! specified transition.
43   - //!
44   - //! The saturation ranges from 0 to 254, whereas 0 is least saturated (white)
45   - //! and 254 is most saturated (vibrant). \param sat The saturation of the
46   - //! color \param transition The time it takes to fade to the new color in
47   - //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
48   - //! light A reference of the light
49   - virtual bool setColorSaturation(uint8_t sat, uint8_t transition,
50   - HueLight &light) const = 0;
51   - //! \brief Virtual function for changing a lights color in hue and saturation
52   - //! format with a specified transition.
53   - //!
54   - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
55   - //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is
56   - //! least saturated (white) and 254 is most saturated (vibrant). \param hue
57   - //! The hue of the color \param sat The saturation of the color \param
58   - //! transition The time it takes to fade to the new color in multiples of
59   - //! 100ms, 4 = 400ms and should be seen as the default \param light A
60   - //! reference of the light
61   - virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat,
62   - uint8_t transition,
63   - HueLight &light) const = 0;
64   - //! \brief Virtual function for changing a lights color in CIE format with a
65   - //! specified transition.
66   - //!
67   - //! \param x The x coordinate in CIE, ranging from 0 to 1
68   - //! \param y The y coordinate in CIE, ranging from 0 to 1
69   - //! \param transition The time it takes to fade to the new color in multiples
70   - //! of 100ms, 4 = 400ms and should be seen as the default \param light A
71   - //! reference of the light
72   - virtual bool setColorXY(float x, float y, uint8_t transition,
73   - HueLight &light) const = 0;
74   - //! \brief Virtual function for changing a lights color in rgb format with a
75   - //! specified transition.
76   - //!
77   - //! Red, green and blue are ranging from 0 to 255.
78   - //! \param r The red portion of the color
79   - //! \param g The green portion of the color
80   - //! \param b The blue portion of the color
81   - //! \param transition The time it takes to fade to the new color in multiples
82   - //! of 100ms, 4 = 400ms and should be seen as the default \param light A
83   - //! reference of the light
84   - virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition,
85   - HueLight &light) const = 0;
86   - //! \brief Virtual function for turning on/off the color loop feature of a
87   - //! light.
88   - //!
89   - //! Can be theoretically set for any light, but it only works for lights that
90   - //! support this feature. When this feature is activated the light will fade
91   - //! through every color on the current hue and saturation settings. Notice
92   - //! that none of the setter functions check whether this feature is enabled
93   - //! and the colorloop can only be disabled with this function or by simply
94   - //! calling Off()/OffNoRefresh() and then On()/OnNoRefresh(), so you could
95   - //! alternatively call Off() and then use any of the setter functions. \param
96   - //! on Boolean to turn this feature on or off, true/1 for on and false/0 for
97   - //! off \param light A reference of the light
98   - virtual bool setColorLoop(bool on, HueLight &light) const = 0;
99   - //! \brief Virtual function that lets the light perform one breath cycle in
100   - //! the specified color.
101   - //!
102   - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
103   - //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is
104   - //! least saturated (white) and 254 is most saturated (vibrant). \param hue
105   - //! The hue of the color \param sat The saturation of the color \param light A
106   - //! reference of the light
107   - virtual bool alertHueSaturation(uint16_t hue, uint8_t sat,
108   - HueLight &light) const = 0;
109   - //! \brief Virtual function that lets the light perform one breath cycle in
110   - //! the specified color.
111   - //!
112   - //! \param x The x coordinate in CIE, ranging from 0 to 1
113   - //! \param y The y coordinate in CIE, ranging from 0 to 1
114   - //! \param light A reference of the light
115   - virtual bool alertXY(float x, float y, HueLight &light) const = 0;
116   - //! \brief Virtual function that lets the light perform one breath cycle in
117   - //! the specified color.
118   - //!
119   - //! Red, green and blue are ranging from 0 to 255.
120   - //! \param r The red portion of the color
121   - //! \param g The green portion of the color
122   - //! \param b The blue portion of the color
123   - //! \param light A reference of the light
124   - virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b,
125   - HueLight &light) const = 0;
126   - //! \brief Virtual function that returns the current color of the light as hue
127   - //! and saturation
128   - //!
129   - //! Should update the lights state by calling refreshState()
130   - //! \param light A reference of the light
131   - //! \return Pair containing the hue as first value and saturation as second
132   - //! value
133   - virtual std::pair<uint16_t, uint8_t>
134   - getColorHueSaturation(HueLight &light) const = 0;
135   - //! \brief Virtual function that returns the current color of the light as hue
136   - //! and saturation
137   - //!
138   - //! \note This should not update the lights state
139   - //! \param light A const reference of the light
140   - //! \return Pair containing the hue as first value and saturation as second
141   - //! value
142   - virtual std::pair<uint16_t, uint8_t>
143   - getColorHueSaturation(const HueLight &light) const = 0;
144   - //! \brief Virtual function that returns the current color of the light as xy
145   - //!
146   - //! Should update the lights state by calling refreshState()
147   - //! \param light A reference of the light
148   - //! \return Pair containing the x as first value and y as second value
149   - virtual std::pair<float, float> getColorXY(HueLight &light) const = 0;
150   - //! \brief Virtual function that returns the current color of the light as xy
151   - //!
152   - //! \note This should not update the lights state
153   - //! \param light A const reference of the light
154   - //! \return Pair containing the x as first value and y as second value
155   - virtual std::pair<float, float> getColorXY(const HueLight &light) const = 0;
156   - //! \brief Virtual dtor
157   - virtual ~ColorHueStrategy() = default;
  33 + //! \brief Virtual function for changing a lights color in hue with a
  34 + //! specified transition.
  35 + //!
  36 + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
  37 + //! green and 46920 is blue. \param hue The hue of the color \param transition
  38 + //! The time it takes to fade to the new color in multiples of 100ms, 4 =
  39 + //! 400ms and should be seen as the default \param light A reference of the
  40 + //! light
  41 + virtual bool setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const = 0;
  42 + //! \brief Virtual function for changing a lights color in saturation with a
  43 + //! specified transition.
  44 + //!
  45 + //! The saturation ranges from 0 to 254, whereas 0 is least saturated (white)
  46 + //! and 254 is most saturated (vibrant). \param sat The saturation of the
  47 + //! color \param transition The time it takes to fade to the new color in
  48 + //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
  49 + //! light A reference of the light
  50 + virtual bool setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const = 0;
  51 + //! \brief Virtual function for changing a lights color in hue and saturation
  52 + //! format with a specified transition.
  53 + //!
  54 + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
  55 + //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is
  56 + //! least saturated (white) and 254 is most saturated (vibrant). \param hue
  57 + //! The hue of the color \param sat The saturation of the color \param
  58 + //! transition The time it takes to fade to the new color in multiples of
  59 + //! 100ms, 4 = 400ms and should be seen as the default \param light A
  60 + //! reference of the light
  61 + virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const = 0;
  62 + //! \brief Virtual function for changing a lights color in CIE format with a
  63 + //! specified transition.
  64 + //!
  65 + //! \param x The x coordinate in CIE, ranging from 0 to 1
  66 + //! \param y The y coordinate in CIE, ranging from 0 to 1
  67 + //! \param transition The time it takes to fade to the new color in multiples
  68 + //! of 100ms, 4 = 400ms and should be seen as the default \param light A
  69 + //! reference of the light
  70 + virtual bool setColorXY(float x, float y, uint8_t transition, HueLight& light) const = 0;
  71 + //! \brief Virtual function for changing a lights color in rgb format with a
  72 + //! specified transition.
  73 + //!
  74 + //! Red, green and blue are ranging from 0 to 255.
  75 + //! \param r The red portion of the color
  76 + //! \param g The green portion of the color
  77 + //! \param b The blue portion of the color
  78 + //! \param transition The time it takes to fade to the new color in multiples
  79 + //! of 100ms, 4 = 400ms and should be seen as the default \param light A
  80 + //! reference of the light
  81 + virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, HueLight& light) const = 0;
  82 + //! \brief Virtual function for turning on/off the color loop feature of a
  83 + //! light.
  84 + //!
  85 + //! Can be theoretically set for any light, but it only works for lights that
  86 + //! support this feature. When this feature is activated the light will fade
  87 + //! through every color on the current hue and saturation settings. Notice
  88 + //! that none of the setter functions check whether this feature is enabled
  89 + //! and the colorloop can only be disabled with this function or by simply
  90 + //! calling Off()/OffNoRefresh() and then On()/OnNoRefresh(), so you could
  91 + //! alternatively call Off() and then use any of the setter functions. \param
  92 + //! on Boolean to turn this feature on or off, true/1 for on and false/0 for
  93 + //! off \param light A reference of the light
  94 + virtual bool setColorLoop(bool on, HueLight& light) const = 0;
  95 + //! \brief Virtual function that lets the light perform one breath cycle in
  96 + //! the specified color.
  97 + //!
  98 + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
  99 + //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is
  100 + //! least saturated (white) and 254 is most saturated (vibrant). \param hue
  101 + //! The hue of the color \param sat The saturation of the color \param light A
  102 + //! reference of the light
  103 + virtual bool alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const = 0;
  104 + //! \brief Virtual function that lets the light perform one breath cycle in
  105 + //! the specified color.
  106 + //!
  107 + //! \param x The x coordinate in CIE, ranging from 0 to 1
  108 + //! \param y The y coordinate in CIE, ranging from 0 to 1
  109 + //! \param light A reference of the light
  110 + virtual bool alertXY(float x, float y, HueLight& light) const = 0;
  111 + //! \brief Virtual function that lets the light perform one breath cycle in
  112 + //! the specified color.
  113 + //!
  114 + //! Red, green and blue are ranging from 0 to 255.
  115 + //! \param r The red portion of the color
  116 + //! \param g The green portion of the color
  117 + //! \param b The blue portion of the color
  118 + //! \param light A reference of the light
  119 + virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const = 0;
  120 + //! \brief Virtual function that returns the current color of the light as hue
  121 + //! and saturation
  122 + //!
  123 + //! Should update the lights state by calling refreshState()
  124 + //! \param light A reference of the light
  125 + //! \return Pair containing the hue as first value and saturation as second
  126 + //! value
  127 + virtual std::pair<uint16_t, uint8_t> getColorHueSaturation(HueLight& light) const = 0;
  128 + //! \brief Virtual function that returns the current color of the light as hue
  129 + //! and saturation
  130 + //!
  131 + //! \note This should not update the lights state
  132 + //! \param light A const reference of the light
  133 + //! \return Pair containing the hue as first value and saturation as second
  134 + //! value
  135 + virtual std::pair<uint16_t, uint8_t> getColorHueSaturation(const HueLight& light) const = 0;
  136 + //! \brief Virtual function that returns the current color of the light as xy
  137 + //!
  138 + //! Should update the lights state by calling refreshState()
  139 + //! \param light A reference of the light
  140 + //! \return Pair containing the x as first value and y as second value
  141 + virtual std::pair<float, float> getColorXY(HueLight& light) const = 0;
  142 + //! \brief Virtual function that returns the current color of the light as xy
  143 + //!
  144 + //! \note This should not update the lights state
  145 + //! \param light A const reference of the light
  146 + //! \return Pair containing the x as first value and y as second value
  147 + virtual std::pair<float, float> getColorXY(const HueLight& light) const = 0;
  148 + //! \brief Virtual dtor
  149 + virtual ~ColorHueStrategy() = default;
158 150 };
159 151  
160 152 #endif
... ...
hueplusplus/include/ColorTemperatureStrategy.h
1 1 /**
2   - \file ColorTemperatureStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file ColorTemperatureStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _COLOR_TEMPERATURE_STRATEGY_H
... ... @@ -25,43 +25,43 @@
25 25 class HueLight;
26 26  
27 27 //! Virtual base class for all ColorTemperatureStrategies
28   -class ColorTemperatureStrategy {
  28 +class ColorTemperatureStrategy
  29 +{
29 30 public:
30   - //! \brief Virtual function for changing a lights color temperature in mired
31   - //! with a specified transition.
32   - //!
33   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
34   - //! and 500 is warm. \param mired The color temperature in mired \param
35   - //! transition The time it takes to fade to the new color in multiples of
36   - //! 100ms, 4 = 400ms and should be seen as the default \param light A
37   - //! reference of the light
38   - virtual bool setColorTemperature(unsigned int mired, uint8_t transition,
39   - HueLight &light) const = 0;
40   - //! \brief Virtual function that lets the light perform one breath cycle in
41   - //! the specified color.
42   - //!
43   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
44   - //! and 500 is warm. \param mired The color temperature in mired \param light
45   - //! A reference of the light
46   - virtual bool alertTemperature(unsigned int mired, HueLight &light) const = 0;
47   - //! \brief Virtual function that returns the current color temperature of the
48   - //! light
49   - //!
50   - //! Should update the lights state by calling refreshState()
51   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
52   - //! and 500 is warm. \param light A reference of the light \return Unsigned
53   - //! int representing the color temperature in mired
54   - virtual unsigned int getColorTemperature(HueLight &light) const = 0;
55   - //! \brief Virtual function that returns the current color temperature of the
56   - //! light
57   - //!
58   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
59   - //! and 500 is warm. \note This should not update the lights state \param
60   - //! light A const reference of the light \return Unsigned int representing the
61   - //! color temperature in mired
62   - virtual unsigned int getColorTemperature(const HueLight &light) const = 0;
63   - //! \brief Virtual dtor
64   - virtual ~ColorTemperatureStrategy() = default;
  31 + //! \brief Virtual function for changing a lights color temperature in mired
  32 + //! with a specified transition.
  33 + //!
  34 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  35 + //! and 500 is warm. \param mired The color temperature in mired \param
  36 + //! transition The time it takes to fade to the new color in multiples of
  37 + //! 100ms, 4 = 400ms and should be seen as the default \param light A
  38 + //! reference of the light
  39 + virtual bool setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const = 0;
  40 + //! \brief Virtual function that lets the light perform one breath cycle in
  41 + //! the specified color.
  42 + //!
  43 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  44 + //! and 500 is warm. \param mired The color temperature in mired \param light
  45 + //! A reference of the light
  46 + virtual bool alertTemperature(unsigned int mired, HueLight& light) const = 0;
  47 + //! \brief Virtual function that returns the current color temperature of the
  48 + //! light
  49 + //!
  50 + //! Should update the lights state by calling refreshState()
  51 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  52 + //! and 500 is warm. \param light A reference of the light \return Unsigned
  53 + //! int representing the color temperature in mired
  54 + virtual unsigned int getColorTemperature(HueLight& light) const = 0;
  55 + //! \brief Virtual function that returns the current color temperature of the
  56 + //! light
  57 + //!
  58 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  59 + //! and 500 is warm. \note This should not update the lights state \param
  60 + //! light A const reference of the light \return Unsigned int representing the
  61 + //! color temperature in mired
  62 + virtual unsigned int getColorTemperature(const HueLight& light) const = 0;
  63 + //! \brief Virtual dtor
  64 + virtual ~ColorTemperatureStrategy() = default;
65 65 };
66 66  
67 67 #endif
... ...
hueplusplus/include/ExtendedColorHueStrategy.h
1 1 /**
2   - \file ExtendedColorHueStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file ExtendedColorHueStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _EXTENDED_COLOR_HUE_STRATEGY_H
... ... @@ -24,38 +24,37 @@
24 24 #include "SimpleColorHueStrategy.h"
25 25  
26 26 //! Class extending the implementation of SimpleColorHueStrategy
27   -class ExtendedColorHueStrategy : public SimpleColorHueStrategy {
  27 +class ExtendedColorHueStrategy : public SimpleColorHueStrategy
  28 +{
28 29 public:
29   - //! \brief Function that lets the light perform one breath cycle in the
30   - //! specified color.
31   - //!
32   - //! It uses this_thread::sleep_for to accomodate for the time an \ref
33   - //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and
34   - //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0
35   - //! to 254, whereas 0 is least saturated (white) and 254 is most saturated
36   - //! (vibrant). \param hue The hue of the color \param sat The saturation of
37   - //! the color \param light A reference of the light
38   - bool alertHueSaturation(uint16_t hue, uint8_t sat,
39   - HueLight &light) const override;
40   - //! \brief Function that lets the light perform one breath cycle in the
41   - //! specified color.
42   - //!
43   - //! It uses this_thread::sleep_for to accomodate for the time an \ref
44   - //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0
45   - //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A
46   - //! reference of the light
47   - bool alertXY(float x, float y, HueLight &light) const override;
48   - //! \brief Function that lets the light perform one breath cycle in the
49   - //! specified color.
50   - //!
51   - //! It uses this_thread::sleep_for to accomodate for the time an \ref
52   - //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255.
53   - //! \param r The red portion of the color
54   - //! \param g The green portion of the color
55   - //! \param b The blue portion of the color
56   - //! \param light A reference of the light
57   - bool alertRGB(uint8_t r, uint8_t g, uint8_t b,
58   - HueLight &light) const override;
  30 + //! \brief Function that lets the light perform one breath cycle in the
  31 + //! specified color.
  32 + //!
  33 + //! It uses this_thread::sleep_for to accomodate for the time an \ref
  34 + //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and
  35 + //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0
  36 + //! to 254, whereas 0 is least saturated (white) and 254 is most saturated
  37 + //! (vibrant). \param hue The hue of the color \param sat The saturation of
  38 + //! the color \param light A reference of the light
  39 + bool alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const override;
  40 + //! \brief Function that lets the light perform one breath cycle in the
  41 + //! specified color.
  42 + //!
  43 + //! It uses this_thread::sleep_for to accomodate for the time an \ref
  44 + //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0
  45 + //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A
  46 + //! reference of the light
  47 + bool alertXY(float x, float y, HueLight& light) const override;
  48 + //! \brief Function that lets the light perform one breath cycle in the
  49 + //! specified color.
  50 + //!
  51 + //! It uses this_thread::sleep_for to accomodate for the time an \ref
  52 + //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255.
  53 + //! \param r The red portion of the color
  54 + //! \param g The green portion of the color
  55 + //! \param b The blue portion of the color
  56 + //! \param light A reference of the light
  57 + bool alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const override;
59 58 };
60 59  
61 60 #endif
... ...
hueplusplus/include/ExtendedColorTemperatureStrategy.h
1 1 /**
2   - \file ExtendedColorTemperatureStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file ExtendedColorTemperatureStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _EXTENDED_COLOR_TEMPERATURE_STRATEGY_H
... ... @@ -24,26 +24,26 @@
24 24 #include "SimpleColorTemperatureStrategy.h"
25 25  
26 26 //! Class implementing the functions of ColorTemperatureStrategy
27   -class ExtendedColorTemperatureStrategy : public SimpleColorTemperatureStrategy {
  27 +class ExtendedColorTemperatureStrategy : public SimpleColorTemperatureStrategy
  28 +{
28 29 public:
29   - //! \brief Function for changing a lights color temperature in mired with a
30   - //! specified transition.
31   - //!
32   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
33   - //! and 500 is warm. \param mired The color temperature in mired \param
34   - //! transition The time it takes to fade to the new color in multiples of
35   - //! 100ms, 4 = 400ms and should be seen as the default \param light A
36   - //! reference of the light
37   - bool setColorTemperature(unsigned int mired, uint8_t transition,
38   - HueLight &light) const override;
39   - //! \brief Function that lets the light perform one breath cycle in the
40   - //! specified color.
41   - //!
42   - //! It uses this_thread::sleep_for to accomodate for the time an \ref
43   - //! HueLight::alert() needs The color temperature in mired ranges from 153 to
44   - //! 500 whereas 153 is cold and 500 is warm. \param mired The color
45   - //! temperature in mired \param light A reference of the light
46   - bool alertTemperature(unsigned int mired, HueLight &light) const override;
  30 + //! \brief Function for changing a lights color temperature in mired with a
  31 + //! specified transition.
  32 + //!
  33 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  34 + //! and 500 is warm. \param mired The color temperature in mired \param
  35 + //! transition The time it takes to fade to the new color in multiples of
  36 + //! 100ms, 4 = 400ms and should be seen as the default \param light A
  37 + //! reference of the light
  38 + bool setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const override;
  39 + //! \brief Function that lets the light perform one breath cycle in the
  40 + //! specified color.
  41 + //!
  42 + //! It uses this_thread::sleep_for to accomodate for the time an \ref
  43 + //! HueLight::alert() needs The color temperature in mired ranges from 153 to
  44 + //! 500 whereas 153 is cold and 500 is warm. \param mired The color
  45 + //! temperature in mired \param light A reference of the light
  46 + bool alertTemperature(unsigned int mired, HueLight& light) const override;
47 47 };
48 48  
49 49 #endif
... ...
hueplusplus/include/Hue.h 100755 → 100644
... ... @@ -41,224 +41,217 @@ class Hue;
41 41 //!
42 42 //! Class to find all Hue bridges on the network and create usernames for them.
43 43 //!
44   -class HueFinder {
  44 +class HueFinder
  45 +{
45 46 public:
46   - struct HueIdentification {
47   - std::string ip;
48   - int port = 80;
49   - std::string mac;
50   - };
  47 + struct HueIdentification
  48 + {
  49 + std::string ip;
  50 + int port = 80;
  51 + std::string mac;
  52 + };
51 53  
52 54 public:
53   - //! \brief Constructor of HueFinder class
54   - //!
55   - //! \param handler HttpHandler of type \ref IHttpHandler for communication
56   - //! with the bridge
57   - HueFinder(std::shared_ptr<const IHttpHandler> handler);
58   -
59   - //! \brief Function that finds all bridges in the network and returns them.
60   - //!
61   - //! The user should be given the opportunity to select the correct one based
62   - //! on the mac address. \return vector containing ip and mac of all found
63   - //! bridges
64   - std::vector<HueIdentification> FindBridges() const;
65   -
66   - //! \brief Function that gets a \ref Hue bridge based on its identification
67   - //!
68   - //! \param identification \ref HueIdentification that specifies a bridge
69   - //! \return \ref Hue class object
70   - Hue GetBridge(const HueIdentification &identification);
71   -
72   - //! \brief Function that adds a username to the \ref usernames map
73   - //!
74   - //! \param mac MAC address of Hue bridge
75   - //! \param username Username that is used to control the Hue bridge
76   - void AddUsername(const std::string &mac, const std::string &username);
77   -
78   - //! \brief Function that returns a map of mac addresses and usernames.
79   - //!
80   - //! Note these should be saved at the end and re-loaded with \ref AddUsername
81   - //! next time, so only one username is generated per bridge. \returns A map
82   - //! mapping mac address to username for every bridge
83   - const std::map<std::string, std::string> &GetAllUsernames() const;
  55 + //! \brief Constructor of HueFinder class
  56 + //!
  57 + //! \param handler HttpHandler of type \ref IHttpHandler for communication
  58 + //! with the bridge
  59 + HueFinder(std::shared_ptr<const IHttpHandler> handler);
  60 +
  61 + //! \brief Function that finds all bridges in the network and returns them.
  62 + //!
  63 + //! The user should be given the opportunity to select the correct one based
  64 + //! on the mac address. \return vector containing ip and mac of all found
  65 + //! bridges
  66 + std::vector<HueIdentification> FindBridges() const;
  67 +
  68 + //! \brief Function that gets a \ref Hue bridge based on its identification
  69 + //!
  70 + //! \param identification \ref HueIdentification that specifies a bridge
  71 + //! \return \ref Hue class object
  72 + Hue GetBridge(const HueIdentification& identification);
  73 +
  74 + //! \brief Function that adds a username to the \ref usernames map
  75 + //!
  76 + //! \param mac MAC address of Hue bridge
  77 + //! \param username Username that is used to control the Hue bridge
  78 + void AddUsername(const std::string& mac, const std::string& username);
  79 +
  80 + //! \brief Function that returns a map of mac addresses and usernames.
  81 + //!
  82 + //! Note these should be saved at the end and re-loaded with \ref AddUsername
  83 + //! next time, so only one username is generated per bridge. \returns A map
  84 + //! mapping mac address to username for every bridge
  85 + const std::map<std::string, std::string>& GetAllUsernames() const;
84 86  
85 87 private:
86   - //! \brief Normalizes mac address to plain hex number.
87   - //! \returns \p input without separators and whitespace, in upper case.
88   - static std::string NormalizeMac(std::string input);
89   -
90   - //! \brief Parses mac address from description.xml
91   - //!
92   - //! \param description Content of description.xml file as returned by GET
93   - //! request. \returns Content of xml element \c serialNumber if description
94   - //! matches a Hue bridge, otherwise an empty string.
95   - static std::string ParseDescription(const std::string &description);
96   -
97   - std::map<std::string, std::string>
98   - usernames; //!< Maps all macs to usernames added by \ref
99   - //!< HueFinder::AddUsername
100   - std::shared_ptr<const IHttpHandler> http_handler;
  88 + //! \brief Normalizes mac address to plain hex number.
  89 + //! \returns \p input without separators and whitespace, in upper case.
  90 + static std::string NormalizeMac(std::string input);
  91 +
  92 + //! \brief Parses mac address from description.xml
  93 + //!
  94 + //! \param description Content of description.xml file as returned by GET
  95 + //! request. \returns Content of xml element \c serialNumber if description
  96 + //! matches a Hue bridge, otherwise an empty string.
  97 + static std::string ParseDescription(const std::string& description);
  98 +
  99 + std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref
  100 + //!< HueFinder::AddUsername
  101 + std::shared_ptr<const IHttpHandler> http_handler;
101 102 };
102 103  
103 104 //! Hue class
104   -class Hue {
105   - friend class HueFinder;
  105 +class Hue
  106 +{
  107 + friend class HueFinder;
106 108  
107 109 public:
108   - //! \brief Constructor of Hue class
109   - //!
110   - //! \param ip String that specifies the ip address of the Hue bridge in dotted
111   - //! decimal notation like "192.168.2.1" \param port Port of the hue bridge
112   - //! \param username String that specifies the username that is used to control
113   - //! the bridge. This needs to be acquired in \ref requestUsername \param handler
114   - //! HttpHandler of type \ref IHttpHandler for communication with the bridge
115   - Hue(const std::string &ip, const int port, const std::string &username,
  110 + //! \brief Constructor of Hue class
  111 + //!
  112 + //! decimal notation like "192.168.2.1" \param port Port of the hue bridge
  113 + //! \param username String that specifies the username that is used to control
  114 + //! the bridge. This needs to be acquired in \ref requestUsername \param handler
  115 + //! HttpHandler of type \ref IHttpHandler for communication with the bridge
  116 + Hue(const std::string& ip, const int port, const std::string& username,
116 117 std::shared_ptr<const IHttpHandler> handler);
117 118  
118   - //! \brief Function to get the ip address of the hue bridge
119   - //!
120   - //! \return string containing ip
121   - std::string getBridgeIP();
122   -
123   - //! \brief Function to get the port of the hue bridge
124   - //!
125   - //! \return integer containing port
126   - int getBridgePort();
127   -
128   - //! \brief Function that sends a username request to the Hue bridge.
129   - //!
130   - //! It does that for about 30 seconds and you have 5 seconds to prepare
131   - //! It automatically sets the \ref username variable according to the username
132   - //! received and returns the username received This function should only be
133   - //! called once to acquire a username to control the bridge and the username
134   - //! should be saved for future use \param ip String that specifies the ip (in
135   - //! dotted decimal notation like "192.168.2.1") the request is send to \return
136   - //! String containing username
137   - std::string requestUsername(const std::string &ip);
138   -
139   - //! \brief Function that returns the \ref username
140   - //!
141   - //! \return String containing \ref username
142   - std::string getUsername();
143   -
144   - //! \brief Function to set the ip address of this class representing a bridge
145   - //!
146   - //! \param ip String that specifies the ip in dotted decimal notation like
147   - //! "192.168.2.1"
148   - void setIP(const std::string &ip);
149   -
150   - //! \brief Function to set the port of this class representing a bridge
151   - //!
152   - //! \param port Integer that specifies the port of an address like
153   - //! "192.168.2.1:8080"
154   - void setPort(const int port);
155   -
156   - //! \brief Function that returns a \ref Hue::HueLight of specified id
157   - //!
158   - //! \param id Integer that specifies the ID of a Hue light
159   - //! \return \ref HueLight that can be controlled
160   - HueLight &getLight(int id);
161   -
162   - //! \brief Function to remove a light from the bridge
163   - //!
164   - //! \attention Any use of the light after it was successfully removed results
165   - //! in undefined behavior \param id Id of the light to remove \return Bool
166   - //! that is true on success
167   - bool removeLight(int id);
168   -
169   - //! \brief Function that returns all light types that are associated with this
170   - //! bridge
171   - //!
172   - //! \return A map mapping light id's to light types for every light
173   - // const std::map<uint8_t, ColorType>& getAllLightTypes();
174   -
175   - //! \brief Function that returns all lights that are associated with this
176   - //! bridge
177   - //!
178   - //! \return A vector containing references to every HueLight
179   - std::vector<std::reference_wrapper<HueLight>> getAllLights();
180   -
181   - //! \brief Function that tells whether a given light id represents an existing
182   - //! light
183   - //!
184   - //! Calls refreshState to update the local bridge state
185   - //! \param id Id of a light to check for existance
186   - //! \return Bool that is true when a light with the given id exists and false
187   - //! when not
188   - bool lightExists(int id);
189   -
190   - //! \brief Const function that tells whether a given light id represents an
191   - //! existing light
192   - //!
193   - //! \note This will not update the local state of the bridge
194   - //! \param id Id of a light to check for existance
195   - //! \return Bool that is true when a light with the given id exists and false
196   - //! when not
197   - bool lightExists(int id) const;
198   -
199   - //! \brief Const function that returns the picture name of a given light id
200   - //!
201   - //! \note This will not update the local state of the bridge.
202   - //! \note This function will only return the filename without extension,
203   - //! because Philips provides different file types. \param id Id of a light to
204   - //! get the picture of \return String that either contains the filename of the
205   - //! picture of the light or if it was not found an empty string
206   - std::string getPictureOfLight(int id) const;
207   -
208   - //! \brief Const function that returns the picture name of a given model id
209   - //!
210   - //! \note This will not update the local state of the bridge.
211   - //! \note This function will only return the filename without extension,
212   - //! because Philips provides different file types. \param model_id Model Id of
213   - //! a device to get the picture of \return String that either contains the
214   - //! filename of the picture of the device or if it was not found an empty
215   - //! string
216   - std::string getPictureOfModel(const std::string &model_id) const;
217   -
218   - //! \brief Function that sets the HttpHandler and updates the HueCommandAPI.
219   - //!
220   - //! The HttpHandler and HueCommandAPI are used for bridge communication
221   - //! \param handler a HttpHandler of type \ref IHttpHandler
222   - void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) {
223   - http_handler = std::move(handler);
224   - commands = HueCommandAPI(ip, port, username, http_handler);
225   - };
  119 + //! \brief Function to get the ip address of the hue bridge
  120 + //!
  121 + //! \return string containing ip
  122 + std::string getBridgeIP();
  123 +
  124 + //! \brief Function to get the port of the hue bridge
  125 + //!
  126 + //! \return integer containing port
  127 + int getBridgePort();
  128 +
  129 + //! \brief Function that sends a username request to the Hue bridge.
  130 + //!
  131 + //! It does that for about 30 seconds and you have 5 seconds to prepare
  132 + //! It automatically sets the \ref username variable according to the username
  133 + //! received and returns the username received This function should only be
  134 + //! called once to acquire a username to control the bridge and the username
  135 + //! should be saved for future use \param ip String that specifies the ip (in
  136 + //! dotted decimal notation like "192.168.2.1") the request is send to \return
  137 + //! String containing username
  138 + std::string requestUsername(const std::string& ip);
  139 +
  140 + //! \brief Function that returns the \ref username
  141 + //!
  142 + //! \return String containing \ref username
  143 + std::string getUsername();
  144 +
  145 + //! \brief Function to set the ip address of this class representing a bridge
  146 + //!
  147 + //! \param ip String that specifies the ip in dotted decimal notation like
  148 + //! "192.168.2.1"
  149 + void setIP(const std::string& ip);
  150 +
  151 + //! \brief Function to set the port of this class representing a bridge
  152 + //!
  153 + //! \param port Integer that specifies the port of an address like
  154 + //! "192.168.2.1:8080"
  155 + void setPort(const int port);
  156 +
  157 + //! \brief Function that returns a \ref Hue::HueLight of specified id
  158 + //!
  159 + //! \param id Integer that specifies the ID of a Hue light
  160 + //! \return \ref HueLight that can be controlled
  161 + HueLight& getLight(int id);
  162 +
  163 + //! \brief Function to remove a light from the bridge
  164 + //!
  165 + //! \attention Any use of the light after it was successfully removed results
  166 + //! in undefined behavior \param id Id of the light to remove \return Bool
  167 + //! that is true on success
  168 + bool removeLight(int id);
  169 +
  170 + //! \brief Function that returns all light types that are associated with this
  171 + //! bridge
  172 + //!
  173 + //! \return A map mapping light id's to light types for every light
  174 + // const std::map<uint8_t, ColorType>& getAllLightTypes();
  175 +
  176 + //! \brief Function that returns all lights that are associated with this
  177 + //! bridge
  178 + //!
  179 + //! \return A vector containing references to every HueLight
  180 + std::vector<std::reference_wrapper<HueLight>> getAllLights();
  181 +
  182 + //! \brief Function that tells whether a given light id represents an existing
  183 + //! light
  184 + //!
  185 + //! Calls refreshState to update the local bridge state
  186 + //! \param id Id of a light to check for existance
  187 + //! \return Bool that is true when a light with the given id exists and false
  188 + //! when not
  189 + bool lightExists(int id);
  190 +
  191 + //! \brief Const function that tells whether a given light id represents an
  192 + //! existing light
  193 + //!
  194 + //! \note This will not update the local state of the bridge
  195 + //! \param id Id of a light to check for existance
  196 + //! \return Bool that is true when a light with the given id exists and false
  197 + //! when not
  198 + bool lightExists(int id) const;
  199 +
  200 + //! \brief Const function that returns the picture name of a given light id
  201 + //!
  202 + //! \note This will not update the local state of the bridge.
  203 + //! \note This function will only return the filename without extension,
  204 + //! because Philips provides different file types. \param id Id of a light to
  205 + //! get the picture of \return String that either contains the filename of the
  206 + //! picture of the light or if it was not found an empty string
  207 + std::string getPictureOfLight(int id) const;
  208 +
  209 + //! \brief Const function that returns the picture name of a given model id
  210 + //!
  211 + //! \note This will not update the local state of the bridge.
  212 + //! \note This function will only return the filename without extension,
  213 + //! because Philips provides different file types. \param model_id Model Id of
  214 + //! a device to get the picture of \return String that either contains the
  215 + //! filename of the picture of the device or if it was not found an empty
  216 + //! string
  217 + std::string getPictureOfModel(const std::string& model_id) const;
  218 +
  219 + //! \brief Function that sets the HttpHandler and updates the HueCommandAPI.
  220 + //!
  221 + //! The HttpHandler and HueCommandAPI are used for bridge communication
  222 + //! \param handler a HttpHandler of type \ref IHttpHandler
  223 + void setHttpHandler(std::shared_ptr<const IHttpHandler> handler)
  224 + {
  225 + http_handler = std::move(handler);
  226 + commands = HueCommandAPI(ip, port, username, http_handler);
  227 + };
226 228  
227 229 private:
228   - //! \brief Function that refreshes the local \ref state of the Hue bridge
229   - void refreshState();
  230 + //! \brief Function that refreshes the local \ref state of the Hue bridge
  231 + void refreshState();
230 232  
231 233 private:
232   - std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation
233   - //!< like "192.168.2.1"
234   - int port;
235   - std::string username; //!< Username that is ussed to access the hue bridge
236   - nlohmann::json
237   - state; //!< The state of the hue bridge as it is returned from it
238   - std::map<uint8_t, HueLight>
239   - lights; //!< Maps ids to HueLights that are controlled by this bridge
240   -
241   - std::shared_ptr<BrightnessStrategy>
242   - simpleBrightnessStrategy; //!< Strategy that is used for controlling the
243   - //!< brightness of lights
244   - std::shared_ptr<ColorHueStrategy>
245   - simpleColorHueStrategy; //!< Strategy that is used for controlling the
246   - //!< color of lights
247   - std::shared_ptr<ColorHueStrategy>
248   - extendedColorHueStrategy; //!< Strategy that is used for controlling the
249   - //!< color of lights
250   - std::shared_ptr<ColorTemperatureStrategy>
251   - simpleColorTemperatureStrategy; //!< Strategy that is used for controlling
252   - //!< the color temperature of lights
253   - std::shared_ptr<ColorTemperatureStrategy>
254   - extendedColorTemperatureStrategy; //!< Strategy that is used for
255   - //!< controlling the color temperature
256   - //!< of lights
257   - std::shared_ptr<const IHttpHandler>
258   - http_handler; //!< A IHttpHandler that is used to communicate with the
259   - //!< bridge
260   - HueCommandAPI
261   - commands; //!< A HueCommandAPI that is used to communicate with the bridge
  234 + std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation
  235 + //!< like "192.168.2.1"
  236 + std::string username; //!< Username that is ussed to access the hue bridge
  237 + int port;
  238 + nlohmann::json state; //!< The state of the hue bridge as it is returned from it
  239 + std::map<uint8_t, HueLight> lights; //!< Maps ids to HueLights that are controlled by this bridge
  240 +
  241 + std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the
  242 + //!< brightness of lights
  243 + std::shared_ptr<ColorHueStrategy> simpleColorHueStrategy; //!< Strategy that is used for controlling the
  244 + //!< color of lights
  245 + std::shared_ptr<ColorHueStrategy> extendedColorHueStrategy; //!< Strategy that is used for controlling the
  246 + //!< color of lights
  247 + std::shared_ptr<ColorTemperatureStrategy> simpleColorTemperatureStrategy; //!< Strategy that is used for controlling
  248 + //!< the color temperature of lights
  249 + std::shared_ptr<ColorTemperatureStrategy> extendedColorTemperatureStrategy; //!< Strategy that is used for
  250 + //!< controlling the color temperature
  251 + //!< of lights
  252 + std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the
  253 + //!< bridge
  254 + HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge
262 255 };
263 256  
264 257 #endif
... ...
hueplusplus/include/HueCommandAPI.h 100755 → 100644
... ... @@ -28,83 +28,81 @@
28 28  
29 29 //! Handles communication to the bridge via IHttpHandler and enforces a timeout
30 30 //! between each request
31   -class HueCommandAPI {
  31 +class HueCommandAPI
  32 +{
32 33 public:
33   - //! \brief Construct from ip, username and HttpHandler
34   - //!
35   - //! \param ip String that specifies the ip address of the Hue bridge in dotted
36   - //! decimal notation like "192.168.2.1" \param port of the hue bridge
37   - //! \param username String that specifies the username that is used to control
38   - //! the bridge \param handler HttpHandler of type \ref IHttpHandler for
39   - //! communication with the bridge
40   - HueCommandAPI(const std::string &ip, const int port, const std::string &username,
41   - std::shared_ptr<const IHttpHandler> httpHandler);
  34 + //! \brief Construct from ip, username and HttpHandler
  35 + //!
  36 + //! \param ip String that specifies the ip address of the Hue bridge in dotted
  37 + //! decimal notation like "192.168.2.1" \param port of the hue bridge
  38 + //! \param username String that specifies the username that is used to control
  39 + //! the bridge \param handler HttpHandler of type \ref IHttpHandler for
  40 + //! communication with the bridge
  41 + HueCommandAPI(const std::string &ip, const int port, const std::string &username,
  42 + std::shared_ptr<const IHttpHandler> httpHandler);
42 43  
43   - //! \brief Copy construct from other HueCommandAPI
44   - //! \note All copies refer to the same timeout data, so even calls from
45   - //! different objects will be delayed
46   - HueCommandAPI(const HueCommandAPI &) = default;
47   - //! \brief Move construct from other HueCommandAPI
48   - //! \note All copies refer to the same timeout data, so even calls from
49   - //! different objects will be delayed
50   - HueCommandAPI(HueCommandAPI &&) = default;
  44 + //! \brief Copy construct from other HueCommandAPI
  45 + //! \note All copies refer to the same timeout data, so even calls from
  46 + //! different objects will be delayed
  47 + HueCommandAPI(const HueCommandAPI&) = default;
  48 + //! \brief Move construct from other HueCommandAPI
  49 + //! \note All copies refer to the same timeout data, so even calls from
  50 + //! different objects will be delayed
  51 + HueCommandAPI(HueCommandAPI&&) = default;
51 52  
52   - //! \brief Copy assign from other HueCommandAPI
53   - //! \note All copies refer to the same timeout data, so even calls from
54   - //! different objects will be delayed
55   - HueCommandAPI &operator=(const HueCommandAPI &) = default;
56   - //! \brief Move assign from other HueCommandAPI
57   - //! \note All copies refer to the same timeout data, so even calls from
58   - //! different objects will be delayed
59   - HueCommandAPI &operator=(HueCommandAPI &&) = default;
  53 + //! \brief Copy assign from other HueCommandAPI
  54 + //! \note All copies refer to the same timeout data, so even calls from
  55 + //! different objects will be delayed
  56 + HueCommandAPI& operator=(const HueCommandAPI&) = default;
  57 + //! \brief Move assign from other HueCommandAPI
  58 + //! \note All copies refer to the same timeout data, so even calls from
  59 + //! different objects will be delayed
  60 + HueCommandAPI& operator=(HueCommandAPI&&) = default;
60 61  
61   - //! \brief Sends a HTTP PUT request via the \ref httpHandler to the bridge and
62   - //! returns the response
63   - //!
64   - //! This function will block until at least \ref minDelay has passed to any
65   - //! previous request \param path String that contains the request path
66   - //! (appended after /api/<username>) \param request Json value containing the
67   - //! request. May be empty \returns The return value of the underlying \ref
68   - //! IHttpHandler::PUTJson call
69   - nlohmann::json PUTRequest(const std::string &path,
70   - const nlohmann::json &request) const;
  62 + //! \brief Sends a HTTP PUT request via the \ref httpHandler to the bridge and
  63 + //! returns the response
  64 + //!
  65 + //! This function will block until at least \ref minDelay has passed to any
  66 + //! previous request \param path String that contains the request path
  67 + //! (appended after /api/<username>) \param request Json value containing the
  68 + //! request. May be empty \returns The return value of the underlying \ref
  69 + //! IHttpHandler::PUTJson call
  70 + nlohmann::json PUTRequest(const std::string& path, const nlohmann::json& request) const;
71 71  
72   - //! \brief Sends a HTTP GET request via the \ref httpHandler to the bridge and
73   - //! returns the response
74   - //!
75   - //! This function will block until at least \ref minDelay has passed to any
76   - //! previous request \param path String that contains the request path
77   - //! (appended after /api/<username>) \param request Json value containing the
78   - //! request. May be empty \returns The return value of the underlying \ref
79   - //! IHttpHandler::GETJson call
80   - nlohmann::json GETRequest(const std::string &path,
81   - const nlohmann::json &request) const;
  72 + //! \brief Sends a HTTP GET request via the \ref httpHandler to the bridge and
  73 + //! returns the response
  74 + //!
  75 + //! This function will block until at least \ref minDelay has passed to any
  76 + //! previous request \param path String that contains the request path
  77 + //! (appended after /api/<username>) \param request Json value containing the
  78 + //! request. May be empty \returns The return value of the underlying \ref
  79 + //! IHttpHandler::GETJson call
  80 + nlohmann::json GETRequest(const std::string& path, const nlohmann::json& request) const;
82 81  
83   - //! \brief Sends a HTTP DELETE request via the \ref httpHandler to the bridge
84   - //! and returns the response
85   - //!
86   - //! This function will block until at least \ref minDelay has passed to any
87   - //! previous request \param path String that contains the request path
88   - //! (appended after /api/<username>) \param request Json value containing the
89   - //! request. May be empty \returns The return value of the underlying \ref
90   - //! IHttpHandler::DELETEJson call
91   - nlohmann::json DELETERequest(const std::string &path,
92   - const nlohmann::json &request) const;
  82 + //! \brief Sends a HTTP DELETE request via the \ref httpHandler to the bridge
  83 + //! and returns the response
  84 + //!
  85 + //! This function will block until at least \ref minDelay has passed to any
  86 + //! previous request \param path String that contains the request path
  87 + //! (appended after /api/<username>) \param request Json value containing the
  88 + //! request. May be empty \returns The return value of the underlying \ref
  89 + //! IHttpHandler::DELETEJson call
  90 + nlohmann::json DELETERequest(const std::string& path, const nlohmann::json& request) const;
93 91  
94 92 private:
95   - struct TimeoutData {
96   - std::chrono::steady_clock::time_point timeout;
97   - std::mutex mutex;
98   - };
  93 + struct TimeoutData
  94 + {
  95 + std::chrono::steady_clock::time_point timeout;
  96 + std::mutex mutex;
  97 + };
99 98  
100 99 private:
101   - static constexpr std::chrono::steady_clock::duration minDelay =
102   - std::chrono::milliseconds(100);
103   - std::string ip;
104   - int port;
105   - std::string username;
106   - std::shared_ptr<const IHttpHandler> httpHandler;
107   - std::shared_ptr<TimeoutData> timeout;
  100 + static constexpr std::chrono::steady_clock::duration minDelay = std::chrono::milliseconds(100);
  101 + std::string ip;
  102 + int port;
  103 + std::string username;
  104 + std::shared_ptr<const IHttpHandler> httpHandler;
  105 + std::shared_ptr<TimeoutData> timeout;
108 106 };
109 107  
110 108 #endif
111 109 \ No newline at end of file
... ...
hueplusplus/include/HueConfig.h
1 1 /**
2   - \file HueConfig.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file HueConfig.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _HUE_CONFIG_H
21 21 #define _HUE_CONFIG_H
22 22  
23   -const uint16_t c_PRE_ALERT_DELAY =
24   - 120; //!< Delay for advanced alerts before the actual alert
25   -const uint16_t c_POST_ALERT_DELAY =
26   - 1600; //!< Delay for advanced alerts after the actual alert
  23 +const uint16_t c_PRE_ALERT_DELAY = 120; //!< Delay for advanced alerts before the actual alert
  24 +const uint16_t c_POST_ALERT_DELAY = 1600; //!< Delay for advanced alerts after the actual alert
27 25  
28 26 #endif
... ...
hueplusplus/include/HueLight.h
1 1 /**
2   - \file HueLight.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
6   -
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  2 + \file HueLight.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _HUE_LIGHT_H
... ... @@ -48,10 +48,9 @@ LST002, // Hue LightStrips Plus, Color Gamut C, ECL
48 48 LLC010, // Hue Living Colors Iris, Color Gamut A, CL
49 49 LLC011, // Hue Living Colors Bloom, Color Gamut A, CL
50 50 LLC012, // Hue Living Colors Bloom, Color Gamut A, CL
51   -LLC006, // Living Colors Gen3 Iris, Color Gamut A, CL,
52   -NO HUE FRIEND
53   -LLC007, // Living Colors Gen3 Bloom, Aura, Color Gamut A, CL,
54   -NO HUE FRIEND LLC013, // Disney Living Colors, Color Gamut A, CL
  51 +LLC006, // Living Colors Gen3 Iris, Color Gamut A, CL, NO HUE FRIEND
  52 +LLC007, // Living Colors Gen3 Bloom, Aura, Color Gamut A, CL, NO HUE FRIEND
  53 +LLC013, // Disney Living Colors, Color Gamut A, CL
55 54  
56 55 LWB004, // Hue A19 Lux, Color Gamut -, DL
57 56 LWB006, // Hue A19 Lux, Color Gamut -, DL
... ... @@ -73,576 +72,601 @@ LLC020 // Hue Go, Color Gamut C, ECL
73 72 };*/
74 73  
75 74 //! enum that specifies the color type of all HueLights
76   -enum ColorType {
77   - UNDEFINED, //!< ColorType for this light is unknown or undefined
78   - NONE, //!< light has no specific ColorType
79   - GAMUT_A,
80   - GAMUT_B,
81   - GAMUT_C,
82   - TEMPERATURE,
83   - GAMUT_A_TEMPERATURE,
84   - GAMUT_B_TEMPERATURE,
85   - GAMUT_C_TEMPERATURE
  75 +enum ColorType
  76 +{
  77 + UNDEFINED, //!< ColorType for this light is unknown or undefined
  78 + NONE, //!< light has no specific ColorType
  79 + GAMUT_A,
  80 + GAMUT_B,
  81 + GAMUT_C,
  82 + TEMPERATURE,
  83 + GAMUT_A_TEMPERATURE,
  84 + GAMUT_B_TEMPERATURE,
  85 + GAMUT_C_TEMPERATURE
86 86 };
87 87  
88 88 //!
89 89 //! Class for Hue Light fixtures
90 90 //!
91   -class HueLight {
92   - friend class Hue;
93   - friend class SimpleBrightnessStrategy;
94   - friend class SimpleColorHueStrategy;
95   - friend class ExtendedColorHueStrategy;
96   - friend class SimpleColorTemperatureStrategy;
97   - friend class ExtendedColorTemperatureStrategy;
  91 +class HueLight
  92 +{
  93 + friend class Hue;
  94 + friend class SimpleBrightnessStrategy;
  95 + friend class SimpleColorHueStrategy;
  96 + friend class ExtendedColorHueStrategy;
  97 + friend class SimpleColorTemperatureStrategy;
  98 + friend class ExtendedColorTemperatureStrategy;
98 99  
99 100 public:
100   - //! \brief std dtor
101   - ~HueLight() = default;
102   -
103   - //! \brief Function that turns the light on.
104   - //!
105   - //! \param transition Optional parameter to set the transition from current
106   - //! state to new, standard is 4 = 400ms \return Bool that is true on success
107   - virtual bool On(uint8_t transition = 4);
108   -
109   - //! \brief Function that turns the light off.
110   - //!
111   - //! \param transition Optional parameter to set the transition from current
112   - //! state to new, standard is 4 = 400ms \return Bool that is true on success
113   - virtual bool Off(uint8_t transition = 4);
114   -
115   - //! \brief Function to check whether a light is on or off
116   - //!
117   - //! \return Bool that is true, when the light is on and false, when off
118   - virtual bool isOn();
119   -
120   - //! \brief Const function to check whether a light is on or off
121   - //!
122   - //! \note This will not refresh the light state
123   - //! \return Bool that is true, when the light is on and false, when off
124   - virtual bool isOn() const;
125   -
126   - //! \brief Const function that returns the id of this light
127   - //!
128   - //! \return integer representing the light id
129   - virtual int getId() const;
130   -
131   - //! \brief Const function that returns the light type
132   - //!
133   - //! \return String containing the type
134   - virtual std::string getType() const;
135   -
136   - //! \brief Function that returns the name of the light.
137   - //!
138   - //! \return String containig the name of the light
139   - virtual std::string getName();
140   -
141   - //! \brief Const function that returns the name of the light.
142   - //!
143   - //! \note This will not refresh the light state
144   - //! \return String containig the name of the light
145   - virtual std::string getName() const;
146   -
147   - //! \brief Const function that returns the modelid of the light
148   - //!
149   - //! \return String conatining the modelid
150   - virtual std::string getModelId() const;
151   -
152   - //! \brief Const function that returns the uniqueid of the light
153   - //!
154   - //! \note Only working on bridges with versions starting at 1.4
155   - //! \return String containing the uniqueid or an empty string when the
156   - //! function is not supported
157   - virtual std::string getUId() const;
158   -
159   - //! \brief Const function that returns the manufacturername of the light
160   - //!
161   - //! \note Only working on bridges with versions starting at 1.7
162   - //! \return String containing the manufacturername or an empty string when the
163   - //! function is not supported
164   - virtual std::string getManufacturername() const;
165   -
166   - //! \brief Const function that returns the productname of the light
167   - //!
168   - //! \note Only working on bridges with versions starting at 1.24
169   - //! \return String containing the productname or an empty string when the
170   - //! function is not supported
171   - virtual std::string getProductname() const;
172   -
173   - //! \brief Const function that returns the luminaireuniqueid of the light
174   - //!
175   - //! \note Only working on bridges with versions starting at 1.9
176   - //! \return String containing the luminaireuniqueid or an empty string when
177   - //! the function is not supported
178   - virtual std::string getLuminaireUId() const;
179   -
180   - //! \brief Function that returns the software version of the light
181   - //!
182   - //! \return String containing the software version
183   - virtual std::string getSwVersion();
184   -
185   - //! \brief Const function that returns the software version of the light
186   - //!
187   - //! \note This will not refresh the light state
188   - //! \return String containing the software version
189   - virtual std::string getSwVersion() const;
190   -
191   - //! \brief Function that sets the name of the light
192   - //!
193   - //! \return Bool that is true on success
194   - virtual bool setName(const std::string &name);
195   -
196   - //! \brief Const function that returns the color type of the light.
197   - //!
198   - //! \return ColorType containig the color type of the light
199   - virtual ColorType getColorType() const;
200   -
201   - //! \brief Const function to check whether this light has brightness control
202   - //!
203   - //! \return Bool that is true when the light has specified abilities and false
204   - //! when not
205   - virtual bool hasBrightnessControl() const {
206   - return brightnessStrategy != nullptr;
207   - };
208   -
209   - //! \brief Const function to check whether this light has color temperature
210   - //! control
211   - //!
212   - //! \return Bool that is true when the light has specified abilities and false
213   - //! when not
214   - virtual bool hasTemperatureControl() const {
215   - return colorTemperatureStrategy != nullptr;
216   - };
217   -
218   - //! \brief Connst function to check whether this light has full color control
219   - //!
220   - //! \return Bool that is true when the light has specified abilities and false
221   - //! when not
222   - virtual bool hasColorControl() const { return colorHueStrategy != nullptr; };
223   -
224   - //! \brief Const function that converts Kelvin to Mired.
225   - //!
226   - //! \param kelvin Unsigned integer value in Kelvin
227   - //! \return Unsigned integer value in Mired
228   - unsigned int KelvinToMired(unsigned int kelvin) const;
229   -
230   - //! \brief Const function that converts Mired to Kelvin.
231   - //!
232   - //! \param mired Unsigned integer value in Mired
233   - //! \return Unsigned integer value in Kelvin
234   - unsigned int MiredToKelvin(unsigned int mired) const;
235   -
236   - //! \brief Function that sets the brightness of this light.
237   - //!
238   - //! \note The brightness will only be set if the light has a reference to a
239   - //! specific \ref BrightnessStrategy. The brightness can range from 0 = off to
240   - //! 254 = fully lit. \param bri Unsigned int that specifies the brightness
241   - //! \param transition Optional parameter to set the transition from current
242   - //! state to new, standard is 4 = 400ms \return Bool that is true on success
243   - virtual bool setBrightness(unsigned int bri, uint8_t transition = 4) {
244   - if (brightnessStrategy) {
245   - return brightnessStrategy->setBrightness(bri, transition, *this);
246   - }
247   - return false;
248   - };
249   -
250   - //! \brief Const function that returns the brightness of this light.
251   - //!
252   - //! \note The brightness will only be returned if the light has a reference to
253   - //! a specific \ref BrightnessStrategy. \note This will not refresh the light
254   - //! state The brightness can range from 0 = off to 254 = fully lit. \return
255   - //! Unsigned int that is 0 when function failed
256   - virtual unsigned int getBrightness() const {
257   - if (brightnessStrategy) {
258   - return brightnessStrategy->getBrightness(*this);
259   - }
260   - return 0;
261   - };
262   -
263   - //! \brief Function that returns the brightness of this light.
264   - //!
265   - //! \note The brightness will only be returned if the light has a reference to
266   - //! a specific \ref BrightnessStrategy. The brightness can range from 0 = off
267   - //! to 254 = fully lit. \return Unsigned int that is 0 when function failed
268   - virtual unsigned int getBrightness() {
269   - if (brightnessStrategy) {
270   - return brightnessStrategy->getBrightness(*this);
271   - }
272   - return 0;
273   - };
274   -
275   - //! \brief Fucntion that sets the color temperature of this light in mired.
276   - //!
277   - //! \note The color temperature will only be set if the light has a reference
278   - //! to a specific \ref ColorTemperatureStrategy. The color temperature can
279   - //! range from 153 to 500. \param mired Unsigned int that specifies the color
280   - //! temperature in Mired \param transition Optional parameter to set the
281   - //! transition from current state to new, standard is 4 = 400ms \return Bool
282   - //! that is true on success
283   - virtual bool setColorTemperature(unsigned int mired, uint8_t transition = 4) {
284   - if (colorTemperatureStrategy) {
285   - return colorTemperatureStrategy->setColorTemperature(mired, transition,
286   - *this);
287   - }
288   - return false;
289   - };
290   -
291   - //! \brief Const function that returns the current color temperature of the
292   - //! light
293   - //!
294   - //! \note The color temperature will only be returned when the light has a
295   - //! reference to a specific \ref ColorTemperatureStrategy. \note This will not
296   - //! refresh the light state
297   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
298   - //! and 500 is warm. \param light A reference of the light \return Unsigned
299   - //! int representing the color temperature in mired or 0 when failed
300   - virtual unsigned int getColorTemperature() const {
301   - if (colorTemperatureStrategy) {
302   - return colorTemperatureStrategy->getColorTemperature(*this);
303   - }
304   - return 0;
305   - };
306   -
307   - //! \brief Function that returns the current color temperature of the light
308   - //!
309   - //! \note The color temperature will only be returned when the light has a
310   - //! reference to a specific \ref ColorTemperatureStrategy.
311   - //! Updates the lights state by calling refreshState()
312   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
313   - //! and 500 is warm. \param light A reference of the light \return Unsigned
314   - //! int representing the color temperature in mired or 0 when failed
315   - virtual unsigned int getColorTemperature() {
316   - if (colorTemperatureStrategy) {
317   - return colorTemperatureStrategy->getColorTemperature(*this);
318   - }
319   - return 0;
320   - };
321   -
322   - //! \brief Function to set the color of this light with specified hue.
323   - //!
324   - //! \note The color will only be set if the light has a reference to a
325   - //! specific \ref ColorHueStrategy. The hue can range from 0 to 65535, whereas
326   - //! 65535 and 0 are red, 25500 is green and 46920 is blue. \param hue uint16_t
327   - //! that specifies the hue \param transition Optional parameter to set the
328   - //! transition from current state to new, standard is 4 = 400ms \return Bool
329   - //! that is true on success
330   - virtual bool setColorHue(uint16_t hue, uint8_t transition = 4) {
331   - if (colorHueStrategy) {
332   - return colorHueStrategy->setColorHue(hue, transition, *this);
333   - }
334   - return false;
335   - };
336   -
337   - //! \brief Function to set the color of this light with specified saturation.
338   - //!
339   - //! \note The color will only be set if the light has a reference to a
340   - //! specific \ref ColorHueStrategy. The saturation can range from 0 to 254,
341   - //! whereas 0 is least saturated (white) and 254 is most saturated. \param sat
342   - //! uint8_t that specifies the saturation \param transition Optional parameter
343   - //! to set the transition from current state to new, standard is 4 = 400ms
344   - //! \return Bool that is true on success
345   - virtual bool setColorSaturation(uint8_t sat, uint8_t transition = 4) {
346   - if (colorHueStrategy) {
347   - return colorHueStrategy->setColorSaturation(sat, transition, *this);
348   - }
349   - return false;
350   - };
351   -
352   - //! \brief Function to set the color of this light with specified hue and
353   - //! saturation.
354   - //!
355   - //! \note The color will only be set if the light has a reference to a
356   - //! specific \ref ColorHueStrategy. \param hue uint16_t that specifies the hue
357   - //! \param sat uint8_t that specifies the saturation
358   - //! \param transition Optional parameter to set the transition from current
359   - //! state to new, standard is 4 = 400ms. \return Bool that is true on success
360   - virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat,
361   - uint8_t transition = 4) {
362   - if (colorHueStrategy) {
363   - return colorHueStrategy->setColorHueSaturation(hue, sat, transition,
364   - *this);
365   - }
366   - return false;
367   - };
368   -
369   - //! \brief Const function that returns the current color of the light as hue
370   - //! and saturation
371   - //!
372   - //! \note The color hue and saturation will only be returned when the light
373   - //! has a reference to a specific \ref ColorHueStrategy.
374   - //! \note This will not refresh the light state
375   - //! \param light A reference of the light
376   - //! \return Pair containing the hue as first value and saturation as second
377   - //! value or an empty one when failed
378   - virtual std::pair<uint16_t, uint8_t> getColorHueSaturation() const {
379   - if (colorHueStrategy) {
380   - return colorHueStrategy->getColorHueSaturation(*this);
381   - }
382   - return {};
383   - };
384   -
385   - //! \brief Function that returns the current color of the light as hue and
386   - //! saturation
387   - //!
388   - //! \note The color hue and saturation will only be returned when the light
389   - //! has a reference to a specific \ref ColorHueStrategy. Updates the lights
390   - //! state by calling refreshState()
391   - //! \param light A const reference of the light
392   - //! \return Pair containing the hue as first value and saturation as second
393   - //! value or an empty one when failed
394   - virtual std::pair<uint16_t, uint8_t> getColorHueSaturation() {
395   - if (colorHueStrategy) {
396   - return colorHueStrategy->getColorHueSaturation(*this);
397   - }
398   - return {};
399   - };
400   -
401   - //! \brief Function to set the color of this light in CIE with specified x y.
402   - //!
403   - //! \note The color will only be set if the light has a reference to a
404   - //! specific \ref ColorHueStrategy. The values of x and y are ranging from 0
405   - //! to 1. \param x float that specifies the x coordinate in CIE \param y float
406   - //! that specifies the y coordinate in CIE \param transition Optional
407   - //! parameter to set the transition from current state to new, standard is 4 =
408   - //! 400ms \return Bool that is true on success
409   - virtual bool setColorXY(float x, float y, uint8_t transition = 4) {
410   - if (colorHueStrategy) {
411   - return colorHueStrategy->setColorXY(x, y, transition, *this);
412   - }
413   - return false;
414   - };
415   -
416   - //! \brief Const function that returns the current color of the light as xy
417   - //!
418   - //! \note The color x and y will only be returned when the light has a
419   - //! reference to a specific \ref ColorHueStrategy.
420   - //! \note This does not update the lights state
421   - //! \param light A const reference of the light
422   - //! \return Pair containing the x as first value and y as second value or an
423   - //! empty one when failed
424   - virtual std::pair<float, float> getColorXY() const {
425   - if (colorHueStrategy) {
426   - return colorHueStrategy->getColorXY(*this);
427   - }
428   - return {};
429   - };
430   -
431   - //! \brief Function that returns the current color of the light as xy
432   - //!
433   - //! \note The color x and y will only be returned when the light has a
434   - //! reference to a specific \ref ColorHueStrategy.
435   - //! Updates the lights state by calling refreshState()
436   - //! \param light A reference of the light
437   - //! \return Pair containing the x as first value and y as second value or an
438   - //! empty one when failed
439   - virtual std::pair<float, float> getColorXY() {
440   - if (colorHueStrategy) {
441   - return colorHueStrategy->getColorXY(*this);
442   - }
443   - return {};
444   - };
445   -
446   - //! \brief Function to set the color of this light with red green and blue
447   - //! values.
448   - //!
449   - //! \note The color will only be set if the light has a reference to a
450   - //! specific \ref ColorHueStrategy. The values of red, green and blue are
451   - //! ranging from 0 to 255. \param r uint8_t that specifies the red color value
452   - //! \param g uint8_t that specifies the green color value
453   - //! \param b uint8_t that specifies the blue color value
454   - //! \param transition Optional parameter to set the transition from current
455   - //! state to new, standard is 4 = 400ms \return Bool that is true on success
456   - virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b,
457   - uint8_t transition = 4) {
458   - if (colorHueStrategy) {
459   - return colorHueStrategy->setColorRGB(r, g, b, transition, *this);
460   - }
461   - return false;
462   - };
463   -
464   - //! \brief Function that lets the light perform one breath cycle.
465   - //!
466   - //! Can be used for locating a light.
467   - //! \return bool that is true on success
468   - virtual bool alert();
469   -
470   - //! \brief Function that lets the light perform one breath cycle in specified
471   - //! color temperature.
472   - //!
473   - //! \note The breath cylce will only be performed if the light has a reference
474   - //! to a specific \ref ColorTemperatureStrategy. \param mired Color
475   - //! temperature in mired \return Bool that is true on success
476   - virtual bool alertTemperature(unsigned int mired) {
477   - if (colorTemperatureStrategy) {
478   - return colorTemperatureStrategy->alertTemperature(mired, *this);
479   - }
480   - return false;
481   - };
482   -
483   - //! \brief Function that lets the light perform one breath cycle in specified
484   - //! color.
485   - //!
486   - //! \note The breath cylce will only be performed if the light has a reference
487   - //! to a specific \ref ColorHueStrategy. \param hue uint16_t that specifies
488   - //! the hue \param sat uint8_t that specifies the saturation \return Bool that
489   - //! is true on success
490   - virtual bool alertHueSaturation(uint16_t hue, uint8_t sat) {
491   - if (colorHueStrategy) {
492   - return colorHueStrategy->alertHueSaturation(hue, sat, *this);
493   - }
494   - return false;
495   - };
496   -
497   - //! \brief Function that lets the light perform one breath cycle in specified
498   - //! color.
499   - //!
500   - //! \note The breath cylce will only be performed if the light has a reference
501   - //! to a specific \ref ColorHueStrategy. The values of x and y are ranging
502   - //! from 0 to 1. \param x float that specifies the x coordinate in CIE \param
503   - //! y float that specifies the y coordinate in CIE \return Bool that is true
504   - //! on success
505   - virtual bool alertXY(float x, float y) {
506   - if (colorHueStrategy) {
507   - return colorHueStrategy->alertXY(x, y, *this);
508   - }
509   - return false;
510   - };
511   -
512   - //! \brief Function that lets the light perform one breath cycle in specified
513   - //! color.
514   - //!
515   - //! \note The breath cylce will only be performed if the light has a reference
516   - //! to a specific \ref ColorHueStrategy. The values of red, green and blue are
517   - //! ranging from 0 to 255. \param r uint8_t that specifies the red color value
518   - //! \param g uint8_t that specifies the green color value
519   - //! \param b uint8_t that specifies the blue color value
520   - //! \return Bool that is true on success
521   - virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b) {
522   - if (colorHueStrategy) {
523   - return colorHueStrategy->alertRGB(r, g, b, *this);
524   - }
525   - return false;
526   - };
527   -
528   - //! \brief Function to turn colorloop effect on/off.
529   - //!
530   - //! Notice this function will only be performed light has a reference to a
531   - //! specific \ref ColorHueStrategy. The colorloop effect will loop through all
532   - //! colors on current hue and saturation levels. Notice that none of the
533   - //! setter functions check whether this feature is enabled and the colorloop
534   - //! can only be disabled with this function or by simply calling
535   - //! Off()/OffNoRefresh() and then On()/OnNoRefresh(), so you could
536   - //! alternatively call Off() and then use any of the setter functions. \param
537   - //! on bool that enables this feature when true and disables it when false
538   - //! \return Bool that is true on success
539   - virtual bool setColorLoop(bool on) {
540   - if (colorHueStrategy) {
541   - return colorHueStrategy->setColorLoop(on, *this);
542   - }
543   - return false;
544   - };
  101 + //! \brief std dtor
  102 + ~HueLight() = default;
  103 +
  104 + //! \brief Function that turns the light on.
  105 + //!
  106 + //! \param transition Optional parameter to set the transition from current
  107 + //! state to new, standard is 4 = 400ms \return Bool that is true on success
  108 + virtual bool On(uint8_t transition = 4);
  109 +
  110 + //! \brief Function that turns the light off.
  111 + //!
  112 + //! \param transition Optional parameter to set the transition from current
  113 + //! state to new, standard is 4 = 400ms \return Bool that is true on success
  114 + virtual bool Off(uint8_t transition = 4);
  115 +
  116 + //! \brief Function to check whether a light is on or off
  117 + //!
  118 + //! \return Bool that is true, when the light is on and false, when off
  119 + virtual bool isOn();
  120 +
  121 + //! \brief Const function to check whether a light is on or off
  122 + //!
  123 + //! \note This will not refresh the light state
  124 + //! \return Bool that is true, when the light is on and false, when off
  125 + virtual bool isOn() const;
  126 +
  127 + //! \brief Const function that returns the id of this light
  128 + //!
  129 + //! \return integer representing the light id
  130 + virtual int getId() const;
  131 +
  132 + //! \brief Const function that returns the light type
  133 + //!
  134 + //! \return String containing the type
  135 + virtual std::string getType() const;
  136 +
  137 + //! \brief Function that returns the name of the light.
  138 + //!
  139 + //! \return String containig the name of the light
  140 + virtual std::string getName();
  141 +
  142 + //! \brief Const function that returns the name of the light.
  143 + //!
  144 + //! \note This will not refresh the light state
  145 + //! \return String containig the name of the light
  146 + virtual std::string getName() const;
  147 +
  148 + //! \brief Const function that returns the modelid of the light
  149 + //!
  150 + //! \return String conatining the modelid
  151 + virtual std::string getModelId() const;
  152 +
  153 + //! \brief Const function that returns the uniqueid of the light
  154 + //!
  155 + //! \note Only working on bridges with versions starting at 1.4
  156 + //! \return String containing the uniqueid or an empty string when the
  157 + //! function is not supported
  158 + virtual std::string getUId() const;
  159 +
  160 + //! \brief Const function that returns the manufacturername of the light
  161 + //!
  162 + //! \note Only working on bridges with versions starting at 1.7
  163 + //! \return String containing the manufacturername or an empty string when the
  164 + //! function is not supported
  165 + virtual std::string getManufacturername() const;
  166 +
  167 + //! \brief Const function that returns the productname of the light
  168 + //!
  169 + //! \note Only working on bridges with versions starting at 1.24
  170 + //! \return String containing the productname or an empty string when the
  171 + //! function is not supported
  172 + virtual std::string getProductname() const;
  173 +
  174 + //! \brief Const function that returns the luminaireuniqueid of the light
  175 + //!
  176 + //! \note Only working on bridges with versions starting at 1.9
  177 + //! \return String containing the luminaireuniqueid or an empty string when
  178 + //! the function is not supported
  179 + virtual std::string getLuminaireUId() const;
  180 +
  181 + //! \brief Function that returns the software version of the light
  182 + //!
  183 + //! \return String containing the software version
  184 + virtual std::string getSwVersion();
  185 +
  186 + //! \brief Const function that returns the software version of the light
  187 + //!
  188 + //! \note This will not refresh the light state
  189 + //! \return String containing the software version
  190 + virtual std::string getSwVersion() const;
  191 +
  192 + //! \brief Function that sets the name of the light
  193 + //!
  194 + //! \return Bool that is true on success
  195 + virtual bool setName(const std::string& name);
  196 +
  197 + //! \brief Const function that returns the color type of the light.
  198 + //!
  199 + //! \return ColorType containig the color type of the light
  200 + virtual ColorType getColorType() const;
  201 +
  202 + //! \brief Const function to check whether this light has brightness control
  203 + //!
  204 + //! \return Bool that is true when the light has specified abilities and false
  205 + //! when not
  206 + virtual bool hasBrightnessControl() const { return brightnessStrategy != nullptr; };
  207 +
  208 + //! \brief Const function to check whether this light has color temperature
  209 + //! control
  210 + //!
  211 + //! \return Bool that is true when the light has specified abilities and false
  212 + //! when not
  213 + virtual bool hasTemperatureControl() const { return colorTemperatureStrategy != nullptr; };
  214 +
  215 + //! \brief Connst function to check whether this light has full color control
  216 + //!
  217 + //! \return Bool that is true when the light has specified abilities and false
  218 + //! when not
  219 + virtual bool hasColorControl() const { return colorHueStrategy != nullptr; };
  220 +
  221 + //! \brief Const function that converts Kelvin to Mired.
  222 + //!
  223 + //! \param kelvin Unsigned integer value in Kelvin
  224 + //! \return Unsigned integer value in Mired
  225 + unsigned int KelvinToMired(unsigned int kelvin) const;
  226 +
  227 + //! \brief Const function that converts Mired to Kelvin.
  228 + //!
  229 + //! \param mired Unsigned integer value in Mired
  230 + //! \return Unsigned integer value in Kelvin
  231 + unsigned int MiredToKelvin(unsigned int mired) const;
  232 +
  233 + //! \brief Function that sets the brightness of this light.
  234 + //!
  235 + //! \note The brightness will only be set if the light has a reference to a
  236 + //! specific \ref BrightnessStrategy. The brightness can range from 0 = off to
  237 + //! 254 = fully lit. \param bri Unsigned int that specifies the brightness
  238 + //! \param transition Optional parameter to set the transition from current
  239 + //! state to new, standard is 4 = 400ms \return Bool that is true on success
  240 + virtual bool setBrightness(unsigned int bri, uint8_t transition = 4)
  241 + {
  242 + if (brightnessStrategy)
  243 + {
  244 + return brightnessStrategy->setBrightness(bri, transition, *this);
  245 + }
  246 + return false;
  247 + };
  248 +
  249 + //! \brief Const function that returns the brightness of this light.
  250 + //!
  251 + //! \note The brightness will only be returned if the light has a reference to
  252 + //! a specific \ref BrightnessStrategy. \note This will not refresh the light
  253 + //! state The brightness can range from 0 = off to 254 = fully lit. \return
  254 + //! Unsigned int that is 0 when function failed
  255 + virtual unsigned int getBrightness() const
  256 + {
  257 + if (brightnessStrategy)
  258 + {
  259 + return brightnessStrategy->getBrightness(*this);
  260 + }
  261 + return 0;
  262 + };
  263 +
  264 + //! \brief Function that returns the brightness of this light.
  265 + //!
  266 + //! \note The brightness will only be returned if the light has a reference to
  267 + //! a specific \ref BrightnessStrategy. The brightness can range from 0 = off
  268 + //! to 254 = fully lit. \return Unsigned int that is 0 when function failed
  269 + virtual unsigned int getBrightness()
  270 + {
  271 + if (brightnessStrategy)
  272 + {
  273 + return brightnessStrategy->getBrightness(*this);
  274 + }
  275 + return 0;
  276 + };
  277 +
  278 + //! \brief Fucntion that sets the color temperature of this light in mired.
  279 + //!
  280 + //! \note The color temperature will only be set if the light has a reference
  281 + //! to a specific \ref ColorTemperatureStrategy. The color temperature can
  282 + //! range from 153 to 500. \param mired Unsigned int that specifies the color
  283 + //! temperature in Mired \param transition Optional parameter to set the
  284 + //! transition from current state to new, standard is 4 = 400ms \return Bool
  285 + //! that is true on success
  286 + virtual bool setColorTemperature(unsigned int mired, uint8_t transition = 4)
  287 + {
  288 + if (colorTemperatureStrategy)
  289 + {
  290 + return colorTemperatureStrategy->setColorTemperature(mired, transition, *this);
  291 + }
  292 + return false;
  293 + };
  294 +
  295 + //! \brief Const function that returns the current color temperature of the
  296 + //! light
  297 + //!
  298 + //! \note The color temperature will only be returned when the light has a
  299 + //! reference to a specific \ref ColorTemperatureStrategy. \note This will not
  300 + //! refresh the light state
  301 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  302 + //! and 500 is warm. \param light A reference of the light \return Unsigned
  303 + //! int representing the color temperature in mired or 0 when failed
  304 + virtual unsigned int getColorTemperature() const
  305 + {
  306 + if (colorTemperatureStrategy)
  307 + {
  308 + return colorTemperatureStrategy->getColorTemperature(*this);
  309 + }
  310 + return 0;
  311 + };
  312 +
  313 + //! \brief Function that returns the current color temperature of the light
  314 + //!
  315 + //! \note The color temperature will only be returned when the light has a
  316 + //! reference to a specific \ref ColorTemperatureStrategy.
  317 + //! Updates the lights state by calling refreshState()
  318 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  319 + //! and 500 is warm. \param light A reference of the light \return Unsigned
  320 + //! int representing the color temperature in mired or 0 when failed
  321 + virtual unsigned int getColorTemperature()
  322 + {
  323 + if (colorTemperatureStrategy)
  324 + {
  325 + return colorTemperatureStrategy->getColorTemperature(*this);
  326 + }
  327 + return 0;
  328 + };
  329 +
  330 + //! \brief Function to set the color of this light with specified hue.
  331 + //!
  332 + //! \note The color will only be set if the light has a reference to a
  333 + //! specific \ref ColorHueStrategy. The hue can range from 0 to 65535, whereas
  334 + //! 65535 and 0 are red, 25500 is green and 46920 is blue. \param hue uint16_t
  335 + //! that specifies the hue \param transition Optional parameter to set the
  336 + //! transition from current state to new, standard is 4 = 400ms \return Bool
  337 + //! that is true on success
  338 + virtual bool setColorHue(uint16_t hue, uint8_t transition = 4)
  339 + {
  340 + if (colorHueStrategy)
  341 + {
  342 + return colorHueStrategy->setColorHue(hue, transition, *this);
  343 + }
  344 + return false;
  345 + };
  346 +
  347 + //! \brief Function to set the color of this light with specified saturation.
  348 + //!
  349 + //! \note The color will only be set if the light has a reference to a
  350 + //! specific \ref ColorHueStrategy. The saturation can range from 0 to 254,
  351 + //! whereas 0 is least saturated (white) and 254 is most saturated. \param sat
  352 + //! uint8_t that specifies the saturation \param transition Optional parameter
  353 + //! to set the transition from current state to new, standard is 4 = 400ms
  354 + //! \return Bool that is true on success
  355 + virtual bool setColorSaturation(uint8_t sat, uint8_t transition = 4)
  356 + {
  357 + if (colorHueStrategy)
  358 + {
  359 + return colorHueStrategy->setColorSaturation(sat, transition, *this);
  360 + }
  361 + return false;
  362 + };
  363 +
  364 + //! \brief Function to set the color of this light with specified hue and
  365 + //! saturation.
  366 + //!
  367 + //! \note The color will only be set if the light has a reference to a
  368 + //! specific \ref ColorHueStrategy. \param hue uint16_t that specifies the hue
  369 + //! \param sat uint8_t that specifies the saturation
  370 + //! \param transition Optional parameter to set the transition from current
  371 + //! state to new, standard is 4 = 400ms. \return Bool that is true on success
  372 + virtual bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition = 4)
  373 + {
  374 + if (colorHueStrategy)
  375 + {
  376 + return colorHueStrategy->setColorHueSaturation(hue, sat, transition, *this);
  377 + }
  378 + return false;
  379 + };
  380 +
  381 + //! \brief Const function that returns the current color of the light as hue
  382 + //! and saturation
  383 + //!
  384 + //! \note The color hue and saturation will only be returned when the light
  385 + //! has a reference to a specific \ref ColorHueStrategy.
  386 + //! \note This will not refresh the light state
  387 + //! \param light A reference of the light
  388 + //! \return Pair containing the hue as first value and saturation as second
  389 + //! value or an empty one when failed
  390 + virtual std::pair<uint16_t, uint8_t> getColorHueSaturation() const
  391 + {
  392 + if (colorHueStrategy)
  393 + {
  394 + return colorHueStrategy->getColorHueSaturation(*this);
  395 + }
  396 + return {};
  397 + };
  398 +
  399 + //! \brief Function that returns the current color of the light as hue and
  400 + //! saturation
  401 + //!
  402 + //! \note The color hue and saturation will only be returned when the light
  403 + //! has a reference to a specific \ref ColorHueStrategy. Updates the lights
  404 + //! state by calling refreshState()
  405 + //! \param light A const reference of the light
  406 + //! \return Pair containing the hue as first value and saturation as second
  407 + //! value or an empty one when failed
  408 + virtual std::pair<uint16_t, uint8_t> getColorHueSaturation()
  409 + {
  410 + if (colorHueStrategy)
  411 + {
  412 + return colorHueStrategy->getColorHueSaturation(*this);
  413 + }
  414 + return {};
  415 + };
  416 +
  417 + //! \brief Function to set the color of this light in CIE with specified x y.
  418 + //!
  419 + //! \note The color will only be set if the light has a reference to a
  420 + //! specific \ref ColorHueStrategy. The values of x and y are ranging from 0
  421 + //! to 1. \param x float that specifies the x coordinate in CIE \param y float
  422 + //! that specifies the y coordinate in CIE \param transition Optional
  423 + //! parameter to set the transition from current state to new, standard is 4 =
  424 + //! 400ms \return Bool that is true on success
  425 + virtual bool setColorXY(float x, float y, uint8_t transition = 4)
  426 + {
  427 + if (colorHueStrategy)
  428 + {
  429 + return colorHueStrategy->setColorXY(x, y, transition, *this);
  430 + }
  431 + return false;
  432 + };
  433 +
  434 + //! \brief Const function that returns the current color of the light as xy
  435 + //!
  436 + //! \note The color x and y will only be returned when the light has a
  437 + //! reference to a specific \ref ColorHueStrategy.
  438 + //! \note This does not update the lights state
  439 + //! \param light A const reference of the light
  440 + //! \return Pair containing the x as first value and y as second value or an
  441 + //! empty one when failed
  442 + virtual std::pair<float, float> getColorXY() const
  443 + {
  444 + if (colorHueStrategy)
  445 + {
  446 + return colorHueStrategy->getColorXY(*this);
  447 + }
  448 + return {};
  449 + };
  450 +
  451 + //! \brief Function that returns the current color of the light as xy
  452 + //!
  453 + //! \note The color x and y will only be returned when the light has a
  454 + //! reference to a specific \ref ColorHueStrategy.
  455 + //! Updates the lights state by calling refreshState()
  456 + //! \param light A reference of the light
  457 + //! \return Pair containing the x as first value and y as second value or an
  458 + //! empty one when failed
  459 + virtual std::pair<float, float> getColorXY()
  460 + {
  461 + if (colorHueStrategy)
  462 + {
  463 + return colorHueStrategy->getColorXY(*this);
  464 + }
  465 + return {};
  466 + };
  467 +
  468 + //! \brief Function to set the color of this light with red green and blue
  469 + //! values.
  470 + //!
  471 + //! \note The color will only be set if the light has a reference to a
  472 + //! specific \ref ColorHueStrategy. The values of red, green and blue are
  473 + //! ranging from 0 to 255. \param r uint8_t that specifies the red color value
  474 + //! \param g uint8_t that specifies the green color value
  475 + //! \param b uint8_t that specifies the blue color value
  476 + //! \param transition Optional parameter to set the transition from current
  477 + //! state to new, standard is 4 = 400ms \return Bool that is true on success
  478 + virtual bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition = 4)
  479 + {
  480 + if (colorHueStrategy)
  481 + {
  482 + return colorHueStrategy->setColorRGB(r, g, b, transition, *this);
  483 + }
  484 + return false;
  485 + };
  486 +
  487 + //! \brief Function that lets the light perform one breath cycle.
  488 + //!
  489 + //! Can be used for locating a light.
  490 + //! \return bool that is true on success
  491 + virtual bool alert();
  492 +
  493 + //! \brief Function that lets the light perform one breath cycle in specified
  494 + //! color temperature.
  495 + //!
  496 + //! \note The breath cylce will only be performed if the light has a reference
  497 + //! to a specific \ref ColorTemperatureStrategy. \param mired Color
  498 + //! temperature in mired \return Bool that is true on success
  499 + virtual bool alertTemperature(unsigned int mired)
  500 + {
  501 + if (colorTemperatureStrategy)
  502 + {
  503 + return colorTemperatureStrategy->alertTemperature(mired, *this);
  504 + }
  505 + return false;
  506 + };
  507 +
  508 + //! \brief Function that lets the light perform one breath cycle in specified
  509 + //! color.
  510 + //!
  511 + //! \note The breath cylce will only be performed if the light has a reference
  512 + //! to a specific \ref ColorHueStrategy. \param hue uint16_t that specifies
  513 + //! the hue \param sat uint8_t that specifies the saturation \return Bool that
  514 + //! is true on success
  515 + virtual bool alertHueSaturation(uint16_t hue, uint8_t sat)
  516 + {
  517 + if (colorHueStrategy)
  518 + {
  519 + return colorHueStrategy->alertHueSaturation(hue, sat, *this);
  520 + }
  521 + return false;
  522 + };
  523 +
  524 + //! \brief Function that lets the light perform one breath cycle in specified
  525 + //! color.
  526 + //!
  527 + //! \note The breath cylce will only be performed if the light has a reference
  528 + //! to a specific \ref ColorHueStrategy. The values of x and y are ranging
  529 + //! from 0 to 1. \param x float that specifies the x coordinate in CIE \param
  530 + //! y float that specifies the y coordinate in CIE \return Bool that is true
  531 + //! on success
  532 + virtual bool alertXY(float x, float y)
  533 + {
  534 + if (colorHueStrategy)
  535 + {
  536 + return colorHueStrategy->alertXY(x, y, *this);
  537 + }
  538 + return false;
  539 + };
  540 +
  541 + //! \brief Function that lets the light perform one breath cycle in specified
  542 + //! color.
  543 + //!
  544 + //! \note The breath cylce will only be performed if the light has a reference
  545 + //! to a specific \ref ColorHueStrategy. The values of red, green and blue are
  546 + //! ranging from 0 to 255. \param r uint8_t that specifies the red color value
  547 + //! \param g uint8_t that specifies the green color value
  548 + //! \param b uint8_t that specifies the blue color value
  549 + //! \return Bool that is true on success
  550 + virtual bool alertRGB(uint8_t r, uint8_t g, uint8_t b)
  551 + {
  552 + if (colorHueStrategy)
  553 + {
  554 + return colorHueStrategy->alertRGB(r, g, b, *this);
  555 + }
  556 + return false;
  557 + };
  558 +
  559 + //! \brief Function to turn colorloop effect on/off.
  560 + //!
  561 + //! Notice this function will only be performed light has a reference to a
  562 + //! specific \ref ColorHueStrategy. The colorloop effect will loop through all
  563 + //! colors on current hue and saturation levels. Notice that none of the
  564 + //! setter functions check whether this feature is enabled and the colorloop
  565 + //! can only be disabled with this function or by simply calling
  566 + //! Off()/OffNoRefresh() and then On()/OnNoRefresh(), so you could
  567 + //! alternatively call Off() and then use any of the setter functions. \param
  568 + //! on bool that enables this feature when true and disables it when false
  569 + //! \return Bool that is true on success
  570 + virtual bool setColorLoop(bool on)
  571 + {
  572 + if (colorHueStrategy)
  573 + {
  574 + return colorHueStrategy->setColorLoop(on, *this);
  575 + }
  576 + return false;
  577 + };
545 578  
546 579 protected:
547   - //! \brief Protected ctor that is used by \ref Hue class.
548   - //!
549   - //! \param id Integer that specifies the id of this light
550   - //! \param commands HueCommandAPI for communication with the bridge
551   - //!
552   - //! leaves strategies unset
553   - HueLight(int id, const HueCommandAPI &commands);
554   -
555   - //! \brief Protected ctor that is used by \ref Hue class, also sets
556   - //! strategies.
557   - //!
558   - //! \param id Integer that specifies the id of this light
559   - //! \param commands HueCommandAPI for communication with the bridge
560   - //! \param brightnessStrategy Strategy for brightness. May be nullptr.
561   - //! \param colorTempStrategy Strategy for color temperature. May be nullptr.
562   - //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr.
563   - HueLight(int id, const HueCommandAPI &commands,
564   - std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
565   - std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
566   - std::shared_ptr<const ColorHueStrategy> colorHueStrategy);
567   -
568   - //! \brief Protected function that sets the brightness strategy.
569   - //!
570   - //! The strategy defines how specific commands that deal with brightness
571   - //! control are executed \param strat a strategy of type \ref
572   - //! BrightnessStrategy
573   - virtual void
574   - setBrightnessStrategy(std::shared_ptr<const BrightnessStrategy> strat) {
575   - brightnessStrategy = std::move(strat);
576   - };
577   -
578   - //! \brief Protected function that sets the colorTemperature strategy.
579   - //!
580   - //! The strategy defines how specific commands that deal with colortemperature
581   - //! control are executed \param strat a strategy of type \ref
582   - //! ColorTemperatureStrategy
583   - virtual void setColorTemperatureStrategy(
584   - std::shared_ptr<const ColorTemperatureStrategy> strat) {
585   - colorTemperatureStrategy = std::move(strat);
586   - };
587   -
588   - //! \brief Protected function that sets the colorHue strategy.
589   - //!
590   - //! The strategy defines how specific commands that deal with color control
591   - //! are executed \param strat a strategy of type \ref ColorHueStrategy
592   - virtual void
593   - setColorHueStrategy(std::shared_ptr<const ColorHueStrategy> strat) {
594   - colorHueStrategy = std::move(strat);
595   - };
596   -
597   - //! \brief Protected function that sets the HueCommandAPI.
598   - //!
599   - //! The HueCommandAPI is used for bridge communication
600   - //! \param commandAPI the new HueCommandAPI
601   - virtual void setCommandAPI(const HueCommandAPI &commandAPI) {
602   - commands = commandAPI;
603   - };
604   -
605   - //! \brief Function that turns the light on without refreshing its state.
606   - //!
607   - //! \param transition Optional parameter to set the transition from current
608   - //! state to new standard is 4 = 400ms \return Bool that is true on success
609   - virtual bool OnNoRefresh(uint8_t transition = 4);
610   -
611   - //! \brief Function that turns the light off without refreshing its state.
612   - //!
613   - //! \param transition Optional parameter to set the transition from current
614   - //! state to new standard is 4 = 400ms \return Bool that is true on success
615   - virtual bool OffNoRefresh(uint8_t transition = 4);
616   -
617   - //! \brief Utility function to send a put request to the light.
618   - //!
619   - //! \throws std::runtime_error if the reply could not be parsed
620   - //! \param request A nlohmann::json aka the request to send
621   - //! \param subPath A path that is appended to the uri, note it should always
622   - //! start with a slash ("/") \return The parsed reply
623   - virtual nlohmann::json SendPutRequest(const nlohmann::json &request,
624   - const std::string &subPath);
625   -
626   - //! \brief Virtual function that refreshes the \ref state of the light.
627   - virtual void refreshState();
  580 + //! \brief Protected ctor that is used by \ref Hue class.
  581 + //!
  582 + //! \param id Integer that specifies the id of this light
  583 + //! \param commands HueCommandAPI for communication with the bridge
  584 + //!
  585 + //! leaves strategies unset
  586 + HueLight(int id, const HueCommandAPI& commands);
  587 +
  588 + //! \brief Protected ctor that is used by \ref Hue class, also sets
  589 + //! strategies.
  590 + //!
  591 + //! \param id Integer that specifies the id of this light
  592 + //! \param commands HueCommandAPI for communication with the bridge
  593 + //! \param brightnessStrategy Strategy for brightness. May be nullptr.
  594 + //! \param colorTempStrategy Strategy for color temperature. May be nullptr.
  595 + //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr.
  596 + HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
  597 + std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
  598 + std::shared_ptr<const ColorHueStrategy> colorHueStrategy);
  599 +
  600 + //! \brief Protected function that sets the brightness strategy.
  601 + //!
  602 + //! The strategy defines how specific commands that deal with brightness
  603 + //! control are executed \param strat a strategy of type \ref
  604 + //! BrightnessStrategy
  605 + virtual void setBrightnessStrategy(std::shared_ptr<const BrightnessStrategy> strat)
  606 + {
  607 + brightnessStrategy = std::move(strat);
  608 + };
  609 +
  610 + //! \brief Protected function that sets the colorTemperature strategy.
  611 + //!
  612 + //! The strategy defines how specific commands that deal with colortemperature
  613 + //! control are executed \param strat a strategy of type \ref
  614 + //! ColorTemperatureStrategy
  615 + virtual void setColorTemperatureStrategy(std::shared_ptr<const ColorTemperatureStrategy> strat)
  616 + {
  617 + colorTemperatureStrategy = std::move(strat);
  618 + };
  619 +
  620 + //! \brief Protected function that sets the colorHue strategy.
  621 + //!
  622 + //! The strategy defines how specific commands that deal with color control
  623 + //! are executed \param strat a strategy of type \ref ColorHueStrategy
  624 + virtual void setColorHueStrategy(std::shared_ptr<const ColorHueStrategy> strat)
  625 + {
  626 + colorHueStrategy = std::move(strat);
  627 + };
  628 +
  629 + //! \brief Protected function that sets the HueCommandAPI.
  630 + //!
  631 + //! The HueCommandAPI is used for bridge communication
  632 + //! \param commandAPI the new HueCommandAPI
  633 + virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; };
  634 +
  635 + //! \brief Function that turns the light on without refreshing its state.
  636 + //!
  637 + //! \param transition Optional parameter to set the transition from current
  638 + //! state to new standard is 4 = 400ms \return Bool that is true on success
  639 + virtual bool OnNoRefresh(uint8_t transition = 4);
  640 +
  641 + //! \brief Function that turns the light off without refreshing its state.
  642 + //!
  643 + //! \param transition Optional parameter to set the transition from current
  644 + //! state to new standard is 4 = 400ms \return Bool that is true on success
  645 + virtual bool OffNoRefresh(uint8_t transition = 4);
  646 +
  647 + //! \brief Utility function to send a put request to the light.
  648 + //!
  649 + //! \throws std::runtime_error if the reply could not be parsed
  650 + //! \param request A nlohmann::json aka the request to send
  651 + //! \param subPath A path that is appended to the uri, note it should always
  652 + //! start with a slash ("/") \return The parsed reply
  653 + virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath);
  654 +
  655 + //! \brief Virtual function that refreshes the \ref state of the light.
  656 + virtual void refreshState();
628 657  
629 658 protected:
630   - int id; //!< holds the id of the light
631   - nlohmann::json state; //!< holds the current state of the light updated by
632   - //!< \ref refreshState
633   - ColorType colorType; //!< holds the \ref ColorType of the light
634   -
635   - std::shared_ptr<const BrightnessStrategy>
636   - brightnessStrategy; //!< holds a reference to the strategy that handles
637   - //!< brightness commands
638   - std::shared_ptr<const ColorTemperatureStrategy>
639   - colorTemperatureStrategy; //!< holds a reference to the strategy that
640   - //!< handles colortemperature commands
641   - std::shared_ptr<const ColorHueStrategy>
642   - colorHueStrategy; //!< holds a reference to the strategy that handles all
643   - //!< color commands
644   - HueCommandAPI
645   - commands; //!< A IHttpHandler that is used to communicate with the bridge
  659 + int id; //!< holds the id of the light
  660 + nlohmann::json state; //!< holds the current state of the light updated by \ref refreshState
  661 + ColorType colorType; //!< holds the \ref ColorType of the light
  662 +
  663 + std::shared_ptr<const BrightnessStrategy>
  664 + brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands
  665 + std::shared_ptr<const ColorTemperatureStrategy>
  666 + colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands
  667 + std::shared_ptr<const ColorHueStrategy>
  668 + colorHueStrategy; //!< holds a reference to the strategy that handles all color commands
  669 + HueCommandAPI commands; //!< A IHttpHandler that is used to communicate with the bridge
646 670 };
647 671  
648 672 #endif
... ...
hueplusplus/include/IHttpHandler.h
1 1 /**
2   - \file IHttpHandler.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
6   -
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  2 + \file IHttpHandler.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _IHTTPHANDLER_H
... ... @@ -28,183 +28,169 @@
28 28 #include "json/json.hpp"
29 29  
30 30 //! Abstract class for classes that handle http requests and multicast requests
31   -class IHttpHandler {
  31 +class IHttpHandler
  32 +{
32 33 public:
33   - //! \brief Virtual dtor
34   - virtual ~IHttpHandler() = default;
35   -
36   - //! \brief Virtual function that should send a given message to a specified
37   - //! host and return the response.
38   - //!
39   - //! \param msg String that contains the message that should be sent to the
40   - //! specified address \param adr String that contains an ip or hostname in
41   - //! dotted decimal notation like "192.168.2.1" \param port Optional integer
42   - //! that specifies the port to which the request should be sent to. Default is
43   - //! 80 \return String containing the response of the host
44   - virtual std::string send(const std::string &msg, const std::string &adr,
45   - int port = 80) const = 0;
46   -
47   - //! \brief Virtual function that should given message to a specified host and
48   - //! return the body of the response.
49   - //!
50   - //! Note if no body is found a runtime error is thrown!
51   - //! \param msg String that contains the message that should sent to the
52   - //! specified address \param adr String that contains an ip or hostname in
53   - //! dotted decimal notation like "192.168.2.1" \param port Optional integer
54   - //! that specifies the port to which the request should be sent. Default is 80
55   - //! \return String containing the body of the response of the host
56   - virtual std::string sendGetHTTPBody(const std::string &msg,
57   - const std::string &adr,
58   - int port = 80) const = 0;
59   -
60   - //! \brief Virtual function that should send a multicast request with a
61   - //! specified message.
62   - //!
63   - //! \param msg String that contains the request that should be sent to the
64   - //! specified address \param adr Optional String that contains an ip or
65   - //! hostname in dotted decimal notation, default is "239.255.255.250" \param
66   - //! port Optional integer that specifies the port to which the request should
67   - //! be sent. Default is 1900 \param timeout Optional Integer that specifies
68   - //! the timeout of the request in seconds. Default is 5 \return Vector
69   - //! containing strings of each answer received
70   - virtual std::vector<std::string>
71   - sendMulticast(const std::string &msg,
72   - const std::string &adr = "239.255.255.250", int port = 1900,
73   - int timeout = 5) const = 0;
74   -
75   - //! \brief Virtual function that should send a HTTP request with the given
76   - //! method to the specified host and return the body of the response.
77   - //!
78   - //! Note body can also be left empty!
79   - //! \param method String that contains the HTTP method type e.g. GET, HEAD,
80   - //! POST, PUT, DELETE, ... \param uri String that contains the uniform
81   - //! resource identifier \param content_type String that contains the
82   - //! type(MIME) of the body data e.g. "text/html", "application/json", ...
83   - //! \param body String that contains the data of the request
84   - //! \param adr String that contains an ip or hostname in dotted decimal
85   - //! notation like "192.168.2.1" \param port Optional integer that specifies
86   - //! the port to which the request is sent to. Default is 80 \return String
87   - //! containing the body of the response of the host
88   - virtual std::string sendHTTPRequest(std::string method, std::string uri,
89   - std::string content_type,
90   - std::string body, const std::string &adr,
91   - int port = 80) const = 0;
92   -
93   - //! \brief Virtual function that should send a HTTP GET request to the
94   - //! specified host and return the body of the response.
95   - //!
96   - //! Note body can also be left empty!
97   - //! \param uri String that contains the uniform resource identifier
98   - //! \param content_type String that contains the type(MIME) of the body data
99   - //! e.g. "text/html", "application/json", ... \param body String that contains
100   - //! the data of the request \param adr String that contains an ip or hostname
101   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
102   - //! that specifies the port to which the request is sent to. Default is 80
103   - //! \return String containing the body of the response of the host
104   - virtual std::string GETString(std::string uri, std::string content_type,
105   - std::string body, const std::string &adr,
106   - int port = 80) const = 0;
107   -
108   - //! \brief Virtual function that should send a HTTP POST request to the
109   - //! specified host and returns the body of the response.
110   - //!
111   - //! Note body can also be left empty!
112   - //! \param uri String that contains the uniform resource identifier
113   - //! \param content_type String that contains the type(MIME) of the body data
114   - //! e.g. "text/html", "application/json", ... \param body String that contains
115   - //! the data of the request \param adr String that contains an ip or hostname
116   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
117   - //! that specifies the port to which the request is sent to. Default is 80
118   - //! \return String containing the body of the response of the host
119   - virtual std::string POSTString(std::string uri, std::string content_type,
120   - std::string body, const std::string &adr,
121   - int port = 80) const = 0;
122   -
123   - //! \brief Virtual function that should send a HTTP PUT request to the
124   - //! specified host and return the body of the response.
125   - //!
126   - //! Note body can also be left empty!
127   - //! \param uri String that contains the uniform resource identifier
128   - //! \param content_type String that contains the type(MIME) of the body data
129   - //! e.g. "text/html", "application/json", ... \param body String that contains
130   - //! the data of the request \param adr String that contains an ip or hostname
131   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
132   - //! that specifies the port to which the request is sent to. Default is 80
133   - //! \return String containing the body of the response of the host
134   - virtual std::string PUTString(std::string uri, std::string content_type,
135   - std::string body, const std::string &adr,
136   - int port = 80) const = 0;
137   -
138   - //! \brief Virtual function that should send a HTTP DELETE request to the
139   - //! specified host and return the body of the response.
140   - //!
141   - //! Note body can also be left empty!
142   - //! \param uri String that contains the uniform resource identifier
143   - //! \param content_type String that contains the type(MIME) of the body data
144   - //! e.g. "text/html", "application/json", ... \param body String that contains
145   - //! the data of the request \param adr String that contains an ip or hostname
146   - //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
147   - //! that specifies the port to which the request is sent to. Default is 80
148   - //! \return String containing the body of the response of the host
149   - virtual std::string DELETEString(std::string uri, std::string content_type,
150   - std::string body, const std::string &adr,
151   - int port = 80) const = 0;
152   -
153   - //! \brief Virtual function that should send a HTTP GET request to the
154   - //! specified host and return the body of the response.
155   - //!
156   - //! Note body can also be left empty!
157   - //! \param uri String that contains the uniform resource identifier
158   - //! \param body nlohmann::json that contains the data of the request
159   - //! \param adr String that contains an ip or hostname in dotted decimal
160   - //! notation like "192.168.2.1" \param port Optional integer that specifies
161   - //! the port to which the request is sent to. Default is 80 \return
162   - //! nlohmann::json containing the parsed body of the response of the host
163   - virtual nlohmann::json GETJson(std::string uri, const nlohmann::json &body,
164   - const std::string &adr,
165   - int port = 80) const = 0;
166   -
167   - //! \brief Virtual function that should send a HTTP POST request to the
168   - //! specified host and return the body of the response.
169   - //!
170   - //! Note body can also be left empty!
171   - //! \param uri String that contains the uniform resource identifier
172   - //! \param body nlohmann::json that contains the data of the request
173   - //! \param adr String that contains an ip or hostname in dotted decimal
174   - //! notation like "192.168.2.1" \param port Optional integer that specifies
175   - //! the port to which the request is sent to. Default is 80 \return
176   - //! nlohmann::json containing the parsed body of the response of the host
177   - virtual nlohmann::json POSTJson(std::string uri, const nlohmann::json &body,
178   - const std::string &adr,
179   - int port = 80) const = 0;
180   -
181   - //! \brief Virtual function that should send a HTTP PUT request to the
182   - //! specified host and return the body of the response.
183   - //!
184   - //! Note body can also be left empty!
185   - //! \param uri String that contains the uniform resource identifier
186   - //! \param body nlohmann::json that contains the data of the request
187   - //! \param adr String that contains an ip or hostname in dotted decimal
188   - //! notation like "192.168.2.1" \param port Optional integer that specifies
189   - //! the port to which the request is sent to. Default is 80 \return
190   - //! nlohmann::json containing the parsed body of the response of the host
191   - virtual nlohmann::json PUTJson(std::string uri, const nlohmann::json &body,
192   - const std::string &adr,
193   - int port = 80) const = 0;
194   -
195   - //! \brief Virtual function that should send a HTTP DELETE request to the
196   - //! specified host and return the body of the response.
197   - //!
198   - //! Note body can also be left empty!
199   - //! \param uri String that contains the uniform resource identifier
200   - //! \param body nlohmann::json that contains the data of the request
201   - //! \param adr String that contains an ip or hostname in dotted decimal
202   - //! notation like "192.168.2.1" \param port Optional integer that specifies
203   - //! the port to which the request is sent to. Default is 80 \return
204   - //! nlohmann::json containing the parsed body of the response of the host
205   - virtual nlohmann::json DELETEJson(std::string uri, const nlohmann::json &body,
206   - const std::string &adr,
207   - int port = 80) const = 0;
  34 + //! \brief Virtual dtor
  35 + virtual ~IHttpHandler() = default;
  36 +
  37 + //! \brief Virtual function that should send a given message to a specified
  38 + //! host and return the response.
  39 + //!
  40 + //! \param msg String that contains the message that should be sent to the
  41 + //! specified address \param adr String that contains an ip or hostname in
  42 + //! dotted decimal notation like "192.168.2.1" \param port Optional integer
  43 + //! that specifies the port to which the request should be sent to. Default is
  44 + //! 80 \return String containing the response of the host
  45 + virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const = 0;
  46 +
  47 + //! \brief Virtual function that should given message to a specified host and
  48 + //! return the body of the response.
  49 + //!
  50 + //! Note if no body is found a runtime error is thrown!
  51 + //! \param msg String that contains the message that should sent to the
  52 + //! specified address \param adr String that contains an ip or hostname in
  53 + //! dotted decimal notation like "192.168.2.1" \param port Optional integer
  54 + //! that specifies the port to which the request should be sent. Default is 80
  55 + //! \return String containing the body of the response of the host
  56 + virtual std::string sendGetHTTPBody(const std::string& msg, const std::string& adr, int port = 80) const = 0;
  57 +
  58 + //! \brief Virtual function that should send a multicast request with a
  59 + //! specified message.
  60 + //!
  61 + //! \param msg String that contains the request that should be sent to the
  62 + //! specified address \param adr Optional String that contains an ip or
  63 + //! hostname in dotted decimal notation, default is "239.255.255.250" \param
  64 + //! port Optional integer that specifies the port to which the request should
  65 + //! be sent. Default is 1900 \param timeout Optional Integer that specifies
  66 + //! the timeout of the request in seconds. Default is 5 \return Vector
  67 + //! containing strings of each answer received
  68 + virtual std::vector<std::string> sendMulticast(
  69 + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const = 0;
  70 +
  71 + //! \brief Virtual function that should send a HTTP request with the given
  72 + //! method to the specified host and return the body of the response.
  73 + //!
  74 + //! Note body can also be left empty!
  75 + //! \param method String that contains the HTTP method type e.g. GET, HEAD,
  76 + //! POST, PUT, DELETE, ... \param uri String that contains the uniform
  77 + //! resource identifier \param content_type String that contains the
  78 + //! type(MIME) of the body data e.g. "text/html", "application/json", ...
  79 + //! \param body String that contains the data of the request
  80 + //! \param adr String that contains an ip or hostname in dotted decimal
  81 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  82 + //! the port to which the request is sent to. Default is 80 \return String
  83 + //! containing the body of the response of the host
  84 + virtual std::string sendHTTPRequest(std::string method, std::string uri, std::string content_type, std::string body,
  85 + const std::string& adr, int port = 80) const = 0;
  86 +
  87 + //! \brief Virtual function that should send a HTTP GET request to the
  88 + //! specified host and return the body of the response.
  89 + //!
  90 + //! Note body can also be left empty!
  91 + //! \param uri String that contains the uniform resource identifier
  92 + //! \param content_type String that contains the type(MIME) of the body data
  93 + //! e.g. "text/html", "application/json", ... \param body String that contains
  94 + //! the data of the request \param adr String that contains an ip or hostname
  95 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  96 + //! that specifies the port to which the request is sent to. Default is 80
  97 + //! \return String containing the body of the response of the host
  98 + virtual std::string GETString(
  99 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0;
  100 +
  101 + //! \brief Virtual function that should send a HTTP POST request to the
  102 + //! specified host and returns the body of the response.
  103 + //!
  104 + //! Note body can also be left empty!
  105 + //! \param uri String that contains the uniform resource identifier
  106 + //! \param content_type String that contains the type(MIME) of the body data
  107 + //! e.g. "text/html", "application/json", ... \param body String that contains
  108 + //! the data of the request \param adr String that contains an ip or hostname
  109 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  110 + //! that specifies the port to which the request is sent to. Default is 80
  111 + //! \return String containing the body of the response of the host
  112 + virtual std::string POSTString(
  113 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0;
  114 +
  115 + //! \brief Virtual function that should send a HTTP PUT request to the
  116 + //! specified host and return the body of the response.
  117 + //!
  118 + //! Note body can also be left empty!
  119 + //! \param uri String that contains the uniform resource identifier
  120 + //! \param content_type String that contains the type(MIME) of the body data
  121 + //! e.g. "text/html", "application/json", ... \param body String that contains
  122 + //! the data of the request \param adr String that contains an ip or hostname
  123 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  124 + //! that specifies the port to which the request is sent to. Default is 80
  125 + //! \return String containing the body of the response of the host
  126 + virtual std::string PUTString(
  127 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0;
  128 +
  129 + //! \brief Virtual function that should send a HTTP DELETE request to the
  130 + //! specified host and return the body of the response.
  131 + //!
  132 + //! Note body can also be left empty!
  133 + //! \param uri String that contains the uniform resource identifier
  134 + //! \param content_type String that contains the type(MIME) of the body data
  135 + //! e.g. "text/html", "application/json", ... \param body String that contains
  136 + //! the data of the request \param adr String that contains an ip or hostname
  137 + //! in dotted decimal notation like "192.168.2.1" \param port Optional integer
  138 + //! that specifies the port to which the request is sent to. Default is 80
  139 + //! \return String containing the body of the response of the host
  140 + virtual std::string DELETEString(
  141 + std::string uri, std::string content_type, std::string body, const std::string& adr, int port = 80) const = 0;
  142 +
  143 + //! \brief Virtual function that should send a HTTP GET request to the
  144 + //! specified host and return the body of the response.
  145 + //!
  146 + //! Note body can also be left empty!
  147 + //! \param uri String that contains the uniform resource identifier
  148 + //! \param body nlohmann::json that contains the data of the request
  149 + //! \param adr String that contains an ip or hostname in dotted decimal
  150 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  151 + //! the port to which the request is sent to. Default is 80 \return
  152 + //! nlohmann::json containing the parsed body of the response of the host
  153 + virtual nlohmann::json GETJson(
  154 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
  155 +
  156 + //! \brief Virtual function that should send a HTTP POST request to the
  157 + //! specified host and return the body of the response.
  158 + //!
  159 + //! Note body can also be left empty!
  160 + //! \param uri String that contains the uniform resource identifier
  161 + //! \param body nlohmann::json that contains the data of the request
  162 + //! \param adr String that contains an ip or hostname in dotted decimal
  163 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  164 + //! the port to which the request is sent to. Default is 80 \return
  165 + //! nlohmann::json containing the parsed body of the response of the host
  166 + virtual nlohmann::json POSTJson(
  167 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
  168 +
  169 + //! \brief Virtual function that should send a HTTP PUT request to the
  170 + //! specified host and return the body of the response.
  171 + //!
  172 + //! Note body can also be left empty!
  173 + //! \param uri String that contains the uniform resource identifier
  174 + //! \param body nlohmann::json that contains the data of the request
  175 + //! \param adr String that contains an ip or hostname in dotted decimal
  176 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  177 + //! the port to which the request is sent to. Default is 80 \return
  178 + //! nlohmann::json containing the parsed body of the response of the host
  179 + virtual nlohmann::json PUTJson(
  180 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
  181 +
  182 + //! \brief Virtual function that should send a HTTP DELETE request to the
  183 + //! specified host and return the body of the response.
  184 + //!
  185 + //! Note body can also be left empty!
  186 + //! \param uri String that contains the uniform resource identifier
  187 + //! \param body nlohmann::json that contains the data of the request
  188 + //! \param adr String that contains an ip or hostname in dotted decimal
  189 + //! notation like "192.168.2.1" \param port Optional integer that specifies
  190 + //! the port to which the request is sent to. Default is 80 \return
  191 + //! nlohmann::json containing the parsed body of the response of the host
  192 + virtual nlohmann::json DELETEJson(
  193 + std::string uri, const nlohmann::json& body, const std::string& adr, int port = 80) const = 0;
208 194 };
209 195  
210 196 #endif
... ...
hueplusplus/include/LinHttpHandler.h
1 1 /**
2   - \file LinHttpHandler.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
6   -
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  2 + \file LinHttpHandler.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _LINHTTPHANDLER_H
... ... @@ -28,32 +28,30 @@
28 28 #include "json/json.hpp"
29 29  
30 30 //! Class to handle http requests and multicast requests on linux systems
31   -class LinHttpHandler : public BaseHttpHandler {
  31 +class LinHttpHandler : public BaseHttpHandler
  32 +{
32 33 public:
33   - //! \brief Function that sends a given message to the specified host and
34   - //! returns the response.
35   - //!
36   - //! \param msg String that contains the message that is sent to the specified
37   - //! address \param adr String that contains an ip or hostname in dotted
38   - //! decimal notation like "192.168.2.1" \param port Optional integer that
39   - //! specifies the port to which the request is sent to. Default is 80 \return
40   - //! String containing the response of the host
41   - virtual std::string send(const std::string &msg, const std::string &adr,
42   - int port = 80) const;
43   -
44   - //! \brief Function that sends a multicast request with the specified message.
45   - //!
46   - //! \param msg String that contains the request that is sent to the specified
47   - //! address \param adr Optional String that contains an ip or hostname in
48   - //! dotted decimal notation, default is "239.255.255.250" \param port Optional
49   - //! integer that specifies the port to which the request is sent. Default is
50   - //! 1900 \param timeout Optional Integer that specifies the timeout of the
51   - //! request in seconds. Default is 5 \return Vector containing strings of each
52   - //! answer received
53   - virtual std::vector<std::string>
54   - sendMulticast(const std::string &msg,
55   - const std::string &adr = "239.255.255.250", int port = 1900,
56   - int timeout = 5) const;
  34 + //! \brief Function that sends a given message to the specified host and
  35 + //! returns the response.
  36 + //!
  37 + //! \param msg String that contains the message that is sent to the specified
  38 + //! address \param adr String that contains an ip or hostname in dotted
  39 + //! decimal notation like "192.168.2.1" \param port Optional integer that
  40 + //! specifies the port to which the request is sent to. Default is 80 \return
  41 + //! String containing the response of the host
  42 + virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const;
  43 +
  44 + //! \brief Function that sends a multicast request with the specified message.
  45 + //!
  46 + //! \param msg String that contains the request that is sent to the specified
  47 + //! address \param adr Optional String that contains an ip or hostname in
  48 + //! dotted decimal notation, default is "239.255.255.250" \param port Optional
  49 + //! integer that specifies the port to which the request is sent. Default is
  50 + //! 1900 \param timeout Optional Integer that specifies the timeout of the
  51 + //! request in seconds. Default is 5 \return Vector containing strings of each
  52 + //! answer received
  53 + virtual std::vector<std::string> sendMulticast(
  54 + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const;
57 55 };
58 56  
59 57 #endif
... ...
hueplusplus/include/SimpleBrightnessStrategy.h
1 1 /**
2   - \file SimpleBrightnessStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file SimpleBrightnessStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _SIMPLE_BRIGHTNESS_STRATEGY_H
... ... @@ -24,29 +24,29 @@
24 24 #include "HueLight.h"
25 25  
26 26 //! Class implementing the functions of BrightnessStrategy
27   -class SimpleBrightnessStrategy : public BrightnessStrategy {
  27 +class SimpleBrightnessStrategy : public BrightnessStrategy
  28 +{
28 29 public:
29   - //! \brief Function for changing a lights brightness with a specified
30   - //! transition.
31   - //!
32   - //! \param bri The brightness raning from 0 = off to 255 = fully lit
33   - //! \param transition The time it takes to fade to the new brightness in
34   - //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
35   - //! light A reference of the light
36   - bool setBrightness(unsigned int bri, uint8_t transition,
37   - HueLight &light) const override;
38   - //! \brief Function that returns the current brightness of the light
39   - //!
40   - //! Updates the lights state by calling refreshState()
41   - //! \param light A reference of the light
42   - //! \return Unsigned int representing the brightness
43   - unsigned int getBrightness(HueLight &light) const override;
44   - //! \brief Function that returns the current brightness of the light
45   - //!
46   - //! \note This does not update the lights state
47   - //! \param light A const reference of the light
48   - //! \return Unsigned int representing the brightness
49   - unsigned int getBrightness(const HueLight &light) const override;
  30 + //! \brief Function for changing a lights brightness with a specified
  31 + //! transition.
  32 + //!
  33 + //! \param bri The brightness raning from 0 = off to 255 = fully lit
  34 + //! \param transition The time it takes to fade to the new brightness in
  35 + //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
  36 + //! light A reference of the light
  37 + bool setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const override;
  38 + //! \brief Function that returns the current brightness of the light
  39 + //!
  40 + //! Updates the lights state by calling refreshState()
  41 + //! \param light A reference of the light
  42 + //! \return Unsigned int representing the brightness
  43 + unsigned int getBrightness(HueLight& light) const override;
  44 + //! \brief Function that returns the current brightness of the light
  45 + //!
  46 + //! \note This does not update the lights state
  47 + //! \param light A const reference of the light
  48 + //! \return Unsigned int representing the brightness
  49 + unsigned int getBrightness(const HueLight& light) const override;
50 50 };
51 51  
52 52 #endif
... ...
hueplusplus/include/SimpleColorHueStrategy.h
1 1 /**
2   - \file SimpleColorHueStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file SimpleColorHueStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _SIMPLE_COLOR_HUE_STRATEGY_H
... ... @@ -24,134 +24,126 @@
24 24 #include "HueLight.h"
25 25  
26 26 //! Class implementing the functions of ColorHueStrategy
27   -class SimpleColorHueStrategy : public ColorHueStrategy {
  27 +class SimpleColorHueStrategy : public ColorHueStrategy
  28 +{
28 29 public:
29   - //! \brief Function for changing a lights color in hue with a specified
30   - //! transition.
31   - //!
32   - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
33   - //! green and 46920 is blue. \param hue The hue of the color \param transition
34   - //! The time it takes to fade to the new color in multiples of 100ms, 4 =
35   - //! 400ms and should be seen as the default \param light A reference of the
36   - //! light
37   - bool setColorHue(uint16_t hue, uint8_t transition,
38   - HueLight &light) const override;
39   - //! \brief Function for changing a lights color in saturation with a specified
40   - //! transition.
41   - //!
42   - //! The saturation ranges from 0 to 254, whereas 0 is least saturated (white)
43   - //! and 254 is most saturated (vibrant). \param sat The saturation of the
44   - //! color \param transition The time it takes to fade to the new color in
45   - //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
46   - //! light A reference of the light
47   - bool setColorSaturation(uint8_t sat, uint8_t transition,
48   - HueLight &light) const override;
49   - //! \brief Function for changing a lights color in hue and saturation format
50   - //! with a specified transition.
51   - //!
52   - //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
53   - //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is
54   - //! least saturated (white) and 254 is most saturated (vibrant). \param hue
55   - //! The hue of the color \param sat The saturation of the color \param
56   - //! transition The time it takes to fade to the new color in multiples of
57   - //! 100ms, 4 = 400ms and should be seen as the default \param light A
58   - //! reference of the light
59   - bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition,
60   - HueLight &light) const override;
61   - //! \brief Function for changing a lights color in CIE format with a specified
62   - //! transition.
63   - //!
64   - //! \param x The x coordinate in CIE, ranging from 0 to 1
65   - //! \param y The y coordinate in CIE, ranging from 0 to 1
66   - //! \param transition The time it takes to fade to the new color in multiples
67   - //! of 100ms, 4 = 400ms and should be seen as the default \param light A
68   - //! reference of the light
69   - bool setColorXY(float x, float y, uint8_t transition,
70   - HueLight &light) const override;
71   - //! \brief Function for changing a lights color in rgb format with a specified
72   - //! transition.
73   - //!
74   - //! Red, green and blue are ranging from 0 to 255.
75   - //! \param r The red portion of the color
76   - //! \param g The green portion of the color
77   - //! \param b The blue portion of the color
78   - //! \param transition The time it takes to fade to the new color in multiples
79   - //! of 100ms, 4 = 400ms and should be seen as the default \param light A
80   - //! reference of the light
81   - bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition,
82   - HueLight &light) const override;
83   - //! \brief Function for turning on/off the color loop feature of a light.
84   - //!
85   - //! Can be theoretically set for any light, but it only works for lights that
86   - //! support this feature. When this feature is activated the light will fade
87   - //! through every color on the current hue and saturation settings. Notice
88   - //! that none of the setter functions check whether this feature is enabled
89   - //! and the colorloop can only be disabled with this function or by simply
90   - //! calling Off()/OffNoRefresh() and then On()/OnNoRefresh(), so you could
91   - //! alternatively call Off() and then use any of the setter functions.
92   - //! \param on Boolean to turn this feature on or off, true/1 for on and
93   - //! false/0 for off \param light A reference of the light
94   - bool setColorLoop(bool on, HueLight &light) const override;
95   - //! \brief Function that lets the light perform one breath cycle in the
96   - //! specified color.
97   - //!
98   - //! \note It uses this_thread::sleep_for to accomodate for the time an \ref
99   - //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and
100   - //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0
101   - //! to 254, whereas 0 is least saturated (white) and 254 is most saturated
102   - //! (vibrant). \param hue The hue of the color \param sat The saturation of
103   - //! the color \param light A reference of the light
104   - bool alertHueSaturation(uint16_t hue, uint8_t sat,
105   - HueLight &light) const override;
106   - //! \brief Function that lets the light perform one breath cycle in the
107   - //! specified color.
108   - //!
109   - //! \note It uses this_thread::sleep_for to accomodate for the time an \ref
110   - //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0
111   - //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A
112   - //! reference of the light
113   - bool alertXY(float x, float y, HueLight &light) const override;
114   - //! \brief Function that lets the light perform one breath cycle in the
115   - //! specified color.
116   - //!
117   - //! \note It uses this_thread::sleep_for to accomodate for the time an \ref
118   - //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255.
119   - //! \param r The red portion of the color
120   - //! \param g The green portion of the color
121   - //! \param b The blue portion of the color
122   - //! \param light A reference of the light
123   - bool alertRGB(uint8_t r, uint8_t g, uint8_t b,
124   - HueLight &light) const override;
125   - //! \brief Function that returns the current color of the light as hue and
126   - //! saturation
127   - //!
128   - //! Updates the lights state by calling refreshState()
129   - //! \param light A reference of the light
130   - //! \return Pair containing the hue as first value and saturation as second
131   - //! value
132   - std::pair<uint16_t, uint8_t>
133   - getColorHueSaturation(HueLight &light) const override;
134   - //! \brief Function that returns the current color of the light as hue and
135   - //! saturation
136   - //!
137   - //! \note This does not update the lights state
138   - //! \param light A const reference of the light
139   - //! \return Pair containing the hue as first value and saturation as second
140   - //! value
141   - std::pair<uint16_t, uint8_t>
142   - getColorHueSaturation(const HueLight &light) const override;
143   - //! \brief Function that returns the current color of the light as xy
144   - //!
145   - //! Updates the lights state by calling refreshState()
146   - //! \param light A reference of the light
147   - //! \return Pair containing the x as first value and y as second value
148   - std::pair<float, float> getColorXY(HueLight &light) const override;
149   - //! \brief Function that returns the current color of the light as xy
150   - //!
151   - //! \note This does not update the lights state
152   - //! \param light A const reference of the light
153   - //! \return Pair containing the x as first value and y as second value
154   - std::pair<float, float> getColorXY(const HueLight &light) const override;
  30 + //! \brief Function for changing a lights color in hue with a specified
  31 + //! transition.
  32 + //!
  33 + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
  34 + //! green and 46920 is blue. \param hue The hue of the color \param transition
  35 + //! The time it takes to fade to the new color in multiples of 100ms, 4 =
  36 + //! 400ms and should be seen as the default \param light A reference of the
  37 + //! light
  38 + bool setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const override;
  39 + //! \brief Function for changing a lights color in saturation with a specified
  40 + //! transition.
  41 + //!
  42 + //! The saturation ranges from 0 to 254, whereas 0 is least saturated (white)
  43 + //! and 254 is most saturated (vibrant). \param sat The saturation of the
  44 + //! color \param transition The time it takes to fade to the new color in
  45 + //! multiples of 100ms, 4 = 400ms and should be seen as the default \param
  46 + //! light A reference of the light
  47 + bool setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const override;
  48 + //! \brief Function for changing a lights color in hue and saturation format
  49 + //! with a specified transition.
  50 + //!
  51 + //! The hue ranges from 0 to 65535, whereas 65535 and 0 are red, 25500 is
  52 + //! green and 46920 is blue. The saturation ranges from 0 to 254, whereas 0 is
  53 + //! least saturated (white) and 254 is most saturated (vibrant). \param hue
  54 + //! The hue of the color \param sat The saturation of the color \param
  55 + //! transition The time it takes to fade to the new color in multiples of
  56 + //! 100ms, 4 = 400ms and should be seen as the default \param light A
  57 + //! reference of the light
  58 + bool setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const override;
  59 + //! \brief Function for changing a lights color in CIE format with a specified
  60 + //! transition.
  61 + //!
  62 + //! \param x The x coordinate in CIE, ranging from 0 to 1
  63 + //! \param y The y coordinate in CIE, ranging from 0 to 1
  64 + //! \param transition The time it takes to fade to the new color in multiples
  65 + //! of 100ms, 4 = 400ms and should be seen as the default \param light A
  66 + //! reference of the light
  67 + bool setColorXY(float x, float y, uint8_t transition, HueLight& light) const override;
  68 + //! \brief Function for changing a lights color in rgb format with a specified
  69 + //! transition.
  70 + //!
  71 + //! Red, green and blue are ranging from 0 to 255.
  72 + //! \param r The red portion of the color
  73 + //! \param g The green portion of the color
  74 + //! \param b The blue portion of the color
  75 + //! \param transition The time it takes to fade to the new color in multiples
  76 + //! of 100ms, 4 = 400ms and should be seen as the default \param light A
  77 + //! reference of the light
  78 + bool setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t transition, HueLight& light) const override;
  79 + //! \brief Function for turning on/off the color loop feature of a light.
  80 + //!
  81 + //! Can be theoretically set for any light, but it only works for lights that
  82 + //! support this feature. When this feature is activated the light will fade
  83 + //! through every color on the current hue and saturation settings. Notice
  84 + //! that none of the setter functions check whether this feature is enabled
  85 + //! and the colorloop can only be disabled with this function or by simply
  86 + //! calling Off()/OffNoRefresh() and then On()/OnNoRefresh(), so you could
  87 + //! alternatively call Off() and then use any of the setter functions.
  88 + //! \param on Boolean to turn this feature on or off, true/1 for on and
  89 + //! false/0 for off \param light A reference of the light
  90 + bool setColorLoop(bool on, HueLight& light) const override;
  91 + //! \brief Function that lets the light perform one breath cycle in the
  92 + //! specified color.
  93 + //!
  94 + //! \note It uses this_thread::sleep_for to accomodate for the time an \ref
  95 + //! HueLight::alert() needs The hue ranges from 0 to 65535, whereas 65535 and
  96 + //! 0 are red, 25500 is green and 46920 is blue. The saturation ranges from 0
  97 + //! to 254, whereas 0 is least saturated (white) and 254 is most saturated
  98 + //! (vibrant). \param hue The hue of the color \param sat The saturation of
  99 + //! the color \param light A reference of the light
  100 + bool alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const override;
  101 + //! \brief Function that lets the light perform one breath cycle in the
  102 + //! specified color.
  103 + //!
  104 + //! \note It uses this_thread::sleep_for to accomodate for the time an \ref
  105 + //! HueLight::alert() needs \param x The x coordinate in CIE, ranging from 0
  106 + //! to 1 \param y The y coordinate in CIE, ranging from 0 to 1 \param light A
  107 + //! reference of the light
  108 + bool alertXY(float x, float y, HueLight& light) const override;
  109 + //! \brief Function that lets the light perform one breath cycle in the
  110 + //! specified color.
  111 + //!
  112 + //! \note It uses this_thread::sleep_for to accomodate for the time an \ref
  113 + //! HueLight::alert() needs Red, green and blue are ranging from 0 to 255.
  114 + //! \param r The red portion of the color
  115 + //! \param g The green portion of the color
  116 + //! \param b The blue portion of the color
  117 + //! \param light A reference of the light
  118 + bool alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const override;
  119 + //! \brief Function that returns the current color of the light as hue and
  120 + //! saturation
  121 + //!
  122 + //! Updates the lights state by calling refreshState()
  123 + //! \param light A reference of the light
  124 + //! \return Pair containing the hue as first value and saturation as second
  125 + //! value
  126 + std::pair<uint16_t, uint8_t> getColorHueSaturation(HueLight& light) const override;
  127 + //! \brief Function that returns the current color of the light as hue and
  128 + //! saturation
  129 + //!
  130 + //! \note This does not update the lights state
  131 + //! \param light A const reference of the light
  132 + //! \return Pair containing the hue as first value and saturation as second
  133 + //! value
  134 + std::pair<uint16_t, uint8_t> getColorHueSaturation(const HueLight& light) const override;
  135 + //! \brief Function that returns the current color of the light as xy
  136 + //!
  137 + //! Updates the lights state by calling refreshState()
  138 + //! \param light A reference of the light
  139 + //! \return Pair containing the x as first value and y as second value
  140 + std::pair<float, float> getColorXY(HueLight& light) const override;
  141 + //! \brief Function that returns the current color of the light as xy
  142 + //!
  143 + //! \note This does not update the lights state
  144 + //! \param light A const reference of the light
  145 + //! \return Pair containing the x as first value and y as second value
  146 + std::pair<float, float> getColorXY(const HueLight& light) const override;
155 147 };
156 148  
157 149 #endif
... ...
hueplusplus/include/SimpleColorTemperatureStrategy.h
1 1 /**
2   - \file SimpleColorTemperatureStrategy.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file SimpleColorTemperatureStrategy.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _SIMPLE_COLOR_TEMPERATURE_STRATEGY_H
... ... @@ -24,40 +24,40 @@
24 24 #include "HueLight.h"
25 25  
26 26 //! Class implementing the functions of ColorTemperatureStrategy
27   -class SimpleColorTemperatureStrategy : public ColorTemperatureStrategy {
  27 +class SimpleColorTemperatureStrategy : public ColorTemperatureStrategy
  28 +{
28 29 public:
29   - //! \brief Function for changing a lights color temperature in mired with a
30   - //! specified transition.
31   - //!
32   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
33   - //! and 500 is warm. \param mired The color temperature in mired \param
34   - //! transition The time it takes to fade to the new color in multiples of
35   - //! 100ms, 4 = 400ms and should be seen as the default \param light A
36   - //! reference of the light
37   - bool setColorTemperature(unsigned int mired, uint8_t transition,
38   - HueLight &light) const override;
39   - //! \brief Function that lets the light perform one breath cycle in the
40   - //! specified color.
41   - //!
42   - //! It uses this_thread::sleep_for to accomodate for the time an \ref
43   - //! HueLight::alert() needs The color temperature in mired ranges from 153 to
44   - //! 500 whereas 153 is cold and 500 is warm. \param mired The color
45   - //! temperature in mired \param light A reference of the light
46   - bool alertTemperature(unsigned int mired, HueLight &light) const override;
47   - //! \brief Function that returns the current color temperature of the light
48   - //!
49   - //! Updates the lights state by calling refreshState()
50   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
51   - //! and 500 is warm. \param light A reference of the light \return Unsigned
52   - //! int representing the color temperature in mired
53   - unsigned int getColorTemperature(HueLight &light) const override;
54   - //! \brief Function that returns the current color temperature of the light
55   - //!
56   - //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
57   - //! and 500 is warm. \note This does not update the lights state \param light
58   - //! A const reference of the light \return Unsigned int representing the color
59   - //! temperature in mired
60   - unsigned int getColorTemperature(const HueLight &light) const override;
  30 + //! \brief Function for changing a lights color temperature in mired with a
  31 + //! specified transition.
  32 + //!
  33 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  34 + //! and 500 is warm. \param mired The color temperature in mired \param
  35 + //! transition The time it takes to fade to the new color in multiples of
  36 + //! 100ms, 4 = 400ms and should be seen as the default \param light A
  37 + //! reference of the light
  38 + bool setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const override;
  39 + //! \brief Function that lets the light perform one breath cycle in the
  40 + //! specified color.
  41 + //!
  42 + //! It uses this_thread::sleep_for to accomodate for the time an \ref
  43 + //! HueLight::alert() needs The color temperature in mired ranges from 153 to
  44 + //! 500 whereas 153 is cold and 500 is warm. \param mired The color
  45 + //! temperature in mired \param light A reference of the light
  46 + bool alertTemperature(unsigned int mired, HueLight& light) const override;
  47 + //! \brief Function that returns the current color temperature of the light
  48 + //!
  49 + //! Updates the lights state by calling refreshState()
  50 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  51 + //! and 500 is warm. \param light A reference of the light \return Unsigned
  52 + //! int representing the color temperature in mired
  53 + unsigned int getColorTemperature(HueLight& light) const override;
  54 + //! \brief Function that returns the current color temperature of the light
  55 + //!
  56 + //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold
  57 + //! and 500 is warm. \note This does not update the lights state \param light
  58 + //! A const reference of the light \return Unsigned int representing the color
  59 + //! temperature in mired
  60 + unsigned int getColorTemperature(const HueLight& light) const override;
61 61 };
62 62  
63 63 #endif
... ...
hueplusplus/include/UPnP.h
1 1 /**
2   - \file UPnP.h
3   - Copyright Notice\n
4   - Copyright (C) 2017 Jan Rogall - developer\n
5   - Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file UPnP.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   - This program is free software; you can redistribute it and/or modify
8   - it under the terms of the GNU General Public License as published by
9   - the Free Software Foundation; either version 3 of the License, or
10   - (at your option) any later version.
11   - This program is distributed in the hope that it will be useful,
12   - but WITHOUT ANY WARRANTY; without even the implied warranty of
13   - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   - GNU General Public License for more details.
15   - You should have received a copy of the GNU General Public License
16   - along with this program; if not, write to the Free Software Foundation,
17   - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _UPNP_H
... ... @@ -27,17 +27,17 @@
27 27 #include "IHttpHandler.h"
28 28  
29 29 //! Class that looks for UPnP devices using an m-search package
30   -class UPnP {
  30 +class UPnP
  31 +{
31 32 public:
32   - //! \brief Function that searches for UPnP devices and returns all found ones.
33   - //!
34   - //! It does it by sending an m-search packet and waits for all responses.
35   - //! Since responses can be received multiple times this function conveniently
36   - //! removes all duplicates. \param handler HttpHandler of type \ref
37   - //! IHttpHandler for communication with the bridge \return A vector containing
38   - //! pairs of address and name of all found devices
39   - std::vector<std::pair<std::string, std::string>>
40   - getDevices(std::shared_ptr<const IHttpHandler> handler);
  33 + //! \brief Function that searches for UPnP devices and returns all found ones.
  34 + //!
  35 + //! It does it by sending an m-search packet and waits for all responses.
  36 + //! Since responses can be received multiple times this function conveniently
  37 + //! removes all duplicates. \param handler HttpHandler of type \ref
  38 + //! IHttpHandler for communication with the bridge \return A vector containing
  39 + //! pairs of address and name of all found devices
  40 + std::vector<std::pair<std::string, std::string>> getDevices(std::shared_ptr<const IHttpHandler> handler);
41 41 };
42 42  
43 43 #endif
... ...
hueplusplus/include/Units.h
1 1 #ifndef _UNITS_H
2 2 #define _UNITS_H
3 3  
4   -struct Kelvin {
5   - int value;
  4 +struct Kelvin
  5 +{
  6 + int value;
6 7 };
7 8  
8   -struct Mired {
9   - int value;
  9 +struct Mired
  10 +{
  11 + int value;
10 12 };
11 13  
12   -struct Brightness {
13   - int value;
  14 +struct Brightness
  15 +{
  16 + int value;
14 17 };
15 18  
16   -struct HueSaturation {
17   - int hue;
18   - int saturation;
  19 +struct HueSaturation
  20 +{
  21 + int hue;
  22 + int saturation;
19 23 };
20 24  
21   -struct XY {
22   - float x;
23   - float y;
  25 +struct XY
  26 +{
  27 + float x;
  28 + float y;
24 29 };
25 30  
26   -struct RGB {
27   - uint8_t r;
28   - uint8_t g;
29   - uint8_t b;
  31 +struct RGB
  32 +{
  33 + uint8_t r;
  34 + uint8_t g;
  35 + uint8_t b;
30 36 };
31 37  
32 38 #endif
... ...
hueplusplus/include/Utils.h 0 → 100644
  1 +/**
  2 + \file Utils.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2020 Jan Rogall - developer\n
  5 + Copyright (C) 2020 Moritz Wirger - developer\n
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18 +**/
  19 +
  20 +#ifndef _UTILS_H
  21 +#define _UTILS_H
  22 +
  23 +#include "json/json.hpp"
  24 +
  25 +namespace utils
  26 +{
  27 + //! \brief Function for validating that a request was executed correctly
  28 + //!
  29 + //! \param request The request that was sent initially
  30 + //! \param reply The reply that was received
  31 + //! \param lightId The identifier of the light
  32 + //! \return True if request was executed correctly
  33 + bool validateReplyForLight(nlohmann::json request, nlohmann::json reply, int lightId);
  34 +} // namespace utils
  35 +
  36 +#endif
0 37 \ No newline at end of file
... ...
hueplusplus/include/WinHttpHandler.h
1 1 /**
2   -\file WinHttpHandler.h
3   -Copyright Notice\n
4   -Copyright (C) 2017 Jan Rogall - developer\n
5   -Copyright (C) 2017 Moritz Wirger - developer\n
  2 + \file WinHttpHandler.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2017 Jan Rogall - developer\n
  5 + Copyright (C) 2017 Moritz Wirger - developer\n
6 6  
7   -This program is free software; you can redistribute it and/or modify
8   -it under the terms of the GNU General Public License as published by
9   -the Free Software Foundation; either version 3 of the License, or
10   -(at your option) any later version.
11   -This program is distributed in the hope that it will be useful,
12   -but WITHOUT ANY WARRANTY; without even the implied warranty of
13   -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   -GNU General Public License for more details.
15   -You should have received a copy of the GNU General Public License
16   -along with this program; if not, write to the Free Software Foundation,
17   -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 3 of the License, or
  10 + (at your option) any later version.
  11 + This program is distributed in the hope that it will be useful,
  12 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + GNU General Public License for more details.
  15 + You should have received a copy of the GNU General Public License
  16 + along with this program; if not, write to the Free Software Foundation,
  17 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18 **/
19 19  
20 20 #ifndef _WINHTTPHANDLER_H
... ... @@ -22,46 +22,45 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 22  
23 23 #include <string>
24 24 #include <vector>
  25 +
25 26 #include <winsock2.h>
26 27  
27 28 #include "BaseHttpHandler.h"
28 29  
29 30 //! Class to handle http requests and multicast requests on windows systems
30   -class WinHttpHandler : public BaseHttpHandler {
  31 +class WinHttpHandler : public BaseHttpHandler
  32 +{
31 33 public:
32   - //! \brief Ctor needed for initializing wsaData
33   - WinHttpHandler();
  34 + //! \brief Ctor needed for initializing wsaData
  35 + WinHttpHandler();
34 36  
35   - //! \brief Dtor needed for wsaData cleanup
36   - ~WinHttpHandler();
  37 + //! \brief Dtor needed for wsaData cleanup
  38 + ~WinHttpHandler();
37 39  
38   - //! \brief Function that sends a given message to the specified host and
39   - //! returns the response.
40   - //!
41   - //! \param msg String that contains the message that is sent to the specified
42   - //! address \param adr String that contains an ip or hostname in dotted
43   - //! decimal notation like "192.168.2.1" \param port Optional integer that
44   - //! specifies the port to which the request is sent to. Default is 80 \return
45   - //! String containing the response of the host
46   - std::string send(const std::string &msg, const std::string &adr,
47   - int port = 80) const;
  40 + //! \brief Function that sends a given message to the specified host and
  41 + //! returns the response.
  42 + //!
  43 + //! \param msg String that contains the message that is sent to the specified
  44 + //! address \param adr String that contains an ip or hostname in dotted
  45 + //! decimal notation like "192.168.2.1" \param port Optional integer that
  46 + //! specifies the port to which the request is sent to. Default is 80 \return
  47 + //! String containing the response of the host
  48 + std::string send(const std::string& msg, const std::string& adr, int port = 80) const;
48 49  
49   - //! \brief Function that sends a multicast request with the specified message.
50   - //!
51   - //! \param msg String that contains the request that is sent to the specified
52   - //! address \param adr Optional String that contains an ip or hostname in
53   - //! dotted decimal notation, default is "239.255.255.250" \param port Optional
54   - //! integer that specifies the port to which the request is sent. Default is
55   - //! 1900 \param timeout Optional Integer that specifies the timeout of the
56   - //! request in seconds. Default is 5 \return Vector containing strings of each
57   - //! answer received
58   - std::vector<std::string>
59   - sendMulticast(const std::string &msg,
60   - const std::string &adr = "239.255.255.250", int port = 1900,
61   - int timeout = 5) const;
  50 + //! \brief Function that sends a multicast request with the specified message.
  51 + //!
  52 + //! \param msg String that contains the request that is sent to the specified
  53 + //! address \param adr Optional String that contains an ip or hostname in
  54 + //! dotted decimal notation, default is "239.255.255.250" \param port Optional
  55 + //! integer that specifies the port to which the request is sent. Default is
  56 + //! 1900 \param timeout Optional Integer that specifies the timeout of the
  57 + //! request in seconds. Default is 5 \return Vector containing strings of each
  58 + //! answer received
  59 + std::vector<std::string> sendMulticast(
  60 + const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const;
62 61  
63 62 private:
64   - WSADATA wsaData;
  63 + WSADATA wsaData;
65 64 };
66 65  
67 66 #endif
... ...
hueplusplus/test/CMakeLists.txt
  1 +# Set cmake cxx standard to 14
  2 +set(CMAKE_CXX_STANDARD 14)
  3 +
1 4 # Download and unpack googletest at configure time
2 5 configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
3 6 execute_process(COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} .
... ...
hueplusplus/test/mocks/mock_BaseHttpHandler.h
... ... @@ -26,18 +26,16 @@
26 26 #include <gmock/gmock.h>
27 27  
28 28 #include "../hueplusplus/include/BaseHttpHandler.h"
29   -#include "../hueplusplus/include/json/json.h"
  29 +#include "../hueplusplus/include/json/json.hpp"
30 30  
31 31 //! Mock Class
32   -class MockBaseHttpHandler : public BaseHttpHandler {
  32 +class MockBaseHttpHandler : public BaseHttpHandler
  33 +{
33 34 public:
34   - MOCK_CONST_METHOD3(send, std::string(const std::string &msg,
35   - const std::string &adr, int port));
  35 + MOCK_CONST_METHOD3(send, std::string(const std::string& msg, const std::string& adr, int port));
36 36  
37   - MOCK_CONST_METHOD4(sendMulticast,
38   - std::vector<std::string>(const std::string &msg,
39   - const std::string &adr, int port,
40   - int timeout));
  37 + MOCK_CONST_METHOD4(
  38 + sendMulticast, std::vector<std::string>(const std::string& msg, const std::string& adr, int port, int timeout));
41 39 };
42 40  
43 41 #endif
... ...
hueplusplus/test/mocks/mock_HttpHandler.h
... ... @@ -26,63 +26,47 @@
26 26 #include <gmock/gmock.h>
27 27  
28 28 #include "../hueplusplus/include/IHttpHandler.h"
29   -#include "../hueplusplus/include/json/json.h"
  29 +#include "../hueplusplus/include/json/json.hpp"
  30 +
30 31  
31 32 //! Mock Class
32   -class MockHttpHandler : public IHttpHandler {
  33 +class MockHttpHandler : public IHttpHandler
  34 +{
33 35 public:
34   - MOCK_CONST_METHOD3(send, std::string(const std::string &msg,
35   - const std::string &adr, int port));
36   -
37   - MOCK_CONST_METHOD3(sendGetHTTPBody,
38   - std::string(const std::string &msg, const std::string &adr,
39   - int port));
40   -
41   - MOCK_CONST_METHOD4(sendMulticast,
42   - std::vector<std::string>(const std::string &msg,
43   - const std::string &adr, int port,
44   - int timeout));
45   -
46   - MOCK_CONST_METHOD6(sendHTTPRequest,
47   - std::string(std::string method, std::string uri,
48   - std::string content_type, std::string body,
49   - const std::string &adr, int port));
50   -
51   - MOCK_CONST_METHOD5(GETString,
52   - std::string(std::string uri, std::string content_type,
53   - std::string body, const std::string &adr,
54   - int port));
55   -
56   - MOCK_CONST_METHOD5(POSTString,
57   - std::string(std::string uri, std::string content_type,
58   - std::string body, const std::string &adr,
59   - int port));
60   -
61   - MOCK_CONST_METHOD5(PUTString,
62   - std::string(std::string uri, std::string content_type,
63   - std::string body, const std::string &adr,
64   - int port));
65   -
66   - MOCK_CONST_METHOD5(DELETEString,
67   - std::string(std::string uri, std::string content_type,
68   - std::string body, const std::string &adr,
69   - int port));
70   -
71   - MOCK_CONST_METHOD4(GETJson,
72   - Json::Value(std::string uri, const Json::Value &body,
73   - const std::string &adr, int port));
74   -
75   - MOCK_CONST_METHOD4(POSTJson,
76   - Json::Value(std::string uri, const Json::Value &body,
77   - const std::string &adr, int port));
78   -
79   - MOCK_CONST_METHOD4(PUTJson,
80   - Json::Value(std::string uri, const Json::Value &body,
81   - const std::string &adr, int port));
82   -
83   - MOCK_CONST_METHOD4(DELETEJson,
84   - Json::Value(std::string uri, const Json::Value &body,
85   - const std::string &adr, int port));
  36 + MOCK_CONST_METHOD3(send, std::string(const std::string& msg, const std::string& adr, int port));
  37 +
  38 + MOCK_CONST_METHOD3(sendGetHTTPBody, std::string(const std::string& msg, const std::string& adr, int port));
  39 +
  40 + MOCK_CONST_METHOD4(
  41 + sendMulticast, std::vector<std::string>(const std::string& msg, const std::string& adr, int port, int timeout));
  42 +
  43 + MOCK_CONST_METHOD6(sendHTTPRequest,
  44 + std::string(std::string method, std::string uri, std::string content_type, std::string body,
  45 + const std::string& adr, int port));
  46 +
  47 + MOCK_CONST_METHOD5(GETString,
  48 + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port));
  49 +
  50 + MOCK_CONST_METHOD5(POSTString,
  51 + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port));
  52 +
  53 + MOCK_CONST_METHOD5(PUTString,
  54 + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port));
  55 +
  56 + MOCK_CONST_METHOD5(DELETEString,
  57 + std::string(std::string uri, std::string content_type, std::string body, const std::string& adr, int port));
  58 +
  59 + MOCK_CONST_METHOD4(
  60 + GETJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port));
  61 +
  62 + MOCK_CONST_METHOD4(
  63 + POSTJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port));
  64 +
  65 + MOCK_CONST_METHOD4(
  66 + PUTJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port));
  67 +
  68 + MOCK_CONST_METHOD4(
  69 + DELETEJson, nlohmann::json(std::string uri, const nlohmann::json& body, const std::string& adr, int port));
86 70 };
87 71  
88 72 #endif
... ...
hueplusplus/test/mocks/mock_HueLight.h 100755 → 100644
... ... @@ -26,18 +26,18 @@
26 26 #include <gmock/gmock.h>
27 27  
28 28 #include "../hueplusplus/include/HueLight.h"
29   -#include "../hueplusplus/include/json/json.h"
  29 +#include "../hueplusplus/include/json/json.hpp"
30 30 #include "../testhelper.h"
31 31  
  32 +
32 33 //! Mock Class
33 34 class MockHueLight : public HueLight
34 35 {
35 36 public:
36   - MockHueLight(std::shared_ptr<const IHttpHandler> handler) : HueLight(1,
37   - HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(),
38   - handler)) {};
  37 + MockHueLight(std::shared_ptr<const IHttpHandler> handler) :
  38 + HueLight(1, HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler)) {};
39 39  
40   - Json::Value& getState() { return state; };
  40 + nlohmann::json& getState() { return state; };
41 41  
42 42 MOCK_METHOD1(On, bool(uint8_t transition));
43 43  
... ... @@ -123,7 +123,7 @@ public:
123 123  
124 124 MOCK_METHOD1(OffNoRefresh, bool(uint8_t transition));
125 125  
126   - MOCK_METHOD2(SendPutRequest, Json::Value(const Json::Value& request, const std::string& subPath));
  126 + MOCK_METHOD2(SendPutRequest, nlohmann::json(const nlohmann::json& request, const std::string& subPath));
127 127  
128 128 MOCK_METHOD0(refreshState, void());
129 129 };
... ...
hueplusplus/test/test_BaseHttpHandler.cpp
1   -#include <gtest/gtest.h>
  1 +#include <memory>
  2 +#include <string>
  3 +
2 4 #include <gmock/gmock.h>
  5 +#include <gtest/gtest.h>
3 6  
4   -#include "../include/json/json.h"
5   -#include "mocks/mock_BaseHttpHandler.h"
6 7 #include "testhelper.h"
7 8  
8   -#include <memory>
9   -#include <string>
  9 +#include "../include/json/json.hpp"
  10 +#include "mocks/mock_BaseHttpHandler.h"
10 11  
11 12 TEST(BaseHttpHandler, sendGetHTTPBody)
12 13 {
... ... @@ -27,7 +28,10 @@ TEST(BaseHttpHandler, sendHTTPRequest)
27 28 using namespace ::testing;
28 29 MockBaseHttpHandler handler;
29 30  
30   - EXPECT_CALL(handler, send("GET UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90))
  31 + EXPECT_CALL(handler,
  32 + send("GET UrI HTTP/1.0\r\nContent-Type: "
  33 + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n",
  34 + "192.168.2.1", 90))
31 35 .Times(AtLeast(2))
32 36 .WillOnce(Return(""))
33 37 .WillRepeatedly(Return("\r\n\r\ntestreply"));
... ... @@ -41,7 +45,10 @@ TEST(BaseHttpHandler, GETString)
41 45 using namespace ::testing;
42 46 MockBaseHttpHandler handler;
43 47  
44   - EXPECT_CALL(handler, send("GET UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90))
  48 + EXPECT_CALL(handler,
  49 + send("GET UrI HTTP/1.0\r\nContent-Type: "
  50 + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n",
  51 + "192.168.2.1", 90))
45 52 .Times(AtLeast(2))
46 53 .WillOnce(Return(""))
47 54 .WillRepeatedly(Return("\r\n\r\ntestreply"));
... ... @@ -55,7 +62,10 @@ TEST(BaseHttpHandler, POSTString)
55 62 using namespace ::testing;
56 63 MockBaseHttpHandler handler;
57 64  
58   - EXPECT_CALL(handler, send("POST UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90))
  65 + EXPECT_CALL(handler,
  66 + send("POST UrI HTTP/1.0\r\nContent-Type: "
  67 + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n",
  68 + "192.168.2.1", 90))
59 69 .Times(AtLeast(2))
60 70 .WillOnce(Return(""))
61 71 .WillRepeatedly(Return("\r\n\r\ntestreply"));
... ... @@ -69,7 +79,10 @@ TEST(BaseHttpHandler, PUTString)
69 79 using namespace ::testing;
70 80 MockBaseHttpHandler handler;
71 81  
72   - EXPECT_CALL(handler, send("PUT UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90))
  82 + EXPECT_CALL(handler,
  83 + send("PUT UrI HTTP/1.0\r\nContent-Type: "
  84 + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n",
  85 + "192.168.2.1", 90))
73 86 .Times(AtLeast(2))
74 87 .WillOnce(Return(""))
75 88 .WillRepeatedly(Return("\r\n\r\ntestreply"));
... ... @@ -83,7 +96,10 @@ TEST(BaseHttpHandler, DELETEString)
83 96 using namespace ::testing;
84 97 MockBaseHttpHandler handler;
85 98  
86   - EXPECT_CALL(handler, send("DELETE UrI HTTP/1.0\r\nContent-Type: text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n", "192.168.2.1", 90))
  99 + EXPECT_CALL(handler,
  100 + send("DELETE UrI HTTP/1.0\r\nContent-Type: "
  101 + "text/html\r\nContent-Length: 4\r\n\r\nbody\r\n\r\n",
  102 + "192.168.2.1", 90))
87 103 .Times(AtLeast(2))
88 104 .WillOnce(Return(""))
89 105 .WillRepeatedly(Return("\r\n\r\ntestreply"));
... ... @@ -97,12 +113,12 @@ TEST(BaseHttpHandler, GETJson)
97 113 using namespace ::testing;
98 114 MockBaseHttpHandler handler;
99 115  
100   - Json::Value testval;
  116 + nlohmann::json testval;
101 117 testval["test"] = 100;
102 118 std::string expected_call = "GET UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: ";
103   - expected_call.append(std::to_string(testval.toStyledString().size()));
  119 + expected_call.append(std::to_string(testval.dump().size()));
104 120 expected_call.append("\r\n\r\n");
105   - expected_call.append(testval.toStyledString());
  121 + expected_call.append(testval.dump());
106 122 expected_call.append("\r\n\r\n");
107 123  
108 124 EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90))
... ... @@ -110,11 +126,11 @@ TEST(BaseHttpHandler, GETJson)
110 126 .WillOnce(Return(""))
111 127 .WillOnce(Return("\r\n\r\n"))
112 128 .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}"));
113   - Json::Value expected;
  129 + nlohmann::json expected;
114 130 expected["test"] = "whatever";
115 131  
116 132 EXPECT_THROW(handler.GETJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
117   - EXPECT_THROW(handler.GETJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
  133 + EXPECT_THROW(handler.GETJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error);
118 134 EXPECT_EQ(expected, handler.GETJson("UrI", testval, "192.168.2.1", 90));
119 135 }
120 136  
... ... @@ -123,12 +139,12 @@ TEST(BaseHttpHandler, POSTJson)
123 139 using namespace ::testing;
124 140 MockBaseHttpHandler handler;
125 141  
126   - Json::Value testval;
  142 + nlohmann::json testval;
127 143 testval["test"] = 100;
128 144 std::string expected_call = "POST UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: ";
129   - expected_call.append(std::to_string(testval.toStyledString().size()));
  145 + expected_call.append(std::to_string(testval.dump().size()));
130 146 expected_call.append("\r\n\r\n");
131   - expected_call.append(testval.toStyledString());
  147 + expected_call.append(testval.dump());
132 148 expected_call.append("\r\n\r\n");
133 149  
134 150 EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90))
... ... @@ -136,11 +152,11 @@ TEST(BaseHttpHandler, POSTJson)
136 152 .WillOnce(Return(""))
137 153 .WillOnce(Return("\r\n\r\n"))
138 154 .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}"));
139   - Json::Value expected;
  155 + nlohmann::json expected;
140 156 expected["test"] = "whatever";
141 157  
142 158 EXPECT_THROW(handler.POSTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
143   - EXPECT_THROW(handler.POSTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
  159 + EXPECT_THROW(handler.POSTJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error);
144 160 EXPECT_EQ(expected, handler.POSTJson("UrI", testval, "192.168.2.1", 90));
145 161 }
146 162  
... ... @@ -149,12 +165,12 @@ TEST(BaseHttpHandler, PUTJson)
149 165 using namespace ::testing;
150 166 MockBaseHttpHandler handler;
151 167  
152   - Json::Value testval;
  168 + nlohmann::json testval;
153 169 testval["test"] = 100;
154 170 std::string expected_call = "PUT UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: ";
155   - expected_call.append(std::to_string(testval.toStyledString().size()));
  171 + expected_call.append(std::to_string(testval.dump().size()));
156 172 expected_call.append("\r\n\r\n");
157   - expected_call.append(testval.toStyledString());
  173 + expected_call.append(testval.dump());
158 174 expected_call.append("\r\n\r\n");
159 175  
160 176 EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90))
... ... @@ -162,11 +178,11 @@ TEST(BaseHttpHandler, PUTJson)
162 178 .WillOnce(Return(""))
163 179 .WillOnce(Return("\r\n\r\n"))
164 180 .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}"));
165   - Json::Value expected;
  181 + nlohmann::json expected;
166 182 expected["test"] = "whatever";
167 183  
168 184 EXPECT_THROW(handler.PUTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
169   - EXPECT_THROW(handler.PUTJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
  185 + EXPECT_THROW(handler.PUTJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error);
170 186 EXPECT_EQ(expected, handler.PUTJson("UrI", testval, "192.168.2.1", 90));
171 187 }
172 188  
... ... @@ -175,12 +191,13 @@ TEST(BaseHttpHandler, DELETEJson)
175 191 using namespace ::testing;
176 192 MockBaseHttpHandler handler;
177 193  
178   - Json::Value testval;
  194 + nlohmann::json testval;
179 195 testval["test"] = 100;
180   - std::string expected_call = "DELETE UrI HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: ";
181   - expected_call.append(std::to_string(testval.toStyledString().size()));
  196 + std::string expected_call = "DELETE UrI HTTP/1.0\r\nContent-Type: "
  197 + "application/json\r\nContent-Length: ";
  198 + expected_call.append(std::to_string(testval.dump().size()));
182 199 expected_call.append("\r\n\r\n");
183   - expected_call.append(testval.toStyledString());
  200 + expected_call.append(testval.dump());
184 201 expected_call.append("\r\n\r\n");
185 202  
186 203 EXPECT_CALL(handler, send(expected_call, "192.168.2.1", 90))
... ... @@ -188,10 +205,10 @@ TEST(BaseHttpHandler, DELETEJson)
188 205 .WillOnce(Return(""))
189 206 .WillOnce(Return("\r\n\r\n"))
190 207 .WillRepeatedly(Return("\r\n\r\n{\"test\" : \"whatever\"}"));
191   - Json::Value expected;
  208 + nlohmann::json expected;
192 209 expected["test"] = "whatever";
193 210  
194 211 EXPECT_THROW(handler.DELETEJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
195   - EXPECT_THROW(handler.DELETEJson("UrI", testval, "192.168.2.1", 90), std::runtime_error);
  212 + EXPECT_THROW(handler.DELETEJson("UrI", testval, "192.168.2.1", 90), nlohmann::json::parse_error);
196 213 EXPECT_EQ(expected, handler.DELETEJson("UrI", testval, "192.168.2.1", 90));
197 214 }
... ...
hueplusplus/test/test_ExtendedColorHueStrategy.cpp
  1 +#include <memory>
  2 +#include <string>
  3 +
1 4 #include <gmock/gmock.h>
2 5 #include <gtest/gtest.h>
3 6  
  7 +#include "testhelper.h"
4 8  
5 9 #include "../include/ExtendedColorHueStrategy.h"
6   -#include "../include/json/json.h"
  10 +#include "../include/json/json.hpp"
7 11 #include "mocks/mock_HttpHandler.h"
8 12 #include "mocks/mock_HueLight.h"
9   -#include "testhelper.h"
10 13  
11   -#include <memory>
12   -#include <string>
13 14  
14   -TEST(ExtendedColorHueStrategy, alertHueSaturation) {
15   - using namespace ::testing;
16   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
17   - EXPECT_CALL(*handler,
18   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
19   - Json::Value(Json::objectValue), getBridgeIp(), 80))
20   - .Times(AtLeast(1))
21   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
22   - MockHueLight test_light(handler);
23   - EXPECT_CALL(test_light, refreshState())
24   - .Times(AtLeast(1))
25   - .WillRepeatedly(Return());
26   -
27   - test_light.getState()["state"]["colormode"] = "invalid";
28   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128,
29   - test_light));
30   -
31   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
32   - .Times(AtLeast(2))
33   - .WillOnce(Return(false))
34   - .WillRepeatedly(Return(true));
35   - test_light.getState()["state"]["colormode"] = "hs";
36   - test_light.getState()["state"]["on"] = true;
37   - test_light.getState()["state"]["sat"] = 100;
38   - test_light.getState()["state"]["hue"] = 200;
39   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
40   - test_light));
41   -
42   - EXPECT_CALL(test_light, alert())
43   - .Times(AtLeast(2))
44   - .WillOnce(Return(false))
45   - .WillRepeatedly(Return(true));
46   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
47   - test_light));
48   -
49   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
50   - test_light));
51   -
52   - EXPECT_CALL(test_light, OffNoRefresh(_))
53   - .Times(AtLeast(1))
54   - .WillRepeatedly(Return(true));
55   - test_light.getState()["state"]["on"] = false;
56   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
57   - test_light));
58   -
59   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
60   - .Times(AtLeast(2))
61   - .WillOnce(Return(false))
62   - .WillRepeatedly(Return(true));
63   - test_light.getState()["state"]["colormode"] = "xy";
64   - test_light.getState()["state"]["on"] = true;
65   - test_light.getState()["state"]["xy"][0] = 0.1;
66   - test_light.getState()["state"]["xy"][1] = 0.1;
67   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
68   - test_light));
69   -
70   - EXPECT_CALL(test_light, alert())
71   - .Times(AtLeast(2))
72   - .WillOnce(Return(false))
73   - .WillRepeatedly(Return(true));
74   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
75   - test_light));
76   -
77   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
78   - .Times(AtLeast(2))
79   - .WillRepeatedly(Return(true));
80   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
81   - test_light));
82   -
83   - EXPECT_CALL(test_light, OffNoRefresh(_))
84   - .Times(AtLeast(1))
85   - .WillRepeatedly(Return(true));
86   - test_light.getState()["state"]["on"] = false;
87   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
88   - test_light));
89   -
90   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
91   - .Times(AtLeast(2))
92   - .WillOnce(Return(false))
93   - .WillRepeatedly(Return(true));
94   - test_light.getState()["state"]["colormode"] = "ct";
95   - test_light.getState()["state"]["on"] = true;
96   - test_light.getState()["state"]["ct"] = 200;
97   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
98   - test_light));
99   -
100   - EXPECT_CALL(test_light, alert())
101   - .Times(AtLeast(2))
102   - .WillOnce(Return(false))
103   - .WillRepeatedly(Return(true));
104   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
105   - test_light));
106   -
107   - EXPECT_CALL(test_light, setColorTemperature(_, 1))
108   - .Times(AtLeast(2))
109   - .WillRepeatedly(Return(true));
110   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
111   - test_light));
112   -
113   - EXPECT_CALL(test_light, OffNoRefresh(_))
114   - .Times(AtLeast(1))
115   - .WillRepeatedly(Return(true));
116   - test_light.getState()["state"]["on"] = false;
117   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100,
118   - test_light));
  15 +TEST(ExtendedColorHueStrategy, alertHueSaturation)
  16 +{
  17 + using namespace ::testing;
  18 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  19 + EXPECT_CALL(
  20 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  21 + .Times(AtLeast(1))
  22 + .WillRepeatedly(Return(nlohmann::json::object()));
  23 + MockHueLight test_light(handler);
  24 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  25 +
  26 + test_light.getState()["state"]["colormode"] = "invalid";
  27 + test_light.getState()["state"]["on"] = false;
  28 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, test_light));
  29 +
  30 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
  31 + .Times(AtLeast(2))
  32 + .WillOnce(Return(false))
  33 + .WillRepeatedly(Return(true));
  34 + test_light.getState()["state"]["colormode"] = "hs";
  35 + test_light.getState()["state"]["on"] = true;
  36 + test_light.getState()["state"]["sat"] = 100;
  37 + test_light.getState()["state"]["hue"] = 200;
  38 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  39 +
  40 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  41 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  42 +
  43 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  44 +
  45 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  46 + test_light.getState()["state"]["on"] = false;
  47 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  48 +
  49 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
  50 + .Times(AtLeast(2))
  51 + .WillOnce(Return(false))
  52 + .WillRepeatedly(Return(true));
  53 + test_light.getState()["state"]["colormode"] = "xy";
  54 + test_light.getState()["state"]["on"] = true;
  55 + test_light.getState()["state"]["xy"][0] = 0.1;
  56 + test_light.getState()["state"]["xy"][1] = 0.1;
  57 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  58 +
  59 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  60 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  61 +
  62 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  63 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  64 +
  65 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  66 + test_light.getState()["state"]["on"] = false;
  67 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  68 +
  69 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
  70 + .Times(AtLeast(2))
  71 + .WillOnce(Return(false))
  72 + .WillRepeatedly(Return(true));
  73 + test_light.getState()["state"]["colormode"] = "ct";
  74 + test_light.getState()["state"]["on"] = true;
  75 + test_light.getState()["state"]["ct"] = 200;
  76 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  77 +
  78 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  79 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  80 +
  81 + EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  82 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
  83 +
  84 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  85 + test_light.getState()["state"]["on"] = false;
  86 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
119 87 }
120 88  
121   -TEST(ExtendedColorHueStrategy, alertXY) {
122   - using namespace ::testing;
123   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
124   - EXPECT_CALL(*handler,
125   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
126   - Json::Value(Json::objectValue), getBridgeIp(), 80))
127   - .Times(AtLeast(1))
128   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
129   - MockHueLight test_light(handler);
130   - EXPECT_CALL(test_light, refreshState())
131   - .Times(AtLeast(1))
132   - .WillRepeatedly(Return());
133   -
134   - test_light.getState()["state"]["colormode"] = "invalid";
135   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
136   -
137   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
138   - .Times(AtLeast(2))
139   - .WillOnce(Return(false))
140   - .WillRepeatedly(Return(true));
141   - test_light.getState()["state"]["colormode"] = "hs";
142   - test_light.getState()["state"]["on"] = true;
143   - test_light.getState()["state"]["xy"][0] = 0.1;
144   - test_light.getState()["state"]["xy"][1] = 0.1;
145   - test_light.getState()["state"]["sat"] = 100;
146   - test_light.getState()["state"]["hue"] = 200;
147   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
148   -
149   - EXPECT_CALL(test_light, alert())
150   - .Times(AtLeast(2))
151   - .WillOnce(Return(false))
152   - .WillRepeatedly(Return(true));
153   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
154   -
155   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
156   - .Times(AtLeast(2))
157   - .WillRepeatedly(Return(true));
158   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
159   -
160   - EXPECT_CALL(test_light, OffNoRefresh(_))
161   - .Times(AtLeast(1))
162   - .WillRepeatedly(Return(true));
163   - test_light.getState()["state"]["on"] = false;
164   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
165   -
166   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
167   - .Times(AtLeast(2))
168   - .WillOnce(Return(false))
169   - .WillRepeatedly(Return(true));
170   - test_light.getState()["state"]["colormode"] = "xy";
171   - test_light.getState()["state"]["on"] = true;
172   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
173   -
174   - EXPECT_CALL(test_light, alert())
175   - .Times(AtLeast(2))
176   - .WillOnce(Return(false))
177   - .WillRepeatedly(Return(true));
178   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
179   -
180   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
181   -
182   - EXPECT_CALL(test_light, OffNoRefresh(_))
183   - .Times(AtLeast(1))
184   - .WillRepeatedly(Return(true));
185   - test_light.getState()["state"]["on"] = false;
186   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
187   -
188   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
189   - .Times(AtLeast(2))
190   - .WillOnce(Return(false))
191   - .WillRepeatedly(Return(true));
192   - test_light.getState()["state"]["colormode"] = "ct";
193   - test_light.getState()["state"]["on"] = true;
194   - test_light.getState()["state"]["ct"] = 200;
195   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
196   -
197   - EXPECT_CALL(test_light, alert())
198   - .Times(AtLeast(2))
199   - .WillOnce(Return(false))
200   - .WillRepeatedly(Return(true));
201   - EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
202   -
203   - EXPECT_CALL(test_light, setColorTemperature(_, 1))
204   - .Times(AtLeast(2))
205   - .WillRepeatedly(Return(true));
206   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
207   -
208   - EXPECT_CALL(test_light, OffNoRefresh(_))
209   - .Times(AtLeast(1))
210   - .WillRepeatedly(Return(true));
211   - test_light.getState()["state"]["on"] = false;
212   - EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  89 +TEST(ExtendedColorHueStrategy, alertXY)
  90 +{
  91 + using namespace ::testing;
  92 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  93 + EXPECT_CALL(
  94 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  95 + .Times(AtLeast(1))
  96 + .WillRepeatedly(Return(nlohmann::json::object()));
  97 + MockHueLight test_light(handler);
  98 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  99 +
  100 + test_light.getState()["state"]["colormode"] = "invalid";
  101 + test_light.getState()["state"]["on"] = false;
  102 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  103 +
  104 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  105 + test_light.getState()["state"]["colormode"] = "hs";
  106 + test_light.getState()["state"]["on"] = true;
  107 + test_light.getState()["state"]["xy"][0] = 0.1;
  108 + test_light.getState()["state"]["xy"][1] = 0.1;
  109 + test_light.getState()["state"]["sat"] = 100;
  110 + test_light.getState()["state"]["hue"] = 200;
  111 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  112 +
  113 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  114 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  115 +
  116 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  117 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  118 +
  119 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  120 + test_light.getState()["state"]["on"] = false;
  121 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  122 +
  123 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  124 + test_light.getState()["state"]["colormode"] = "xy";
  125 + test_light.getState()["state"]["on"] = true;
  126 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  127 +
  128 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  129 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  130 +
  131 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  132 +
  133 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  134 + test_light.getState()["state"]["on"] = false;
  135 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  136 +
  137 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  138 + test_light.getState()["state"]["colormode"] = "ct";
  139 + test_light.getState()["state"]["on"] = true;
  140 + test_light.getState()["state"]["ct"] = 200;
  141 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  142 +
  143 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  144 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  145 +
  146 + EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  147 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  148 +
  149 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  150 + test_light.getState()["state"]["on"] = false;
  151 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
213 152 }
214 153  
215   -TEST(ExtendedColorHueStrategy, alertRGB) {
216   - using namespace ::testing;
217   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
218   - EXPECT_CALL(*handler,
219   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
220   - Json::Value(Json::objectValue), getBridgeIp(), 80))
221   - .Times(AtLeast(1))
222   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
223   - MockHueLight test_light(handler);
224   - EXPECT_CALL(test_light, refreshState())
225   - .Times(AtLeast(1))
226   - .WillRepeatedly(Return());
227   -
228   - test_light.getState()["state"]["colormode"] = "invalid";
229   - EXPECT_EQ(false,
230   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
231   -
232   - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
233   - .Times(AtLeast(2))
234   - .WillOnce(Return(false))
235   - .WillRepeatedly(Return(true));
236   - test_light.getState()["state"]["colormode"] = "hs";
237   - test_light.getState()["state"]["on"] = true;
238   - test_light.getState()["state"]["sat"] = 100;
239   - test_light.getState()["state"]["hue"] = 200;
240   - EXPECT_EQ(false,
241   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
242   -
243   - EXPECT_CALL(test_light, alert())
244   - .Times(AtLeast(2))
245   - .WillOnce(Return(false))
246   - .WillRepeatedly(Return(true));
247   - EXPECT_EQ(false,
248   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
249   -
250   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
251   - .Times(AtLeast(2))
252   - .WillRepeatedly(Return(true));
253   - EXPECT_EQ(true,
254   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
255   -
256   - EXPECT_CALL(test_light, OffNoRefresh(_))
257   - .Times(AtLeast(1))
258   - .WillRepeatedly(Return(true));
259   - test_light.getState()["state"]["on"] = false;
260   - EXPECT_EQ(true,
261   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
262   -
263   - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
264   - .Times(AtLeast(2))
265   - .WillOnce(Return(false))
266   - .WillRepeatedly(Return(true));
267   - test_light.getState()["state"]["colormode"] = "xy";
268   - test_light.getState()["state"]["on"] = true;
269   - test_light.getState()["state"]["xy"][0] = 0.1;
270   - test_light.getState()["state"]["xy"][1] = 0.1;
271   - EXPECT_EQ(false,
272   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
273   -
274   - EXPECT_CALL(test_light, alert())
275   - .Times(AtLeast(2))
276   - .WillOnce(Return(false))
277   - .WillRepeatedly(Return(true));
278   - EXPECT_EQ(false,
279   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
280   -
281   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
282   - .Times(AtLeast(2))
283   - .WillRepeatedly(Return(true));
284   - EXPECT_EQ(true,
285   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
286   -
287   - EXPECT_CALL(test_light, OffNoRefresh(_))
288   - .Times(AtLeast(1))
289   - .WillRepeatedly(Return(true));
290   - test_light.getState()["state"]["on"] = false;
291   - EXPECT_EQ(true,
292   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
293   -
294   - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
295   - .Times(AtLeast(2))
296   - .WillOnce(Return(false))
297   - .WillRepeatedly(Return(true));
298   - test_light.getState()["state"]["colormode"] = "ct";
299   - test_light.getState()["state"]["on"] = true;
300   - test_light.getState()["state"]["ct"] = 200;
301   - EXPECT_EQ(false,
302   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
303   -
304   - EXPECT_CALL(test_light, alert())
305   - .Times(AtLeast(2))
306   - .WillOnce(Return(false))
307   - .WillRepeatedly(Return(true));
308   - EXPECT_EQ(false,
309   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
310   -
311   - EXPECT_CALL(test_light, setColorTemperature(_, 1))
312   - .Times(AtLeast(2))
313   - .WillRepeatedly(Return(true));
314   - EXPECT_EQ(true,
315   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
316   -
317   - EXPECT_CALL(test_light, OffNoRefresh(_))
318   - .Times(AtLeast(1))
319   - .WillRepeatedly(Return(true));
320   - test_light.getState()["state"]["on"] = false;
321   - EXPECT_EQ(true,
322   - ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  154 +TEST(ExtendedColorHueStrategy, alertRGB)
  155 +{
  156 + using namespace ::testing;
  157 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  158 + EXPECT_CALL(
  159 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  160 + .Times(AtLeast(1))
  161 + .WillRepeatedly(Return(nlohmann::json::object()));
  162 + MockHueLight test_light(handler);
  163 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  164 +
  165 + test_light.getState()["state"]["colormode"] = "invalid";
  166 + test_light.getState()["state"]["on"] = false;
  167 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  168 +
  169 + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
  170 + .Times(AtLeast(2))
  171 + .WillOnce(Return(false))
  172 + .WillRepeatedly(Return(true));
  173 + test_light.getState()["state"]["colormode"] = "hs";
  174 + test_light.getState()["state"]["on"] = true;
  175 + test_light.getState()["state"]["sat"] = 100;
  176 + test_light.getState()["state"]["hue"] = 200;
  177 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  178 +
  179 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  180 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  181 +
  182 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  183 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  184 +
  185 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  186 + test_light.getState()["state"]["on"] = false;
  187 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  188 +
  189 + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
  190 + .Times(AtLeast(2))
  191 + .WillOnce(Return(false))
  192 + .WillRepeatedly(Return(true));
  193 + test_light.getState()["state"]["colormode"] = "xy";
  194 + test_light.getState()["state"]["on"] = true;
  195 + test_light.getState()["state"]["xy"][0] = 0.1;
  196 + test_light.getState()["state"]["xy"][1] = 0.1;
  197 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  198 +
  199 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  200 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  201 +
  202 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  203 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  204 +
  205 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  206 + test_light.getState()["state"]["on"] = false;
  207 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  208 +
  209 + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
  210 + .Times(AtLeast(2))
  211 + .WillOnce(Return(false))
  212 + .WillRepeatedly(Return(true));
  213 + test_light.getState()["state"]["colormode"] = "ct";
  214 + test_light.getState()["state"]["on"] = true;
  215 + test_light.getState()["state"]["ct"] = 200;
  216 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  217 +
  218 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  219 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  220 +
  221 + EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  222 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
  223 +
  224 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  225 + test_light.getState()["state"]["on"] = false;
  226 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
323 227 }
... ...
hueplusplus/test/test_ExtendedColorTemperatureStrategy.cpp
  1 +#include <memory>
  2 +#include <string>
  3 +
1 4 #include <gmock/gmock.h>
2 5 #include <gtest/gtest.h>
3 6  
  7 +#include "testhelper.h"
4 8  
5 9 #include "../include/ExtendedColorTemperatureStrategy.h"
6   -#include "../include/json/json.h"
  10 +#include "../include/json/json.hpp"
7 11 #include "mocks/mock_HttpHandler.h"
8 12 #include "mocks/mock_HueLight.h"
9   -#include "testhelper.h"
10 13  
11   -#include <memory>
12   -#include <string>
13 14  
14   -TEST(ExtendedColorTemperatureStrategy, setColorTemperature) {
15   - using namespace ::testing;
16   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
17   - EXPECT_CALL(*handler,
18   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
19   - Json::Value(Json::objectValue), getBridgeIp(), 80))
20   - .Times(AtLeast(1))
21   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
22   - MockHueLight test_light(handler);
23   - EXPECT_CALL(test_light, refreshState())
24   - .Times(AtLeast(1))
25   - .WillRepeatedly(Return());
26   - Json::Value prep_ret;
27   - prep_ret = Json::Value(Json::arrayValue);
28   - prep_ret[0] = Json::Value(Json::objectValue);
29   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
30   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
31   - prep_ret[1] = Json::Value(Json::objectValue);
32   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
33   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
34   - prep_ret[2] = Json::Value(Json::objectValue);
35   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
36   - prep_ret[2]["success"]["/lights/1/state/ct"] = 155;
37   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
38   - .Times(1)
39   - .WillOnce(Return(prep_ret));
40   -
41   - test_light.getState()["state"]["colormode"] = "ct";
42   - test_light.getState()["state"]["on"] = true;
43   - test_light.getState()["state"]["ct"] = 200;
44   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(
45   - 200, 4, test_light));
46   -
47   - test_light.getState()["state"]["on"] = false;
48   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(
49   - 155, 6, test_light));
50   -
51   - prep_ret[2]["success"]["/lights/1/state/ct"] = 153;
52   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
53   - .Times(1)
54   - .WillOnce(Return(prep_ret));
55   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(
56   - 0, 6, test_light));
57   -
58   - prep_ret[2]["success"]["/lights/1/state/ct"] = 500;
59   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
60   - .Times(1)
61   - .WillOnce(Return(prep_ret));
62   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(
63   - 600, 6, test_light));
  15 +TEST(ExtendedColorTemperatureStrategy, setColorTemperature)
  16 +{
  17 + using namespace ::testing;
  18 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  19 + EXPECT_CALL(
  20 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  21 + .Times(AtLeast(1))
  22 + .WillRepeatedly(Return(nlohmann::json::object()));
  23 + MockHueLight test_light(handler);
  24 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  25 + nlohmann::json prep_ret;
  26 + prep_ret = nlohmann::json::array();
  27 + prep_ret[0] = nlohmann::json::object();
  28 + prep_ret[0]["success"] = nlohmann::json::object();
  29 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  30 + prep_ret[1] = nlohmann::json::object();
  31 + prep_ret[1]["success"] = nlohmann::json::object();
  32 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  33 + prep_ret[2] = nlohmann::json::object();
  34 + prep_ret[2]["success"] = nlohmann::json::object();
  35 + prep_ret[2]["success"]["/lights/1/state/ct"] = 155;
  36 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  37 +
  38 + test_light.getState()["state"]["colormode"] = "ct";
  39 + test_light.getState()["state"]["on"] = true;
  40 + test_light.getState()["state"]["ct"] = 200;
  41 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(200, 4, test_light));
  42 +
  43 + test_light.getState()["state"]["on"] = false;
  44 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(155, 6, test_light));
  45 +
  46 + prep_ret[2]["success"]["/lights/1/state/ct"] = 153;
  47 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  48 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(0, 6, test_light));
  49 +
  50 + prep_ret[2]["success"]["/lights/1/state/ct"] = 500;
  51 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  52 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().setColorTemperature(600, 6, test_light));
64 53 }
65 54  
66   -TEST(ExtendedColorTemperatureStrategy, alertTemperature) {
67   - using namespace ::testing;
68   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
69   - EXPECT_CALL(*handler,
70   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
71   - Json::Value(Json::objectValue), getBridgeIp(), 80))
72   - .Times(AtLeast(1))
73   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
74   - MockHueLight test_light(handler);
75   - EXPECT_CALL(test_light, refreshState())
76   - .Times(AtLeast(1))
77   - .WillRepeatedly(Return());
78   -
79   - test_light.getState()["state"]["colormode"] = "invalid";
80   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
81   - 400, test_light));
82   -
83   - EXPECT_CALL(test_light, setColorTemperature(_, _))
84   - .Times(AtLeast(2))
85   - .WillOnce(Return(false))
86   - .WillRepeatedly(Return(true));
87   - test_light.getState()["state"]["colormode"] = "hs";
88   - test_light.getState()["state"]["on"] = true;
89   - test_light.getState()["state"]["ct"] = 200;
90   - test_light.getState()["state"]["sat"] = 100;
91   - test_light.getState()["state"]["hue"] = 200;
92   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
93   - 400, test_light));
94   -
95   - EXPECT_CALL(test_light, alert())
96   - .Times(AtLeast(2))
97   - .WillOnce(Return(false))
98   - .WillRepeatedly(Return(true));
99   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
100   - 400, test_light));
101   -
102   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
103   - .Times(AtLeast(2))
104   - .WillRepeatedly(Return(true));
105   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(
106   - 400, test_light));
107   -
108   - EXPECT_CALL(test_light, OffNoRefresh(_))
109   - .Times(AtLeast(1))
110   - .WillRepeatedly(Return(true));
111   - test_light.getState()["state"]["on"] = false;
112   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(
113   - 400, test_light));
114   -
115   - EXPECT_CALL(test_light, setColorTemperature(_, _))
116   - .Times(AtLeast(2))
117   - .WillOnce(Return(false))
118   - .WillRepeatedly(Return(true));
119   - test_light.getState()["state"]["colormode"] = "xy";
120   - test_light.getState()["state"]["on"] = true;
121   - test_light.getState()["state"]["xy"][0] = 0.1;
122   - test_light.getState()["state"]["xy"][1] = 0.1;
123   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
124   - 400, test_light));
125   -
126   - EXPECT_CALL(test_light, alert())
127   - .Times(AtLeast(2))
128   - .WillOnce(Return(false))
129   - .WillRepeatedly(Return(true));
130   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
131   - 400, test_light));
132   -
133   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
134   - .Times(AtLeast(2))
135   - .WillRepeatedly(Return(true));
136   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(
137   - 400, test_light));
138   -
139   - test_light.getState()["state"]["on"] = false;
140   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(
141   - 400, test_light));
142   -
143   - EXPECT_CALL(test_light, setColorTemperature(_, _))
144   - .Times(AtLeast(2))
145   - .WillOnce(Return(false))
146   - .WillRepeatedly(Return(true));
147   - test_light.getState()["state"]["colormode"] = "ct";
148   - test_light.getState()["state"]["on"] = true;
149   - test_light.getState()["state"]["on"] = true;
150   - test_light.getState()["state"]["ct"] = 200;
151   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
152   - 400, test_light));
153   -
154   - EXPECT_CALL(test_light, alert())
155   - .Times(AtLeast(2))
156   - .WillOnce(Return(false))
157   - .WillRepeatedly(Return(true));
158   - EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(
159   - 400, test_light));
160   -
161   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(
162   - 400, test_light));
163   -
164   - test_light.getState()["state"]["on"] = false;
165   - EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(
166   - 400, test_light));
  55 +TEST(ExtendedColorTemperatureStrategy, alertTemperature)
  56 +{
  57 + using namespace ::testing;
  58 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  59 + EXPECT_CALL(
  60 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  61 + .Times(AtLeast(1))
  62 + .WillRepeatedly(Return(nlohmann::json::object()));
  63 + MockHueLight test_light(handler);
  64 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  65 +
  66 + test_light.getState()["state"]["colormode"] = "invalid";
  67 + test_light.getState()["state"]["on"] = false;
  68 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  69 +
  70 + EXPECT_CALL(test_light, setColorTemperature(_, _))
  71 + .Times(AtLeast(2))
  72 + .WillOnce(Return(false))
  73 + .WillRepeatedly(Return(true));
  74 + test_light.getState()["state"]["colormode"] = "hs";
  75 + test_light.getState()["state"]["on"] = true;
  76 + test_light.getState()["state"]["ct"] = 200;
  77 + test_light.getState()["state"]["sat"] = 100;
  78 + test_light.getState()["state"]["hue"] = 200;
  79 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  80 +
  81 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  82 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  83 +
  84 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  85 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  86 +
  87 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  88 + test_light.getState()["state"]["on"] = false;
  89 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  90 +
  91 + EXPECT_CALL(test_light, setColorTemperature(_, _))
  92 + .Times(AtLeast(2))
  93 + .WillOnce(Return(false))
  94 + .WillRepeatedly(Return(true));
  95 + test_light.getState()["state"]["colormode"] = "xy";
  96 + test_light.getState()["state"]["on"] = true;
  97 + test_light.getState()["state"]["xy"][0] = 0.1;
  98 + test_light.getState()["state"]["xy"][1] = 0.1;
  99 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  100 +
  101 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  102 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  103 +
  104 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  105 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  106 +
  107 + test_light.getState()["state"]["on"] = false;
  108 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  109 +
  110 + EXPECT_CALL(test_light, setColorTemperature(_, _))
  111 + .Times(AtLeast(2))
  112 + .WillOnce(Return(false))
  113 + .WillRepeatedly(Return(true));
  114 + test_light.getState()["state"]["colormode"] = "ct";
  115 + test_light.getState()["state"]["on"] = true;
  116 + test_light.getState()["state"]["on"] = true;
  117 + test_light.getState()["state"]["ct"] = 200;
  118 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  119 +
  120 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  121 + EXPECT_EQ(false, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  122 +
  123 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
  124 +
  125 + test_light.getState()["state"]["on"] = false;
  126 + EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
167 127 }
... ...
hueplusplus/test/test_Hue.cpp 100755 → 100644
  1 +#include <iostream>
  2 +#include <memory>
  3 +#include <string>
  4 +
1 5 #include <gmock/gmock.h>
2 6 #include <gtest/gtest.h>
3 7  
  8 +#include "testhelper.h"
4 9  
5 10 #include "../include/Hue.h"
6   -#include "../include/json/json.h"
  11 +#include "../include/json/json.hpp"
7 12 #include "mocks/mock_HttpHandler.h"
8   -#include "testhelper.h"
9 13  
10   -#include <iostream>
11   -#include <memory>
12   -#include <string>
13   -
14   -class HueFinderTest : public ::testing::Test {
  14 +class HueFinderTest : public ::testing::Test
  15 +{
15 16 protected:
16   - std::shared_ptr<MockHttpHandler> handler;
  17 + std::shared_ptr<MockHttpHandler> handler;
17 18  
18 19 protected:
19   - HueFinderTest() : handler(std::make_shared<MockHttpHandler>()) {
20   - using namespace ::testing;
  20 + HueFinderTest() : handler(std::make_shared<MockHttpHandler>())
  21 + {
  22 + using namespace ::testing;
  23 +
  24 + EXPECT_CALL(*handler,
  25 + sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
  26 + "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
  27 + "239.255.255.250", 1900, 5))
  28 + .Times(AtLeast(1))
  29 + .WillRepeatedly(Return(getMulticastReply()));
  30 +
  31 + EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", "192.168.2.1", getBridgePort()))
  32 + .Times(0);
  33 +
  34 + EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", getBridgeIp(), getBridgePort()))
  35 + .Times(AtLeast(1))
  36 + .WillRepeatedly(Return(getBridgeXml()));
  37 + }
  38 + ~HueFinderTest(){};
  39 +};
21 40  
22   - EXPECT_CALL(*handler,
23   - sendMulticast(
24   - "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
25   - "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
26   - "239.255.255.250", 1900, 5))
  41 +TEST_F(HueFinderTest, FindBridges)
  42 +{
  43 + HueFinder finder(handler);
  44 + std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
  45 +
  46 + HueFinder::HueIdentification bridge_to_comp;
  47 + bridge_to_comp.ip = getBridgeIp();
  48 + bridge_to_comp.port = getBridgePort();
  49 + bridge_to_comp.mac = getBridgeMac();
  50 +
  51 + EXPECT_EQ(bridges.size(), 1) << "HueFinder found more than one Bridge";
  52 + EXPECT_EQ(bridges[0].ip, bridge_to_comp.ip) << "HueIdentification ip does not match";
  53 + EXPECT_EQ(bridges[0].port, bridge_to_comp.port) << "HueIdentification port does not match";
  54 + EXPECT_EQ(bridges[0].mac, bridge_to_comp.mac) << "HueIdentification mac does not match";
  55 +
  56 + // Test invalid description
  57 + EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", getBridgeIp(), getBridgePort()))
  58 + .Times(1)
  59 + .WillOnce(::testing::Return("invalid stuff"));
  60 + bridges = finder.FindBridges();
  61 + EXPECT_TRUE(bridges.empty());
  62 +}
  63 +
  64 +TEST_F(HueFinderTest, GetBridge)
  65 +{
  66 + using namespace ::testing;
  67 + nlohmann::json request;
  68 + request["devicetype"] = "HuePlusPlus#User";
  69 +
  70 + nlohmann::json user_ret_uns;
  71 + user_ret_uns = nlohmann::json::array();
  72 + user_ret_uns[0] = nlohmann::json::object();
  73 + user_ret_uns[0]["error"] = nlohmann::json::object();
  74 + user_ret_uns[0]["error"]["type"] = 101;
  75 + user_ret_uns[0]["error"]["address"] = "";
  76 + user_ret_uns[0]["error"]["description"] = "link button not pressed";
  77 +
  78 + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort()))
27 79 .Times(AtLeast(1))
28   - .WillRepeatedly(Return(getMulticastReply()));
  80 + .WillRepeatedly(Return(user_ret_uns));
29 81  
30   - EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "",
31   - "192.168.2.1", 80))
32   - .Times(0);
  82 + HueFinder finder(handler);
  83 + std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
33 84  
34   - EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "",
35   - getBridgeIp(), 80))
36   - .Times(AtLeast(1))
37   - .WillRepeatedly(Return(getBridgeXml()));
38   - }
39   - ~HueFinderTest(){};
40   -};
  85 + ASSERT_THROW(finder.GetBridge(bridges[0]), std::runtime_error);
41 86  
42   -TEST_F(HueFinderTest, FindBridges) {
43   - HueFinder finder(handler);
44   - std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
45   -
46   - HueFinder::HueIdentification bridge_to_comp;
47   - bridge_to_comp.ip = getBridgeIp();
48   - bridge_to_comp.port = getBridgePort();
49   - bridge_to_comp.mac = getBridgeMac();
50   -
51   - EXPECT_EQ(bridges.size(), 1) << "HueFinder found more than one Bridge";
52   - EXPECT_EQ(bridges[0].ip, bridge_to_comp.ip)
53   - << "HueIdentification ip does not match";
54   - EXPECT_EQ(bridges[0].port, bridge_to_comp.port)
55   - << "HueIdentification port does not match";
56   - EXPECT_EQ(bridges[0].mac, bridge_to_comp.mac)
57   - << "HueIdentification mac does not match";
58   -
59   - // Test invalid description
60   - EXPECT_CALL(*handler, GETString("/description.xml", "application/xml", "", getBridgeIp(), getBridgePort()))
61   - .Times(1)
62   - .WillOnce(::testing::Return("invalid stuff"));
63   - bridges = finder.FindBridges();
64   - EXPECT_TRUE(bridges.empty());
65   -}
  87 + nlohmann::json user_ret_suc;
  88 + user_ret_suc = nlohmann::json::array();
  89 + user_ret_suc[0] = nlohmann::json::object();
  90 + user_ret_suc[0]["success"] = nlohmann::json::object();
  91 + user_ret_suc[0]["success"]["username"] = getBridgeUsername();
  92 +
  93 + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort()))
  94 + .Times(1)
  95 + .WillOnce(Return(user_ret_suc));
  96 +
  97 + finder = HueFinder(handler);
  98 + bridges = finder.FindBridges();
  99 +
  100 + Hue test_bridge = finder.GetBridge(bridges[0]);
66 101  
67   -TEST_F(HueFinderTest, GetBridge) {
68   - using namespace ::testing;
69   - Json::Value request;
70   - request["devicetype"] = "HuePlusPlus#User";
71   -
72   - Json::Value user_ret_uns;
73   - user_ret_uns = Json::Value(Json::arrayValue);
74   - user_ret_uns[0] = Json::Value(Json::objectValue);
75   - user_ret_uns[0]["error"] = Json::Value(Json::objectValue);
76   - user_ret_uns[0]["error"]["type"] = 101;
77   - user_ret_uns[0]["error"]["address"] = "";
78   - user_ret_uns[0]["error"]["description"] = "link button not pressed";
79   -
80   - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), 80))
81   - .Times(AtLeast(1))
82   - .WillRepeatedly(Return(user_ret_uns));
83   -
84   - HueFinder finder(handler);
85   - std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
86   -
87   - ASSERT_THROW(finder.GetBridge(bridges[0]), std::runtime_error);
88   -
89   - Json::Value user_ret_suc;
90   - user_ret_suc = Json::Value(Json::arrayValue);
91   - user_ret_suc[0] = Json::Value(Json::objectValue);
92   - user_ret_suc[0]["success"] = Json::Value(Json::objectValue);
93   - user_ret_suc[0]["success"]["username"] = getBridgeUsername();
94   -
95   - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), 80))
96   - .Times(1)
97   - .WillOnce(Return(user_ret_suc));
98   -
99   - finder = HueFinder(handler);
100   - bridges = finder.FindBridges();
101   -
102   - Hue test_bridge = finder.GetBridge(bridges[0]);
103   -
104   - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp())
105   - << "Bridge IP not matching";
106   - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort())
107   - << "Bridge Port not matching";
108   - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername())
109   - << "Bridge username not matching";
110   -
111   - // Verify that username is correctly set in api requests
112   - Json::Value hue_bridge_state;
113   - hue_bridge_state["lights"] = Json::objectValue;
114   - EXPECT_CALL(*handler,
115   - GETJson("/api/" + getBridgeUsername(),
116   - Json::Value(Json::objectValue), getBridgeIp(), 80))
117   - .Times(1)
118   - .WillOnce(Return(hue_bridge_state));
119   -
120   - test_bridge.getAllLights();
121   -
122   - Mock::VerifyAndClearExpectations(handler.get());
  102 + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching";
  103 + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching";
  104 + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching";
  105 +
  106 + // Verify that username is correctly set in api requests
  107 + nlohmann::json hue_bridge_state;
  108 + hue_bridge_state["lights"] = {};
  109 + EXPECT_CALL(
  110 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  111 + .Times(1)
  112 + .WillOnce(Return(hue_bridge_state));
  113 +
  114 + test_bridge.getAllLights();
  115 +
  116 + Mock::VerifyAndClearExpectations(handler.get());
123 117 }
124 118  
125   -TEST_F(HueFinderTest, AddUsername) {
126   - HueFinder finder(handler);
127   - std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
  119 +TEST_F(HueFinderTest, AddUsername)
  120 +{
  121 + HueFinder finder(handler);
  122 + std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
128 123  
129   - finder.AddUsername(bridges[0].mac, getBridgeUsername());
130   - Hue test_bridge = finder.GetBridge(bridges[0]);
  124 + finder.AddUsername(bridges[0].mac, getBridgeUsername());
  125 + Hue test_bridge = finder.GetBridge(bridges[0]);
131 126  
132   - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp())
133   - << "Bridge IP not matching";
134   - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort())
135   - << "Bridge Port not matching";
136   - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername())
137   - << "Bridge username not matching";
  127 + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching";
  128 + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching";
  129 + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching";
138 130 }
139 131  
140   -TEST_F(HueFinderTest, GetAllUsernames) {
141   - HueFinder finder(handler);
142   - std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
  132 +TEST_F(HueFinderTest, GetAllUsernames)
  133 +{
  134 + HueFinder finder(handler);
  135 + std::vector<HueFinder::HueIdentification> bridges = finder.FindBridges();
143 136  
144   - finder.AddUsername(bridges[0].mac, getBridgeUsername());
  137 + finder.AddUsername(bridges[0].mac, getBridgeUsername());
145 138  
146   - std::map<std::string, std::string> users = finder.GetAllUsernames();
147   - EXPECT_EQ(users[getBridgeMac()], getBridgeUsername())
148   - << "Username of MAC:" << getBridgeMac() << "not matching";
  139 + std::map<std::string, std::string> users = finder.GetAllUsernames();
  140 + EXPECT_EQ(users[getBridgeMac()], getBridgeUsername()) << "Username of MAC:" << getBridgeMac() << "not matching";
149 141 }
150 142  
151   -TEST(Hue, Constructor) {
152   - std::shared_ptr<MockHttpHandler> handler =
153   - std::make_shared<MockHttpHandler>();
154   - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
155   -
156   - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp())
157   - << "Bridge IP not matching";
158   - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort())
159   - << "Bridge Port not matching";
160   - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername())
161   - << "Bridge username not matching";
  143 +TEST(Hue, Constructor)
  144 +{
  145 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  146 + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  147 +
  148 + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching";
  149 + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching";
  150 + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching";
162 151 }
163 152  
164   -TEST(Hue, requestUsername) {
165   - using namespace ::testing;
166   - std::shared_ptr<MockHttpHandler> handler =
167   - std::make_shared<MockHttpHandler>();
168   - Json::Value request;
169   - request["devicetype"] = "HuePlusPlus#User";
170   -
171   - Json::Value user_ret_uns;
172   - user_ret_uns = Json::Value(Json::arrayValue);
173   - user_ret_uns[0] = Json::Value(Json::objectValue);
174   - user_ret_uns[0]["error"] = Json::Value(Json::objectValue);
175   - user_ret_uns[0]["error"]["type"] = 101;
176   - user_ret_uns[0]["error"]["address"] = "";
177   - user_ret_uns[0]["error"]["description"] = "link button not pressed";
178   -
179   - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort()))
180   - .Times(AtLeast(1))
181   - .WillRepeatedly(Return(user_ret_uns));
182   -
183   - Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler);
184   -
185   - test_bridge.requestUsername(test_bridge.getBridgeIP());
186   - EXPECT_EQ(test_bridge.getUsername(), "") << "Bridge username not matching";
187   -
188   - Json::Value user_ret_suc;
189   - user_ret_suc = Json::Value(Json::arrayValue);
190   - user_ret_suc[0] = Json::Value(Json::objectValue);
191   - user_ret_suc[0]["success"] = Json::Value(Json::objectValue);
192   - user_ret_suc[0]["success"]["username"] = getBridgeUsername();
193   - EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), 80))
194   - .Times(1)
195   - .WillRepeatedly(Return(user_ret_suc));
196   -
197   - test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler);
198   -
199   - test_bridge.requestUsername(test_bridge.getBridgeIP());
200   -
201   - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp())
202   - << "Bridge IP not matching";
203   - EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername())
204   - << "Bridge username not matching";
205   -
206   - // Verify that username is correctly set in api requests
207   - Json::Value hue_bridge_state;
208   - hue_bridge_state["lights"] = Json::objectValue;
209   - EXPECT_CALL(*handler,
210   - GETJson("/api/" + getBridgeUsername(),
211   - Json::Value(Json::objectValue), getBridgeIp(), 80))
212   - .Times(1)
213   - .WillOnce(Return(hue_bridge_state));
214   -
215   - test_bridge.getAllLights();
  153 +TEST(Hue, requestUsername)
  154 +{
  155 + using namespace ::testing;
  156 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  157 + nlohmann::json request;
  158 + request["devicetype"] = "HuePlusPlus#User";
  159 +
  160 + nlohmann::json user_ret_uns;
  161 + user_ret_uns = nlohmann::json::array();
  162 + user_ret_uns[0] = nlohmann::json::object();
  163 + user_ret_uns[0]["error"] = nlohmann::json::object();
  164 + user_ret_uns[0]["error"]["type"] = 101;
  165 + user_ret_uns[0]["error"]["address"] = "";
  166 + user_ret_uns[0]["error"]["description"] = "link button not pressed";
  167 +
  168 + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort()))
  169 + .Times(AtLeast(1))
  170 + .WillRepeatedly(Return(user_ret_uns));
  171 +
  172 + Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler);
  173 +
  174 + test_bridge.requestUsername(test_bridge.getBridgeIP());
  175 + EXPECT_EQ(test_bridge.getUsername(), "") << "Bridge username not matching";
  176 +
  177 + nlohmann::json user_ret_suc;
  178 + user_ret_suc = nlohmann::json::array();
  179 + user_ret_suc[0] = nlohmann::json::object();
  180 + user_ret_suc[0]["success"] = nlohmann::json::object();
  181 + user_ret_suc[0]["success"]["username"] = getBridgeUsername();
  182 + EXPECT_CALL(*handler, POSTJson("/api", request, getBridgeIp(), getBridgePort()))
  183 + .Times(1)
  184 + .WillRepeatedly(Return(user_ret_suc));
  185 +
  186 + test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler);
  187 +
  188 + test_bridge.requestUsername(test_bridge.getBridgeIP());
  189 +
  190 + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching";
  191 + EXPECT_EQ(test_bridge.getUsername(), getBridgeUsername()) << "Bridge username not matching";
  192 +
  193 + // Verify that username is correctly set in api requests
  194 + nlohmann::json hue_bridge_state;
  195 + hue_bridge_state["lights"] = {};
  196 + EXPECT_CALL(
  197 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  198 + .Times(1)
  199 + .WillOnce(Return(hue_bridge_state));
  200 +
  201 + test_bridge.getAllLights();
216 202 }
217 203  
218   -TEST(Hue, setIP) {
219   - std::shared_ptr<MockHttpHandler> handler =
220   - std::make_shared<MockHttpHandler>();
221   - Hue test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler);
222   - EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp())
223   - << "Bridge IP not matching after initialization";
224   - test_bridge.setIP("192.168.2.112");
225   - EXPECT_EQ(test_bridge.getBridgeIP(), "192.168.2.112")
226   - << "Bridge IP not matching after setting it";
  204 +TEST(Hue, setIP)
  205 +{
  206 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  207 + Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler);
  208 + EXPECT_EQ(test_bridge.getBridgeIP(), getBridgeIp()) << "Bridge IP not matching after initialization";
  209 + test_bridge.setIP("192.168.2.112");
  210 + EXPECT_EQ(test_bridge.getBridgeIP(), "192.168.2.112") << "Bridge IP not matching after setting it";
227 211 }
228 212  
229   -TEST(Hue, setPort) {
230   - std::shared_ptr<MockHttpHandler> handler =
231   - std::make_shared<MockHttpHandler>();
232   - Hue test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler);
233   - EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort())
234   - << "Bridge Port not matching after initialization";
235   - test_bridge.setPort(81);
236   - EXPECT_EQ(test_bridge.getBridgePort(), 81)
237   - << "Bridge Port not matching after setting it";
  213 +TEST(Hue, setPort)
  214 +{
  215 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  216 + Hue test_bridge = Hue(getBridgeIp(), getBridgePort(), "", handler);
  217 + EXPECT_EQ(test_bridge.getBridgePort(), getBridgePort()) << "Bridge Port not matching after initialization";
  218 + test_bridge.setPort(81);
  219 + EXPECT_EQ(test_bridge.getBridgePort(), 81) << "Bridge Port not matching after setting it";
238 220 }
239 221  
240   -TEST(Hue, getLight) {
241   - using namespace ::testing;
242   - std::shared_ptr<MockHttpHandler> handler =
243   - std::make_shared<MockHttpHandler>();
244   - EXPECT_CALL(*handler,
245   - GETJson("/api/" + getBridgeUsername(),
246   - Json::Value(Json::objectValue), getBridgeIp(), 80))
247   - .Times(1);
248   -
249   - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
250   -
251   - // Test exception
252   - ASSERT_THROW(test_bridge.getLight(1), std::runtime_error);
253   -
254   - Json::Value hue_bridge_state;
255   - hue_bridge_state["lights"] = Json::Value(Json::objectValue);
256   - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue);
257   - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue);
258   - hue_bridge_state["lights"]["1"]["state"]["on"] = true;
259   - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
260   - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
261   - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
262   - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
263   - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
264   - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue);
265   - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
266   - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue;
267   - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
268   - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
269   - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
270   - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
271   - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
272   - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
273   - EXPECT_CALL(*handler,
274   - GETJson("/api/" + getBridgeUsername(),
275   - Json::Value(Json::objectValue), getBridgeIp(), 80))
276   - .Times(1)
277   - .WillOnce(Return(hue_bridge_state));
278   -
279   - EXPECT_CALL(*handler,
280   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
281   - Json::Value(Json::objectValue), getBridgeIp(), 80))
282   - .Times(AtLeast(1))
283   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
284   -
285   - // Test when correct data is sent
286   - HueLight test_light_1 = test_bridge.getLight(1);
287   - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
288   - EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE);
289   -
290   - // Test again to check whether light is returned directly -> interesting for
291   - // code coverage test
292   - test_light_1 = test_bridge.getLight(1);
293   - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
294   - EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE);
295   -
296   - // more coverage stuff
297   - hue_bridge_state["lights"]["1"]["modelid"] = "LCT001";
298   - EXPECT_CALL(*handler,
299   - GETJson("/api/" + getBridgeUsername(),
300   - Json::Value(Json::objectValue), getBridgeIp(), 80))
301   - .Times(1)
302   - .WillOnce(Return(hue_bridge_state));
303   -
304   - EXPECT_CALL(*handler,
305   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
306   - Json::Value(Json::objectValue), getBridgeIp(), 80))
307   - .Times(AtLeast(1))
308   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
309   - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
310   -
311   - // Test when correct data is sent
312   - test_light_1 = test_bridge.getLight(1);
313   - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
314   - EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B);
315   -
316   - hue_bridge_state["lights"]["1"]["modelid"] = "LCT010";
317   - EXPECT_CALL(*handler,
318   - GETJson("/api/" + getBridgeUsername(),
319   - Json::Value(Json::objectValue), getBridgeIp(), 80))
320   - .Times(1)
321   - .WillOnce(Return(hue_bridge_state));
322   -
323   - EXPECT_CALL(*handler,
324   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
325   - Json::Value(Json::objectValue), getBridgeIp(), 80))
326   - .Times(AtLeast(1))
327   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
328   - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
329   -
330   - // Test when correct data is sent
331   - test_light_1 = test_bridge.getLight(1);
332   - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
333   - EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C);
334   -
335   - hue_bridge_state["lights"]["1"]["modelid"] = "LST001";
336   - EXPECT_CALL(*handler,
337   - GETJson("/api/" + getBridgeUsername(),
338   - Json::Value(Json::objectValue), getBridgeIp(), 80))
339   - .Times(1)
340   - .WillOnce(Return(hue_bridge_state));
341   -
342   - EXPECT_CALL(*handler,
343   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
344   - Json::Value(Json::objectValue), getBridgeIp(), 80))
345   - .Times(AtLeast(1))
346   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
347   - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
348   -
349   - // Test when correct data is sent
350   - test_light_1 = test_bridge.getLight(1);
351   - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
352   - EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A);
353   -
354   - hue_bridge_state["lights"]["1"]["modelid"] = "LWB004";
355   - EXPECT_CALL(*handler,
356   - GETJson("/api/" + getBridgeUsername(),
357   - Json::Value(Json::objectValue), getBridgeIp(), 80))
358   - .Times(1)
359   - .WillOnce(Return(hue_bridge_state));
360   -
361   - EXPECT_CALL(*handler,
362   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
363   - Json::Value(Json::objectValue), getBridgeIp(), 80))
364   - .Times(AtLeast(1))
365   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
366   - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
367   -
368   - // Test when correct data is sent
369   - test_light_1 = test_bridge.getLight(1);
370   - EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
371   - EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE);
372   -
373   - hue_bridge_state["lights"]["1"]["modelid"] = "ABC000";
374   - EXPECT_CALL(*handler,
375   - GETJson("/api/" + getBridgeUsername(),
376   - Json::Value(Json::objectValue), getBridgeIp(), 80))
377   - .Times(1)
378   - .WillOnce(Return(hue_bridge_state));
379   - test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
380   -
381   - ASSERT_THROW(test_bridge.getLight(1), std::runtime_error);
  222 +TEST(Hue, getLight)
  223 +{
  224 + using namespace ::testing;
  225 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  226 + EXPECT_CALL(
  227 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  228 + .Times(1);
  229 +
  230 + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  231 +
  232 + // Test exception
  233 + ASSERT_THROW(test_bridge.getLight(1), std::runtime_error);
  234 +
  235 + nlohmann::json hue_bridge_state;
  236 + hue_bridge_state["lights"] = nlohmann::json::object();
  237 + hue_bridge_state["lights"]["1"] = nlohmann::json::object();
  238 + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();
  239 + hue_bridge_state["lights"]["1"]["state"]["on"] = true;
  240 + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
  241 + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
  242 + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
  243 + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
  244 + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
  245 + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();
  246 + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
  247 + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;
  248 + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
  249 + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
  250 + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
  251 + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
  252 + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
  253 + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
  254 + EXPECT_CALL(
  255 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  256 + .Times(1)
  257 + .WillOnce(Return(hue_bridge_state));
  258 +
  259 + EXPECT_CALL(*handler,
  260 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  261 + .Times(AtLeast(1))
  262 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  263 +
  264 + // Test when correct data is sent
  265 + HueLight test_light_1 = test_bridge.getLight(1);
  266 + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
  267 + EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE);
  268 +
  269 + // Test again to check whether light is returned directly -> interesting for
  270 + // code coverage test
  271 + test_light_1 = test_bridge.getLight(1);
  272 + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
  273 + EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE);
  274 +
  275 + // more coverage stuff
  276 + hue_bridge_state["lights"]["1"]["modelid"] = "LCT001";
  277 + EXPECT_CALL(
  278 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  279 + .Times(1)
  280 + .WillOnce(Return(hue_bridge_state));
  281 +
  282 + EXPECT_CALL(*handler,
  283 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  284 + .Times(AtLeast(1))
  285 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  286 + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  287 +
  288 + // Test when correct data is sent
  289 + test_light_1 = test_bridge.getLight(1);
  290 + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
  291 + EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_B);
  292 +
  293 + hue_bridge_state["lights"]["1"]["modelid"] = "LCT010";
  294 + EXPECT_CALL(
  295 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  296 + .Times(1)
  297 + .WillOnce(Return(hue_bridge_state));
  298 +
  299 + EXPECT_CALL(*handler,
  300 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  301 + .Times(AtLeast(1))
  302 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  303 + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  304 +
  305 + // Test when correct data is sent
  306 + test_light_1 = test_bridge.getLight(1);
  307 + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
  308 + EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_C);
  309 +
  310 + hue_bridge_state["lights"]["1"]["modelid"] = "LST001";
  311 + EXPECT_CALL(
  312 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  313 + .Times(1)
  314 + .WillOnce(Return(hue_bridge_state));
  315 +
  316 + EXPECT_CALL(*handler,
  317 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  318 + .Times(AtLeast(1))
  319 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  320 + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  321 +
  322 + // Test when correct data is sent
  323 + test_light_1 = test_bridge.getLight(1);
  324 + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
  325 + EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A);
  326 +
  327 + hue_bridge_state["lights"]["1"]["modelid"] = "LWB004";
  328 + EXPECT_CALL(
  329 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  330 + .Times(1)
  331 + .WillOnce(Return(hue_bridge_state));
  332 +
  333 + EXPECT_CALL(*handler,
  334 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  335 + .Times(AtLeast(1))
  336 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  337 + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  338 +
  339 + // Test when correct data is sent
  340 + test_light_1 = test_bridge.getLight(1);
  341 + EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1");
  342 + EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE);
  343 +
  344 + hue_bridge_state["lights"]["1"]["modelid"] = "ABC000";
  345 + EXPECT_CALL(
  346 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  347 + .Times(1)
  348 + .WillOnce(Return(hue_bridge_state));
  349 + test_bridge = Hue(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  350 +
  351 + ASSERT_THROW(test_bridge.getLight(1), std::runtime_error);
382 352 }
383 353  
384   -TEST(Hue, removeLight) {
385   - using namespace ::testing;
386   - std::shared_ptr<MockHttpHandler> handler =
387   - std::make_shared<MockHttpHandler>();
388   - Json::Value hue_bridge_state;
389   - hue_bridge_state["lights"] = Json::Value(Json::objectValue);
390   - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue);
391   - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue);
392   - hue_bridge_state["lights"]["1"]["state"]["on"] = true;
393   - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
394   - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
395   - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
396   - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
397   - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
398   - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue);
399   - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
400   - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue;
401   - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
402   - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
403   - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
404   - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
405   - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
406   - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
407   - EXPECT_CALL(*handler,
408   - GETJson("/api/" + getBridgeUsername(),
409   - Json::Value(Json::objectValue), getBridgeIp(), 80))
410   - .Times(1)
411   - .WillOnce(Return(hue_bridge_state));
412   -
413   - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
414   -
415   - EXPECT_CALL(*handler,
416   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
417   - Json::Value(Json::objectValue), getBridgeIp(), 80))
418   - .Times(1)
419   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
420   -
421   - Json::Value return_answer;
422   - return_answer = Json::Value(Json::arrayValue);
423   - return_answer[0] = Json::Value(Json::objectValue);
424   - return_answer[0]["success"] = "/lights/1 deleted";
425   - EXPECT_CALL(*handler,
426   - DELETEJson("/api/" + getBridgeUsername() + "/lights/1",
427   - Json::Value(Json::objectValue), getBridgeIp(), 80))
428   - .Times(2)
429   - .WillOnce(Return(return_answer))
430   - .WillOnce(Return(Json::Value()));
431   -
432   - // Test when correct data is sent
433   - HueLight test_light_1 = test_bridge.getLight(1);
434   -
435   - EXPECT_EQ(test_bridge.removeLight(1), true);
436   -
437   - EXPECT_EQ(test_bridge.removeLight(1), false);
  354 +TEST(Hue, removeLight)
  355 +{
  356 + using namespace ::testing;
  357 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  358 + nlohmann::json hue_bridge_state;
  359 + hue_bridge_state["lights"] = nlohmann::json::object();
  360 + hue_bridge_state["lights"]["1"] = nlohmann::json::object();
  361 + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();
  362 + hue_bridge_state["lights"]["1"]["state"]["on"] = true;
  363 + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
  364 + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
  365 + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
  366 + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
  367 + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
  368 + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();
  369 + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
  370 + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;
  371 + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
  372 + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
  373 + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
  374 + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
  375 + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
  376 + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
  377 + EXPECT_CALL(
  378 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  379 + .Times(1)
  380 + .WillOnce(Return(hue_bridge_state));
  381 +
  382 + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  383 +
  384 + EXPECT_CALL(*handler,
  385 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  386 + .Times(1)
  387 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  388 +
  389 + nlohmann::json return_answer;
  390 + return_answer = nlohmann::json::array();
  391 + return_answer[0] = nlohmann::json::object();
  392 + return_answer[0]["success"] = "/lights/1 deleted";
  393 + EXPECT_CALL(*handler,
  394 + DELETEJson(
  395 + "/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  396 + .Times(2)
  397 + .WillOnce(Return(return_answer))
  398 + .WillOnce(Return(nlohmann::json()));
  399 +
  400 + // Test when correct data is sent
  401 + HueLight test_light_1 = test_bridge.getLight(1);
  402 +
  403 + EXPECT_EQ(test_bridge.removeLight(1), true);
  404 +
  405 + EXPECT_EQ(test_bridge.removeLight(1), false);
438 406 }
439 407  
440   -TEST(Hue, getAllLights) {
441   - using namespace ::testing;
442   - std::shared_ptr<MockHttpHandler> handler =
443   - std::make_shared<MockHttpHandler>();
444   - Json::Value hue_bridge_state;
445   - hue_bridge_state["lights"] = Json::Value(Json::objectValue);
446   - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue);
447   - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue);
448   - hue_bridge_state["lights"]["1"]["state"]["on"] = true;
449   - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
450   - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
451   - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
452   - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
453   - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
454   - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue);
455   - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
456   - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue;
457   - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
458   - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
459   - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
460   - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
461   - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
462   - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
463   - EXPECT_CALL(*handler,
464   - GETJson("/api/" + getBridgeUsername(),
465   - Json::Value(Json::objectValue), getBridgeIp(), 80))
466   - .Times(2)
467   - .WillRepeatedly(Return(hue_bridge_state));
468   -
469   - EXPECT_CALL(*handler,
470   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
471   - Json::Value(Json::objectValue), getBridgeIp(), 80))
472   - .Times(2)
473   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
474   -
475   - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
476   -
477   - std::vector<std::reference_wrapper<HueLight>> test_lights =
478   - test_bridge.getAllLights();
479   - ASSERT_EQ(1, test_lights.size());
480   - EXPECT_EQ(test_lights[0].get().getName(), "Hue ambiance lamp 1");
481   - EXPECT_EQ(test_lights[0].get().getColorType(), ColorType::TEMPERATURE);
  408 +TEST(Hue, getAllLights)
  409 +{
  410 + using namespace ::testing;
  411 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  412 + nlohmann::json hue_bridge_state;
  413 + hue_bridge_state["lights"] = nlohmann::json::object();
  414 + hue_bridge_state["lights"]["1"] = nlohmann::json::object();
  415 + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();
  416 + hue_bridge_state["lights"]["1"]["state"]["on"] = true;
  417 + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
  418 + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
  419 + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
  420 + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
  421 + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
  422 + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();
  423 + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
  424 + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;
  425 + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
  426 + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
  427 + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
  428 + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
  429 + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
  430 + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
  431 + EXPECT_CALL(
  432 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  433 + .Times(2)
  434 + .WillRepeatedly(Return(hue_bridge_state));
  435 +
  436 + EXPECT_CALL(*handler,
  437 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  438 + .Times(2)
  439 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  440 +
  441 + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  442 +
  443 + std::vector<std::reference_wrapper<HueLight>> test_lights = test_bridge.getAllLights();
  444 + ASSERT_EQ(1, test_lights.size());
  445 + EXPECT_EQ(test_lights[0].get().getName(), "Hue ambiance lamp 1");
  446 + EXPECT_EQ(test_lights[0].get().getColorType(), ColorType::TEMPERATURE);
482 447 }
483 448  
484   -TEST(Hue, lightExists) {
485   - using namespace ::testing;
486   - std::shared_ptr<MockHttpHandler> handler =
487   - std::make_shared<MockHttpHandler>();
488   - Json::Value hue_bridge_state;
489   - hue_bridge_state["lights"] = Json::Value(Json::objectValue);
490   - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue);
491   - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue);
492   - hue_bridge_state["lights"]["1"]["state"]["on"] = true;
493   - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
494   - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
495   - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
496   - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
497   - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
498   - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue);
499   - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
500   - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue;
501   - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
502   - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
503   - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
504   - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
505   - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
506   - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
507   - EXPECT_CALL(*handler,
508   - GETJson("/api/" + getBridgeUsername(),
509   - Json::Value(Json::objectValue), getBridgeIp(), 80))
510   - .Times(AtLeast(2))
511   - .WillRepeatedly(Return(hue_bridge_state));
512   - EXPECT_CALL(*handler,
513   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
514   - Json::Value(Json::objectValue), getBridgeIp(), 80))
515   - .Times(AtLeast(1))
516   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
517   -
518   - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
519   -
520   - EXPECT_EQ(true, test_bridge.lightExists(1));
521   - EXPECT_EQ(false, test_bridge.lightExists(2));
522   -
523   - const Hue const_test_bridge1 = test_bridge;
524   - EXPECT_EQ(true, const_test_bridge1.lightExists(1));
525   - EXPECT_EQ(false, const_test_bridge1.lightExists(2));
526   -
527   - test_bridge.getLight(1);
528   - const Hue const_test_bridge2 = test_bridge;
529   - EXPECT_EQ(true, test_bridge.lightExists(1));
530   - EXPECT_EQ(true, const_test_bridge2.lightExists(1));
  449 +TEST(Hue, lightExists)
  450 +{
  451 + using namespace ::testing;
  452 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  453 + nlohmann::json hue_bridge_state;
  454 + hue_bridge_state["lights"] = nlohmann::json::object();
  455 + hue_bridge_state["lights"]["1"] = nlohmann::json::object();
  456 + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();
  457 + hue_bridge_state["lights"]["1"]["state"]["on"] = true;
  458 + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
  459 + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
  460 + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
  461 + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
  462 + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
  463 + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();
  464 + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
  465 + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;
  466 + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
  467 + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
  468 + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
  469 + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
  470 + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
  471 + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
  472 + EXPECT_CALL(
  473 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  474 + .Times(AtLeast(2))
  475 + .WillRepeatedly(Return(hue_bridge_state));
  476 + EXPECT_CALL(*handler,
  477 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  478 + .Times(AtLeast(1))
  479 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  480 +
  481 + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  482 +
  483 + EXPECT_EQ(true, test_bridge.lightExists(1));
  484 + EXPECT_EQ(false, test_bridge.lightExists(2));
  485 +
  486 + const Hue const_test_bridge1 = test_bridge;
  487 + EXPECT_EQ(true, const_test_bridge1.lightExists(1));
  488 + EXPECT_EQ(false, const_test_bridge1.lightExists(2));
  489 +
  490 + test_bridge.getLight(1);
  491 + const Hue const_test_bridge2 = test_bridge;
  492 + EXPECT_EQ(true, test_bridge.lightExists(1));
  493 + EXPECT_EQ(true, const_test_bridge2.lightExists(1));
531 494 }
532 495  
533   -TEST(Hue, getPictureOfLight) {
534   - using namespace ::testing;
535   - std::shared_ptr<MockHttpHandler> handler =
536   - std::make_shared<MockHttpHandler>();
537   - Json::Value hue_bridge_state;
538   - hue_bridge_state["lights"] = Json::Value(Json::objectValue);
539   - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue);
540   - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue);
541   - hue_bridge_state["lights"]["1"]["state"]["on"] = true;
542   - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
543   - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
544   - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
545   - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
546   - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
547   - hue_bridge_state["lights"]["1"]["swupdate"] = Json::Value(Json::objectValue);
548   - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
549   - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = Json::nullValue;
550   - hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
551   - hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
552   - hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
553   - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
554   - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
555   - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
556   -
557   - EXPECT_CALL(*handler,
558   - GETJson("/api/" + getBridgeUsername(),
559   - Json::Value(Json::objectValue), getBridgeIp(), 80))
560   - .Times(AtLeast(1))
561   - .WillRepeatedly(Return(hue_bridge_state));
562   - EXPECT_CALL(*handler,
563   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
564   - Json::Value(Json::objectValue), getBridgeIp(), 80))
565   - .Times(AtLeast(1))
566   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
567   -
568   - Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
569   -
570   - test_bridge.getLight(1);
571   -
572   - EXPECT_EQ("", test_bridge.getPictureOfLight(2));
573   -
574   - EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1));
  496 +TEST(Hue, getPictureOfLight)
  497 +{
  498 + using namespace ::testing;
  499 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  500 + nlohmann::json hue_bridge_state;
  501 + hue_bridge_state["lights"] = nlohmann::json::object();
  502 + hue_bridge_state["lights"]["1"] = nlohmann::json::object();
  503 + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();
  504 + hue_bridge_state["lights"]["1"]["state"]["on"] = true;
  505 + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
  506 + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
  507 + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
  508 + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
  509 + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
  510 + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();
  511 + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
  512 + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;
  513 + hue_bridge_state["lights"]["1"]["type"] = "Color temperature light";
  514 + hue_bridge_state["lights"]["1"]["name"] = "Hue ambiance lamp 1";
  515 + hue_bridge_state["lights"]["1"]["modelid"] = "LTW001";
  516 + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
  517 + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
  518 + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
  519 +
  520 + EXPECT_CALL(
  521 + *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  522 + .Times(AtLeast(1))
  523 + .WillRepeatedly(Return(hue_bridge_state));
  524 + EXPECT_CALL(*handler,
  525 + GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
  526 + .Times(AtLeast(1))
  527 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  528 +
  529 + Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
  530 +
  531 + test_bridge.getLight(1);
  532 +
  533 + EXPECT_EQ("", test_bridge.getPictureOfLight(2));
  534 +
  535 + EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1));
575 536 }
576 537  
577   -TEST(Hue, refreshState) {
578   - std::shared_ptr<MockHttpHandler> handler =
579   - std::make_shared<MockHttpHandler>();
580   - Hue test_bridge(getBridgeIp(), getBridgePort(), "",
581   - handler); // NULL as username leads to segfault
  538 +TEST(Hue, refreshState)
  539 +{
  540 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  541 + Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); // NULL as username leads to segfault
582 542  
583   - std::vector<std::reference_wrapper<HueLight>> test_lights =
584   - test_bridge.getAllLights();
585   - EXPECT_EQ(test_lights.size(), 0);
  543 + std::vector<std::reference_wrapper<HueLight>> test_lights = test_bridge.getAllLights();
  544 + EXPECT_EQ(test_lights.size(), 0);
586 545 }
... ...
hueplusplus/test/test_HueCommandAPI.cpp 100755 → 100644
... ... @@ -20,226 +20,191 @@
20 20 #include <gmock/gmock.h>
21 21 #include <gtest/gtest.h>
22 22  
  23 +#include "testhelper.h"
  24 +
23 25 #include "../include/Hue.h"
24   -#include "../include/json/json.h"
  26 +#include "../include/json/json.hpp"
25 27 #include "mocks/mock_HttpHandler.h"
26   -#include "testhelper.h"
27 28  
28   -TEST(HueCommandAPI, PUTRequest) {
29   - using namespace ::testing;
30   - std::shared_ptr<MockHttpHandler> httpHandler =
31   - std::make_shared<MockHttpHandler>();
  29 +TEST(HueCommandAPI, PUTRequest)
  30 +{
  31 + using namespace ::testing;
  32 + std::shared_ptr<MockHttpHandler> httpHandler = std::make_shared<MockHttpHandler>();
32 33  
33   - HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(),
34   - httpHandler);
35   - Json::Value request;
36   - Json::Value result = Json::objectValue;
37   - result["ok"] = true;
  34 + HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), httpHandler);
  35 + nlohmann::json request;
  36 + nlohmann::json result = nlohmann::json::object();
  37 + result["ok"] = true;
38 38  
39   - // empty path
40   - {
41   - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername(), request,
42   - getBridgeIp(), 80))
43   - .WillOnce(Return(result));
44   - EXPECT_EQ(result, api.PUTRequest("", request));
45   - Mock::VerifyAndClearExpectations(httpHandler.get());
46   - }
47   - // not empty path, starting with slash
48   - {
49   - const std::string path = "/test";
50   - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path,
51   - request, getBridgeIp(), 80))
52   - .WillOnce(Return(result));
53   - EXPECT_EQ(result, api.PUTRequest(path, request));
54   - Mock::VerifyAndClearExpectations(httpHandler.get());
55   - }
56   - // not empty path, not starting with slash
57   - {
58   - const std::string path = "test";
59   - EXPECT_CALL(*httpHandler,
60   - PUTJson("/api/" + getBridgeUsername() + '/' + path, request,
61   - getBridgeIp(), 80))
62   - .WillOnce(Return(result));
63   - EXPECT_EQ(result, api.PUTRequest(path, request));
64   - Mock::VerifyAndClearExpectations(httpHandler.get());
65   - }
66   - // recoverable error
67   - {
68   - const std::string path = "/test";
69   - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path,
70   - request, getBridgeIp(), 80))
71   - .WillOnce(Throw(std::system_error(
72   - std::make_error_code(std::errc::connection_reset))))
73   - .WillOnce(Return(result));
74   - EXPECT_EQ(result, api.PUTRequest(path, request));
75   - Mock::VerifyAndClearExpectations(httpHandler.get());
76   - }
77   - // recoverable error x2
78   - {
79   - const std::string path = "/test";
80   - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path,
81   - request, getBridgeIp(), 80))
82   - .WillOnce(Throw(std::system_error(
83   - std::make_error_code(std::errc::connection_reset))))
84   - .WillOnce(Throw(std::system_error(
85   - std::make_error_code(std::errc::connection_reset))));
86   - EXPECT_THROW(api.PUTRequest(path, request), std::system_error);
87   - Mock::VerifyAndClearExpectations(httpHandler.get());
88   - }
89   - // unrecoverable error
90   - {
91   - const std::string path = "/test";
92   - EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path,
93   - request, getBridgeIp(), 80))
94   - .WillOnce(Throw(std::system_error(
95   - std::make_error_code(std::errc::not_enough_memory))));
96   - EXPECT_THROW(api.PUTRequest(path, request), std::system_error);
97   - Mock::VerifyAndClearExpectations(httpHandler.get());
98   - }
  39 + // empty path
  40 + {
  41 + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername(), request, getBridgeIp(), 80))
  42 + .WillOnce(Return(result));
  43 + EXPECT_EQ(result, api.PUTRequest("", request));
  44 + Mock::VerifyAndClearExpectations(httpHandler.get());
  45 + }
  46 + // not empty path, starting with slash
  47 + {
  48 + const std::string path = "/test";
  49 + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  50 + .WillOnce(Return(result));
  51 + EXPECT_EQ(result, api.PUTRequest(path, request));
  52 + Mock::VerifyAndClearExpectations(httpHandler.get());
  53 + }
  54 + // not empty path, not starting with slash
  55 + {
  56 + const std::string path = "test";
  57 + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + '/' + path, request, getBridgeIp(), 80))
  58 + .WillOnce(Return(result));
  59 + EXPECT_EQ(result, api.PUTRequest(path, request));
  60 + Mock::VerifyAndClearExpectations(httpHandler.get());
  61 + }
  62 + // recoverable error
  63 + {
  64 + const std::string path = "/test";
  65 + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  66 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))))
  67 + .WillOnce(Return(result));
  68 + EXPECT_EQ(result, api.PUTRequest(path, request));
  69 + Mock::VerifyAndClearExpectations(httpHandler.get());
  70 + }
  71 + // recoverable error x2
  72 + {
  73 + const std::string path = "/test";
  74 + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  75 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))))
  76 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))));
  77 + EXPECT_THROW(api.PUTRequest(path, request), std::system_error);
  78 + Mock::VerifyAndClearExpectations(httpHandler.get());
  79 + }
  80 + // unrecoverable error
  81 + {
  82 + const std::string path = "/test";
  83 + EXPECT_CALL(*httpHandler, PUTJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  84 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::not_enough_memory))));
  85 + EXPECT_THROW(api.PUTRequest(path, request), std::system_error);
  86 + Mock::VerifyAndClearExpectations(httpHandler.get());
  87 + }
99 88 }
100 89  
101   -TEST(HueCommandAPI, GETRequest) {
102   - using namespace ::testing;
103   - std::shared_ptr<MockHttpHandler> httpHandler =
104   - std::make_shared<MockHttpHandler>();
  90 +TEST(HueCommandAPI, GETRequest)
  91 +{
  92 + using namespace ::testing;
  93 + std::shared_ptr<MockHttpHandler> httpHandler = std::make_shared<MockHttpHandler>();
105 94  
106   - HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(),
107   - httpHandler);
108   - Json::Value request;
109   - Json::Value result = Json::objectValue;
110   - result["ok"] = true;
  95 + HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), httpHandler);
  96 + nlohmann::json request;
  97 + nlohmann::json result = nlohmann::json::object();
  98 + result["ok"] = true;
111 99  
112   - // empty path
113   - {
114   - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername(), request,
115   - getBridgeIp(), 80))
116   - .WillOnce(Return(result));
117   - EXPECT_EQ(result, api.GETRequest("", request));
118   - Mock::VerifyAndClearExpectations(httpHandler.get());
119   - }
120   - // not empty path, starting with slash
121   - {
122   - const std::string path = "/test";
123   - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path,
124   - request, getBridgeIp(), 80))
125   - .WillOnce(Return(result));
126   - EXPECT_EQ(result, api.GETRequest(path, request));
127   - Mock::VerifyAndClearExpectations(httpHandler.get());
128   - }
129   - // not empty path, not starting with slash
130   - {
131   - const std::string path = "test";
132   - EXPECT_CALL(*httpHandler,
133   - GETJson("/api/" + getBridgeUsername() + '/' + path, request,
134   - getBridgeIp(), 80))
135   - .WillOnce(Return(result));
136   - EXPECT_EQ(result, api.GETRequest(path, request));
137   - Mock::VerifyAndClearExpectations(httpHandler.get());
138   - }
139   - // recoverable error
140   - {
141   - const std::string path = "/test";
142   - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path,
143   - request, getBridgeIp(), 80))
144   - .WillOnce(Throw(std::system_error(
145   - std::make_error_code(std::errc::connection_reset))))
146   - .WillOnce(Return(result));
147   - EXPECT_EQ(result, api.GETRequest(path, request));
148   - Mock::VerifyAndClearExpectations(httpHandler.get());
149   - }
150   - // recoverable error x2
151   - {
152   - const std::string path = "/test";
153   - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path,
154   - request, getBridgeIp(), 80))
155   - .WillOnce(Throw(std::system_error(
156   - std::make_error_code(std::errc::connection_reset))))
157   - .WillOnce(Throw(std::system_error(
158   - std::make_error_code(std::errc::connection_reset))));
159   - EXPECT_THROW(api.GETRequest(path, request), std::system_error);
160   - Mock::VerifyAndClearExpectations(httpHandler.get());
161   - }
162   - // unrecoverable error
163   - {
164   - const std::string path = "/test";
165   - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path,
166   - request, getBridgeIp(), 80))
167   - .WillOnce(Throw(std::system_error(
168   - std::make_error_code(std::errc::not_enough_memory))));
169   - EXPECT_THROW(api.GETRequest(path, request), std::system_error);
170   - Mock::VerifyAndClearExpectations(httpHandler.get());
171   - }
  100 + // empty path
  101 + {
  102 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername(), request, getBridgeIp(), 80))
  103 + .WillOnce(Return(result));
  104 + EXPECT_EQ(result, api.GETRequest("", request));
  105 + Mock::VerifyAndClearExpectations(httpHandler.get());
  106 + }
  107 + // not empty path, starting with slash
  108 + {
  109 + const std::string path = "/test";
  110 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  111 + .WillOnce(Return(result));
  112 + EXPECT_EQ(result, api.GETRequest(path, request));
  113 + Mock::VerifyAndClearExpectations(httpHandler.get());
  114 + }
  115 + // not empty path, not starting with slash
  116 + {
  117 + const std::string path = "test";
  118 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + '/' + path, request, getBridgeIp(), 80))
  119 + .WillOnce(Return(result));
  120 + EXPECT_EQ(result, api.GETRequest(path, request));
  121 + Mock::VerifyAndClearExpectations(httpHandler.get());
  122 + }
  123 + // recoverable error
  124 + {
  125 + const std::string path = "/test";
  126 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  127 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))))
  128 + .WillOnce(Return(result));
  129 + EXPECT_EQ(result, api.GETRequest(path, request));
  130 + Mock::VerifyAndClearExpectations(httpHandler.get());
  131 + }
  132 + // recoverable error x2
  133 + {
  134 + const std::string path = "/test";
  135 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  136 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))))
  137 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))));
  138 + EXPECT_THROW(api.GETRequest(path, request), std::system_error);
  139 + Mock::VerifyAndClearExpectations(httpHandler.get());
  140 + }
  141 + // unrecoverable error
  142 + {
  143 + const std::string path = "/test";
  144 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  145 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::not_enough_memory))));
  146 + EXPECT_THROW(api.GETRequest(path, request), std::system_error);
  147 + Mock::VerifyAndClearExpectations(httpHandler.get());
  148 + }
172 149 }
173 150  
174   -TEST(HueCommandAPI, DELETERequest) {
175   - using namespace ::testing;
176   - std::shared_ptr<MockHttpHandler> httpHandler =
177   - std::make_shared<MockHttpHandler>();
  151 +TEST(HueCommandAPI, DELETERequest)
  152 +{
  153 + using namespace ::testing;
  154 + std::shared_ptr<MockHttpHandler> httpHandler = std::make_shared<MockHttpHandler>();
178 155  
179   - HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(),
180   - httpHandler);
181   - Json::Value request;
182   - Json::Value result = Json::objectValue;
183   - result["ok"] = true;
  156 + HueCommandAPI api(getBridgeIp(), getBridgePort(), getBridgeUsername(), httpHandler);
  157 + nlohmann::json request;
  158 + nlohmann::json result = nlohmann::json::object();
  159 + result["ok"] = true;
184 160  
185   - // empty path
186   - {
187   - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername(), request,
188   - getBridgeIp(), 80))
189   - .WillOnce(Return(result));
190   - EXPECT_EQ(result, api.DELETERequest("", request));
191   - Mock::VerifyAndClearExpectations(httpHandler.get());
192   - }
193   - // not empty path, starting with slash
194   - {
195   - const std::string path = "/test";
196   - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path,
197   - request, getBridgeIp(), 80))
198   - .WillOnce(Return(result));
199   - EXPECT_EQ(result, api.DELETERequest(path, request));
200   - Mock::VerifyAndClearExpectations(httpHandler.get());
201   - }
202   - // not empty path, not starting with slash
203   - {
204   - const std::string path = "test";
205   - EXPECT_CALL(*httpHandler,
206   - DELETEJson("/api/" + getBridgeUsername() + '/' + path, request,
207   - getBridgeIp(), 80))
208   - .WillOnce(Return(result));
209   - EXPECT_EQ(result, api.DELETERequest(path, request));
210   - Mock::VerifyAndClearExpectations(httpHandler.get());
211   - }
212   - // recoverable error
213   - {
214   - const std::string path = "/test";
215   - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path,
216   - request, getBridgeIp(), 80))
217   - .WillOnce(Throw(std::system_error(
218   - std::make_error_code(std::errc::connection_reset))))
219   - .WillOnce(Return(result));
220   - EXPECT_EQ(result, api.DELETERequest(path, request));
221   - Mock::VerifyAndClearExpectations(httpHandler.get());
222   - }
223   - // recoverable error x2
224   - {
225   - const std::string path = "/test";
226   - EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path,
227   - request, getBridgeIp(), 80))
228   - .WillOnce(Throw(std::system_error(
229   - std::make_error_code(std::errc::connection_reset))))
230   - .WillOnce(Throw(std::system_error(
231   - std::make_error_code(std::errc::connection_reset))));
232   - EXPECT_THROW(api.DELETERequest(path, request), std::system_error);
233   - Mock::VerifyAndClearExpectations(httpHandler.get());
234   - }
235   - // unrecoverable error
236   - {
237   - const std::string path = "/test";
238   - EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path,
239   - request, getBridgeIp(), 80))
240   - .WillOnce(Throw(std::system_error(
241   - std::make_error_code(std::errc::not_enough_memory))));
242   - EXPECT_THROW(api.GETRequest(path, request), std::system_error);
243   - Mock::VerifyAndClearExpectations(httpHandler.get());
244   - }
  161 + // empty path
  162 + {
  163 + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername(), request, getBridgeIp(), 80))
  164 + .WillOnce(Return(result));
  165 + EXPECT_EQ(result, api.DELETERequest("", request));
  166 + Mock::VerifyAndClearExpectations(httpHandler.get());
  167 + }
  168 + // not empty path, starting with slash
  169 + {
  170 + const std::string path = "/test";
  171 + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  172 + .WillOnce(Return(result));
  173 + EXPECT_EQ(result, api.DELETERequest(path, request));
  174 + Mock::VerifyAndClearExpectations(httpHandler.get());
  175 + }
  176 + // not empty path, not starting with slash
  177 + {
  178 + const std::string path = "test";
  179 + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + '/' + path, request, getBridgeIp(), 80))
  180 + .WillOnce(Return(result));
  181 + EXPECT_EQ(result, api.DELETERequest(path, request));
  182 + Mock::VerifyAndClearExpectations(httpHandler.get());
  183 + }
  184 + // recoverable error
  185 + {
  186 + const std::string path = "/test";
  187 + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  188 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))))
  189 + .WillOnce(Return(result));
  190 + EXPECT_EQ(result, api.DELETERequest(path, request));
  191 + Mock::VerifyAndClearExpectations(httpHandler.get());
  192 + }
  193 + // recoverable error x2
  194 + {
  195 + const std::string path = "/test";
  196 + EXPECT_CALL(*httpHandler, DELETEJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  197 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))))
  198 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::connection_reset))));
  199 + EXPECT_THROW(api.DELETERequest(path, request), std::system_error);
  200 + Mock::VerifyAndClearExpectations(httpHandler.get());
  201 + }
  202 + // unrecoverable error
  203 + {
  204 + const std::string path = "/test";
  205 + EXPECT_CALL(*httpHandler, GETJson("/api/" + getBridgeUsername() + path, request, getBridgeIp(), 80))
  206 + .WillOnce(Throw(std::system_error(std::make_error_code(std::errc::not_enough_memory))));
  207 + EXPECT_THROW(api.GETRequest(path, request), std::system_error);
  208 + Mock::VerifyAndClearExpectations(httpHandler.get());
  209 + }
245 210 }
... ...
hueplusplus/test/test_HueLight.cpp 100755 → 100644
1 1 #include <gmock/gmock.h>
2 2 #include <gtest/gtest.h>
3 3  
  4 +#include "testhelper.h"
  5 +
4 6 #include "../include/Hue.h"
5 7 #include "../include/HueLight.h"
6   -#include "../include/json/json.h"
  8 +#include "../include/json/json.hpp"
7 9 #include "mocks/mock_HttpHandler.h"
8   -#include "testhelper.h"
9 10  
10   -class HueLightTest : public ::testing::Test {
  11 +class HueLightTest : public ::testing::Test
  12 +{
11 13 protected:
12   - std::shared_ptr<MockHttpHandler> handler;
13   - Json::Value hue_bridge_state;
14   - Hue test_bridge;
  14 + std::shared_ptr<MockHttpHandler> handler;
  15 + nlohmann::json hue_bridge_state;
  16 + Hue test_bridge;
15 17  
16 18 protected:
17   - HueLightTest()
18   - : handler(std::make_shared<MockHttpHandler>()),
19   - test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(),
20   - handler) {
21   - using namespace ::testing;
22   - hue_bridge_state["lights"] = Json::Value(Json::objectValue);
23   - hue_bridge_state["lights"]["1"] = Json::Value(Json::objectValue);
24   - hue_bridge_state["lights"]["1"]["state"] = Json::Value(Json::objectValue);
25   - hue_bridge_state["lights"]["1"]["state"]["on"] = true;
26   - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
27   - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
28   - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
29   - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
30   - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
31   - hue_bridge_state["lights"]["1"]["swupdate"] =
32   - Json::Value(Json::objectValue);
33   - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
34   - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] =
35   - Json::nullValue;
36   - hue_bridge_state["lights"]["1"]["type"] = "Dimmable light";
37   - hue_bridge_state["lights"]["1"]["name"] = "Hue lamp 1";
38   - hue_bridge_state["lights"]["1"]["modelid"] = "LWB004";
39   - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
40   - hue_bridge_state["lights"]["1"]["productname"] = "Hue bloom";
41   - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
42   - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
43   - hue_bridge_state["lights"]["1"]["luminaireuniqueid"] = "0000000";
44   - hue_bridge_state["lights"]["2"] = Json::Value(Json::objectValue);
45   - hue_bridge_state["lights"]["2"]["state"] = Json::Value(Json::objectValue);
46   - hue_bridge_state["lights"]["2"]["state"]["on"] = false;
47   - hue_bridge_state["lights"]["2"]["state"]["bri"] = 254;
48   - hue_bridge_state["lights"]["2"]["state"]["ct"] = 366;
49   - hue_bridge_state["lights"]["2"]["state"]["hue"] = 123456;
50   - hue_bridge_state["lights"]["2"]["state"]["sat"] = 123;
51   - hue_bridge_state["lights"]["2"]["state"]["xy"][0] = 0.102;
52   - hue_bridge_state["lights"]["2"]["state"]["xy"][1] = 0.102;
53   - hue_bridge_state["lights"]["2"]["state"]["alert"] = "none";
54   - hue_bridge_state["lights"]["2"]["state"]["colormode"] = "ct";
55   - hue_bridge_state["lights"]["2"]["state"]["reachable"] = true;
56   - hue_bridge_state["lights"]["2"]["swupdate"] =
57   - Json::Value(Json::objectValue);
58   - hue_bridge_state["lights"]["2"]["swupdate"]["state"] = "noupdates";
59   - hue_bridge_state["lights"]["2"]["swupdate"]["lastinstall"] =
60   - Json::nullValue;
61   - hue_bridge_state["lights"]["2"]["type"] = "Color light";
62   - hue_bridge_state["lights"]["2"]["name"] = "Hue lamp 2";
63   - hue_bridge_state["lights"]["2"]["modelid"] = "LST001";
64   - hue_bridge_state["lights"]["2"]["uniqueid"] = "11:11:11:11:11:11:11:11-11";
65   - hue_bridge_state["lights"]["2"]["swversion"] = "5.50.1.19085";
66   - hue_bridge_state["lights"]["3"] = Json::Value(Json::objectValue);
67   - hue_bridge_state["lights"]["3"]["state"] = Json::Value(Json::objectValue);
68   - hue_bridge_state["lights"]["3"]["state"]["on"] = false;
69   - hue_bridge_state["lights"]["3"]["state"]["bri"] = 254;
70   - hue_bridge_state["lights"]["3"]["state"]["ct"] = 366;
71   - hue_bridge_state["lights"]["3"]["state"]["hue"] = 123456;
72   - hue_bridge_state["lights"]["3"]["state"]["sat"] = 123;
73   - hue_bridge_state["lights"]["3"]["state"]["xy"][0] = 0.102;
74   - hue_bridge_state["lights"]["3"]["state"]["xy"][1] = 0.102;
75   - hue_bridge_state["lights"]["3"]["state"]["alert"] = "none";
76   - hue_bridge_state["lights"]["3"]["state"]["colormode"] = "ct";
77   - hue_bridge_state["lights"]["3"]["state"]["reachable"] = true;
78   - hue_bridge_state["lights"]["3"]["swupdate"] =
79   - Json::Value(Json::objectValue);
80   - hue_bridge_state["lights"]["3"]["swupdate"]["state"] = "noupdates";
81   - hue_bridge_state["lights"]["3"]["swupdate"]["lastinstall"] =
82   - Json::nullValue;
83   - hue_bridge_state["lights"]["3"]["type"] = "Color extended light";
84   - hue_bridge_state["lights"]["3"]["name"] = "Hue lamp 3";
85   - hue_bridge_state["lights"]["3"]["modelid"] = "LCT010";
86   - hue_bridge_state["lights"]["3"]["manufacturername"] = "Philips";
87   - hue_bridge_state["lights"]["3"]["productname"] = "Hue bloom";
88   - hue_bridge_state["lights"]["3"]["swversion"] = "5.50.1.19085";
89   -
90   - EXPECT_CALL(*handler,
91   - GETJson("/api/" + getBridgeUsername(),
92   - Json::Value(Json::objectValue), getBridgeIp(), 80))
93   - .Times(AtLeast(1))
94   - .WillRepeatedly(Return(hue_bridge_state));
95   - EXPECT_CALL(*handler,
96   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
97   - Json::Value(Json::objectValue), getBridgeIp(), 80))
98   - .Times(AtLeast(1))
99   - .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
100   - EXPECT_CALL(*handler,
101   - GETJson("/api/" + getBridgeUsername() + "/lights/2",
102   - Json::Value(Json::objectValue), getBridgeIp(), 80))
103   - .Times(AtLeast(1))
104   - .WillRepeatedly(Return(hue_bridge_state["lights"]["2"]));
105   - EXPECT_CALL(*handler,
106   - GETJson("/api/" + getBridgeUsername() + "/lights/3",
107   - Json::Value(Json::objectValue), getBridgeIp(), 80))
108   - .Times(AtLeast(1))
109   - .WillRepeatedly(Return(hue_bridge_state["lights"]["3"]));
110   - }
111   - ~HueLightTest(){};
  19 + HueLightTest()
  20 + : handler(std::make_shared<MockHttpHandler>()),
  21 + test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler)
  22 + {
  23 + using namespace ::testing;
  24 + hue_bridge_state["lights"] = nlohmann::json::object();
  25 + hue_bridge_state["lights"]["1"] = nlohmann::json::object();
  26 + hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();
  27 + hue_bridge_state["lights"]["1"]["state"]["on"] = true;
  28 + hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;
  29 + hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;
  30 + hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";
  31 + hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";
  32 + hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;
  33 + hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();
  34 + hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";
  35 + hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;
  36 + hue_bridge_state["lights"]["1"]["type"] = "Dimmable light";
  37 + hue_bridge_state["lights"]["1"]["name"] = "Hue lamp 1";
  38 + hue_bridge_state["lights"]["1"]["modelid"] = "LWB004";
  39 + hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";
  40 + hue_bridge_state["lights"]["1"]["productname"] = "Hue bloom";
  41 + hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";
  42 + hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";
  43 + hue_bridge_state["lights"]["1"]["luminaireuniqueid"] = "0000000";
  44 + hue_bridge_state["lights"]["2"] = nlohmann::json::object();
  45 + hue_bridge_state["lights"]["2"]["state"] = nlohmann::json::object();
  46 + hue_bridge_state["lights"]["2"]["state"]["on"] = false;
  47 + hue_bridge_state["lights"]["2"]["state"]["bri"] = 254;
  48 + hue_bridge_state["lights"]["2"]["state"]["ct"] = 366;
  49 + hue_bridge_state["lights"]["2"]["state"]["hue"] = 123456;
  50 + hue_bridge_state["lights"]["2"]["state"]["sat"] = 123;
  51 + hue_bridge_state["lights"]["2"]["state"]["xy"][0] = 0.102;
  52 + hue_bridge_state["lights"]["2"]["state"]["xy"][1] = 0.102;
  53 + hue_bridge_state["lights"]["2"]["state"]["alert"] = "none";
  54 + hue_bridge_state["lights"]["2"]["state"]["colormode"] = "ct";
  55 + hue_bridge_state["lights"]["2"]["state"]["reachable"] = true;
  56 + hue_bridge_state["lights"]["2"]["swupdate"] = nlohmann::json::object();
  57 + hue_bridge_state["lights"]["2"]["swupdate"]["state"] = "noupdates";
  58 + hue_bridge_state["lights"]["2"]["swupdate"]["lastinstall"] = nullptr;
  59 + hue_bridge_state["lights"]["2"]["type"] = "Color light";
  60 + hue_bridge_state["lights"]["2"]["name"] = "Hue lamp 2";
  61 + hue_bridge_state["lights"]["2"]["modelid"] = "LST001";
  62 + hue_bridge_state["lights"]["2"]["uniqueid"] = "11:11:11:11:11:11:11:11-11";
  63 + hue_bridge_state["lights"]["2"]["swversion"] = "5.50.1.19085";
  64 + hue_bridge_state["lights"]["3"] = nlohmann::json::object();
  65 + hue_bridge_state["lights"]["3"]["state"] = nlohmann::json::object();
  66 + hue_bridge_state["lights"]["3"]["state"]["on"] = false;
  67 + hue_bridge_state["lights"]["3"]["state"]["bri"] = 254;
  68 + hue_bridge_state["lights"]["3"]["state"]["ct"] = 366;
  69 + hue_bridge_state["lights"]["3"]["state"]["hue"] = 123456;
  70 + hue_bridge_state["lights"]["3"]["state"]["sat"] = 123;
  71 + hue_bridge_state["lights"]["3"]["state"]["xy"][0] = 0.102;
  72 + hue_bridge_state["lights"]["3"]["state"]["xy"][1] = 0.102;
  73 + hue_bridge_state["lights"]["3"]["state"]["alert"] = "none";
  74 + hue_bridge_state["lights"]["3"]["state"]["colormode"] = "ct";
  75 + hue_bridge_state["lights"]["3"]["state"]["reachable"] = true;
  76 + hue_bridge_state["lights"]["3"]["swupdate"] = nlohmann::json::object();
  77 + hue_bridge_state["lights"]["3"]["swupdate"]["state"] = "noupdates";
  78 + hue_bridge_state["lights"]["3"]["swupdate"]["lastinstall"] = nullptr;
  79 + hue_bridge_state["lights"]["3"]["type"] = "Color extended light";
  80 + hue_bridge_state["lights"]["3"]["name"] = "Hue lamp 3";
  81 + hue_bridge_state["lights"]["3"]["modelid"] = "LCT010";
  82 + hue_bridge_state["lights"]["3"]["manufacturername"] = "Philips";
  83 + hue_bridge_state["lights"]["3"]["productname"] = "Hue bloom";
  84 + hue_bridge_state["lights"]["3"]["swversion"] = "5.50.1.19085";
  85 +
  86 + EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), 80))
  87 + .Times(AtLeast(1))
  88 + .WillRepeatedly(Return(hue_bridge_state));
  89 + EXPECT_CALL(
  90 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  91 + .Times(AtLeast(1))
  92 + .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
  93 + EXPECT_CALL(
  94 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/2", nlohmann::json::object(), getBridgeIp(), 80))
  95 + .Times(AtLeast(1))
  96 + .WillRepeatedly(Return(hue_bridge_state["lights"]["2"]));
  97 + EXPECT_CALL(
  98 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/3", nlohmann::json::object(), getBridgeIp(), 80))
  99 + .Times(AtLeast(1))
  100 + .WillRepeatedly(Return(hue_bridge_state["lights"]["3"]));
  101 + }
  102 + ~HueLightTest(){};
112 103 };
113 104  
114   -TEST_F(HueLightTest, Constructor) {
115   - const HueLight ctest_light_1 = test_bridge.getLight(1);
116   - HueLight test_light_1 = test_bridge.getLight(1);
117   - const HueLight ctest_light_2 = test_bridge.getLight(2);
118   - HueLight test_light_2 = test_bridge.getLight(2);
119   - const HueLight ctest_light_3 = test_bridge.getLight(3);
120   - HueLight test_light_3 = test_bridge.getLight(3);
121   -}
122   -
123   -TEST_F(HueLightTest, On) {
124   - using namespace ::testing;
125   - EXPECT_CALL(*handler,
126   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
127   - getBridgeIp(), 80))
128   - .Times(1)
129   - .WillOnce(Return(Json::Value(Json::arrayValue)));
130   -
131   - Json::Value prep_ret;
132   - prep_ret = Json::Value(Json::arrayValue);
133   - prep_ret[0] = Json::Value(Json::objectValue);
134   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
135   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 255;
136   - prep_ret[1] = Json::Value(Json::objectValue);
137   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
138   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
139   - EXPECT_CALL(*handler,
140   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
141   - getBridgeIp(), 80))
142   - .Times(1)
143   - .WillOnce(Return(prep_ret));
144   -
145   - HueLight test_light_1 = test_bridge.getLight(1);
146   - HueLight test_light_2 = test_bridge.getLight(2);
147   - HueLight test_light_3 = test_bridge.getLight(3);
148   -
149   - EXPECT_EQ(true, test_light_1.On(33));
150   - EXPECT_EQ(false, test_light_2.On());
151   - EXPECT_EQ(true, test_light_3.On(255));
152   -}
153   -
154   -TEST_F(HueLightTest, Off) {
155   - using namespace ::testing;
156   - Json::Value prep_ret;
157   - prep_ret = Json::Value(Json::arrayValue);
158   - prep_ret[0] = Json::Value(Json::objectValue);
159   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
160   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 33;
161   - prep_ret[1] = Json::Value(Json::objectValue);
162   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
163   - prep_ret[1]["success"]["/lights/1/state/on"] = false;
164   - EXPECT_CALL(*handler,
165   - PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _,
166   - getBridgeIp(), 80))
167   - .Times(1)
168   - .WillOnce(Return(prep_ret));
169   -
170   - HueLight test_light_1 = test_bridge.getLight(1);
171   - HueLight test_light_2 = test_bridge.getLight(2);
172   - HueLight test_light_3 = test_bridge.getLight(3);
173   -
174   - EXPECT_EQ(true, test_light_1.Off(33));
175   - EXPECT_EQ(true, test_light_2.Off());
176   - EXPECT_EQ(true, test_light_3.Off(255));
177   -}
178   -
179   -TEST_F(HueLightTest, isOn) {
180   - const HueLight ctest_light_1 = test_bridge.getLight(1);
181   - const HueLight ctest_light_2 = test_bridge.getLight(2);
182   - const HueLight ctest_light_3 = test_bridge.getLight(3);
183   - HueLight test_light_1 = test_bridge.getLight(1);
184   - HueLight test_light_2 = test_bridge.getLight(2);
185   - HueLight test_light_3 = test_bridge.getLight(3);
186   -
187   - EXPECT_EQ(true, ctest_light_1.isOn());
188   - EXPECT_EQ(false, ctest_light_2.isOn());
189   - EXPECT_EQ(false, ctest_light_3.isOn());
190   - EXPECT_EQ(true, test_light_1.isOn());
191   - EXPECT_EQ(false, test_light_2.isOn());
192   - EXPECT_EQ(false, test_light_3.isOn());
193   -}
194   -
195   -TEST_F(HueLightTest, getId) {
196   - const HueLight ctest_light_1 = test_bridge.getLight(1);
197   - const HueLight ctest_light_2 = test_bridge.getLight(2);
198   - const HueLight ctest_light_3 = test_bridge.getLight(3);
199   - HueLight test_light_1 = test_bridge.getLight(1);
200   - HueLight test_light_2 = test_bridge.getLight(2);
201   - HueLight test_light_3 = test_bridge.getLight(3);
202   -
203   - EXPECT_EQ(1, ctest_light_1.getId());
204   - EXPECT_EQ(2, ctest_light_2.getId());
205   - EXPECT_EQ(3, ctest_light_3.getId());
206   - EXPECT_EQ(1, test_light_1.getId());
207   - EXPECT_EQ(2, test_light_2.getId());
208   - EXPECT_EQ(3, test_light_3.getId());
209   -}
210   -
211   -TEST_F(HueLightTest, getType) {
212   - const HueLight ctest_light_1 = test_bridge.getLight(1);
213   - const HueLight ctest_light_2 = test_bridge.getLight(2);
214   - const HueLight ctest_light_3 = test_bridge.getLight(3);
215   - HueLight test_light_1 = test_bridge.getLight(1);
216   - HueLight test_light_2 = test_bridge.getLight(2);
217   - HueLight test_light_3 = test_bridge.getLight(3);
218   -
219   - EXPECT_EQ("Dimmable light", ctest_light_1.getType());
220   - EXPECT_EQ("Color light", ctest_light_2.getType());
221   - EXPECT_EQ("Color extended light", ctest_light_3.getType());
222   - EXPECT_EQ("Dimmable light", test_light_1.getType());
223   - EXPECT_EQ("Color light", test_light_2.getType());
224   - EXPECT_EQ("Color extended light", test_light_3.getType());
225   -}
226   -
227   -TEST_F(HueLightTest, getName) {
228   - const HueLight ctest_light_1 = test_bridge.getLight(1);
229   - const HueLight ctest_light_2 = test_bridge.getLight(2);
230   - const HueLight ctest_light_3 = test_bridge.getLight(3);
231   - HueLight test_light_1 = test_bridge.getLight(1);
232   - HueLight test_light_2 = test_bridge.getLight(2);
233   - HueLight test_light_3 = test_bridge.getLight(3);
234   -
235   - EXPECT_EQ("Hue lamp 1", ctest_light_1.getName());
236   - EXPECT_EQ("Hue lamp 2", ctest_light_2.getName());
237   - EXPECT_EQ("Hue lamp 3", ctest_light_3.getName());
238   - EXPECT_EQ("Hue lamp 1", test_light_1.getName());
239   - EXPECT_EQ("Hue lamp 2", test_light_2.getName());
240   - EXPECT_EQ("Hue lamp 3", test_light_3.getName());
241   -}
242   -
243   -TEST_F(HueLightTest, getModelId) {
244   - const HueLight ctest_light_1 = test_bridge.getLight(1);
245   - const HueLight ctest_light_2 = test_bridge.getLight(2);
246   - const HueLight ctest_light_3 = test_bridge.getLight(3);
247   - HueLight test_light_1 = test_bridge.getLight(1);
248   - HueLight test_light_2 = test_bridge.getLight(2);
249   - HueLight test_light_3 = test_bridge.getLight(3);
250   -
251   - EXPECT_EQ("LWB004", ctest_light_1.getModelId());
252   - EXPECT_EQ("LST001", ctest_light_2.getModelId());
253   - EXPECT_EQ("LCT010", ctest_light_3.getModelId());
254   - EXPECT_EQ("LWB004", test_light_1.getModelId());
255   - EXPECT_EQ("LST001", test_light_2.getModelId());
256   - EXPECT_EQ("LCT010", test_light_3.getModelId());
257   -}
258   -
259   -TEST_F(HueLightTest, getUId) {
260   - const HueLight ctest_light_1 = test_bridge.getLight(1);
261   - const HueLight ctest_light_2 = test_bridge.getLight(2);
262   - const HueLight ctest_light_3 = test_bridge.getLight(3);
263   - HueLight test_light_1 = test_bridge.getLight(1);
264   - HueLight test_light_2 = test_bridge.getLight(2);
265   - HueLight test_light_3 = test_bridge.getLight(3);
266   -
267   - EXPECT_EQ("00:00:00:00:00:00:00:00-00", ctest_light_1.getUId());
268   - EXPECT_EQ("11:11:11:11:11:11:11:11-11", ctest_light_2.getUId());
269   - EXPECT_EQ("", ctest_light_3.getUId());
270   - EXPECT_EQ("00:00:00:00:00:00:00:00-00", test_light_1.getUId());
271   - EXPECT_EQ("11:11:11:11:11:11:11:11-11", test_light_2.getUId());
272   - EXPECT_EQ("", test_light_3.getUId());
273   -}
274   -
275   -TEST_F(HueLightTest, getManufacturername) {
276   - const HueLight ctest_light_1 = test_bridge.getLight(1);
277   - const HueLight ctest_light_2 = test_bridge.getLight(2);
278   - const HueLight ctest_light_3 = test_bridge.getLight(3);
279   - HueLight test_light_1 = test_bridge.getLight(1);
280   - HueLight test_light_2 = test_bridge.getLight(2);
281   - HueLight test_light_3 = test_bridge.getLight(3);
282   -
283   - EXPECT_EQ("Philips", ctest_light_1.getManufacturername());
284   - EXPECT_EQ("", ctest_light_2.getManufacturername());
285   - EXPECT_EQ("Philips", ctest_light_3.getManufacturername());
286   - EXPECT_EQ("Philips", test_light_1.getManufacturername());
287   - EXPECT_EQ("", test_light_2.getManufacturername());
288   - EXPECT_EQ("Philips", test_light_3.getManufacturername());
289   -}
290   -
291   -TEST_F(HueLightTest, getProductname) {
292   - const HueLight ctest_light_1 = test_bridge.getLight(1);
293   - const HueLight ctest_light_2 = test_bridge.getLight(2);
294   - const HueLight ctest_light_3 = test_bridge.getLight(3);
295   - HueLight test_light_1 = test_bridge.getLight(1);
296   - HueLight test_light_2 = test_bridge.getLight(2);
297   - HueLight test_light_3 = test_bridge.getLight(3);
298   -
299   - EXPECT_EQ("Hue bloom", ctest_light_1.getProductname());
300   - EXPECT_EQ("", ctest_light_2.getProductname());
301   - EXPECT_EQ("Hue bloom", ctest_light_3.getProductname());
302   - EXPECT_EQ("Hue bloom", test_light_1.getProductname());
303   - EXPECT_EQ("", test_light_2.getProductname());
304   - EXPECT_EQ("Hue bloom", test_light_3.getProductname());
305   -}
306   -
307   -TEST_F(HueLightTest, getLuminaireUId) {
308   - const HueLight ctest_light_1 = test_bridge.getLight(1);
309   - const HueLight ctest_light_2 = test_bridge.getLight(2);
310   - const HueLight ctest_light_3 = test_bridge.getLight(3);
311   - HueLight test_light_1 = test_bridge.getLight(1);
312   - HueLight test_light_2 = test_bridge.getLight(2);
313   - HueLight test_light_3 = test_bridge.getLight(3);
314   -
315   - EXPECT_EQ("0000000", ctest_light_1.getLuminaireUId());
316   - EXPECT_EQ("", ctest_light_2.getLuminaireUId());
317   - EXPECT_EQ("", ctest_light_3.getLuminaireUId());
318   - EXPECT_EQ("0000000", test_light_1.getLuminaireUId());
319   - EXPECT_EQ("", test_light_2.getLuminaireUId());
320   - EXPECT_EQ("", test_light_3.getLuminaireUId());
321   -}
322   -
323   -TEST_F(HueLightTest, getSwVersion) {
324   - const HueLight ctest_light_1 = test_bridge.getLight(1);
325   - const HueLight ctest_light_2 = test_bridge.getLight(2);
326   - const HueLight ctest_light_3 = test_bridge.getLight(3);
327   - HueLight test_light_1 = test_bridge.getLight(1);
328   - HueLight test_light_2 = test_bridge.getLight(2);
329   - HueLight test_light_3 = test_bridge.getLight(3);
330   -
331   - EXPECT_EQ("5.50.1.19085", ctest_light_1.getSwVersion());
332   - EXPECT_EQ("5.50.1.19085", ctest_light_2.getSwVersion());
333   - EXPECT_EQ("5.50.1.19085", ctest_light_3.getSwVersion());
334   - EXPECT_EQ("5.50.1.19085", test_light_1.getSwVersion());
335   - EXPECT_EQ("5.50.1.19085", test_light_2.getSwVersion());
336   - EXPECT_EQ("5.50.1.19085", test_light_3.getSwVersion());
337   -}
338   -
339   -TEST_F(HueLightTest, setName) {
340   - using namespace ::testing;
341   - Json::Value expected_request(Json::objectValue);
342   - expected_request["name"] = "Baskj189";
343   - Json::Value prep_ret;
344   - prep_ret = Json::Value(Json::arrayValue);
345   - prep_ret[0] = Json::Value(Json::objectValue);
346   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
347   - prep_ret[0]["success"]["/lights/1/name"] =
348   - expected_request["name"].asString();
349   - EXPECT_CALL(*handler,
350   - PUTJson("/api/" + getBridgeUsername() + "/lights/1/name",
351   - expected_request, getBridgeIp(), 80))
352   - .Times(1)
353   - .WillOnce(Return(prep_ret));
354   - EXPECT_CALL(*handler,
355   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/name",
356   - expected_request, getBridgeIp(), 80))
357   - .Times(1)
358   - .WillOnce(Return(Json::Value(Json::arrayValue)));
359   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
360   - prep_ret[0]["success"]["/lights/3/name"] =
361   - expected_request["name"].asString();
362   - EXPECT_CALL(*handler,
363   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/name",
364   - expected_request, getBridgeIp(), 80))
365   - .Times(1)
366   - .WillOnce(Return(prep_ret));
367   -
368   - HueLight test_light_1 = test_bridge.getLight(1);
369   - HueLight test_light_2 = test_bridge.getLight(2);
370   - HueLight test_light_3 = test_bridge.getLight(3);
371   -
372   - EXPECT_EQ(true, test_light_1.setName(expected_request["name"].asString()));
373   - EXPECT_EQ(false, test_light_2.setName(expected_request["name"].asString()));
374   - EXPECT_EQ(true, test_light_3.setName(expected_request["name"].asString()));
375   -}
376   -
377   -TEST_F(HueLightTest, getColorType) {
378   - const HueLight ctest_light_1 = test_bridge.getLight(1);
379   - const HueLight ctest_light_2 = test_bridge.getLight(2);
380   - const HueLight ctest_light_3 = test_bridge.getLight(3);
381   - HueLight test_light_1 = test_bridge.getLight(1);
382   - HueLight test_light_2 = test_bridge.getLight(2);
383   - HueLight test_light_3 = test_bridge.getLight(3);
384   -
385   - EXPECT_EQ(ColorType::NONE, ctest_light_1.getColorType());
386   - EXPECT_EQ(ColorType::GAMUT_A, ctest_light_2.getColorType());
387   - EXPECT_EQ(ColorType::GAMUT_C, ctest_light_3.getColorType());
388   - EXPECT_EQ(ColorType::NONE, test_light_1.getColorType());
389   - EXPECT_EQ(ColorType::GAMUT_A, test_light_2.getColorType());
390   - EXPECT_EQ(ColorType::GAMUT_C, test_light_3.getColorType());
391   -}
392   -
393   -TEST_F(HueLightTest, KelvinToMired) {
394   - const HueLight ctest_light_1 = test_bridge.getLight(1);
395   - const HueLight ctest_light_2 = test_bridge.getLight(2);
396   - const HueLight ctest_light_3 = test_bridge.getLight(3);
397   - HueLight test_light_1 = test_bridge.getLight(1);
398   - HueLight test_light_2 = test_bridge.getLight(2);
399   - HueLight test_light_3 = test_bridge.getLight(3);
400   -
401   - EXPECT_EQ(10000, ctest_light_1.KelvinToMired(100));
402   - EXPECT_EQ(500, ctest_light_2.KelvinToMired(2000));
403   - EXPECT_EQ(303, ctest_light_3.KelvinToMired(3300));
404   - EXPECT_EQ(250, test_light_1.KelvinToMired(4000));
405   - EXPECT_EQ(200, test_light_2.KelvinToMired(5000));
406   - EXPECT_EQ(166, test_light_3.KelvinToMired(6000));
407   -}
408   -
409   -TEST_F(HueLightTest, MiredToKelvin) {
410   - const HueLight ctest_light_1 = test_bridge.getLight(1);
411   - const HueLight ctest_light_2 = test_bridge.getLight(2);
412   - const HueLight ctest_light_3 = test_bridge.getLight(3);
413   - HueLight test_light_1 = test_bridge.getLight(1);
414   - HueLight test_light_2 = test_bridge.getLight(2);
415   - HueLight test_light_3 = test_bridge.getLight(3);
416   -
417   - EXPECT_EQ(100, ctest_light_1.MiredToKelvin(10000));
418   - EXPECT_EQ(2000, ctest_light_2.MiredToKelvin(500));
419   - EXPECT_EQ(3300, ctest_light_3.MiredToKelvin(303));
420   - EXPECT_EQ(4000, test_light_1.MiredToKelvin(250));
421   - EXPECT_EQ(5000, test_light_2.MiredToKelvin(200));
422   - EXPECT_EQ(6024, test_light_3.MiredToKelvin(
423   - 166)); // 6000 kelvin should be 166 mired, but keep in
424   - // mind flops are not exact
425   -}
426   -
427   -TEST_F(HueLightTest, hasBrightnessControl) {
428   - const HueLight ctest_light_1 = test_bridge.getLight(1);
429   - const HueLight ctest_light_2 = test_bridge.getLight(2);
430   - const HueLight ctest_light_3 = test_bridge.getLight(3);
431   - HueLight test_light_1 = test_bridge.getLight(1);
432   - HueLight test_light_2 = test_bridge.getLight(2);
433   - HueLight test_light_3 = test_bridge.getLight(3);
434   -
435   - EXPECT_EQ(true, ctest_light_1.hasBrightnessControl());
436   - EXPECT_EQ(true, ctest_light_2.hasBrightnessControl());
437   - EXPECT_EQ(true, ctest_light_3.hasBrightnessControl());
438   - EXPECT_EQ(true, test_light_1.hasBrightnessControl());
439   - EXPECT_EQ(true, test_light_2.hasBrightnessControl());
440   - EXPECT_EQ(true, test_light_3.hasBrightnessControl());
441   -}
442   -
443   -TEST_F(HueLightTest, hasTemperatureControl) {
444   - const HueLight ctest_light_1 = test_bridge.getLight(1);
445   - const HueLight ctest_light_2 = test_bridge.getLight(2);
446   - const HueLight ctest_light_3 = test_bridge.getLight(3);
447   - HueLight test_light_1 = test_bridge.getLight(1);
448   - HueLight test_light_2 = test_bridge.getLight(2);
449   - HueLight test_light_3 = test_bridge.getLight(3);
450   -
451   - EXPECT_EQ(false, ctest_light_1.hasTemperatureControl());
452   - EXPECT_EQ(false, ctest_light_2.hasTemperatureControl());
453   - EXPECT_EQ(true, ctest_light_3.hasTemperatureControl());
454   - EXPECT_EQ(false, test_light_1.hasTemperatureControl());
455   - EXPECT_EQ(false, test_light_2.hasTemperatureControl());
456   - EXPECT_EQ(true, test_light_3.hasTemperatureControl());
457   -}
458   -
459   -TEST_F(HueLightTest, hasColorControl) {
460   - const HueLight ctest_light_1 = test_bridge.getLight(1);
461   - const HueLight ctest_light_2 = test_bridge.getLight(2);
462   - const HueLight ctest_light_3 = test_bridge.getLight(3);
463   - HueLight test_light_1 = test_bridge.getLight(1);
464   - HueLight test_light_2 = test_bridge.getLight(2);
465   - HueLight test_light_3 = test_bridge.getLight(3);
466   -
467   - EXPECT_EQ(false, ctest_light_1.hasColorControl());
468   - EXPECT_EQ(true, ctest_light_2.hasColorControl());
469   - EXPECT_EQ(true, ctest_light_3.hasColorControl());
470   - EXPECT_EQ(false, test_light_1.hasColorControl());
471   - EXPECT_EQ(true, test_light_2.hasColorControl());
472   - EXPECT_EQ(true, test_light_3.hasColorControl());
473   -}
474   -
475   -TEST_F(HueLightTest, setBrightness) {
476   - using namespace ::testing;
477   - EXPECT_CALL(*handler,
478   - PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _,
479   - getBridgeIp(), 80))
480   - .Times(1)
481   - .WillOnce(Return(Json::Value(Json::arrayValue)));
482   - Json::Value prep_ret;
483   - prep_ret = Json::Value(Json::arrayValue);
484   - prep_ret[0] = Json::Value(Json::objectValue);
485   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
486   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
487   - prep_ret[1] = Json::Value(Json::objectValue);
488   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
489   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
490   - prep_ret[2] = Json::Value(Json::objectValue);
491   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
492   - prep_ret[2]["success"]["/lights/3/state/bri"] = 254;
493   - EXPECT_CALL(*handler,
494   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
495   - getBridgeIp(), 80))
496   - .Times(1)
497   - .WillOnce(Return(prep_ret));
498   -
499   - HueLight test_light_1 = test_bridge.getLight(1);
500   - HueLight test_light_2 = test_bridge.getLight(2);
501   - HueLight test_light_3 = test_bridge.getLight(3);
502   -
503   - EXPECT_EQ(false, test_light_1.setBrightness(200));
504   - EXPECT_EQ(true, test_light_2.setBrightness(0, 2));
505   - EXPECT_EQ(true, test_light_3.setBrightness(255, 0));
506   -}
507   -
508   -TEST_F(HueLightTest, getBrightness) {
509   - const HueLight ctest_light_1 = test_bridge.getLight(1);
510   - const HueLight ctest_light_2 = test_bridge.getLight(2);
511   - const HueLight ctest_light_3 = test_bridge.getLight(3);
512   - HueLight test_light_1 = test_bridge.getLight(1);
513   - HueLight test_light_2 = test_bridge.getLight(2);
514   - HueLight test_light_3 = test_bridge.getLight(3);
515   -
516   - EXPECT_EQ(254, ctest_light_1.getBrightness());
517   - EXPECT_EQ(254, ctest_light_2.getBrightness());
518   - EXPECT_EQ(254, ctest_light_3.getBrightness());
519   - EXPECT_EQ(254, test_light_1.getBrightness());
520   - EXPECT_EQ(254, test_light_2.getBrightness());
521   - EXPECT_EQ(254, test_light_3.getBrightness());
522   -}
523   -
524   -TEST_F(HueLightTest, setColorTemperature) {
525   - using namespace ::testing;
526   - Json::Value prep_ret;
527   - prep_ret = Json::Value(Json::arrayValue);
528   - prep_ret[2] = Json::Value(Json::objectValue);
529   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
530   - prep_ret[2]["success"]["/lights/3/state/ct"] = 153;
531   - prep_ret[1] = Json::Value(Json::objectValue);
532   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
533   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
534   - prep_ret[0] = Json::Value(Json::objectValue);
535   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
536   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
537   - EXPECT_CALL(*handler,
538   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
539   - getBridgeIp(), 80))
540   - .Times(1)
541   - .WillOnce(Return(prep_ret));
542   -
543   - HueLight test_light_1 = test_bridge.getLight(1);
544   - HueLight test_light_2 = test_bridge.getLight(2);
545   - HueLight test_light_3 = test_bridge.getLight(3);
546   -
547   - EXPECT_EQ(false, test_light_1.setColorTemperature(153));
548   - EXPECT_EQ(false, test_light_2.setColorTemperature(400, 2));
549   - EXPECT_EQ(true, test_light_3.setColorTemperature(100, 0));
550   -}
551   -
552   -TEST_F(HueLightTest, getColorTemperature) {
553   - const HueLight ctest_light_1 = test_bridge.getLight(1);
554   - const HueLight ctest_light_2 = test_bridge.getLight(2);
555   - const HueLight ctest_light_3 = test_bridge.getLight(3);
556   - HueLight test_light_1 = test_bridge.getLight(1);
557   - HueLight test_light_2 = test_bridge.getLight(2);
558   - HueLight test_light_3 = test_bridge.getLight(3);
559   -
560   - EXPECT_EQ(0, ctest_light_1.getColorTemperature());
561   - EXPECT_EQ(0, ctest_light_2.getColorTemperature());
562   - EXPECT_EQ(366, ctest_light_3.getColorTemperature());
563   - EXPECT_EQ(0, test_light_1.getColorTemperature());
564   - EXPECT_EQ(0, test_light_2.getColorTemperature());
565   - EXPECT_EQ(366, test_light_3.getColorTemperature());
566   -}
567   -
568   -TEST_F(HueLightTest, setColorHue) {
569   - using namespace ::testing;
570   - EXPECT_CALL(*handler,
571   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
572   - getBridgeIp(), 80))
573   - .Times(1)
574   - .WillOnce(Return(Json::Value(Json::arrayValue)));
575   - Json::Value prep_ret;
576   - prep_ret = Json::Value(Json::arrayValue);
577   - prep_ret[2] = Json::Value(Json::objectValue);
578   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
579   - prep_ret[2]["success"]["/lights/3/state/hue"] = 65500;
580   - prep_ret[1] = Json::Value(Json::objectValue);
581   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
582   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
583   - prep_ret[0] = Json::Value(Json::objectValue);
584   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
585   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
586   - EXPECT_CALL(*handler,
587   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
588   - getBridgeIp(), 80))
589   - .Times(1)
590   - .WillOnce(Return(prep_ret));
591   -
592   - HueLight test_light_1 = test_bridge.getLight(1);
593   - HueLight test_light_2 = test_bridge.getLight(2);
594   - HueLight test_light_3 = test_bridge.getLight(3);
595   -
596   - EXPECT_EQ(false, test_light_1.setColorHue(153));
597   - EXPECT_EQ(false, test_light_2.setColorHue(30000, 2));
598   - EXPECT_EQ(true, test_light_3.setColorHue(65500, 0));
599   -}
600   -
601   -TEST_F(HueLightTest, setColorSaturation) {
602   - using namespace ::testing;
603   - EXPECT_CALL(*handler,
604   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
605   - getBridgeIp(), 80))
606   - .Times(1)
607   - .WillOnce(Return(Json::Value(Json::arrayValue)));
608   - Json::Value prep_ret;
609   - prep_ret = Json::Value(Json::arrayValue);
610   - prep_ret[2] = Json::Value(Json::objectValue);
611   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
612   - prep_ret[2]["success"]["/lights/3/state/sat"] = 250;
613   - prep_ret[1] = Json::Value(Json::objectValue);
614   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
615   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
616   - prep_ret[0] = Json::Value(Json::objectValue);
617   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
618   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
619   - EXPECT_CALL(*handler,
620   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
621   - getBridgeIp(), 80))
622   - .Times(1)
623   - .WillOnce(Return(prep_ret));
624   -
625   - HueLight test_light_1 = test_bridge.getLight(1);
626   - HueLight test_light_2 = test_bridge.getLight(2);
627   - HueLight test_light_3 = test_bridge.getLight(3);
628   -
629   - EXPECT_EQ(false, test_light_1.setColorSaturation(0));
630   - EXPECT_EQ(false, test_light_2.setColorSaturation(140, 2));
631   - EXPECT_EQ(true, test_light_3.setColorSaturation(250, 0));
632   -}
633   -
634   -TEST_F(HueLightTest, setColorHueSaturation) {
635   - using namespace ::testing;
636   - EXPECT_CALL(*handler,
637   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
638   - getBridgeIp(), 80))
639   - .Times(1)
640   - .WillOnce(Return(Json::Value(Json::arrayValue)));
641   - Json::Value prep_ret;
642   - prep_ret = Json::Value(Json::arrayValue);
643   - prep_ret[3] = Json::Value(Json::objectValue);
644   - prep_ret[3]["success"] = Json::Value(Json::objectValue);
645   - prep_ret[3]["success"]["/lights/3/state/sat"] = 250;
646   - prep_ret[2] = Json::Value(Json::objectValue);
647   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
648   - prep_ret[2]["success"]["/lights/3/state/hue"] = 65500;
649   - prep_ret[1] = Json::Value(Json::objectValue);
650   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
651   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
652   - prep_ret[0] = Json::Value(Json::objectValue);
653   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
654   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
655   - EXPECT_CALL(*handler,
656   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
657   - getBridgeIp(), 80))
658   - .Times(1)
659   - .WillOnce(Return(prep_ret));
660   -
661   - HueLight test_light_1 = test_bridge.getLight(1);
662   - HueLight test_light_2 = test_bridge.getLight(2);
663   - HueLight test_light_3 = test_bridge.getLight(3);
664   -
665   - EXPECT_EQ(false, test_light_1.setColorHueSaturation(153, 0));
666   - EXPECT_EQ(false, test_light_2.setColorHueSaturation(30000, 140, 2));
667   - EXPECT_EQ(true, test_light_3.setColorHueSaturation(65500, 250, 0));
668   -}
669   -
670   -TEST_F(HueLightTest, getColorHueSaturation) {
671   - const HueLight ctest_light_1 = test_bridge.getLight(1);
672   - const HueLight ctest_light_2 = test_bridge.getLight(2);
673   - const HueLight ctest_light_3 = test_bridge.getLight(3);
674   - HueLight test_light_1 = test_bridge.getLight(1);
675   - HueLight test_light_2 = test_bridge.getLight(2);
676   - HueLight test_light_3 = test_bridge.getLight(3);
677   -
678   - EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)),
679   - ctest_light_1.getColorHueSaturation());
680   - EXPECT_EQ(
681   - std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),
682   - ctest_light_2.getColorHueSaturation());
683   - EXPECT_EQ(
684   - std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),
685   - ctest_light_3.getColorHueSaturation());
686   - EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)),
687   - test_light_1.getColorHueSaturation());
688   - EXPECT_EQ(
689   - std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),
690   - test_light_2.getColorHueSaturation());
691   - EXPECT_EQ(
692   - std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),
693   - test_light_3.getColorHueSaturation());
694   -}
695   -
696   -TEST_F(HueLightTest, setColorXY) {
697   - using namespace ::testing;
698   - EXPECT_CALL(*handler,
699   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
700   - getBridgeIp(), 80))
701   - .Times(1)
702   - .WillOnce(Return(Json::Value(Json::arrayValue)));
703   - Json::Value prep_ret;
704   - prep_ret = Json::Value(Json::arrayValue);
705   - prep_ret[2] = Json::Value(Json::objectValue);
706   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
707   - prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.4232;
708   - prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1231;
709   - prep_ret[1] = Json::Value(Json::objectValue);
710   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
711   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
712   - prep_ret[0] = Json::Value(Json::objectValue);
713   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
714   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
715   - EXPECT_CALL(*handler,
716   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
717   - getBridgeIp(), 80))
718   - .Times(1)
719   - .WillOnce(Return(prep_ret));
720   -
721   - HueLight test_light_1 = test_bridge.getLight(1);
722   - HueLight test_light_2 = test_bridge.getLight(2);
723   - HueLight test_light_3 = test_bridge.getLight(3);
724   -
725   - EXPECT_EQ(false, test_light_1.setColorXY(0.01, 0));
726   - EXPECT_EQ(false, test_light_2.setColorXY(0.123, 1, 2));
727   - EXPECT_EQ(true, test_light_3.setColorXY(0.4232, 0.1231, 0));
728   -}
729   -
730   -TEST_F(HueLightTest, getColorXY) {
731   - const HueLight ctest_light_1 = test_bridge.getLight(1);
732   - const HueLight ctest_light_2 = test_bridge.getLight(2);
733   - const HueLight ctest_light_3 = test_bridge.getLight(3);
734   - HueLight test_light_1 = test_bridge.getLight(1);
735   - HueLight test_light_2 = test_bridge.getLight(2);
736   - HueLight test_light_3 = test_bridge.getLight(3);
737   -
738   - EXPECT_EQ(std::make_pair(static_cast<float>(0), static_cast<float>(0)),
739   - ctest_light_1.getColorXY());
740   - EXPECT_EQ(
741   - std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)),
742   - ctest_light_2.getColorXY());
743   - EXPECT_EQ(
744   - std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)),
745   - ctest_light_3.getColorXY());
746   - EXPECT_EQ(std::make_pair(static_cast<float>(0), static_cast<float>(0)),
747   - test_light_1.getColorXY());
748   - EXPECT_EQ(
749   - std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)),
750   - test_light_2.getColorXY());
751   - EXPECT_EQ(
752   - std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)),
753   - test_light_3.getColorXY());
754   -}
755   -
756   -TEST_F(HueLightTest, setColorRGB) {
757   - using namespace ::testing;
758   - EXPECT_CALL(*handler,
759   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
760   - getBridgeIp(), 80))
761   - .Times(1)
762   - .WillOnce(Return(Json::Value(Json::arrayValue)));
763   - Json::Value prep_ret;
764   - prep_ret = Json::Value(Json::arrayValue);
765   - prep_ret[2] = Json::Value(Json::objectValue);
766   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
767   - prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.1596;
768   - prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1437;
769   - prep_ret[1] = Json::Value(Json::objectValue);
770   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
771   - prep_ret[1]["success"]["/lights/3/state/on"] = true;
772   - prep_ret[0] = Json::Value(Json::objectValue);
773   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
774   - prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
775   - EXPECT_CALL(*handler,
776   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
777   - getBridgeIp(), 80))
778   - .Times(1)
779   - .WillOnce(Return(prep_ret));
780   -
781   - HueLight test_light_1 = test_bridge.getLight(1);
782   - HueLight test_light_2 = test_bridge.getLight(2);
783   - HueLight test_light_3 = test_bridge.getLight(3);
784   -
785   - EXPECT_EQ(false, test_light_1.setColorRGB(0, 0, 0, 0));
786   - EXPECT_EQ(false, test_light_2.setColorRGB(32, 64, 128, 2));
787   - EXPECT_EQ(true, test_light_3.setColorRGB(64, 128, 255, 0));
788   -}
789   -
790   -TEST_F(HueLightTest, alert) {
791   - using namespace ::testing;
792   - EXPECT_CALL(*handler,
793   - PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _,
794   - getBridgeIp(), 80))
795   - .Times(1)
796   - .WillOnce(Return(Json::Value(Json::arrayValue)));
797   - EXPECT_CALL(*handler,
798   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
799   - getBridgeIp(), 80))
800   - .Times(1)
801   - .WillOnce(Return(Json::Value(Json::arrayValue)));
802   - Json::Value prep_ret;
803   - prep_ret = Json::Value(Json::arrayValue);
804   - prep_ret[0] = Json::Value(Json::objectValue);
805   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
806   - prep_ret[0]["success"]["/lights/3/state/alert"] = "select";
807   - EXPECT_CALL(*handler,
808   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
809   - getBridgeIp(), 80))
810   - .Times(1)
811   - .WillOnce(Return(prep_ret));
812   -
813   - HueLight test_light_1 = test_bridge.getLight(1);
814   - HueLight test_light_2 = test_bridge.getLight(2);
815   - HueLight test_light_3 = test_bridge.getLight(3);
816   -
817   - EXPECT_EQ(false, test_light_1.alert());
818   - EXPECT_EQ(false, test_light_2.alert());
819   - EXPECT_EQ(true, test_light_3.alert());
820   -}
821   -
822   -TEST_F(HueLightTest, alertTemperature) {
823   - using namespace ::testing;
824   - EXPECT_CALL(*handler,
825   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
826   - getBridgeIp(), 80))
827   - .Times(1)
828   - .WillOnce(Return(Json::Value(Json::arrayValue)));
829   -
830   - HueLight test_light_1 = test_bridge.getLight(1);
831   - HueLight test_light_2 = test_bridge.getLight(2);
832   - HueLight test_light_3 = test_bridge.getLight(3);
833   -
834   - EXPECT_EQ(false, test_light_1.alertTemperature(400));
835   - EXPECT_EQ(false, test_light_2.alertTemperature(100));
836   - EXPECT_EQ(false, test_light_3.alertTemperature(0));
837   -}
838   -
839   -TEST_F(HueLightTest, alertHueSaturation) {
840   - using namespace ::testing;
841   - EXPECT_CALL(*handler,
842   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
843   - getBridgeIp(), 80))
844   - .Times(1)
845   - .WillOnce(Return(Json::Value(Json::arrayValue)));
846   -
847   - HueLight test_light_1 = test_bridge.getLight(1);
848   - HueLight test_light_2 = test_bridge.getLight(2);
849   - HueLight test_light_3 = test_bridge.getLight(3);
850   -
851   - EXPECT_EQ(false, test_light_1.alertHueSaturation(0, 255));
852   - EXPECT_EQ(false, test_light_2.alertHueSaturation(3000, 100));
853   - EXPECT_EQ(false, test_light_3.alertHueSaturation(50000, 0));
854   -}
855   -
856   -TEST_F(HueLightTest, alertXY) {
857   - using namespace ::testing;
858   - EXPECT_CALL(*handler,
859   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
860   - getBridgeIp(), 80))
861   - .Times(1)
862   - .WillOnce(Return(Json::Value(Json::arrayValue)));
863   -
864   - HueLight test_light_1 = test_bridge.getLight(1);
865   - HueLight test_light_2 = test_bridge.getLight(2);
866   - HueLight test_light_3 = test_bridge.getLight(3);
867   -
868   - EXPECT_EQ(false, test_light_1.alertXY(0.1, 0.1));
869   - EXPECT_EQ(false, test_light_2.alertXY(0.2434, 0.2344));
870   - EXPECT_EQ(false, test_light_3.alertXY(0.1234, 0.1234));
871   -}
872   -
873   -TEST_F(HueLightTest, alertRGB) {
874   - using namespace ::testing;
875   - EXPECT_CALL(*handler,
876   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
877   - getBridgeIp(), 80))
878   - .Times(1)
879   - .WillOnce(Return(Json::Value(Json::arrayValue)));
880   -
881   - HueLight test_light_1 = test_bridge.getLight(1);
882   - HueLight test_light_2 = test_bridge.getLight(2);
883   - HueLight test_light_3 = test_bridge.getLight(3);
884   -
885   - EXPECT_EQ(false, test_light_1.alertRGB(0, 0, 0));
886   - EXPECT_EQ(false, test_light_2.alertRGB(32, 64, 128));
887   - EXPECT_EQ(false, test_light_3.alertRGB(64, 128, 255));
888   -}
889   -
890   -TEST_F(HueLightTest, setColorLoop) {
891   - using namespace ::testing;
892   - EXPECT_CALL(*handler,
893   - PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _,
894   - getBridgeIp(), 80))
895   - .Times(1)
896   - .WillOnce(Return(Json::Value(Json::arrayValue)));
897   - EXPECT_CALL(*handler,
898   - PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _,
899   - getBridgeIp(), 80))
900   - .Times(1)
901   - .WillOnce(Return(Json::Value(Json::arrayValue)));
902   -
903   - HueLight test_light_1 = test_bridge.getLight(1);
904   - HueLight test_light_2 = test_bridge.getLight(2);
905   - HueLight test_light_3 = test_bridge.getLight(3);
906   -
907   - EXPECT_EQ(false, test_light_1.setColorLoop(true));
908   - EXPECT_EQ(false, test_light_2.setColorLoop(false));
909   - EXPECT_EQ(false, test_light_3.setColorLoop(true));
910   -}
911   -
912   -TEST_F(HueLightTest, refreshState) {
913   - using namespace ::testing;
914   - test_bridge.getLight(1);
915   - test_bridge.getLight(2);
916   - test_bridge.getLight(3);
917   -
918   - EXPECT_CALL(*handler,
919   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
920   - Json::Value(Json::objectValue), getBridgeIp(), 80))
921   - .Times(2)
922   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
923   -
924   - const HueLight ctest_light_1 = test_bridge.getLight(1);
925   - HueLight test_light_1 = test_bridge.getLight(1);
  105 +TEST_F(HueLightTest, Constructor)
  106 +{
  107 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  108 + HueLight test_light_1 = test_bridge.getLight(1);
  109 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  110 + HueLight test_light_2 = test_bridge.getLight(2);
  111 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  112 + HueLight test_light_3 = test_bridge.getLight(3);
  113 +}
  114 +
  115 +TEST_F(HueLightTest, On)
  116 +{
  117 + using namespace ::testing;
  118 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  119 + .Times(1)
  120 + .WillOnce(Return(nlohmann::json::array()));
  121 +
  122 + nlohmann::json prep_ret;
  123 + prep_ret = nlohmann::json::array();
  124 + prep_ret[0] = nlohmann::json::object();
  125 + prep_ret[0]["success"] = nlohmann::json::object();
  126 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 255;
  127 + prep_ret[1] = nlohmann::json::object();
  128 + prep_ret[1]["success"] = nlohmann::json::object();
  129 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  130 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  131 + .Times(1)
  132 + .WillOnce(Return(prep_ret));
  133 +
  134 + HueLight test_light_1 = test_bridge.getLight(1);
  135 + HueLight test_light_2 = test_bridge.getLight(2);
  136 + HueLight test_light_3 = test_bridge.getLight(3);
  137 +
  138 + EXPECT_EQ(true, test_light_1.On(33));
  139 + EXPECT_EQ(false, test_light_2.On());
  140 + EXPECT_EQ(true, test_light_3.On(255));
  141 +}
  142 +
  143 +TEST_F(HueLightTest, Off)
  144 +{
  145 + using namespace ::testing;
  146 + nlohmann::json prep_ret;
  147 + prep_ret = nlohmann::json::array();
  148 + prep_ret[0] = nlohmann::json::object();
  149 + prep_ret[0]["success"] = nlohmann::json::object();
  150 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 33;
  151 + prep_ret[1] = nlohmann::json::object();
  152 + prep_ret[1]["success"] = nlohmann::json::object();
  153 + prep_ret[1]["success"]["/lights/1/state/on"] = false;
  154 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, getBridgeIp(), 80))
  155 + .Times(1)
  156 + .WillOnce(Return(prep_ret));
  157 +
  158 + HueLight test_light_1 = test_bridge.getLight(1);
  159 + HueLight test_light_2 = test_bridge.getLight(2);
  160 + HueLight test_light_3 = test_bridge.getLight(3);
  161 +
  162 + EXPECT_EQ(true, test_light_1.Off(33));
  163 + EXPECT_EQ(true, test_light_2.Off());
  164 + EXPECT_EQ(true, test_light_3.Off(255));
  165 +}
  166 +
  167 +TEST_F(HueLightTest, isOn)
  168 +{
  169 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  170 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  171 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  172 + HueLight test_light_1 = test_bridge.getLight(1);
  173 + HueLight test_light_2 = test_bridge.getLight(2);
  174 + HueLight test_light_3 = test_bridge.getLight(3);
  175 +
  176 + EXPECT_EQ(true, ctest_light_1.isOn());
  177 + EXPECT_EQ(false, ctest_light_2.isOn());
  178 + EXPECT_EQ(false, ctest_light_3.isOn());
  179 + EXPECT_EQ(true, test_light_1.isOn());
  180 + EXPECT_EQ(false, test_light_2.isOn());
  181 + EXPECT_EQ(false, test_light_3.isOn());
  182 +}
  183 +
  184 +TEST_F(HueLightTest, getId)
  185 +{
  186 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  187 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  188 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  189 + HueLight test_light_1 = test_bridge.getLight(1);
  190 + HueLight test_light_2 = test_bridge.getLight(2);
  191 + HueLight test_light_3 = test_bridge.getLight(3);
  192 +
  193 + EXPECT_EQ(1, ctest_light_1.getId());
  194 + EXPECT_EQ(2, ctest_light_2.getId());
  195 + EXPECT_EQ(3, ctest_light_3.getId());
  196 + EXPECT_EQ(1, test_light_1.getId());
  197 + EXPECT_EQ(2, test_light_2.getId());
  198 + EXPECT_EQ(3, test_light_3.getId());
  199 +}
  200 +
  201 +TEST_F(HueLightTest, getType)
  202 +{
  203 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  204 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  205 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  206 + HueLight test_light_1 = test_bridge.getLight(1);
  207 + HueLight test_light_2 = test_bridge.getLight(2);
  208 + HueLight test_light_3 = test_bridge.getLight(3);
  209 +
  210 + EXPECT_EQ("Dimmable light", ctest_light_1.getType());
  211 + EXPECT_EQ("Color light", ctest_light_2.getType());
  212 + EXPECT_EQ("Color extended light", ctest_light_3.getType());
  213 + EXPECT_EQ("Dimmable light", test_light_1.getType());
  214 + EXPECT_EQ("Color light", test_light_2.getType());
  215 + EXPECT_EQ("Color extended light", test_light_3.getType());
  216 +}
  217 +
  218 +TEST_F(HueLightTest, getName)
  219 +{
  220 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  221 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  222 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  223 + HueLight test_light_1 = test_bridge.getLight(1);
  224 + HueLight test_light_2 = test_bridge.getLight(2);
  225 + HueLight test_light_3 = test_bridge.getLight(3);
  226 +
  227 + EXPECT_EQ("Hue lamp 1", ctest_light_1.getName());
  228 + EXPECT_EQ("Hue lamp 2", ctest_light_2.getName());
  229 + EXPECT_EQ("Hue lamp 3", ctest_light_3.getName());
  230 + EXPECT_EQ("Hue lamp 1", test_light_1.getName());
  231 + EXPECT_EQ("Hue lamp 2", test_light_2.getName());
  232 + EXPECT_EQ("Hue lamp 3", test_light_3.getName());
  233 +}
  234 +
  235 +TEST_F(HueLightTest, getModelId)
  236 +{
  237 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  238 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  239 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  240 + HueLight test_light_1 = test_bridge.getLight(1);
  241 + HueLight test_light_2 = test_bridge.getLight(2);
  242 + HueLight test_light_3 = test_bridge.getLight(3);
  243 +
  244 + EXPECT_EQ("LWB004", ctest_light_1.getModelId());
  245 + EXPECT_EQ("LST001", ctest_light_2.getModelId());
  246 + EXPECT_EQ("LCT010", ctest_light_3.getModelId());
  247 + EXPECT_EQ("LWB004", test_light_1.getModelId());
  248 + EXPECT_EQ("LST001", test_light_2.getModelId());
  249 + EXPECT_EQ("LCT010", test_light_3.getModelId());
  250 +}
  251 +
  252 +TEST_F(HueLightTest, getUId)
  253 +{
  254 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  255 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  256 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  257 + HueLight test_light_1 = test_bridge.getLight(1);
  258 + HueLight test_light_2 = test_bridge.getLight(2);
  259 + HueLight test_light_3 = test_bridge.getLight(3);
  260 +
  261 + EXPECT_EQ("00:00:00:00:00:00:00:00-00", ctest_light_1.getUId());
  262 + EXPECT_EQ("11:11:11:11:11:11:11:11-11", ctest_light_2.getUId());
  263 + EXPECT_EQ("", ctest_light_3.getUId());
  264 + EXPECT_EQ("00:00:00:00:00:00:00:00-00", test_light_1.getUId());
  265 + EXPECT_EQ("11:11:11:11:11:11:11:11-11", test_light_2.getUId());
  266 + EXPECT_EQ("", test_light_3.getUId());
  267 +}
  268 +
  269 +TEST_F(HueLightTest, getManufacturername)
  270 +{
  271 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  272 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  273 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  274 + HueLight test_light_1 = test_bridge.getLight(1);
  275 + HueLight test_light_2 = test_bridge.getLight(2);
  276 + HueLight test_light_3 = test_bridge.getLight(3);
  277 +
  278 + EXPECT_EQ("Philips", ctest_light_1.getManufacturername());
  279 + EXPECT_EQ("", ctest_light_2.getManufacturername());
  280 + EXPECT_EQ("Philips", ctest_light_3.getManufacturername());
  281 + EXPECT_EQ("Philips", test_light_1.getManufacturername());
  282 + EXPECT_EQ("", test_light_2.getManufacturername());
  283 + EXPECT_EQ("Philips", test_light_3.getManufacturername());
  284 +}
  285 +
  286 +TEST_F(HueLightTest, getProductname)
  287 +{
  288 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  289 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  290 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  291 + HueLight test_light_1 = test_bridge.getLight(1);
  292 + HueLight test_light_2 = test_bridge.getLight(2);
  293 + HueLight test_light_3 = test_bridge.getLight(3);
  294 +
  295 + EXPECT_EQ("Hue bloom", ctest_light_1.getProductname());
  296 + EXPECT_EQ("", ctest_light_2.getProductname());
  297 + EXPECT_EQ("Hue bloom", ctest_light_3.getProductname());
  298 + EXPECT_EQ("Hue bloom", test_light_1.getProductname());
  299 + EXPECT_EQ("", test_light_2.getProductname());
  300 + EXPECT_EQ("Hue bloom", test_light_3.getProductname());
  301 +}
  302 +
  303 +TEST_F(HueLightTest, getLuminaireUId)
  304 +{
  305 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  306 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  307 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  308 + HueLight test_light_1 = test_bridge.getLight(1);
  309 + HueLight test_light_2 = test_bridge.getLight(2);
  310 + HueLight test_light_3 = test_bridge.getLight(3);
  311 +
  312 + EXPECT_EQ("0000000", ctest_light_1.getLuminaireUId());
  313 + EXPECT_EQ("", ctest_light_2.getLuminaireUId());
  314 + EXPECT_EQ("", ctest_light_3.getLuminaireUId());
  315 + EXPECT_EQ("0000000", test_light_1.getLuminaireUId());
  316 + EXPECT_EQ("", test_light_2.getLuminaireUId());
  317 + EXPECT_EQ("", test_light_3.getLuminaireUId());
  318 +}
  319 +
  320 +TEST_F(HueLightTest, getSwVersion)
  321 +{
  322 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  323 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  324 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  325 + HueLight test_light_1 = test_bridge.getLight(1);
  326 + HueLight test_light_2 = test_bridge.getLight(2);
  327 + HueLight test_light_3 = test_bridge.getLight(3);
  328 +
  329 + EXPECT_EQ("5.50.1.19085", ctest_light_1.getSwVersion());
  330 + EXPECT_EQ("5.50.1.19085", ctest_light_2.getSwVersion());
  331 + EXPECT_EQ("5.50.1.19085", ctest_light_3.getSwVersion());
  332 + EXPECT_EQ("5.50.1.19085", test_light_1.getSwVersion());
  333 + EXPECT_EQ("5.50.1.19085", test_light_2.getSwVersion());
  334 + EXPECT_EQ("5.50.1.19085", test_light_3.getSwVersion());
  335 +}
  336 +
  337 +TEST_F(HueLightTest, setName)
  338 +{
  339 + using namespace ::testing;
  340 + nlohmann::json expected_request({});
  341 + expected_request["name"] = "Baskj189";
  342 + nlohmann::json prep_ret;
  343 + prep_ret = nlohmann::json::array();
  344 + prep_ret[0] = nlohmann::json::object();
  345 + prep_ret[0]["success"] = nlohmann::json::object();
  346 + prep_ret[0]["success"]["/lights/1/name"] = expected_request["name"];
  347 + EXPECT_CALL(
  348 + *handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/name", expected_request, getBridgeIp(), 80))
  349 + .Times(1)
  350 + .WillOnce(Return(prep_ret));
  351 + EXPECT_CALL(
  352 + *handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/name", expected_request, getBridgeIp(), 80))
  353 + .Times(1)
  354 + .WillOnce(Return(nlohmann::json::array()));
  355 + prep_ret[0]["success"] = nlohmann::json::object();
  356 + prep_ret[0]["success"]["/lights/3/name"] = expected_request["name"];
  357 + EXPECT_CALL(
  358 + *handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/name", expected_request, getBridgeIp(), 80))
  359 + .Times(1)
  360 + .WillOnce(Return(prep_ret));
  361 +
  362 + HueLight test_light_1 = test_bridge.getLight(1);
  363 + HueLight test_light_2 = test_bridge.getLight(2);
  364 + HueLight test_light_3 = test_bridge.getLight(3);
  365 +
  366 + EXPECT_EQ(true, test_light_1.setName(expected_request["name"]));
  367 + EXPECT_EQ(false, test_light_2.setName(expected_request["name"]));
  368 + EXPECT_EQ(true, test_light_3.setName(expected_request["name"]));
  369 +}
  370 +
  371 +TEST_F(HueLightTest, getColorType)
  372 +{
  373 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  374 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  375 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  376 + HueLight test_light_1 = test_bridge.getLight(1);
  377 + HueLight test_light_2 = test_bridge.getLight(2);
  378 + HueLight test_light_3 = test_bridge.getLight(3);
  379 +
  380 + EXPECT_EQ(ColorType::NONE, ctest_light_1.getColorType());
  381 + EXPECT_EQ(ColorType::GAMUT_A, ctest_light_2.getColorType());
  382 + EXPECT_EQ(ColorType::GAMUT_C, ctest_light_3.getColorType());
  383 + EXPECT_EQ(ColorType::NONE, test_light_1.getColorType());
  384 + EXPECT_EQ(ColorType::GAMUT_A, test_light_2.getColorType());
  385 + EXPECT_EQ(ColorType::GAMUT_C, test_light_3.getColorType());
  386 +}
  387 +
  388 +TEST_F(HueLightTest, KelvinToMired)
  389 +{
  390 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  391 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  392 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  393 + HueLight test_light_1 = test_bridge.getLight(1);
  394 + HueLight test_light_2 = test_bridge.getLight(2);
  395 + HueLight test_light_3 = test_bridge.getLight(3);
  396 +
  397 + EXPECT_EQ(10000, ctest_light_1.KelvinToMired(100));
  398 + EXPECT_EQ(500, ctest_light_2.KelvinToMired(2000));
  399 + EXPECT_EQ(303, ctest_light_3.KelvinToMired(3300));
  400 + EXPECT_EQ(250, test_light_1.KelvinToMired(4000));
  401 + EXPECT_EQ(200, test_light_2.KelvinToMired(5000));
  402 + EXPECT_EQ(166, test_light_3.KelvinToMired(6000));
  403 +}
  404 +
  405 +TEST_F(HueLightTest, MiredToKelvin)
  406 +{
  407 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  408 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  409 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  410 + HueLight test_light_1 = test_bridge.getLight(1);
  411 + HueLight test_light_2 = test_bridge.getLight(2);
  412 + HueLight test_light_3 = test_bridge.getLight(3);
  413 +
  414 + EXPECT_EQ(100, ctest_light_1.MiredToKelvin(10000));
  415 + EXPECT_EQ(2000, ctest_light_2.MiredToKelvin(500));
  416 + EXPECT_EQ(3300, ctest_light_3.MiredToKelvin(303));
  417 + EXPECT_EQ(4000, test_light_1.MiredToKelvin(250));
  418 + EXPECT_EQ(5000, test_light_2.MiredToKelvin(200));
  419 + EXPECT_EQ(6024, test_light_3.MiredToKelvin(166)); // 6000 kelvin should be 166 mired, but keep in
  420 + // mind flops are not exact
  421 +}
  422 +
  423 +TEST_F(HueLightTest, hasBrightnessControl)
  424 +{
  425 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  426 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  427 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  428 + HueLight test_light_1 = test_bridge.getLight(1);
  429 + HueLight test_light_2 = test_bridge.getLight(2);
  430 + HueLight test_light_3 = test_bridge.getLight(3);
  431 +
  432 + EXPECT_EQ(true, ctest_light_1.hasBrightnessControl());
  433 + EXPECT_EQ(true, ctest_light_2.hasBrightnessControl());
  434 + EXPECT_EQ(true, ctest_light_3.hasBrightnessControl());
  435 + EXPECT_EQ(true, test_light_1.hasBrightnessControl());
  436 + EXPECT_EQ(true, test_light_2.hasBrightnessControl());
  437 + EXPECT_EQ(true, test_light_3.hasBrightnessControl());
  438 +}
  439 +
  440 +TEST_F(HueLightTest, hasTemperatureControl)
  441 +{
  442 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  443 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  444 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  445 + HueLight test_light_1 = test_bridge.getLight(1);
  446 + HueLight test_light_2 = test_bridge.getLight(2);
  447 + HueLight test_light_3 = test_bridge.getLight(3);
  448 +
  449 + EXPECT_EQ(false, ctest_light_1.hasTemperatureControl());
  450 + EXPECT_EQ(false, ctest_light_2.hasTemperatureControl());
  451 + EXPECT_EQ(true, ctest_light_3.hasTemperatureControl());
  452 + EXPECT_EQ(false, test_light_1.hasTemperatureControl());
  453 + EXPECT_EQ(false, test_light_2.hasTemperatureControl());
  454 + EXPECT_EQ(true, test_light_3.hasTemperatureControl());
  455 +}
  456 +
  457 +TEST_F(HueLightTest, hasColorControl)
  458 +{
  459 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  460 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  461 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  462 + HueLight test_light_1 = test_bridge.getLight(1);
  463 + HueLight test_light_2 = test_bridge.getLight(2);
  464 + HueLight test_light_3 = test_bridge.getLight(3);
  465 +
  466 + EXPECT_EQ(false, ctest_light_1.hasColorControl());
  467 + EXPECT_EQ(true, ctest_light_2.hasColorControl());
  468 + EXPECT_EQ(true, ctest_light_3.hasColorControl());
  469 + EXPECT_EQ(false, test_light_1.hasColorControl());
  470 + EXPECT_EQ(true, test_light_2.hasColorControl());
  471 + EXPECT_EQ(true, test_light_3.hasColorControl());
  472 +}
  473 +
  474 +TEST_F(HueLightTest, setBrightness)
  475 +{
  476 + using namespace ::testing;
  477 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, getBridgeIp(), 80))
  478 + .Times(1)
  479 + .WillOnce(Return(nlohmann::json::array()));
  480 + nlohmann::json prep_ret;
  481 + prep_ret = nlohmann::json::array();
  482 + prep_ret[0] = nlohmann::json::object();
  483 + prep_ret[0]["success"] = nlohmann::json::object();
  484 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  485 + prep_ret[1] = nlohmann::json::object();
  486 + prep_ret[1]["success"] = nlohmann::json::object();
  487 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  488 + prep_ret[2] = nlohmann::json::object();
  489 + prep_ret[2]["success"] = nlohmann::json::object();
  490 + prep_ret[2]["success"]["/lights/3/state/bri"] = 254;
  491 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  492 + .Times(1)
  493 + .WillOnce(Return(prep_ret));
  494 +
  495 + HueLight test_light_1 = test_bridge.getLight(1);
  496 + HueLight test_light_2 = test_bridge.getLight(2);
  497 + HueLight test_light_3 = test_bridge.getLight(3);
  498 +
  499 + EXPECT_EQ(false, test_light_1.setBrightness(200));
  500 + EXPECT_EQ(true, test_light_2.setBrightness(0, 2));
  501 + EXPECT_EQ(true, test_light_3.setBrightness(255, 0));
  502 +}
  503 +
  504 +TEST_F(HueLightTest, getBrightness)
  505 +{
  506 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  507 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  508 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  509 + HueLight test_light_1 = test_bridge.getLight(1);
  510 + HueLight test_light_2 = test_bridge.getLight(2);
  511 + HueLight test_light_3 = test_bridge.getLight(3);
  512 +
  513 + EXPECT_EQ(254, ctest_light_1.getBrightness());
  514 + EXPECT_EQ(254, ctest_light_2.getBrightness());
  515 + EXPECT_EQ(254, ctest_light_3.getBrightness());
  516 + EXPECT_EQ(254, test_light_1.getBrightness());
  517 + EXPECT_EQ(254, test_light_2.getBrightness());
  518 + EXPECT_EQ(254, test_light_3.getBrightness());
  519 +}
  520 +
  521 +TEST_F(HueLightTest, setColorTemperature)
  522 +{
  523 + using namespace ::testing;
  524 + nlohmann::json prep_ret;
  525 + prep_ret = nlohmann::json::array();
  526 + prep_ret[2] = nlohmann::json::object();
  527 + prep_ret[2]["success"] = nlohmann::json::object();
  528 + prep_ret[2]["success"]["/lights/3/state/ct"] = 153;
  529 + prep_ret[1] = nlohmann::json::object();
  530 + prep_ret[1]["success"] = nlohmann::json::object();
  531 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  532 + prep_ret[0] = nlohmann::json::object();
  533 + prep_ret[0]["success"] = nlohmann::json::object();
  534 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  535 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  536 + .Times(1)
  537 + .WillOnce(Return(prep_ret));
  538 +
  539 + HueLight test_light_1 = test_bridge.getLight(1);
  540 + HueLight test_light_2 = test_bridge.getLight(2);
  541 + HueLight test_light_3 = test_bridge.getLight(3);
  542 +
  543 + EXPECT_EQ(false, test_light_1.setColorTemperature(153));
  544 + EXPECT_EQ(false, test_light_2.setColorTemperature(400, 2));
  545 + EXPECT_EQ(true, test_light_3.setColorTemperature(100, 0));
  546 +}
  547 +
  548 +TEST_F(HueLightTest, getColorTemperature)
  549 +{
  550 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  551 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  552 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  553 + HueLight test_light_1 = test_bridge.getLight(1);
  554 + HueLight test_light_2 = test_bridge.getLight(2);
  555 + HueLight test_light_3 = test_bridge.getLight(3);
  556 +
  557 + EXPECT_EQ(0, ctest_light_1.getColorTemperature());
  558 + EXPECT_EQ(0, ctest_light_2.getColorTemperature());
  559 + EXPECT_EQ(366, ctest_light_3.getColorTemperature());
  560 + EXPECT_EQ(0, test_light_1.getColorTemperature());
  561 + EXPECT_EQ(0, test_light_2.getColorTemperature());
  562 + EXPECT_EQ(366, test_light_3.getColorTemperature());
  563 +}
  564 +
  565 +TEST_F(HueLightTest, setColorHue)
  566 +{
  567 + using namespace ::testing;
  568 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  569 + .Times(1)
  570 + .WillOnce(Return(nlohmann::json::array()));
  571 + nlohmann::json prep_ret;
  572 + prep_ret = nlohmann::json::array();
  573 + prep_ret[2] = nlohmann::json::object();
  574 + prep_ret[2]["success"] = nlohmann::json::object();
  575 + prep_ret[2]["success"]["/lights/3/state/hue"] = 65500;
  576 + prep_ret[1] = nlohmann::json::object();
  577 + prep_ret[1]["success"] = nlohmann::json::object();
  578 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  579 + prep_ret[0] = nlohmann::json::object();
  580 + prep_ret[0]["success"] = nlohmann::json::object();
  581 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  582 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  583 + .Times(1)
  584 + .WillOnce(Return(prep_ret));
  585 +
  586 + HueLight test_light_1 = test_bridge.getLight(1);
  587 + HueLight test_light_2 = test_bridge.getLight(2);
  588 + HueLight test_light_3 = test_bridge.getLight(3);
  589 +
  590 + EXPECT_EQ(false, test_light_1.setColorHue(153));
  591 + EXPECT_EQ(false, test_light_2.setColorHue(30000, 2));
  592 + EXPECT_EQ(true, test_light_3.setColorHue(65500, 0));
  593 +}
  594 +
  595 +TEST_F(HueLightTest, setColorSaturation)
  596 +{
  597 + using namespace ::testing;
  598 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  599 + .Times(1)
  600 + .WillOnce(Return(nlohmann::json::array()));
  601 + nlohmann::json prep_ret;
  602 + prep_ret = nlohmann::json::array();
  603 + prep_ret[2] = nlohmann::json::object();
  604 + prep_ret[2]["success"] = nlohmann::json::object();
  605 + prep_ret[2]["success"]["/lights/3/state/sat"] = 250;
  606 + prep_ret[1] = nlohmann::json::object();
  607 + prep_ret[1]["success"] = nlohmann::json::object();
  608 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  609 + prep_ret[0] = nlohmann::json::object();
  610 + prep_ret[0]["success"] = nlohmann::json::object();
  611 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  612 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  613 + .Times(1)
  614 + .WillOnce(Return(prep_ret));
  615 +
  616 + HueLight test_light_1 = test_bridge.getLight(1);
  617 + HueLight test_light_2 = test_bridge.getLight(2);
  618 + HueLight test_light_3 = test_bridge.getLight(3);
  619 +
  620 + EXPECT_EQ(false, test_light_1.setColorSaturation(0));
  621 + EXPECT_EQ(false, test_light_2.setColorSaturation(140, 2));
  622 + EXPECT_EQ(true, test_light_3.setColorSaturation(250, 0));
  623 +}
  624 +
  625 +TEST_F(HueLightTest, setColorHueSaturation)
  626 +{
  627 + using namespace ::testing;
  628 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  629 + .Times(1)
  630 + .WillOnce(Return(nlohmann::json::array()));
  631 + nlohmann::json prep_ret;
  632 + prep_ret = nlohmann::json::array();
  633 + prep_ret[0] = nlohmann::json::object();
  634 + prep_ret[0]["success"] = nlohmann::json::object();
  635 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  636 + prep_ret[1] = nlohmann::json::object();
  637 + prep_ret[1]["success"] = nlohmann::json::object();
  638 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  639 + prep_ret[2] = nlohmann::json::object();
  640 + prep_ret[2]["success"] = nlohmann::json::object();
  641 + prep_ret[2]["success"]["/lights/3/state/hue"] = 65500;
  642 + prep_ret[3] = nlohmann::json::object();
  643 + prep_ret[3]["success"] = nlohmann::json::object();
  644 + prep_ret[3]["success"]["/lights/3/state/sat"] = 250;
  645 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  646 + .Times(1)
  647 + .WillOnce(Return(prep_ret));
  648 +
  649 + HueLight test_light_1 = test_bridge.getLight(1);
  650 + HueLight test_light_2 = test_bridge.getLight(2);
  651 + HueLight test_light_3 = test_bridge.getLight(3);
  652 +
  653 + EXPECT_EQ(false, test_light_1.setColorHueSaturation(153, 0));
  654 + EXPECT_EQ(false, test_light_2.setColorHueSaturation(30000, 140, 2));
  655 + EXPECT_EQ(true, test_light_3.setColorHueSaturation(65500, 250, 0));
  656 +}
  657 +
  658 +TEST_F(HueLightTest, getColorHueSaturation)
  659 +{
  660 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  661 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  662 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  663 + HueLight test_light_1 = test_bridge.getLight(1);
  664 + HueLight test_light_2 = test_bridge.getLight(2);
  665 + HueLight test_light_3 = test_bridge.getLight(3);
  666 +
  667 + EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)), ctest_light_1.getColorHueSaturation());
  668 + EXPECT_EQ(std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),
  669 + ctest_light_2.getColorHueSaturation());
  670 + EXPECT_EQ(std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),
  671 + ctest_light_3.getColorHueSaturation());
  672 + EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)), test_light_1.getColorHueSaturation());
  673 + EXPECT_EQ(
  674 + std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)), test_light_2.getColorHueSaturation());
  675 + EXPECT_EQ(
  676 + std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)), test_light_3.getColorHueSaturation());
  677 +}
  678 +
  679 +TEST_F(HueLightTest, setColorXY)
  680 +{
  681 + using namespace ::testing;
  682 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  683 + .Times(1)
  684 + .WillOnce(Return(nlohmann::json::array()));
  685 + nlohmann::json prep_ret;
  686 + prep_ret = nlohmann::json::array();
  687 + prep_ret[2] = nlohmann::json::object();
  688 + prep_ret[2]["success"] = nlohmann::json::object();
  689 + prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.4232;
  690 + prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1231;
  691 + prep_ret[1] = nlohmann::json::object();
  692 + prep_ret[1]["success"] = nlohmann::json::object();
  693 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  694 + prep_ret[0] = nlohmann::json::object();
  695 + prep_ret[0]["success"] = nlohmann::json::object();
  696 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  697 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  698 + .Times(1)
  699 + .WillOnce(Return(prep_ret));
  700 +
  701 + HueLight test_light_1 = test_bridge.getLight(1);
  702 + HueLight test_light_2 = test_bridge.getLight(2);
  703 + HueLight test_light_3 = test_bridge.getLight(3);
  704 +
  705 + EXPECT_EQ(false, test_light_1.setColorXY(0.01, 0));
  706 + EXPECT_EQ(false, test_light_2.setColorXY(0.123, 1, 2));
  707 + EXPECT_EQ(true, test_light_3.setColorXY(0.4232, 0.1231, 0));
  708 +}
  709 +
  710 +TEST_F(HueLightTest, getColorXY)
  711 +{
  712 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  713 + const HueLight ctest_light_2 = test_bridge.getLight(2);
  714 + const HueLight ctest_light_3 = test_bridge.getLight(3);
  715 + HueLight test_light_1 = test_bridge.getLight(1);
  716 + HueLight test_light_2 = test_bridge.getLight(2);
  717 + HueLight test_light_3 = test_bridge.getLight(3);
  718 +
  719 + EXPECT_EQ(std::make_pair(static_cast<float>(0), static_cast<float>(0)), ctest_light_1.getColorXY());
  720 + EXPECT_EQ(std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)), ctest_light_2.getColorXY());
  721 + EXPECT_EQ(std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)), ctest_light_3.getColorXY());
  722 + EXPECT_EQ(std::make_pair(static_cast<float>(0), static_cast<float>(0)), test_light_1.getColorXY());
  723 + EXPECT_EQ(std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)), test_light_2.getColorXY());
  724 + EXPECT_EQ(std::make_pair(static_cast<float>(0.102), static_cast<float>(0.102)), test_light_3.getColorXY());
  725 +}
  726 +
  727 +TEST_F(HueLightTest, setColorRGB)
  728 +{
  729 + using namespace ::testing;
  730 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  731 + .Times(1)
  732 + .WillOnce(Return(nlohmann::json::array()));
  733 + nlohmann::json prep_ret;
  734 + prep_ret = nlohmann::json::array();
  735 + prep_ret[2] = nlohmann::json::object();
  736 + prep_ret[2]["success"] = nlohmann::json::object();
  737 + prep_ret[2]["success"]["/lights/3/state/xy"][0] = 0.1596;
  738 + prep_ret[2]["success"]["/lights/3/state/xy"][1] = 0.1437;
  739 + prep_ret[1] = nlohmann::json::object();
  740 + prep_ret[1]["success"] = nlohmann::json::object();
  741 + prep_ret[1]["success"]["/lights/3/state/on"] = true;
  742 + prep_ret[0] = nlohmann::json::object();
  743 + prep_ret[0]["success"] = nlohmann::json::object();
  744 + prep_ret[0]["success"]["/lights/3/state/transitiontime"] = 0;
  745 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  746 + .Times(1)
  747 + .WillOnce(Return(prep_ret));
  748 +
  749 + HueLight test_light_1 = test_bridge.getLight(1);
  750 + HueLight test_light_2 = test_bridge.getLight(2);
  751 + HueLight test_light_3 = test_bridge.getLight(3);
  752 +
  753 + EXPECT_EQ(false, test_light_1.setColorRGB(0, 0, 0, 0));
  754 + EXPECT_EQ(false, test_light_2.setColorRGB(32, 64, 128, 2));
  755 + EXPECT_EQ(true, test_light_3.setColorRGB(64, 128, 255, 0));
  756 +}
  757 +
  758 +TEST_F(HueLightTest, alert)
  759 +{
  760 + using namespace ::testing;
  761 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/1/state", _, getBridgeIp(), 80))
  762 + .Times(1)
  763 + .WillOnce(Return(nlohmann::json::array()));
  764 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  765 + .Times(1)
  766 + .WillOnce(Return(nlohmann::json::array()));
  767 + nlohmann::json prep_ret;
  768 + prep_ret = nlohmann::json::array();
  769 + prep_ret[0] = nlohmann::json::object();
  770 + prep_ret[0]["success"] = nlohmann::json::object();
  771 + prep_ret[0]["success"]["/lights/3/state/alert"] = "select";
  772 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  773 + .Times(1)
  774 + .WillOnce(Return(prep_ret));
  775 +
  776 + HueLight test_light_1 = test_bridge.getLight(1);
  777 + HueLight test_light_2 = test_bridge.getLight(2);
  778 + HueLight test_light_3 = test_bridge.getLight(3);
  779 +
  780 + EXPECT_EQ(false, test_light_1.alert());
  781 + EXPECT_EQ(false, test_light_2.alert());
  782 + EXPECT_EQ(true, test_light_3.alert());
  783 +}
  784 +
  785 +TEST_F(HueLightTest, alertTemperature)
  786 +{
  787 + using namespace ::testing;
  788 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  789 + .Times(1)
  790 + .WillOnce(Return(nlohmann::json::array()));
  791 +
  792 + HueLight test_light_1 = test_bridge.getLight(1);
  793 + HueLight test_light_2 = test_bridge.getLight(2);
  794 + HueLight test_light_3 = test_bridge.getLight(3);
  795 +
  796 + EXPECT_EQ(false, test_light_1.alertTemperature(400));
  797 + EXPECT_EQ(false, test_light_2.alertTemperature(100));
  798 + EXPECT_EQ(false, test_light_3.alertTemperature(0));
  799 +}
  800 +
  801 +TEST_F(HueLightTest, alertHueSaturation)
  802 +{
  803 + using namespace ::testing;
  804 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  805 + .Times(1)
  806 + .WillOnce(Return(nlohmann::json::array()));
  807 +
  808 + HueLight test_light_1 = test_bridge.getLight(1);
  809 + HueLight test_light_2 = test_bridge.getLight(2);
  810 + HueLight test_light_3 = test_bridge.getLight(3);
  811 +
  812 + EXPECT_EQ(false, test_light_1.alertHueSaturation(0, 255));
  813 + EXPECT_EQ(false, test_light_2.alertHueSaturation(3000, 100));
  814 + EXPECT_EQ(false, test_light_3.alertHueSaturation(50000, 0));
  815 +}
  816 +
  817 +TEST_F(HueLightTest, alertXY)
  818 +{
  819 + using namespace ::testing;
  820 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  821 + .Times(1)
  822 + .WillOnce(Return(nlohmann::json::array()));
  823 +
  824 + HueLight test_light_1 = test_bridge.getLight(1);
  825 + HueLight test_light_2 = test_bridge.getLight(2);
  826 + HueLight test_light_3 = test_bridge.getLight(3);
  827 +
  828 + EXPECT_EQ(false, test_light_1.alertXY(0.1, 0.1));
  829 + EXPECT_EQ(false, test_light_2.alertXY(0.2434, 0.2344));
  830 + EXPECT_EQ(false, test_light_3.alertXY(0.1234, 0.1234));
  831 +}
  832 +
  833 +TEST_F(HueLightTest, alertRGB)
  834 +{
  835 + using namespace ::testing;
  836 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  837 + .Times(1)
  838 + .WillOnce(Return(nlohmann::json::array()));
  839 +
  840 + HueLight test_light_1 = test_bridge.getLight(1);
  841 + HueLight test_light_2 = test_bridge.getLight(2);
  842 + HueLight test_light_3 = test_bridge.getLight(3);
  843 +
  844 + EXPECT_EQ(false, test_light_1.alertRGB(0, 0, 0));
  845 + EXPECT_EQ(false, test_light_2.alertRGB(32, 64, 128));
  846 + EXPECT_EQ(false, test_light_3.alertRGB(64, 128, 255));
  847 +}
  848 +
  849 +TEST_F(HueLightTest, setColorLoop)
  850 +{
  851 + using namespace ::testing;
  852 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/2/state", _, getBridgeIp(), 80))
  853 + .Times(1)
  854 + .WillOnce(Return(nlohmann::json::array()));
  855 + EXPECT_CALL(*handler, PUTJson("/api/" + getBridgeUsername() + "/lights/3/state", _, getBridgeIp(), 80))
  856 + .Times(1)
  857 + .WillOnce(Return(nlohmann::json::array()));
  858 +
  859 + HueLight test_light_1 = test_bridge.getLight(1);
  860 + HueLight test_light_2 = test_bridge.getLight(2);
  861 + HueLight test_light_3 = test_bridge.getLight(3);
  862 +
  863 + EXPECT_EQ(false, test_light_1.setColorLoop(true));
  864 + EXPECT_EQ(false, test_light_2.setColorLoop(false));
  865 + EXPECT_EQ(false, test_light_3.setColorLoop(true));
  866 +}
  867 +
  868 +TEST_F(HueLightTest, refreshState)
  869 +{
  870 + using namespace ::testing;
  871 + test_bridge.getLight(1);
  872 + test_bridge.getLight(2);
  873 + test_bridge.getLight(3);
  874 +
  875 + EXPECT_CALL(
  876 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  877 + .Times(2)
  878 + .WillRepeatedly(Return(nlohmann::json::object()));
  879 +
  880 + const HueLight ctest_light_1 = test_bridge.getLight(1);
  881 + HueLight test_light_1 = test_bridge.getLight(1);
926 882 }
... ...
hueplusplus/test/test_Main.cpp
1 1 #include <gtest/gtest.h>
2 2  
3   -int main(int argc, char **argv) {
4   - ::testing::InitGoogleTest(&argc, argv);
5   - return RUN_ALL_TESTS();
  3 +
  4 +int main(int argc, char** argv)
  5 +{
  6 + ::testing::InitGoogleTest(&argc, argv);
  7 + return RUN_ALL_TESTS();
6 8 }
... ...
hueplusplus/test/test_SimpleBrightnessStrategy.cpp
  1 +#include <iostream>
  2 +#include <memory>
  3 +#include <string>
  4 +
1 5 #include <gmock/gmock.h>
2 6 #include <gtest/gtest.h>
3 7  
  8 +#include "testhelper.h"
4 9  
5 10 #include "../include/SimpleBrightnessStrategy.h"
6   -#include "../include/json/json.h"
  11 +#include "../include/json/json.hpp"
7 12 #include "mocks/mock_HttpHandler.h"
8 13 #include "mocks/mock_HueLight.h"
9   -#include "testhelper.h"
10 14  
11   -#include <iostream>
12   -#include <memory>
13   -#include <string>
14 15  
15   -TEST(SimpleBrightnessStrategy, setBrightness) {
16   - using namespace ::testing;
17   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
18   - EXPECT_CALL(*handler,
19   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
20   - Json::Value(Json::objectValue), getBridgeIp(), 80))
21   - .Times(AtLeast(1))
22   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
23   - MockHueLight test_light(handler);
24   - EXPECT_CALL(test_light, refreshState())
25   - .Times(AtLeast(1))
26   - .WillRepeatedly(Return());
27   - EXPECT_CALL(test_light, OffNoRefresh(_))
28   - .Times(AtLeast(1))
29   - .WillRepeatedly(Return(true));
30   - Json::Value prep_ret;
31   - prep_ret = Json::Value(Json::arrayValue);
32   - prep_ret[0] = Json::Value(Json::objectValue);
33   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
34   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
35   - prep_ret[1] = Json::Value(Json::objectValue);
36   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
37   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
38   - prep_ret[2] = Json::Value(Json::objectValue);
39   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
40   - prep_ret[2]["success"]["/lights/1/state/bri"] = 50;
41   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
42   - .Times(1)
43   - .WillOnce(Return(prep_ret));
  16 +TEST(SimpleBrightnessStrategy, setBrightness)
  17 +{
  18 + using namespace ::testing;
  19 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  20 + EXPECT_CALL(
  21 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  22 + .Times(AtLeast(1))
  23 + .WillRepeatedly(Return(nlohmann::json::object()));
  24 + MockHueLight test_light(handler);
  25 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  26 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  27 + nlohmann::json prep_ret;
  28 + prep_ret = nlohmann::json::array();
  29 + prep_ret[0] = nlohmann::json::object();
  30 + prep_ret[0]["success"] = nlohmann::json::object();
  31 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  32 + prep_ret[1] = nlohmann::json::object();
  33 + prep_ret[1]["success"] = nlohmann::json::object();
  34 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  35 + prep_ret[2] = nlohmann::json::object();
  36 + prep_ret[2]["success"] = nlohmann::json::object();
  37 + prep_ret[2]["success"]["/lights/1/state/bri"] = 50;
  38 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
44 39  
45   - test_light.getState()["state"]["on"] = true;
46   - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light));
47   - test_light.getState()["state"]["on"] = false;
48   - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light));
  40 + test_light.getState()["state"]["on"] = true;
  41 + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light));
  42 + test_light.getState()["state"]["on"] = false;
  43 + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(0, 4, test_light));
49 44  
50   - test_light.getState()["state"]["bri"] = 0;
51   - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light));
52   - test_light.getState()["state"]["on"] = true;
53   - test_light.getState()["state"]["bri"] = 50;
54   - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light));
  45 + test_light.getState()["state"]["bri"] = 0;
  46 + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light));
  47 + test_light.getState()["state"]["on"] = true;
  48 + test_light.getState()["state"]["bri"] = 50;
  49 + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(50, 6, test_light));
55 50  
56   - prep_ret[2]["success"]["/lights/1/state/bri"] = 254;
57   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
58   - .Times(1)
59   - .WillOnce(Return(prep_ret));
60   - test_light.getState()["state"]["on"] = false;
61   - EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(255, 6, test_light));
  51 + prep_ret[2]["success"]["/lights/1/state/bri"] = 254;
  52 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  53 + test_light.getState()["state"]["on"] = false;
  54 + EXPECT_EQ(true, SimpleBrightnessStrategy().setBrightness(255, 6, test_light));
62 55 }
63 56  
64   -TEST(SimpleBrightnessStrategy, getBrightness) {
65   - using namespace ::testing;
66   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
67   - EXPECT_CALL(*handler,
68   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
69   - Json::Value(Json::objectValue), getBridgeIp(), 80))
70   - .Times(AtLeast(1))
71   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
72   - MockHueLight test_light(handler);
73   - EXPECT_CALL(test_light, refreshState())
74   - .Times(AtLeast(1))
75   - .WillRepeatedly(Return());
  57 +TEST(SimpleBrightnessStrategy, getBrightness)
  58 +{
  59 + using namespace ::testing;
  60 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  61 + EXPECT_CALL(
  62 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  63 + .Times(AtLeast(1))
  64 + .WillRepeatedly(Return(nlohmann::json::object()));
  65 + MockHueLight test_light(handler);
  66 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
76 67  
77   - test_light.getState()["state"]["bri"] = 200;
78   - EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light));
79   - test_light.getState()["state"]["bri"] = 0;
80   - EXPECT_EQ(0, SimpleBrightnessStrategy().getBrightness(
81   - static_cast<const HueLight>(test_light)));
  68 + test_light.getState()["state"]["bri"] = 200;
  69 + EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light));
  70 + test_light.getState()["state"]["bri"] = 0;
  71 + EXPECT_EQ(0, SimpleBrightnessStrategy().getBrightness(static_cast<const HueLight>(test_light)));
82 72 }
... ...
hueplusplus/test/test_SimpleColorHueStrategy.cpp
  1 +#include <memory>
  2 +#include <string>
  3 +
1 4 #include <gmock/gmock.h>
2 5 #include <gtest/gtest.h>
3 6  
  7 +#include "testhelper.h"
4 8  
5 9 #include "../include/SimpleColorHueStrategy.h"
6   -#include "../include/json/json.h"
  10 +#include "../include/json/json.hpp"
7 11 #include "mocks/mock_HttpHandler.h"
8 12 #include "mocks/mock_HueLight.h"
9   -#include "testhelper.h"
10 13  
11   -#include <memory>
12   -#include <string>
13   -
14   -TEST(SimpleColorHueStrategy, setColorHue) {
15   - using namespace ::testing;
16   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
17   - EXPECT_CALL(*handler,
18   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
19   - Json::Value(Json::objectValue), getBridgeIp(), 80))
20   - .Times(AtLeast(1))
21   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
22   - MockHueLight test_light(handler);
23   - EXPECT_CALL(test_light, refreshState())
24   - .Times(AtLeast(1))
25   - .WillRepeatedly(Return());
26   - Json::Value prep_ret;
27   - prep_ret = Json::Value(Json::arrayValue);
28   - prep_ret[0] = Json::Value(Json::objectValue);
29   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
30   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
31   - prep_ret[1] = Json::Value(Json::objectValue);
32   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
33   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
34   - prep_ret[2] = Json::Value(Json::objectValue);
35   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
36   - prep_ret[2]["success"]["/lights/1/state/hue"] = 30500;
37   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
38   - .Times(1)
39   - .WillOnce(Return(prep_ret));
40   -
41   - test_light.getState()["state"]["on"] = true;
42   - test_light.getState()["state"]["hue"] = 200;
43   - test_light.getState()["state"]["colormode"] = "hs";
44   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(200, 4, test_light));
45   -
46   - test_light.getState()["state"]["on"] = false;
47   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(30500, 6, test_light));
  14 +TEST(SimpleColorHueStrategy, setColorHue)
  15 +{
  16 + using namespace ::testing;
  17 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  18 + EXPECT_CALL(
  19 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  20 + .Times(AtLeast(1))
  21 + .WillRepeatedly(Return(nlohmann::json::object()));
  22 + MockHueLight test_light(handler);
  23 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  24 + nlohmann::json prep_ret;
  25 + prep_ret = nlohmann::json::array();
  26 + prep_ret[0] = nlohmann::json::object();
  27 + prep_ret[0]["success"] = nlohmann::json::object();
  28 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  29 + prep_ret[1] = nlohmann::json::object();
  30 + prep_ret[1]["success"] = nlohmann::json::object();
  31 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  32 + prep_ret[2] = nlohmann::json::object();
  33 + prep_ret[2]["success"] = nlohmann::json::object();
  34 + prep_ret[2]["success"]["/lights/1/state/hue"] = 30500;
  35 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  36 +
  37 + test_light.getState()["state"]["on"] = true;
  38 + test_light.getState()["state"]["hue"] = 200;
  39 + test_light.getState()["state"]["colormode"] = "hs";
  40 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(200, 4, test_light));
  41 +
  42 + test_light.getState()["state"]["on"] = false;
  43 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHue(30500, 6, test_light));
48 44 }
49 45  
50   -TEST(SimpleColorHueStrategy, setColorSaturation) {
51   - using namespace ::testing;
52   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
53   - EXPECT_CALL(*handler,
54   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
55   - Json::Value(Json::objectValue), getBridgeIp(), 80))
56   - .Times(AtLeast(1))
57   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
58   - MockHueLight test_light(handler);
59   - EXPECT_CALL(test_light, refreshState())
60   - .Times(AtLeast(1))
61   - .WillRepeatedly(Return());
62   - Json::Value prep_ret;
63   - prep_ret = Json::Value(Json::arrayValue);
64   - prep_ret[0] = Json::Value(Json::objectValue);
65   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
66   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
67   - prep_ret[1] = Json::Value(Json::objectValue);
68   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
69   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
70   - prep_ret[2] = Json::Value(Json::objectValue);
71   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
72   - prep_ret[2]["success"]["/lights/1/state/sat"] = 254;
73   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
74   - .Times(1)
75   - .WillOnce(Return(prep_ret));
76   -
77   - test_light.getState()["state"]["on"] = true;
78   - test_light.getState()["state"]["sat"] = 100;
79   - test_light.getState()["state"]["colormode"] = "hs";
80   - EXPECT_EQ(true,
81   - SimpleColorHueStrategy().setColorSaturation(100, 4, test_light));
82   -
83   - test_light.getState()["state"]["on"] = false;
84   - EXPECT_EQ(true,
85   - SimpleColorHueStrategy().setColorSaturation(255, 6, test_light));
  46 +TEST(SimpleColorHueStrategy, setColorSaturation)
  47 +{
  48 + using namespace ::testing;
  49 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  50 + EXPECT_CALL(
  51 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  52 + .Times(AtLeast(1))
  53 + .WillRepeatedly(Return(nlohmann::json::object()));
  54 + MockHueLight test_light(handler);
  55 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  56 + nlohmann::json prep_ret;
  57 + prep_ret = nlohmann::json::array();
  58 + prep_ret[0] = nlohmann::json::object();
  59 + prep_ret[0]["success"] = nlohmann::json::object();
  60 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  61 + prep_ret[1] = nlohmann::json::object();
  62 + prep_ret[1]["success"] = nlohmann::json::object();
  63 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  64 + prep_ret[2] = nlohmann::json::object();
  65 + prep_ret[2]["success"] = nlohmann::json::object();
  66 + prep_ret[2]["success"]["/lights/1/state/sat"] = 254;
  67 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  68 +
  69 + test_light.getState()["state"]["on"] = true;
  70 + test_light.getState()["state"]["sat"] = 100;
  71 + test_light.getState()["state"]["colormode"] = "hs";
  72 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorSaturation(100, 4, test_light));
  73 +
  74 + test_light.getState()["state"]["on"] = false;
  75 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorSaturation(255, 6, test_light));
86 76 }
87 77  
88   -TEST(SimpleColorHueStrategy, setColorHueSaturation) {
89   - using namespace ::testing;
90   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
91   - EXPECT_CALL(*handler,
92   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
93   - Json::Value(Json::objectValue), getBridgeIp(), 80))
94   - .Times(AtLeast(1))
95   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
96   - MockHueLight test_light(handler);
97   - EXPECT_CALL(test_light, refreshState())
98   - .Times(AtLeast(1))
99   - .WillRepeatedly(Return());
100   - Json::Value prep_ret;
101   - prep_ret = Json::Value(Json::arrayValue);
102   - prep_ret[0] = Json::Value(Json::objectValue);
103   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
104   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
105   - prep_ret[1] = Json::Value(Json::objectValue);
106   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
107   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
108   - prep_ret[2] = Json::Value(Json::objectValue);
109   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
110   - prep_ret[2]["success"]["/lights/1/state/hue"] = 30500;
111   - prep_ret[3] = Json::Value(Json::objectValue);
112   - prep_ret[3]["success"] = Json::Value(Json::objectValue);
113   - prep_ret[3]["success"]["/lights/1/state/sat"] = 254;
114   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
115   - .Times(1)
116   - .WillOnce(Return(prep_ret));
117   -
118   - test_light.getState()["state"]["on"] = true;
119   - test_light.getState()["state"]["sat"] = 100;
120   - test_light.getState()["state"]["hue"] = 200;
121   - test_light.getState()["state"]["colormode"] = "hs";
122   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(200, 100, 4,
123   - test_light));
124   -
125   - test_light.getState()["state"]["on"] = false;
126   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(30500, 255, 6,
127   - test_light));
  78 +TEST(SimpleColorHueStrategy, setColorHueSaturation)
  79 +{
  80 + using namespace ::testing;
  81 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  82 + EXPECT_CALL(
  83 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  84 + .Times(AtLeast(1))
  85 + .WillRepeatedly(Return(nlohmann::json::object()));
  86 + MockHueLight test_light(handler);
  87 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  88 + nlohmann::json prep_ret;
  89 + prep_ret = nlohmann::json::array();
  90 + prep_ret[0] = nlohmann::json::object();
  91 + prep_ret[0]["success"] = nlohmann::json::object();
  92 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  93 + prep_ret[1] = nlohmann::json::object();
  94 + prep_ret[1]["success"] = nlohmann::json::object();
  95 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  96 + prep_ret[2] = nlohmann::json::object();
  97 + prep_ret[2]["success"] = nlohmann::json::object();
  98 + prep_ret[2]["success"]["/lights/1/state/hue"] = 30500;
  99 + prep_ret[3] = nlohmann::json::object();
  100 + prep_ret[3]["success"] = nlohmann::json::object();
  101 + prep_ret[3]["success"]["/lights/1/state/sat"] = 254;
  102 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  103 +
  104 + test_light.getState()["state"]["on"] = true;
  105 + test_light.getState()["state"]["sat"] = 100;
  106 + test_light.getState()["state"]["hue"] = 200;
  107 + test_light.getState()["state"]["colormode"] = "hs";
  108 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(200, 100, 4, test_light));
  109 +
  110 + test_light.getState()["state"]["on"] = false;
  111 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorHueSaturation(30500, 255, 6, test_light));
128 112 }
129 113  
130   -TEST(SimpleColorHueStrategy, setColorXY) {
131   - using namespace ::testing;
132   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
133   - EXPECT_CALL(*handler,
134   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
135   - Json::Value(Json::objectValue), getBridgeIp(), 80))
136   - .Times(AtLeast(1))
137   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
138   - MockHueLight test_light(handler);
139   - EXPECT_CALL(test_light, refreshState())
140   - .Times(AtLeast(1))
141   - .WillRepeatedly(Return());
142   - Json::Value prep_ret;
143   - prep_ret = Json::Value(Json::arrayValue);
144   - prep_ret[0] = Json::Value(Json::objectValue);
145   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
146   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
147   - prep_ret[1] = Json::Value(Json::objectValue);
148   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
149   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
150   - prep_ret[2] = Json::Value(Json::objectValue);
151   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
152   - prep_ret[2]["success"]["/lights/1/state/xy"][0] = 0.2355;
153   - prep_ret[2]["success"]["/lights/1/state/xy"][1] = 0.1234;
154   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
155   - .Times(1)
156   - .WillOnce(Return(prep_ret));
157   -
158   - test_light.getState()["state"]["on"] = true;
159   - test_light.getState()["state"]["xy"][0] = 0.1;
160   - test_light.getState()["state"]["xy"][1] = 0.1;
161   - test_light.getState()["state"]["colormode"] = "xy";
162   - EXPECT_EQ(true,
163   - SimpleColorHueStrategy().setColorXY(0.1f, 0.1f, 4, test_light));
164   -
165   - test_light.getState()["state"]["on"] = false;
166   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorXY(0.2355f, 0.1234f, 6,
167   - test_light));
  114 +TEST(SimpleColorHueStrategy, setColorXY)
  115 +{
  116 + using namespace ::testing;
  117 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  118 + EXPECT_CALL(
  119 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  120 + .Times(AtLeast(1))
  121 + .WillRepeatedly(Return(nlohmann::json::object()));
  122 + MockHueLight test_light(handler);
  123 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  124 + nlohmann::json prep_ret;
  125 + prep_ret = nlohmann::json::array();
  126 + prep_ret[0] = nlohmann::json::object();
  127 + prep_ret[0]["success"] = nlohmann::json::object();
  128 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  129 + prep_ret[1] = nlohmann::json::object();
  130 + prep_ret[1]["success"] = nlohmann::json::object();
  131 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  132 + prep_ret[2] = nlohmann::json::object();
  133 + prep_ret[2]["success"] = nlohmann::json::object();
  134 + prep_ret[2]["success"]["/lights/1/state/xy"][0] = 0.2355;
  135 + prep_ret[2]["success"]["/lights/1/state/xy"][1] = 0.1234;
  136 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  137 +
  138 + test_light.getState()["state"]["on"] = true;
  139 + test_light.getState()["state"]["xy"][0] = 0.1f;
  140 + test_light.getState()["state"]["xy"][1] = 0.1f;
  141 + test_light.getState()["state"]["colormode"] = "xy";
  142 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorXY(0.1f, 0.1f, 4, test_light));
  143 +
  144 + test_light.getState()["state"]["on"] = false;
  145 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorXY(0.2355f, 0.1234f, 6, test_light));
168 146 }
169 147  
170   -TEST(SimpleColorHueStrategy, setColorRGB) {
171   - using namespace ::testing;
172   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
173   - EXPECT_CALL(*handler,
174   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
175   - Json::Value(Json::objectValue), getBridgeIp(), 80))
176   - .Times(AtLeast(1))
177   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
178   - MockHueLight test_light(handler);
179   - EXPECT_CALL(test_light, setColorXY(_, _, 4))
180   - .Times(2)
181   - .WillRepeatedly(Return(true));
182   -
183   - EXPECT_EQ(true,
184   - SimpleColorHueStrategy().setColorRGB(128, 128, 128, 4, test_light));
185   -
186   - EXPECT_EQ(true,
187   - SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light));
188   -
189   - EXPECT_CALL(test_light, OffNoRefresh(4)).Times(1).WillOnce(Return(true));
190   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light));
  148 +TEST(SimpleColorHueStrategy, setColorRGB)
  149 +{
  150 + using namespace ::testing;
  151 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  152 + EXPECT_CALL(
  153 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  154 + .Times(AtLeast(1))
  155 + .WillRepeatedly(Return(nlohmann::json::object()));
  156 + MockHueLight test_light(handler);
  157 + EXPECT_CALL(test_light, setColorXY(_, _, 4)).Times(2).WillRepeatedly(Return(true));
  158 +
  159 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(128, 128, 128, 4, test_light));
  160 +
  161 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light));
  162 +
  163 + EXPECT_CALL(test_light, OffNoRefresh(4)).Times(1).WillOnce(Return(true));
  164 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light));
191 165 }
192 166  
193   -TEST(SimpleColorHueStrategy, setColorLoop) {
194   - using namespace ::testing;
195   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
196   - EXPECT_CALL(*handler,
197   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
198   - Json::Value(Json::objectValue), getBridgeIp(), 80))
199   - .Times(AtLeast(1))
200   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
201   - MockHueLight test_light(handler);
202   - EXPECT_CALL(test_light, refreshState())
203   - .Times(AtLeast(1))
204   - .WillRepeatedly(Return());
205   - Json::Value prep_ret;
206   - prep_ret = Json::Value(Json::arrayValue);
207   - prep_ret[0] = Json::Value(Json::objectValue);
208   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
209   - prep_ret[0]["success"]["/lights/1/state/on"] = true;
210   - prep_ret[1] = Json::Value(Json::objectValue);
211   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
212   - prep_ret[1]["success"]["/lights/1/state/effect"] = "colorloop";
213   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
214   - .Times(1)
215   - .WillOnce(Return(prep_ret));
216   -
217   - test_light.getState()["state"]["on"] = true;
218   - test_light.getState()["state"]["effect"] = "colorloop";
219   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light));
220   -
221   - test_light.getState()["state"]["on"] = false;
222   - test_light.getState()["state"]["effect"] = "none";
223   - EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light));
  167 +TEST(SimpleColorHueStrategy, setColorLoop)
  168 +{
  169 + using namespace ::testing;
  170 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  171 + EXPECT_CALL(
  172 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  173 + .Times(AtLeast(1))
  174 + .WillRepeatedly(Return(nlohmann::json::object()));
  175 + MockHueLight test_light(handler);
  176 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  177 + nlohmann::json prep_ret;
  178 + prep_ret = nlohmann::json::array();
  179 + prep_ret[0] = nlohmann::json::object();
  180 + prep_ret[0]["success"] = nlohmann::json::object();
  181 + prep_ret[0]["success"]["/lights/1/state/on"] = true;
  182 + prep_ret[1] = nlohmann::json::object();
  183 + prep_ret[1]["success"] = nlohmann::json::object();
  184 + prep_ret[1]["success"]["/lights/1/state/effect"] = "colorloop";
  185 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  186 +
  187 + test_light.getState()["state"]["on"] = true;
  188 + test_light.getState()["state"]["effect"] = "colorloop";
  189 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light));
  190 +
  191 + test_light.getState()["state"]["on"] = false;
  192 + test_light.getState()["state"]["effect"] = "none";
  193 + EXPECT_EQ(true, SimpleColorHueStrategy().setColorLoop(true, test_light));
224 194 }
225 195  
226   -TEST(SimpleColorHueStrategy, alertHueSaturation) {
227   - using namespace ::testing;
228   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
229   - EXPECT_CALL(*handler,
230   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
231   - Json::Value(Json::objectValue), getBridgeIp(), 80))
232   - .Times(AtLeast(1))
233   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
234   - MockHueLight test_light(handler);
235   - EXPECT_CALL(test_light, refreshState())
236   - .Times(AtLeast(1))
237   - .WillRepeatedly(Return());
238   -
239   - test_light.getState()["state"]["colormode"] = "invalid";
240   - EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(30000, 128,
241   - test_light));
242   -
243   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
244   - .Times(AtLeast(2))
245   - .WillOnce(Return(false))
246   - .WillRepeatedly(Return(true));
247   - test_light.getState()["state"]["colormode"] = "hs";
248   - test_light.getState()["state"]["on"] = true;
249   - test_light.getState()["state"]["sat"] = 100;
250   - test_light.getState()["state"]["hue"] = 200;
251   - EXPECT_EQ(false,
252   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
253   -
254   - EXPECT_CALL(test_light, alert())
255   - .Times(AtLeast(2))
256   - .WillOnce(Return(false))
257   - .WillRepeatedly(Return(true));
258   - EXPECT_EQ(false,
259   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
260   -
261   - EXPECT_EQ(true,
262   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
263   -
264   - EXPECT_CALL(test_light, OffNoRefresh(_))
265   - .Times(AtLeast(1))
266   - .WillRepeatedly(Return(true));
267   - test_light.getState()["state"]["on"] = false;
268   - EXPECT_EQ(true,
269   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
270   -
271   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
272   - .Times(AtLeast(2))
273   - .WillOnce(Return(false))
274   - .WillRepeatedly(Return(true));
275   - test_light.getState()["state"]["colormode"] = "xy";
276   - test_light.getState()["state"]["on"] = true;
277   - test_light.getState()["state"]["xy"][0] = 0.1;
278   - test_light.getState()["state"]["xy"][1] = 0.1;
279   - EXPECT_EQ(false,
280   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
281   -
282   - EXPECT_CALL(test_light, alert())
283   - .Times(AtLeast(2))
284   - .WillOnce(Return(false))
285   - .WillRepeatedly(Return(true));
286   - EXPECT_EQ(false,
287   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
288   -
289   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
290   - .Times(AtLeast(2))
291   - .WillRepeatedly(Return(true));
292   - EXPECT_EQ(true,
293   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
294   -
295   - EXPECT_CALL(test_light, OffNoRefresh(_))
296   - .Times(AtLeast(1))
297   - .WillRepeatedly(Return(true));
298   - test_light.getState()["state"]["on"] = false;
299   - EXPECT_EQ(true,
300   - SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  196 +TEST(SimpleColorHueStrategy, alertHueSaturation)
  197 +{
  198 + using namespace ::testing;
  199 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  200 + EXPECT_CALL(
  201 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  202 + .Times(AtLeast(1))
  203 + .WillRepeatedly(Return(nlohmann::json::object()));
  204 + MockHueLight test_light(handler);
  205 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  206 +
  207 + test_light.getState()["state"]["colormode"] = "invalid";
  208 + test_light.getState()["state"]["on"] = false;
  209 + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(30000, 128, test_light));
  210 +
  211 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
  212 + .Times(AtLeast(2))
  213 + .WillOnce(Return(false))
  214 + .WillRepeatedly(Return(true));
  215 + test_light.getState()["state"]["colormode"] = "hs";
  216 + test_light.getState()["state"]["on"] = true;
  217 + test_light.getState()["state"]["sat"] = 100;
  218 + test_light.getState()["state"]["hue"] = 200;
  219 + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  220 +
  221 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  222 + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  223 +
  224 + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  225 +
  226 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  227 + test_light.getState()["state"]["on"] = false;
  228 + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  229 +
  230 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
  231 + .Times(AtLeast(2))
  232 + .WillOnce(Return(false))
  233 + .WillRepeatedly(Return(true));
  234 + test_light.getState()["state"]["colormode"] = "xy";
  235 + test_light.getState()["state"]["on"] = true;
  236 + test_light.getState()["state"]["xy"][0] = 0.1;
  237 + test_light.getState()["state"]["xy"][1] = 0.1;
  238 + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  239 +
  240 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  241 + EXPECT_EQ(false, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  242 +
  243 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  244 + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
  245 +
  246 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  247 + test_light.getState()["state"]["on"] = false;
  248 + EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
301 249 }
302 250  
303   -TEST(SimpleColorHueStrategy, alertXY) {
304   - using namespace ::testing;
305   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
306   - EXPECT_CALL(*handler,
307   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
308   - Json::Value(Json::objectValue), getBridgeIp(), 80))
309   - .Times(AtLeast(1))
310   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
311   - MockHueLight test_light(handler);
312   - EXPECT_CALL(test_light, refreshState())
313   - .Times(AtLeast(1))
314   - .WillRepeatedly(Return());
315   -
316   - test_light.getState()["state"]["colormode"] = "invalid";
317   - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
318   -
319   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
320   - .Times(AtLeast(2))
321   - .WillOnce(Return(false))
322   - .WillRepeatedly(Return(true));
323   - test_light.getState()["state"]["colormode"] = "hs";
324   - test_light.getState()["state"]["on"] = true;
325   - test_light.getState()["state"]["xy"][0] = 0.1;
326   - test_light.getState()["state"]["xy"][1] = 0.1;
327   - test_light.getState()["state"]["sat"] = 100;
328   - test_light.getState()["state"]["hue"] = 200;
329   - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
330   -
331   - EXPECT_CALL(test_light, alert())
332   - .Times(AtLeast(2))
333   - .WillOnce(Return(false))
334   - .WillRepeatedly(Return(true));
335   - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
336   -
337   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
338   - .Times(AtLeast(2))
339   - .WillRepeatedly(Return(true));
340   - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
341   -
342   - EXPECT_CALL(test_light, OffNoRefresh(_))
343   - .Times(AtLeast(1))
344   - .WillRepeatedly(Return(true));
345   - test_light.getState()["state"]["on"] = false;
346   - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
347   -
348   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
349   - .Times(AtLeast(2))
350   - .WillOnce(Return(false))
351   - .WillRepeatedly(Return(true));
352   - test_light.getState()["state"]["colormode"] = "xy";
353   - test_light.getState()["state"]["on"] = true;
354   - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
355   -
356   - EXPECT_CALL(test_light, alert())
357   - .Times(AtLeast(2))
358   - .WillOnce(Return(false))
359   - .WillRepeatedly(Return(true));
360   - EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
361   -
362   - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
363   -
364   - EXPECT_CALL(test_light, OffNoRefresh(_))
365   - .Times(AtLeast(1))
366   - .WillRepeatedly(Return(true));
367   - test_light.getState()["state"]["on"] = false;
368   - EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  251 +TEST(SimpleColorHueStrategy, alertXY)
  252 +{
  253 + using namespace ::testing;
  254 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  255 + EXPECT_CALL(
  256 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  257 + .Times(AtLeast(1))
  258 + .WillRepeatedly(Return(nlohmann::json::object()));
  259 + MockHueLight test_light(handler);
  260 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  261 +
  262 + test_light.getState()["state"]["colormode"] = "invalid";
  263 + test_light.getState()["state"]["on"] = false;
  264 + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  265 +
  266 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  267 + test_light.getState()["state"]["colormode"] = "hs";
  268 + test_light.getState()["state"]["on"] = true;
  269 + test_light.getState()["state"]["xy"][0] = 0.1;
  270 + test_light.getState()["state"]["xy"][1] = 0.1;
  271 + test_light.getState()["state"]["sat"] = 100;
  272 + test_light.getState()["state"]["hue"] = 200;
  273 + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  274 +
  275 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  276 + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  277 +
  278 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  279 + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  280 +
  281 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  282 + test_light.getState()["state"]["on"] = false;
  283 + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  284 +
  285 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  286 + test_light.getState()["state"]["colormode"] = "xy";
  287 + test_light.getState()["state"]["on"] = true;
  288 + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  289 +
  290 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  291 + EXPECT_EQ(false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  292 +
  293 + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
  294 +
  295 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  296 + test_light.getState()["state"]["on"] = false;
  297 + EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
369 298 }
370 299  
371   -TEST(SimpleColorHueStrategy, alertRGB) {
372   - using namespace ::testing;
373   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
374   - EXPECT_CALL(*handler,
375   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
376   - Json::Value(Json::objectValue), getBridgeIp(), 80))
377   - .Times(AtLeast(1))
378   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
379   - MockHueLight test_light(handler);
380   - EXPECT_CALL(test_light, refreshState())
381   - .Times(AtLeast(1))
382   - .WillRepeatedly(Return());
383   -
384   - test_light.getState()["state"]["colormode"] = "invalid";
385   - EXPECT_EQ(false,
386   - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
387   -
388   - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
389   - .Times(AtLeast(2))
390   - .WillOnce(Return(false))
391   - .WillRepeatedly(Return(true));
392   - test_light.getState()["state"]["colormode"] = "hs";
393   - test_light.getState()["state"]["on"] = true;
394   - test_light.getState()["state"]["sat"] = 100;
395   - test_light.getState()["state"]["hue"] = 200;
396   - EXPECT_EQ(false,
397   - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
398   -
399   - EXPECT_CALL(test_light, alert())
400   - .Times(AtLeast(2))
401   - .WillOnce(Return(false))
402   - .WillRepeatedly(Return(true));
403   - EXPECT_EQ(false,
404   - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
405   -
406   - EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
407   - .Times(AtLeast(2))
408   - .WillRepeatedly(Return(true));
409   - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
410   -
411   - EXPECT_CALL(test_light, OffNoRefresh(_))
412   - .Times(AtLeast(1))
413   - .WillRepeatedly(Return(true));
414   - test_light.getState()["state"]["on"] = false;
415   - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
416   -
417   - EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
418   - .Times(AtLeast(2))
419   - .WillOnce(Return(false))
420   - .WillRepeatedly(Return(true));
421   - test_light.getState()["state"]["colormode"] = "xy";
422   - test_light.getState()["state"]["on"] = true;
423   - test_light.getState()["state"]["xy"][0] = 0.1;
424   - test_light.getState()["state"]["xy"][1] = 0.1;
425   - EXPECT_EQ(false,
426   - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
427   -
428   - EXPECT_CALL(test_light, alert())
429   - .Times(AtLeast(2))
430   - .WillOnce(Return(false))
431   - .WillRepeatedly(Return(true));
432   - EXPECT_EQ(false,
433   - SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
434   -
435   - EXPECT_CALL(test_light, setColorXY(_, _, 1))
436   - .Times(AtLeast(2))
437   - .WillRepeatedly(Return(true));
438   - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
439   -
440   - EXPECT_CALL(test_light, OffNoRefresh(_))
441   - .Times(AtLeast(1))
442   - .WillRepeatedly(Return(true));
443   - test_light.getState()["state"]["on"] = false;
444   - EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  300 +TEST(SimpleColorHueStrategy, alertRGB)
  301 +{
  302 + using namespace ::testing;
  303 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  304 + EXPECT_CALL(
  305 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  306 + .Times(AtLeast(1))
  307 + .WillRepeatedly(Return(nlohmann::json::object()));
  308 + MockHueLight test_light(handler);
  309 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  310 +
  311 + test_light.getState()["state"]["colormode"] = "invalid";
  312 + test_light.getState()["state"]["on"] = false;
  313 + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  314 +
  315 + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
  316 + .Times(AtLeast(2))
  317 + .WillOnce(Return(false))
  318 + .WillRepeatedly(Return(true));
  319 + test_light.getState()["state"]["colormode"] = "hs";
  320 + test_light.getState()["state"]["on"] = true;
  321 + test_light.getState()["state"]["sat"] = 100;
  322 + test_light.getState()["state"]["hue"] = 200;
  323 + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  324 +
  325 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  326 + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  327 +
  328 + EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  329 + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  330 +
  331 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  332 + test_light.getState()["state"]["on"] = false;
  333 + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  334 +
  335 + EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
  336 + .Times(AtLeast(2))
  337 + .WillOnce(Return(false))
  338 + .WillRepeatedly(Return(true));
  339 + test_light.getState()["state"]["colormode"] = "xy";
  340 + test_light.getState()["state"]["on"] = true;
  341 + test_light.getState()["state"]["xy"][0] = 0.1;
  342 + test_light.getState()["state"]["xy"][1] = 0.1;
  343 + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  344 +
  345 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  346 + EXPECT_EQ(false, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  347 +
  348 + EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
  349 + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
  350 +
  351 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  352 + test_light.getState()["state"]["on"] = false;
  353 + EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
445 354 }
446 355  
447   -TEST(SimpleColorHueStrategy, getColorHueSaturation) {
448   - using namespace ::testing;
449   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
450   - EXPECT_CALL(*handler,
451   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
452   - Json::Value(Json::objectValue), getBridgeIp(), 80))
453   - .Times(AtLeast(1))
454   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
455   - MockHueLight test_light(handler);
456   - EXPECT_CALL(test_light, refreshState())
457   - .Times(AtLeast(1))
458   - .WillRepeatedly(Return());
459   -
460   - test_light.getState()["state"]["hue"] = 5000;
461   - test_light.getState()["state"]["sat"] = 128;
462   - EXPECT_EQ(
463   - std::make_pair(static_cast<uint16_t>(5000), static_cast<uint8_t>(128)),
464   - SimpleColorHueStrategy().getColorHueSaturation(test_light));
465   - test_light.getState()["state"]["hue"] = 50000;
466   - test_light.getState()["state"]["sat"] = 158;
467   - EXPECT_EQ(
468   - std::make_pair(static_cast<uint16_t>(50000), static_cast<uint8_t>(158)),
469   - SimpleColorHueStrategy().getColorHueSaturation(
470   - static_cast<const HueLight>(test_light)));
  356 +TEST(SimpleColorHueStrategy, getColorHueSaturation)
  357 +{
  358 + using namespace ::testing;
  359 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  360 + EXPECT_CALL(
  361 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  362 + .Times(AtLeast(1))
  363 + .WillRepeatedly(Return(nlohmann::json::object()));
  364 + MockHueLight test_light(handler);
  365 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  366 +
  367 + test_light.getState()["state"]["hue"] = 5000;
  368 + test_light.getState()["state"]["sat"] = 128;
  369 + EXPECT_EQ(std::make_pair(static_cast<uint16_t>(5000), static_cast<uint8_t>(128)),
  370 + SimpleColorHueStrategy().getColorHueSaturation(test_light));
  371 + test_light.getState()["state"]["hue"] = 50000;
  372 + test_light.getState()["state"]["sat"] = 158;
  373 + EXPECT_EQ(std::make_pair(static_cast<uint16_t>(50000), static_cast<uint8_t>(158)),
  374 + SimpleColorHueStrategy().getColorHueSaturation(static_cast<const HueLight>(test_light)));
471 375 }
472 376  
473   -TEST(SimpleColorHueStrategy, getColorXY) {
474   - using namespace ::testing;
475   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
476   - EXPECT_CALL(*handler,
477   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
478   - Json::Value(Json::objectValue), getBridgeIp(), 80))
479   - .Times(AtLeast(1))
480   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
481   - MockHueLight test_light(handler);
482   - EXPECT_CALL(test_light, refreshState())
483   - .Times(AtLeast(1))
484   - .WillRepeatedly(Return());
485   -
486   - test_light.getState()["state"]["xy"][0] = 0.1234;
487   - test_light.getState()["state"]["xy"][1] = 0.1234;
488   - EXPECT_EQ(
489   - std::make_pair(static_cast<float>(0.1234), static_cast<float>(0.1234)),
490   - SimpleColorHueStrategy().getColorXY(test_light));
491   - test_light.getState()["state"]["xy"][0] = 0.12;
492   - test_light.getState()["state"]["xy"][1] = 0.6458;
493   - EXPECT_EQ(
494   - std::make_pair(static_cast<float>(0.12), static_cast<float>(0.6458)),
495   - SimpleColorHueStrategy().getColorXY(
496   - static_cast<const HueLight>(test_light)));
  377 +TEST(SimpleColorHueStrategy, getColorXY)
  378 +{
  379 + using namespace ::testing;
  380 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  381 + EXPECT_CALL(
  382 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  383 + .Times(AtLeast(1))
  384 + .WillRepeatedly(Return(nlohmann::json::object()));
  385 + MockHueLight test_light(handler);
  386 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  387 +
  388 + test_light.getState()["state"]["xy"][0] = 0.1234;
  389 + test_light.getState()["state"]["xy"][1] = 0.1234;
  390 + EXPECT_EQ(std::make_pair(static_cast<float>(0.1234), static_cast<float>(0.1234)),
  391 + SimpleColorHueStrategy().getColorXY(test_light));
  392 + test_light.getState()["state"]["xy"][0] = 0.12;
  393 + test_light.getState()["state"]["xy"][1] = 0.6458;
  394 + EXPECT_EQ(std::make_pair(static_cast<float>(0.12), static_cast<float>(0.6458)),
  395 + SimpleColorHueStrategy().getColorXY(static_cast<const HueLight>(test_light)));
497 396 }
... ...
hueplusplus/test/test_SimpleColorTemperatureStrategy.cpp
  1 +#include <iostream>
  2 +#include <memory>
  3 +#include <string>
  4 +
1 5 #include <gmock/gmock.h>
2 6 #include <gtest/gtest.h>
3 7  
  8 +#include "testhelper.h"
4 9  
5 10 #include "../include/SimpleColorTemperatureStrategy.h"
6   -#include "../include/json/json.h"
  11 +#include "../include/json/json.hpp"
7 12 #include "mocks/mock_HttpHandler.h"
8 13 #include "mocks/mock_HueLight.h"
9   -#include "testhelper.h"
10 14  
11   -#include <iostream>
12   -#include <memory>
13   -#include <string>
14 15  
15   -TEST(SimpleColorTemperatureStrategy, setColorTemperature) {
16   - using namespace ::testing;
17   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
18   - EXPECT_CALL(*handler,
19   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
20   - Json::Value(Json::objectValue), getBridgeIp(), 80))
21   - .Times(AtLeast(1))
22   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
23   - MockHueLight test_light(handler);
24   - EXPECT_CALL(test_light, refreshState())
25   - .Times(AtLeast(1))
26   - .WillRepeatedly(Return());
27   - Json::Value prep_ret;
28   - prep_ret = Json::Value(Json::arrayValue);
29   - prep_ret[0] = Json::Value(Json::objectValue);
30   - prep_ret[0]["success"] = Json::Value(Json::objectValue);
31   - prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
32   - prep_ret[1] = Json::Value(Json::objectValue);
33   - prep_ret[1]["success"] = Json::Value(Json::objectValue);
34   - prep_ret[1]["success"]["/lights/1/state/on"] = true;
35   - prep_ret[2] = Json::Value(Json::objectValue);
36   - prep_ret[2]["success"] = Json::Value(Json::objectValue);
37   - prep_ret[2]["success"]["/lights/1/state/ct"] = 155;
38   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
39   - .Times(1)
40   - .WillOnce(Return(prep_ret));
41   -
42   - test_light.getState()["state"]["on"] = true;
43   - test_light.getState()["state"]["ct"] = 200;
44   - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(
45   - 200, 4, test_light));
46   -
47   - test_light.getState()["state"]["on"] = false;
48   - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(
49   - 155, 6, test_light));
50   -
51   - prep_ret[2]["success"]["/lights/1/state/ct"] = 153;
52   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
53   - .Times(1)
54   - .WillOnce(Return(prep_ret));
55   - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(
56   - 0, 6, test_light));
57   -
58   - prep_ret[2]["success"]["/lights/1/state/ct"] = 500;
59   - EXPECT_CALL(test_light, SendPutRequest(_, "/state"))
60   - .Times(1)
61   - .WillOnce(Return(prep_ret));
62   - EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(
63   - 600, 6, test_light));
  16 +TEST(SimpleColorTemperatureStrategy, setColorTemperature)
  17 +{
  18 + using namespace ::testing;
  19 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  20 + EXPECT_CALL(
  21 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  22 + .Times(AtLeast(1))
  23 + .WillRepeatedly(Return(nlohmann::json::object()));
  24 + MockHueLight test_light(handler);
  25 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  26 + nlohmann::json prep_ret;
  27 + prep_ret = nlohmann::json::array();
  28 + prep_ret[0] = nlohmann::json::object();
  29 + prep_ret[0]["success"] = nlohmann::json::object();
  30 + prep_ret[0]["success"]["/lights/1/state/transitiontime"] = 6;
  31 + prep_ret[1] = nlohmann::json::object();
  32 + prep_ret[1]["success"] = nlohmann::json::object();
  33 + prep_ret[1]["success"]["/lights/1/state/on"] = true;
  34 + prep_ret[2] = nlohmann::json::object();
  35 + prep_ret[2]["success"] = nlohmann::json::object();
  36 + prep_ret[2]["success"]["/lights/1/state/ct"] = 155;
  37 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  38 +
  39 + test_light.getState()["state"]["on"] = true;
  40 + test_light.getState()["state"]["ct"] = 200;
  41 + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(200, 4, test_light));
  42 +
  43 + test_light.getState()["state"]["on"] = false;
  44 + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(155, 6, test_light));
  45 +
  46 + prep_ret[2]["success"]["/lights/1/state/ct"] = 153;
  47 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  48 + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(0, 6, test_light));
  49 +
  50 + prep_ret[2]["success"]["/lights/1/state/ct"] = 500;
  51 + EXPECT_CALL(test_light, SendPutRequest(_, "/state")).Times(1).WillOnce(Return(prep_ret));
  52 + EXPECT_EQ(true, SimpleColorTemperatureStrategy().setColorTemperature(600, 6, test_light));
64 53 }
65 54  
66   -TEST(SimpleColorTemperatureStrategy, alertTemperature) {
67   - using namespace ::testing;
68   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
69   - EXPECT_CALL(*handler,
70   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
71   - Json::Value(Json::objectValue), getBridgeIp(), 80))
72   - .Times(AtLeast(1))
73   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
74   - MockHueLight test_light(handler);
75   - EXPECT_CALL(test_light, refreshState())
76   - .Times(AtLeast(1))
77   - .WillRepeatedly(Return());
78   -
79   - test_light.getState()["state"]["colormode"] = "invalid";
80   - EXPECT_EQ(false,
81   - SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
82   -
83   - EXPECT_CALL(test_light, setColorTemperature(_, _))
84   - .Times(AtLeast(2))
85   - .WillOnce(Return(false))
86   - .WillRepeatedly(Return(true));
87   - test_light.getState()["state"]["colormode"] = "ct";
88   - test_light.getState()["state"]["on"] = true;
89   - test_light.getState()["state"]["ct"] = 200;
90   - EXPECT_EQ(false,
91   - SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
92   -
93   - EXPECT_CALL(test_light, alert())
94   - .Times(AtLeast(2))
95   - .WillOnce(Return(false))
96   - .WillRepeatedly(Return(true));
97   - EXPECT_EQ(false,
98   - SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
99   -
100   - EXPECT_EQ(true,
101   - SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
102   -
103   - EXPECT_CALL(test_light, OffNoRefresh(_))
104   - .Times(AtLeast(1))
105   - .WillRepeatedly(Return(true));
106   - test_light.getState()["state"]["on"] = false;
107   - EXPECT_EQ(true,
108   - SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
  55 +TEST(SimpleColorTemperatureStrategy, alertTemperature)
  56 +{
  57 + using namespace ::testing;
  58 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  59 + EXPECT_CALL(
  60 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  61 + .Times(AtLeast(1))
  62 + .WillRepeatedly(Return(nlohmann::json::object()));
  63 + MockHueLight test_light(handler);
  64 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  65 +
  66 + test_light.getState()["state"]["colormode"] = "invalid";
  67 + test_light.getState()["state"]["on"] = false;
  68 + EXPECT_EQ(false, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
  69 +
  70 + EXPECT_CALL(test_light, setColorTemperature(_, _))
  71 + .Times(AtLeast(2))
  72 + .WillOnce(Return(false))
  73 + .WillRepeatedly(Return(true));
  74 + test_light.getState()["state"]["colormode"] = "ct";
  75 + test_light.getState()["state"]["on"] = true;
  76 + test_light.getState()["state"]["ct"] = 200;
  77 + EXPECT_EQ(false, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
  78 +
  79 + EXPECT_CALL(test_light, alert()).Times(AtLeast(2)).WillOnce(Return(false)).WillRepeatedly(Return(true));
  80 + EXPECT_EQ(false, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
  81 +
  82 + EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
  83 +
  84 + EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
  85 + test_light.getState()["state"]["on"] = false;
  86 + EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
109 87 }
110 88  
111   -TEST(SimpleColorTemperatureStrategy, getColorTemperature) {
112   - using namespace ::testing;
113   - std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
114   - EXPECT_CALL(*handler,
115   - GETJson("/api/" + getBridgeUsername() + "/lights/1",
116   - Json::Value(Json::objectValue), getBridgeIp(), 80))
117   - .Times(AtLeast(1))
118   - .WillRepeatedly(Return(Json::Value(Json::objectValue)));
119   - MockHueLight test_light(handler);
120   - EXPECT_CALL(test_light, refreshState())
121   - .Times(AtLeast(1))
122   - .WillRepeatedly(Return());
123   -
124   - test_light.getState()["state"]["ct"] = 200;
125   - EXPECT_EQ(200,
126   - SimpleColorTemperatureStrategy().getColorTemperature(test_light));
127   - test_light.getState()["state"]["ct"] = 500;
128   - EXPECT_EQ(500, SimpleColorTemperatureStrategy().getColorTemperature(
129   - static_cast<const HueLight>(test_light)));
  89 +TEST(SimpleColorTemperatureStrategy, getColorTemperature)
  90 +{
  91 + using namespace ::testing;
  92 + std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
  93 + EXPECT_CALL(
  94 + *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))
  95 + .Times(AtLeast(1))
  96 + .WillRepeatedly(Return(nlohmann::json::object()));
  97 + MockHueLight test_light(handler);
  98 + EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());
  99 +
  100 + test_light.getState()["state"]["ct"] = 200;
  101 + EXPECT_EQ(200, SimpleColorTemperatureStrategy().getColorTemperature(test_light));
  102 + test_light.getState()["state"]["ct"] = 500;
  103 + EXPECT_EQ(500, SimpleColorTemperatureStrategy().getColorTemperature(static_cast<const HueLight>(test_light)));
130 104 }
... ...
hueplusplus/test/test_UPnP.cpp
1 1 #include <gmock/gmock.h>
2 2 #include <gtest/gtest.h>
3 3  
4   -#include "../include/UPnP.h"
5   -#include "../include/json/json.h"
6   -#include "mocks/mock_HttpHandler.h"
  4 +#include "iostream"
7 5 #include "testhelper.h"
8 6  
9   -#include "iostream"
  7 +#include "../include/UPnP.h"
  8 +#include "../include/json/json.hpp"
  9 +#include "mocks/mock_HttpHandler.h"
10 10  
11   -const std::vector<std::pair<std::string, std::string>> expected_uplug_dev = {
12   - {"http://192.168.2.1:1900/gatedesc.xml",
13   - "Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19"},
14   - {"http://192.168.2.116:80/description.xml",
15   - "Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0"}};
  11 +const std::vector<std::pair<std::string, std::string>> expected_uplug_dev
  12 + = {{"http://192.168.2.1:1900/gatedesc.xml", "Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19"},
  13 + {"http://192.168.2.116:80/description.xml", "Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0"}};
16 14  
17   -TEST(UPnP, getDevices) {
18   - std::shared_ptr<MockHttpHandler> handler =
19   - std::make_shared<MockHttpHandler>();
20   - EXPECT_CALL(
21   - *handler,
22   - sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
23   - "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
24   - "239.255.255.250", 1900, 5))
25   - .Times(1)
26   - .WillRepeatedly(::testing::Return(getMulticastReply()));
  15 +TEST(UPnP, getDevices)
  16 +{
  17 + std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();
  18 + EXPECT_CALL(*handler,
  19 + sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
  20 + "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
  21 + "239.255.255.250", 1900, 5))
  22 + .Times(1)
  23 + .WillRepeatedly(::testing::Return(getMulticastReply()));
27 24  
28   - UPnP uplug;
29   - std::vector<std::pair<std::string, std::string>> foundDevices =
30   - uplug.getDevices(handler);
  25 + UPnP uplug;
  26 + std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(handler);
31 27  
32   - EXPECT_EQ(foundDevices, expected_uplug_dev);
  28 + EXPECT_EQ(foundDevices, expected_uplug_dev);
33 29 }
... ...
hueplusplus/test/testhelper.h 100755 → 100644
1 1 #ifndef _TEST_HELPER_H
2 2 #define _TEST_HELPER_H
3 3  
4   -inline std::string getBridgeIp() {
5   - return "192.168.2.116"; //!< IP-Address of the fake hue bridge in dotted
6   - //!< decimal notation like "192.168.2.1"
  4 +inline std::string getBridgeIp()
  5 +{
  6 + return "192.168.2.116"; //!< IP-Address of the fake hue bridge in dotted
  7 + //!< decimal notation like "192.168.2.1"
7 8 }
8 9  
9 10 inline int getBridgePort() {
10   - return 80;
  11 + return 80;
11 12 }
12 13  
13 14 inline std::string getBridgeUsername() {
14   - return "83b7780291a6ceffbe0bd049104df"; //!< Username that is ussed to access
15   - //!< the fake hue bridge
  15 + return "83b7780291a6ceffbe0bd049104df"; //!< Username that is used to access
  16 + //!< the fake hue bridge
16 17 }
17   -inline std::string getBridgeId() { return "111111FFFE11E111"; }
18   -inline std::string getBridgeUuid() {
19   - return "1f111f11-da11-11e1-1b11-11111111e111";
  18 +inline std::string getBridgeId()
  19 +{
  20 + return "111111FFFE11E111";
  21 +}
  22 +inline std::string getBridgeUuid()
  23 +{
  24 + return "1f111f11-da11-11e1-1b11-11111111e111";
  25 +}
  26 +inline std::string getBridgeMac()
  27 +{
  28 + return "11111111e111";
20 29 }
21   -inline std::string getBridgeMac() { return "11111111e111"; }
22 30  
23   -inline std::string getBridgeXml() {
24   - return R"xml(<?xml version="1.0" encoding="UTF-8" ?>
  31 +inline std::string getBridgeXml()
  32 +{
  33 + return R"xml(<?xml version="1.0" encoding="UTF-8" ?>
25 34 <root xmlns="urn:schemas-upnp-org:device-1-0">
26 35 <specVersion>
27 36 <major>1</major>
... ... @@ -53,198 +62,198 @@ inline std::string getBridgeXml() {
53 62 </root>)xml";
54 63 }
55 64  
56   -inline std::vector<std::string> getMulticastReply() {
57   - return {
58   - "HTTP/1.1 200 OK\r\n"
59   - "CACHE-CONTROL: max-age=300\r\n"
60   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
61   - "EXT:\r\n"
62   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
63   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
64   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
65   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
66   - "X-User-Agent: redsonic\r\n"
67   - "ST: upnp:rootdevice\r\n"
68   - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::upnp:rootdevice",
69   -
70   - "HTTP/1.1 200 OK\r\n"
71   - "CACHE-CONTROL: max-age=300\r\n"
72   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
73   - "EXT:\r\n"
74   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
75   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
76   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
77   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
78   - "X-User-Agent: redsonic\r\n"
79   - "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n"
80   - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00",
81   -
82   - "HTTP/1.1 200 OK\r\n"
83   - "CACHE-CONTROL: max-age=300\r\n"
84   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
85   - "EXT:\r\n"
86   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
87   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
88   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
89   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
90   - "X-User-Agent: redsonic\r\n"
91   - "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
92   - "USN: "
93   - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:"
94   - "InternetGatewayDevice:1",
95   -
96   - "HTTP/1.1 200 OK\r\n"
97   - "CACHE-CONTROL: max-age=300\r\n"
98   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
99   - "EXT:\r\n"
100   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
101   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
102   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
103   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
104   - "X-User-Agent: redsonic\r\n"
105   - "ST: urn:schemas-upnp-org:service:Layer3Forwarding:1\r\n"
106   - "USN: "
107   - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:"
108   - "Layer3Forwarding:1",
109   -
110   - "HTTP/1.1 200 OK\r\n"
111   - "CACHE-CONTROL: max-age=300\r\n"
112   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
113   - "EXT:\r\n"
114   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
115   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
116   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
117   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
118   - "X-User-Agent: redsonic\r\n"
119   - "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n"
120   - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00",
121   -
122   - "HTTP/1.1 200 OK\r\n"
123   - "CACHE-CONTROL: max-age=300\r\n"
124   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
125   - "EXT:\r\n"
126   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
127   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
128   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
129   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
130   - "X-User-Agent: redsonic\r\n"
131   - "ST: urn:schemas-upnp-org:device:WANDevice:1\r\n"
132   - "USN: "
133   - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:"
134   - "WANDevice:1",
135   -
136   - "HTTP/1.1 200 OK\r\n"
137   - "CACHE-CONTROL: max-age=300\r\n"
138   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
139   - "EXT:\r\n"
140   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
141   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
142   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
143   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
144   - "X-User-Agent: redsonic\r\n"
145   - "ST: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\r\n"
146   - "USN: "
147   - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:"
148   - "WANCommonInterfaceConfig:1",
149   -
150   - "HTTP/1.1 200 OK\r\n"
151   - "CACHE-CONTROL: max-age=300\r\n"
152   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
153   - "EXT:\r\n"
154   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
155   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
156   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
157   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
158   - "X-User-Agent: redsonic\r\n"
159   - "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n"
160   - "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00",
161   -
162   - "HTTP/1.1 200 OK\r\n"
163   - "CACHE-CONTROL: max-age=300\r\n"
164   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
165   - "EXT:\r\n"
166   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
167   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
168   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
169   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
170   - "X-User-Agent: redsonic\r\n"
171   - "ST: urn:schemas-upnp-org:device:WANConnectionDevice:1\r\n"
172   - "USN: "
173   - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:"
174   - "WANConnectionDevice:1",
175   -
176   - "HTTP/1.1 200 OK\r\n"
177   - "CACHE-CONTROL: max-age=300\r\n"
178   - "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
179   - "EXT:\r\n"
180   - "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
181   - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
182   - "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
183   - "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
184   - "X-User-Agent: redsonic\r\n"
185   - "ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n"
186   - "USN: "
187   - "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:"
188   - "WANIPConnection:1",
189   -
190   - "HTTP/1.1 200 OK\r\n"
191   - "HOST: 239.255.255.250:1900\r\n"
192   - "EXT:\r\n"
193   - "CACHE-CONTROL: max-age=100\r\n"
194   - "LOCATION: http://192.168.2.116:80/description.xml\r\n"
195   - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
196   - "hue-bridgeid: 111111FFFE11E111\r\n"
197   - "ST: upnp:rootdevice\r\n"
198   - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice",
199   -
200   - "HTTP/1.1 200 OK\r\n"
201   - "HOST: 239.255.255.250:1900\r\n"
202   - "EXT:\r\n"
203   - "CACHE-CONTROL: max-age=100\r\n"
204   - "LOCATION: http://192.168.2.116:80/description.xml\r\n"
205   - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
206   - "hue-bridgeid: 111111FFFE11E111\r\n"
207   - "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n"
208   - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111",
209   -
210   - "HTTP/1.1 200 OK\r\n"
211   - "HOST: 239.255.255.250:1900\r\n"
212   - "EXT:\r\n"
213   - "CACHE-CONTROL: max-age=100\r\n"
214   - "LOCATION: http://192.168.2.116:80/description.xml\r\n"
215   - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
216   - "hue-bridgeid: 111111FFFE11E111\r\n"
217   - "ST: urn:schemas-upnp-org:device:basic:1\r\n"
218   - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111",
219   -
220   - "HTTP/1.1 200 OK\r\n"
221   - "HOST: 239.255.255.250:1900\r\n"
222   - "EXT:\r\n"
223   - "CACHE-CONTROL: max-age=100\r\n"
224   - "LOCATION: http://192.168.2.116:80/description.xml\r\n"
225   - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
226   - "hue-bridgeid: 111111FFFE11E111\r\n"
227   - "ST: upnp:rootdevice\r\n"
228   - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice",
229   -
230   - "HTTP/1.1 200 OK\r\n"
231   - "HOST: 239.255.255.250:1900\r\n"
232   - "EXT:\r\n"
233   - "CACHE-CONTROL: max-age=100\r\n"
234   - "LOCATION: http://192.168.2.116:80/description.xml\r\n"
235   - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
236   - "hue-bridgeid: 111111FFFE11E111\r\n"
237   - "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n"
238   - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111",
239   -
240   - "HTTP/1.1 200 OK\r\n"
241   - "HOST: 239.255.255.250:1900\r\n"
242   - "EXT:\r\n"
243   - "CACHE-CONTROL: max-age=100\r\n"
244   - "LOCATION: http://192.168.2.116:80/description.xml\r\n"
245   - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
246   - "hue-bridgeid: 111111FFFE11E111\r\n"
247   - "ST: urn:schemas-upnp-org:device:basic:1\r\n"
248   - "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111"};
  65 +inline std::vector<std::string> getMulticastReply()
  66 +{
  67 + return { "HTTP/1.1 200 OK\r\n"
  68 + "CACHE-CONTROL: max-age=300\r\n"
  69 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  70 + "EXT:\r\n"
  71 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  72 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  73 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  74 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  75 + "X-User-Agent: redsonic\r\n"
  76 + "ST: upnp:rootdevice\r\n"
  77 + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::upnp:rootdevice",
  78 +
  79 + "HTTP/1.1 200 OK\r\n"
  80 + "CACHE-CONTROL: max-age=300\r\n"
  81 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  82 + "EXT:\r\n"
  83 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  84 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  85 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  86 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  87 + "X-User-Agent: redsonic\r\n"
  88 + "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n"
  89 + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00",
  90 +
  91 + "HTTP/1.1 200 OK\r\n"
  92 + "CACHE-CONTROL: max-age=300\r\n"
  93 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  94 + "EXT:\r\n"
  95 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  96 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  97 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  98 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  99 + "X-User-Agent: redsonic\r\n"
  100 + "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
  101 + "USN: "
  102 + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:"
  103 + "InternetGatewayDevice:1",
  104 +
  105 + "HTTP/1.1 200 OK\r\n"
  106 + "CACHE-CONTROL: max-age=300\r\n"
  107 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  108 + "EXT:\r\n"
  109 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  110 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  111 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  112 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  113 + "X-User-Agent: redsonic\r\n"
  114 + "ST: urn:schemas-upnp-org:service:Layer3Forwarding:1\r\n"
  115 + "USN: "
  116 + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:"
  117 + "Layer3Forwarding:1",
  118 +
  119 + "HTTP/1.1 200 OK\r\n"
  120 + "CACHE-CONTROL: max-age=300\r\n"
  121 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  122 + "EXT:\r\n"
  123 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  124 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  125 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  126 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  127 + "X-User-Agent: redsonic\r\n"
  128 + "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n"
  129 + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00",
  130 +
  131 + "HTTP/1.1 200 OK\r\n"
  132 + "CACHE-CONTROL: max-age=300\r\n"
  133 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  134 + "EXT:\r\n"
  135 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  136 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  137 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  138 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  139 + "X-User-Agent: redsonic\r\n"
  140 + "ST: urn:schemas-upnp-org:device:WANDevice:1\r\n"
  141 + "USN: "
  142 + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:"
  143 + "WANDevice:1",
  144 +
  145 + "HTTP/1.1 200 OK\r\n"
  146 + "CACHE-CONTROL: max-age=300\r\n"
  147 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  148 + "EXT:\r\n"
  149 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  150 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  151 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  152 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  153 + "X-User-Agent: redsonic\r\n"
  154 + "ST: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\r\n"
  155 + "USN: "
  156 + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:"
  157 + "WANCommonInterfaceConfig:1",
  158 +
  159 + "HTTP/1.1 200 OK\r\n"
  160 + "CACHE-CONTROL: max-age=300\r\n"
  161 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  162 + "EXT:\r\n"
  163 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  164 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  165 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  166 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  167 + "X-User-Agent: redsonic\r\n"
  168 + "ST: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00\r\n"
  169 + "USN: uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00",
  170 +
  171 + "HTTP/1.1 200 OK\r\n"
  172 + "CACHE-CONTROL: max-age=300\r\n"
  173 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  174 + "EXT:\r\n"
  175 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  176 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  177 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  178 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  179 + "X-User-Agent: redsonic\r\n"
  180 + "ST: urn:schemas-upnp-org:device:WANConnectionDevice:1\r\n"
  181 + "USN: "
  182 + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:device:"
  183 + "WANConnectionDevice:1",
  184 +
  185 + "HTTP/1.1 200 OK\r\n"
  186 + "CACHE-CONTROL: max-age=300\r\n"
  187 + "DATE: Wed, 21 Jan 1970 05:42:21 GMT\r\n"
  188 + "EXT:\r\n"
  189 + "LOCATION: http://192.168.2.1:1900/gatedesc.xml\r\n"
  190 + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
  191 + "01-NLS: 000c0000-0dd0-00b0-0da0-00a000e000c0\r\n"
  192 + "SERVER: Linux/2.6.36, UPnP/1.0, Portable SDK for UPnP devices/1.6.19\r\n"
  193 + "X-User-Agent: redsonic\r\n"
  194 + "ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n"
  195 + "USN: "
  196 + "uuid:0f0000b0-f0da-0ad0-00b0-0000000fdf00::urn:schemas-upnp-org:service:"
  197 + "WANIPConnection:1",
  198 +
  199 + "HTTP/1.1 200 OK\r\n"
  200 + "HOST: 239.255.255.250:1900\r\n"
  201 + "EXT:\r\n"
  202 + "CACHE-CONTROL: max-age=100\r\n"
  203 + "LOCATION: http://192.168.2.116:80/description.xml\r\n"
  204 + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
  205 + "hue-bridgeid: 111111FFFE11E111\r\n"
  206 + "ST: upnp:rootdevice\r\n"
  207 + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice",
  208 +
  209 + "HTTP/1.1 200 OK\r\n"
  210 + "HOST: 239.255.255.250:1900\r\n"
  211 + "EXT:\r\n"
  212 + "CACHE-CONTROL: max-age=100\r\n"
  213 + "LOCATION: http://192.168.2.116:80/description.xml\r\n"
  214 + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
  215 + "hue-bridgeid: 111111FFFE11E111\r\n"
  216 + "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n"
  217 + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111",
  218 +
  219 + "HTTP/1.1 200 OK\r\n"
  220 + "HOST: 239.255.255.250:1900\r\n"
  221 + "EXT:\r\n"
  222 + "CACHE-CONTROL: max-age=100\r\n"
  223 + "LOCATION: http://192.168.2.116:80/description.xml\r\n"
  224 + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
  225 + "hue-bridgeid: 111111FFFE11E111\r\n"
  226 + "ST: urn:schemas-upnp-org:device:basic:1\r\n"
  227 + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111",
  228 +
  229 + "HTTP/1.1 200 OK\r\n"
  230 + "HOST: 239.255.255.250:1900\r\n"
  231 + "EXT:\r\n"
  232 + "CACHE-CONTROL: max-age=100\r\n"
  233 + "LOCATION: http://192.168.2.116:80/description.xml\r\n"
  234 + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
  235 + "hue-bridgeid: 111111FFFE11E111\r\n"
  236 + "ST: upnp:rootdevice\r\n"
  237 + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111::upnp:rootdevice",
  238 +
  239 + "HTTP/1.1 200 OK\r\n"
  240 + "HOST: 239.255.255.250:1900\r\n"
  241 + "EXT:\r\n"
  242 + "CACHE-CONTROL: max-age=100\r\n"
  243 + "LOCATION: http://192.168.2.116:80/description.xml\r\n"
  244 + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
  245 + "hue-bridgeid: 111111FFFE11E111\r\n"
  246 + "ST: uuid:1f111f11-da11-11e1-1b11-11111111e111\r\n"
  247 + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111",
  248 +
  249 + "HTTP/1.1 200 OK\r\n"
  250 + "HOST: 239.255.255.250:1900\r\n"
  251 + "EXT:\r\n"
  252 + "CACHE-CONTROL: max-age=100\r\n"
  253 + "LOCATION: http://192.168.2.116:80/description.xml\r\n"
  254 + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.21.0\r\n"
  255 + "hue-bridgeid: 111111FFFE11E111\r\n"
  256 + "ST: urn:schemas-upnp-org:device:basic:1\r\n"
  257 + "USN: uuid:1f111f11-da11-11e1-1b11-11111111e111" };
249 258 }
250 259 #endif
... ...