Commit 47a624a2cb0cf48f9c504a9f2aa400d14ab80d2b

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent f9a1f744

Add HueCommandAPI as a layer over HttpHandler.

- Used to enforce a timeout between api requests, closes #15
hueplusplus/CMakeLists.txt
@@ -3,6 +3,7 @@ set(hueplusplus_SOURCES @@ -3,6 +3,7 @@ set(hueplusplus_SOURCES
3 ${CMAKE_CURRENT_SOURCE_DIR}/ExtendedColorHueStrategy.cpp 3 ${CMAKE_CURRENT_SOURCE_DIR}/ExtendedColorHueStrategy.cpp
4 ${CMAKE_CURRENT_SOURCE_DIR}/ExtendedColorTemperatureStrategy.cpp 4 ${CMAKE_CURRENT_SOURCE_DIR}/ExtendedColorTemperatureStrategy.cpp
5 ${CMAKE_CURRENT_SOURCE_DIR}/Hue.cpp 5 ${CMAKE_CURRENT_SOURCE_DIR}/Hue.cpp
  6 + ${CMAKE_CURRENT_SOURCE_DIR}/HueCommandAPI.cpp
6 ${CMAKE_CURRENT_SOURCE_DIR}/HueLight.cpp 7 ${CMAKE_CURRENT_SOURCE_DIR}/HueLight.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp.cpp 8 ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp.cpp
8 ${CMAKE_CURRENT_SOURCE_DIR}/SimpleBrightnessStrategy.cpp 9 ${CMAKE_CURRENT_SOURCE_DIR}/SimpleBrightnessStrategy.cpp
hueplusplus/Hue.cpp
1 /** 1 /**
2 - \file Hue.cpp  
3 - Copyright Notice\n  
4 - Copyright (C) 2017 Jan Rogall - developer\n  
5 - Copyright (C) 2017 Moritz Wirger - developer\n 2 + \file Hue.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 #include "include/Hue.h" 20 #include "include/Hue.h"
@@ -38,270 +38,267 @@ HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler @@ -38,270 +38,267 @@ HueFinder::HueFinder(std::shared_ptr<const IHttpHandler> handler) : http_handler
38 38
39 std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const 39 std::vector<HueFinder::HueIdentification> HueFinder::FindBridges() const
40 { 40 {
41 - UPnP uplug;  
42 - std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(http_handler); 41 + UPnP uplug;
  42 + std::vector<std::pair<std::string, std::string>> foundDevices = uplug.getDevices(http_handler);
43 43
44 - //Does not work  
45 - std::regex manufRegex("<manufacturer>Royal Philips Electronics</manufacturer>");  
46 - std::regex manURLRegex("<manufacturerURL>http://www\\.philips\\.com</manufacturerURL>");  
47 - std::regex modelRegex("<modelName>Philips hue bridge[^<]*</modelName>");  
48 - std::regex serialRegex("<serialNumber>(\\w+)</serialNumber>");  
49 - std::vector<HueIdentification> foundBridges;  
50 - for (const std::pair<std::string, std::string> &p : foundDevices)  
51 - {  
52 - size_t found = p.second.find("IpBridge");  
53 - if (found != std::string::npos)  
54 - {  
55 - HueIdentification bridge;  
56 - size_t start = p.first.find("//") + 2;  
57 - size_t length = p.first.find(":", start) - start;  
58 - bridge.ip = p.first.substr(start, length);  
59 - std::string desc = http_handler->GETString("/description.xml", "application/xml", "", bridge.ip);  
60 - std::smatch matchResult;  
61 - if (std::regex_search(desc, manufRegex) && std::regex_search(desc, manURLRegex) && std::regex_search(desc, modelRegex) && std::regex_search(desc, matchResult, serialRegex))  
62 - {  
63 - //The string matches  
64 - //Get 1st submatch (0 is whole match)  
65 - bridge.mac = matchResult[1].str();  
66 - foundBridges.push_back(std::move(bridge));  
67 - }  
68 - //break;  
69 - }  
70 - }  
71 - return foundBridges; 44 + //Does not work
  45 + std::regex manufRegex("<manufacturer>Royal Philips Electronics</manufacturer>");
  46 + std::regex manURLRegex("<manufacturerURL>http://www\\.philips\\.com</manufacturerURL>");
  47 + std::regex modelRegex("<modelName>Philips hue bridge[^<]*</modelName>");
  48 + std::regex serialRegex("<serialNumber>(\\w+)</serialNumber>");
  49 + std::vector<HueIdentification> foundBridges;
  50 + for (const std::pair<std::string, std::string> &p : foundDevices)
  51 + {
  52 + size_t found = p.second.find("IpBridge");
  53 + if (found != std::string::npos)
  54 + {
  55 + HueIdentification bridge;
  56 + size_t start = p.first.find("//") + 2;
  57 + size_t length = p.first.find(":", start) - start;
  58 + bridge.ip = p.first.substr(start, length);
  59 + std::string desc = http_handler->GETString("/description.xml", "application/xml", "", bridge.ip);
  60 + std::smatch matchResult;
  61 + if (std::regex_search(desc, manufRegex) && std::regex_search(desc, manURLRegex) && std::regex_search(desc, modelRegex) && std::regex_search(desc, matchResult, serialRegex))
  62 + {
  63 + //The string matches
  64 + //Get 1st submatch (0 is whole match)
  65 + bridge.mac = matchResult[1].str();
  66 + foundBridges.push_back(std::move(bridge));
  67 + }
  68 + //break;
  69 + }
  70 + }
  71 + return foundBridges;
72 } 72 }
73 73
74 74
75 Hue HueFinder::GetBridge(const HueIdentification& identification) 75 Hue HueFinder::GetBridge(const HueIdentification& identification)
76 { 76 {
77 - Hue bridge(identification.ip, "", http_handler);  
78 - auto pos = usernames.find(identification.mac);  
79 - if (pos != usernames.end())  
80 - {  
81 - bridge.username = pos->second;  
82 - }  
83 - else  
84 - {  
85 - bridge.requestUsername(identification.ip);  
86 - if (bridge.getUsername().empty() || bridge.getUsername() == "")  
87 - {  
88 - std::cerr << "Failed to request username for ip " << identification.ip << std::endl;  
89 - throw std::runtime_error("Failed to request username!");  
90 - }  
91 - else  
92 - {  
93 - AddUsername(identification.mac, bridge.getUsername());  
94 - }  
95 - }  
96 - return bridge; 77 + Hue bridge(identification.ip, "", http_handler);
  78 + auto pos = usernames.find(identification.mac);
  79 + if (pos != usernames.end())
  80 + {
  81 + bridge.username = pos->second;
  82 + }
  83 + else
  84 + {
  85 + bridge.requestUsername(identification.ip);
  86 + if (bridge.getUsername().empty() || bridge.getUsername() == "")
  87 + {
  88 + std::cerr << "Failed to request username for ip " << identification.ip << std::endl;
  89 + throw std::runtime_error("Failed to request username!");
  90 + }
  91 + else
  92 + {
  93 + AddUsername(identification.mac, bridge.getUsername());
  94 + }
  95 + }
  96 + return bridge;
97 } 97 }
98 98
99 void HueFinder::AddUsername(const std::string& mac, const std::string& username) 99 void HueFinder::AddUsername(const std::string& mac, const std::string& username)
100 { 100 {
101 - usernames[mac] = username; 101 + usernames[mac] = username;
102 } 102 }
103 103
104 const std::map<std::string, std::string>& HueFinder::GetAllUsernames() const 104 const std::map<std::string, std::string>& HueFinder::GetAllUsernames() const
105 { 105 {
106 - return usernames; 106 + return usernames;
107 } 107 }
108 108
109 109
110 -Hue::Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler) :  
111 -ip(ip),  
112 -username(username),  
113 -http_handler(std::move(handler)) 110 +Hue::Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler)
  111 + : ip(ip),
  112 + username(username),
  113 + http_handler(std::move(handler)),
  114 + commands(ip, username, http_handler)
114 { 115 {
115 - simpleBrightnessStrategy = std::make_shared<SimpleBrightnessStrategy>();  
116 - simpleColorHueStrategy = std::make_shared<SimpleColorHueStrategy>();  
117 - extendedColorHueStrategy = std::make_shared<ExtendedColorHueStrategy>();  
118 - simpleColorTemperatureStrategy = std::make_shared<SimpleColorTemperatureStrategy>();  
119 - extendedColorTemperatureStrategy = std::make_shared<ExtendedColorTemperatureStrategy>(); 116 + simpleBrightnessStrategy = std::make_shared<SimpleBrightnessStrategy>();
  117 + simpleColorHueStrategy = std::make_shared<SimpleColorHueStrategy>();
  118 + extendedColorHueStrategy = std::make_shared<ExtendedColorHueStrategy>();
  119 + simpleColorTemperatureStrategy = std::make_shared<SimpleColorTemperatureStrategy>();
  120 + extendedColorTemperatureStrategy = std::make_shared<ExtendedColorTemperatureStrategy>();
120 } 121 }
121 122
122 std::string Hue::getBridgeIP() 123 std::string Hue::getBridgeIP()
123 { 124 {
124 - return ip; 125 + return ip;
125 } 126 }
126 127
127 std::string Hue::requestUsername(const std::string& ip) 128 std::string Hue::requestUsername(const std::string& ip)
128 { 129 {
129 - std::cout << "Please press the link Button! You've got 35 secs!\n"; // when the link button was presed we got 30 seconds to get our username for control 130 + std::cout << "Please press the link Button! You've got 35 secs!\n"; // when the link button was presed we got 30 seconds to get our username for control
130 131
131 - Json::Value request;  
132 - request["devicetype"] = "HuePlusPlus#User"; 132 + Json::Value request;
  133 + request["devicetype"] = "HuePlusPlus#User";
133 134
134 - Json::Value answer;  
135 - std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();  
136 - std::chrono::steady_clock::time_point lastCheck;  
137 - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35))  
138 - {  
139 - if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1))  
140 - {  
141 - lastCheck = std::chrono::steady_clock::now();  
142 - answer = http_handler->POSTJson("/api", request, ip); 135 + Json::Value answer;
  136 + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
  137 + std::chrono::steady_clock::time_point lastCheck;
  138 + while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35))
  139 + {
  140 + if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1))
  141 + {
  142 + lastCheck = std::chrono::steady_clock::now();
  143 + answer = http_handler->POSTJson("/api", request, ip);
143 144
144 - if (answer[0]["success"] != Json::nullValue)  
145 - {  
146 - // [{"success":{"username": "<username>"}}]  
147 - username = answer[0]["success"]["username"].asString();  
148 - this->ip = ip;  
149 - std::cout << "Success! Link button was pressed!\n";  
150 - std::cout << "Username is \"" << username << "\"\n";  
151 - break;  
152 - }  
153 - if (answer[0]["error"] != Json::nullValue)  
154 - {  
155 - std::cout << "Link button not pressed!\n";  
156 - }  
157 - }  
158 - }  
159 - return username; 145 + if (answer[0]["success"] != Json::nullValue)
  146 + {
  147 + // [{"success":{"username": "<username>"}}]
  148 + username = answer[0]["success"]["username"].asString();
  149 + this->ip = ip;
  150 + std::cout << "Success! Link button was pressed!\n";
  151 + std::cout << "Username is \"" << username << "\"\n";
  152 + break;
  153 + }
  154 + if (answer[0]["error"] != Json::nullValue)
  155 + {
  156 + std::cout << "Link button not pressed!\n";
  157 + }
  158 + }
  159 + }
  160 + return username;
160 } 161 }
161 162
162 std::string Hue::getUsername() 163 std::string Hue::getUsername()
163 { 164 {
164 - return username; 165 + return username;
165 } 166 }
166 167
167 void Hue::setIP(const std::string ip) 168 void Hue::setIP(const std::string ip)
168 { 169 {
169 - this->ip = ip; 170 + this->ip = ip;
170 } 171 }
171 172
172 HueLight& Hue::getLight(int id) 173 HueLight& Hue::getLight(int id)
173 { 174 {
174 - auto pos = lights.find(id);  
175 - if(pos != lights.end())  
176 - {  
177 - pos->second.refreshState();  
178 - return pos->second;  
179 - }  
180 - refreshState();  
181 - if (!state["lights"].isMember(std::to_string(id)))  
182 - {  
183 - std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n";  
184 - throw(std::runtime_error("Error in Hue getLight(): light id is not valid"));  
185 - }  
186 - //std::cout << state["lights"][std::to_string(id)] << std::endl;  
187 - std::string type = state["lights"][std::to_string(id)]["modelid"].asString();  
188 - //std::cout << type << std::endl;  
189 - if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001")  
190 - {  
191 - // HueExtendedColorLight Gamut B  
192 - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy, http_handler);  
193 - light.colorType = ColorType::GAMUT_B;  
194 - lights.emplace(id, light);  
195 - return lights.find(id)->second;  
196 - }  
197 - else if (type == "LCT010" || type == "LCT011" || type == "LCT014" || type == "LLC020" || type == "LST002")  
198 - {  
199 - // HueExtendedColorLight Gamut C  
200 - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy, http_handler);  
201 - light.colorType = ColorType::GAMUT_C;  
202 - lights.emplace(id, light);  
203 - return lights.find(id)->second;  
204 - }  
205 - else if (type == "LST001" || type == "LLC006" || type == "LLC007" || type == "LLC010" || type == "LLC011" || type == "LLC012" || type == "LLC013")  
206 - {  
207 - // HueColorLight Gamut A  
208 - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, nullptr, simpleColorHueStrategy, http_handler);  
209 - light.colorType = ColorType::GAMUT_A;  
210 - lights.emplace(id, light);  
211 - return lights.find(id)->second;  
212 - }  
213 - else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014")  
214 - {  
215 - // HueDimmableLight No Color Type  
216 - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, nullptr, nullptr, http_handler);  
217 - light.colorType = ColorType::NONE;  
218 - lights.emplace(id, light);  
219 - return lights.find(id)->second;  
220 - }  
221 - else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004" || type == "LTW013" || type == "LTW014")  
222 - {  
223 - // HueTemperatureLight  
224 - HueLight light = HueLight(ip, username, id, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr, http_handler);  
225 - light.colorType = ColorType::TEMPERATURE;  
226 - lights.emplace(id, light);  
227 - return lights.find(id)->second;  
228 - }  
229 - std::cerr << "Could not determine HueLight type!\n";  
230 - throw(std::runtime_error("Could not determine HueLight type!")); 175 + auto pos = lights.find(id);
  176 + if (pos != lights.end())
  177 + {
  178 + pos->second.refreshState();
  179 + return pos->second;
  180 + }
  181 + refreshState();
  182 + if (!state["lights"].isMember(std::to_string(id)))
  183 + {
  184 + std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n";
  185 + throw(std::runtime_error("Error in Hue getLight(): light id is not valid"));
  186 + }
  187 + //std::cout << state["lights"][std::to_string(id)] << std::endl;
  188 + std::string type = state["lights"][std::to_string(id)]["modelid"].asString();
  189 + //std::cout << type << std::endl;
  190 + if (type == "LCT001" || type == "LCT002" || type == "LCT003" || type == "LCT007" || type == "LLM001")
  191 + {
  192 + // HueExtendedColorLight Gamut B
  193 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy);
  194 + light.colorType = ColorType::GAMUT_B;
  195 + lights.emplace(id, light);
  196 + return lights.find(id)->second;
  197 + }
  198 + else if (type == "LCT010" || type == "LCT011" || type == "LCT014" || type == "LLC020" || type == "LST002")
  199 + {
  200 + // HueExtendedColorLight Gamut C
  201 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, extendedColorHueStrategy);
  202 + light.colorType = ColorType::GAMUT_C;
  203 + lights.emplace(id, light);
  204 + return lights.find(id)->second;
  205 + }
  206 + else if (type == "LST001" || type == "LLC006" || type == "LLC007" || type == "LLC010" || type == "LLC011" || type == "LLC012" || type == "LLC013")
  207 + {
  208 + // HueColorLight Gamut A
  209 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, simpleColorHueStrategy);
  210 + light.colorType = ColorType::GAMUT_A;
  211 + lights.emplace(id, light);
  212 + return lights.find(id)->second;
  213 + }
  214 + else if (type == "LWB004" || type == "LWB006" || type == "LWB007" || type == "LWB010" || type == "LWB014")
  215 + {
  216 + // HueDimmableLight No Color Type
  217 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, nullptr, nullptr);
  218 + light.colorType = ColorType::NONE;
  219 + lights.emplace(id, light);
  220 + return lights.find(id)->second;
  221 + }
  222 + else if (type == "LLM010" || type == "LLM011" || type == "LLM012" || type == "LTW001" || type == "LTW004" || type == "LTW013" || type == "LTW014")
  223 + {
  224 + // HueTemperatureLight
  225 + HueLight light = HueLight(id, commands, simpleBrightnessStrategy, simpleColorTemperatureStrategy, nullptr);
  226 + light.colorType = ColorType::TEMPERATURE;
  227 + lights.emplace(id, light);
  228 + return lights.find(id)->second;
  229 + }
  230 + std::cerr << "Could not determine HueLight type!\n";
  231 + throw(std::runtime_error("Could not determine HueLight type!"));
231 } 232 }
232 233
233 bool Hue::removeLight(int id) 234 bool Hue::removeLight(int id)
234 { 235 {
235 - Json::Value result = http_handler->DELETEJson("/api/"+username+"/lights/"+std::to_string(id), Json::objectValue, ip);  
236 - bool success = result.isArray() && !result[0].isNull() && result[0].isMember("success") && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted";  
237 - if (success && lights.count(id) != 0)  
238 - {  
239 - lights.erase(id);  
240 - }  
241 - return success; 236 + Json::Value result = commands.DELETERequest("/lights/" + std::to_string(id), Json::objectValue);
  237 + bool success = result.isArray() && !result[0].isNull() && result[0].isMember("success") && result[0]["success"] == "/lights/" + std::to_string(id) + " deleted";
  238 + if (success && lights.count(id) != 0)
  239 + {
  240 + lights.erase(id);
  241 + }
  242 + return success;
242 } 243 }
243 244
244 std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights() 245 std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights()
245 { 246 {
246 - refreshState();  
247 - for (const auto& name : state["lights"].getMemberNames())  
248 - {  
249 - uint8_t id = std::stoi(name);  
250 - if(lights.count(id)<=0)  
251 - {  
252 - getLight(id);  
253 - }  
254 - }  
255 - std::vector<std::reference_wrapper<HueLight>> result;  
256 - for (auto& entry : lights)  
257 - {  
258 - result.emplace_back(entry.second);  
259 - }  
260 - return result; 247 + refreshState();
  248 + for (const auto& id : state["lights"].getMemberNames())
  249 + {
  250 + getLight(std::stoi(id));
  251 + }
  252 + std::vector<std::reference_wrapper<HueLight>> result;
  253 + for (auto& entry : lights)
  254 + {
  255 + result.emplace_back(entry.second);
  256 + }
  257 + return result;
261 } 258 }
262 259
263 bool Hue::lightExists(int id) 260 bool Hue::lightExists(int id)
264 { 261 {
265 - refreshState();  
266 - auto pos = lights.find(id);  
267 - if (pos != lights.end())  
268 - {  
269 - return true;  
270 - }  
271 - if (state["lights"].isMember(std::to_string(id)))  
272 - {  
273 - return true;  
274 - }  
275 - return false; 262 + refreshState();
  263 + auto pos = lights.find(id);
  264 + if (pos != lights.end())
  265 + {
  266 + return true;
  267 + }
  268 + if (state["lights"].isMember(std::to_string(id)))
  269 + {
  270 + return true;
  271 + }
  272 + return false;
276 } 273 }
277 274
278 bool Hue::lightExists(int id) const 275 bool Hue::lightExists(int id) const
279 { 276 {
280 - auto pos = lights.find(id);  
281 - if (pos != lights.end())  
282 - {  
283 - return true;  
284 - }  
285 - if (state["lights"].isMember(std::to_string(id)))  
286 - {  
287 - return true;  
288 - }  
289 - return false; 277 + auto pos = lights.find(id);
  278 + if (pos != lights.end())
  279 + {
  280 + return true;
  281 + }
  282 + if (state["lights"].isMember(std::to_string(id)))
  283 + {
  284 + return true;
  285 + }
  286 + return false;
290 } 287 }
291 288
292 void Hue::refreshState() 289 void Hue::refreshState()
293 { 290 {
294 - if (username.empty())  
295 - {  
296 - return;  
297 - }  
298 - Json::Value answer = http_handler->GETJson("/api/"+username, Json::objectValue, ip);  
299 - if (answer.isObject() && answer.isMember("lights"))  
300 - {  
301 - state = answer;  
302 - }  
303 - else  
304 - {  
305 - std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl;  
306 - } 291 + if (username.empty())
  292 + {
  293 + return;
  294 + }
  295 + Json::Value answer = commands.GETRequest("", Json::objectValue);
  296 + if (answer.isObject() && answer.isMember("lights"))
  297 + {
  298 + state = answer;
  299 + }
  300 + else
  301 + {
  302 + std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl;
  303 + }
307 } 304 }
hueplusplus/HueCommandAPI.cpp 0 โ†’ 100644
  1 +/**
  2 + \file HueCommandAPI.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2018 Jan Rogall - developer\n
  5 + Copyright (C) 2018 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\HueCommandAPI.h"
  21 +
  22 +#include <thread>
  23 +
  24 +HueCommandAPI::HueCommandAPI(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> httpHandler)
  25 + : ip(ip),
  26 + username(username),
  27 + httpHandler(std::move(httpHandler)),
  28 + timeout(new TimeoutData{std::chrono::steady_clock::now()})
  29 +{}
  30 +
  31 +Json::Value HueCommandAPI::PUTRequest(const std::string& path, const Json::Value& request) const
  32 +{
  33 + auto now = std::chrono::steady_clock::now();
  34 + std::lock_guard<std::mutex> lock(timeout->mutex);
  35 + if (timeout->timeout > now)
  36 + {
  37 + std::this_thread::sleep_until(timeout->timeout);
  38 + }
  39 + Json::Value v = httpHandler->PUTJson("/api/" + username + path, request, ip);
  40 + timeout->timeout = now + minDelay;
  41 +
  42 + return v;
  43 +}
  44 +
  45 +Json::Value HueCommandAPI::GETRequest(const std::string& path, const Json::Value& request) const
  46 +{
  47 + auto now = std::chrono::steady_clock::now();
  48 + std::lock_guard<std::mutex> lock(timeout->mutex);
  49 + if (timeout->timeout > now)
  50 + {
  51 + std::this_thread::sleep_until(timeout->timeout);
  52 + }
  53 + Json::Value v = httpHandler->GETJson("/api/" + username + path, request, ip);
  54 + timeout->timeout = now + minDelay;
  55 +
  56 + return v;
  57 +}
  58 +
  59 +Json::Value HueCommandAPI::DELETERequest(const std::string& path, const Json::Value& request) const
  60 +{
  61 + auto now = std::chrono::steady_clock::now();
  62 + std::lock_guard<std::mutex> lock(timeout->mutex);
  63 + if (timeout->timeout > now)
  64 + {
  65 + std::this_thread::sleep_until(timeout->timeout);
  66 + }
  67 + Json::Value v = httpHandler->DELETEJson("/api/" + username + path, request, ip);
  68 + timeout->timeout = now + minDelay;
  69 +
  70 + return v;
  71 +}
hueplusplus/HueLight.cpp
1 /** 1 /**
2 - \file HueLight.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 HueLight.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 #include "include/HueLight.h" 20 #include "include/HueLight.h"
@@ -27,250 +27,250 @@ @@ -27,250 +27,250 @@
27 27
28 bool HueLight::On(uint8_t transition) 28 bool HueLight::On(uint8_t transition)
29 { 29 {
30 - refreshState();  
31 - return OnNoRefresh(transition); 30 + refreshState();
  31 + return OnNoRefresh(transition);
32 } 32 }
33 33
34 bool HueLight::Off(uint8_t transition) 34 bool HueLight::Off(uint8_t transition)
35 { 35 {
36 - refreshState();  
37 - return OffNoRefresh(transition); 36 + refreshState();
  37 + return OffNoRefresh(transition);
38 } 38 }
39 39
40 bool HueLight::isOn() 40 bool HueLight::isOn()
41 { 41 {
42 - refreshState();  
43 - return state["state"]["on"].asBool(); 42 + refreshState();
  43 + return state["state"]["on"].asBool();
44 } 44 }
45 45
46 bool HueLight::isOn() const 46 bool HueLight::isOn() const
47 { 47 {
48 - return state["state"]["on"].asBool(); 48 + return state["state"]["on"].asBool();
49 } 49 }
50 50
51 int HueLight::getId() const 51 int HueLight::getId() const
52 { 52 {
53 - return id; 53 + return id;
54 } 54 }
55 55
56 std::string HueLight::getType() const 56 std::string HueLight::getType() const
57 { 57 {
58 - return state["type"].asString(); 58 + return state["type"].asString();
59 } 59 }
60 60
61 std::string HueLight::getName() 61 std::string HueLight::getName()
62 { 62 {
63 - refreshState();  
64 - return state["name"].asString(); 63 + refreshState();
  64 + return state["name"].asString();
65 } 65 }
66 66
67 std::string HueLight::getName() const 67 std::string HueLight::getName() const
68 { 68 {
69 - return state["name"].asString(); 69 + return state["name"].asString();
70 } 70 }
71 71
72 std::string HueLight::getModelId() const 72 std::string HueLight::getModelId() const
73 { 73 {
74 - return state["modelid"].asString(); 74 + return state["modelid"].asString();
75 } 75 }
76 76
77 std::string HueLight::getUId() const 77 std::string HueLight::getUId() const
78 { 78 {
79 - if (state.isMember("uniqueid"))  
80 - {  
81 - return state["uniqueid"].asString();  
82 - }  
83 - return std::string(); 79 + if (state.isMember("uniqueid"))
  80 + {
  81 + return state["uniqueid"].asString();
  82 + }
  83 + return std::string();
84 } 84 }
85 85
86 std::string HueLight::getManufacturername() const 86 std::string HueLight::getManufacturername() const
87 { 87 {
88 - if (state.isMember("manufacturername"))  
89 - {  
90 - return state["manufacturername"].asString();  
91 - }  
92 - return std::string(); 88 + if (state.isMember("manufacturername"))
  89 + {
  90 + return state["manufacturername"].asString();
  91 + }
  92 + return std::string();
93 } 93 }
94 94
95 std::string HueLight::getProductname() const 95 std::string HueLight::getProductname() const
96 { 96 {
97 - if (state.isMember("productname"))  
98 - {  
99 - return state["productname"].asString();  
100 - }  
101 - return std::string(); 97 + if (state.isMember("productname"))
  98 + {
  99 + return state["productname"].asString();
  100 + }
  101 + return std::string();
102 } 102 }
103 103
104 std::string HueLight::getLuminaireUId() const 104 std::string HueLight::getLuminaireUId() const
105 { 105 {
106 - if (state.isMember("luminaireuniqueid"))  
107 - {  
108 - return state["luminaireuniqueid"].asString();  
109 - }  
110 - return std::string(); 106 + if (state.isMember("luminaireuniqueid"))
  107 + {
  108 + return state["luminaireuniqueid"].asString();
  109 + }
  110 + return std::string();
111 } 111 }
112 112
113 std::string HueLight::getSwVersion() 113 std::string HueLight::getSwVersion()
114 { 114 {
115 - refreshState();  
116 - return state["swversion"].asString(); 115 + refreshState();
  116 + return state["swversion"].asString();
117 } 117 }
118 118
119 std::string HueLight::getSwVersion() const 119 std::string HueLight::getSwVersion() const
120 { 120 {
121 - return state["swversion"].asString(); 121 + return state["swversion"].asString();
122 } 122 }
123 123
124 bool HueLight::setName(const std::string& name) 124 bool HueLight::setName(const std::string& name)
125 { 125 {
126 - Json::Value request(Json::objectValue);  
127 - request["name"] = name;  
128 - Json::Value reply = SendPutRequest(request, "/name"); 126 + Json::Value request(Json::objectValue);
  127 + request["name"] = name;
  128 + Json::Value reply = SendPutRequest(request, "/name");
129 129
130 - //Check whether request was successful  
131 - return !reply[0].isNull() && reply[0].isMember("success") && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name; 130 + //Check whether request was successful
  131 + return !reply[0].isNull() && reply[0].isMember("success") && reply[0]["success"]["/lights/" + std::to_string(id) + "/name"] == name;
132 } 132 }
133 133
134 ColorType HueLight::getColorType() const 134 ColorType HueLight::getColorType() const
135 { 135 {
136 - return colorType; 136 + return colorType;
137 } 137 }
138 138
139 unsigned int HueLight::KelvinToMired(unsigned int kelvin) const 139 unsigned int HueLight::KelvinToMired(unsigned int kelvin) const
140 { 140 {
141 - return int(0.5f + (1000000 / kelvin)); 141 + return int(0.5f + (1000000 / kelvin));
142 } 142 }
143 143
144 unsigned int HueLight::MiredToKelvin(unsigned int mired) const 144 unsigned int HueLight::MiredToKelvin(unsigned int mired) const
145 { 145 {
146 - return int(0.5f + (1000000 / mired)); 146 + return int(0.5f + (1000000 / mired));
147 } 147 }
148 148
149 bool HueLight::alert() 149 bool HueLight::alert()
150 { 150 {
151 - Json::Value request;  
152 - request["alert"] = "select"; 151 + Json::Value request;
  152 + request["alert"] = "select";
153 153
154 - Json::Value reply = SendPutRequest(request, "/state"); 154 + Json::Value reply = SendPutRequest(request, "/state");
155 155
156 - if (reply[0]["success"]["/lights/" + std::to_string(id) + "/state/alert"].asString() == "select")  
157 - {  
158 - return true;  
159 - } 156 + if (reply[0]["success"]["/lights/" + std::to_string(id) + "/state/alert"].asString() == "select")
  157 + {
  158 + return true;
  159 + }
160 160
161 - return false; 161 + return false;
162 } 162 }
163 163
164 -HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const IHttpHandler> handler)  
165 - : HueLight(ip, username, id, nullptr, nullptr, nullptr, handler) 164 +HueLight::HueLight(int id, const HueCommandAPI& commands)
  165 + : HueLight(id, commands, nullptr, nullptr, nullptr)
166 {} 166 {}
167 167
168 -HueLight::HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::shared_ptr<const IHttpHandler> handler)  
169 - : ip(ip),  
170 - username(username),  
171 - id(id),  
172 - brightnessStrategy(std::move(brightnessStrategy)),  
173 - colorTemperatureStrategy(std::move(colorTempStrategy)),  
174 - colorHueStrategy(std::move(colorHueStrategy)),  
175 - http_handler(std::move(handler)) 168 +HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy)
  169 + : ip(ip),
  170 + username(username),
  171 + id(id),
  172 + brightnessStrategy(std::move(brightnessStrategy)),
  173 + colorTemperatureStrategy(std::move(colorTempStrategy)),
  174 + colorHueStrategy(std::move(colorHueStrategy)),
  175 + commands(commands)
176 176
177 { 177 {
178 - refreshState(); 178 + refreshState();
179 } 179 }
180 180
181 bool HueLight::OnNoRefresh(uint8_t transition) 181 bool HueLight::OnNoRefresh(uint8_t transition)
182 { 182 {
183 - Json::Value request(Json::objectValue);  
184 - if (transition != 4)  
185 - {  
186 - request["transitiontime"] = transition;  
187 - }  
188 - if (state["state"]["on"].asBool() != true)  
189 - {  
190 - request["on"] = true;  
191 - }  
192 -  
193 - if (!request.isMember("on"))  
194 - {  
195 - //Nothing needs to be changed  
196 - return true;  
197 - }  
198 -  
199 - Json::Value reply = SendPutRequest(request, "/state");  
200 -  
201 - //Check whether request was successful  
202 - std::string path = "/lights/" + std::to_string(id) + "/state/";  
203 - bool success = true;  
204 - int i = 0;  
205 - if (success && request.isMember("transitiontime"))  
206 - {  
207 - //Check if success was sent and the value was changed  
208 - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt();  
209 - ++i;  
210 - }  
211 - if (success && request.isMember("on"))  
212 - {  
213 - //Check if success was sent and the value was changed  
214 - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool();  
215 - }  
216 - return success; 183 + Json::Value request(Json::objectValue);
  184 + if (transition != 4)
  185 + {
  186 + request["transitiontime"] = transition;
  187 + }
  188 + if (state["state"]["on"].asBool() != true)
  189 + {
  190 + request["on"] = true;
  191 + }
  192 +
  193 + if (!request.isMember("on"))
  194 + {
  195 + //Nothing needs to be changed
  196 + return true;
  197 + }
  198 +
  199 + Json::Value reply = SendPutRequest(request, "/state");
  200 +
  201 + //Check whether request was successful
  202 + std::string path = "/lights/" + std::to_string(id) + "/state/";
  203 + bool success = true;
  204 + int i = 0;
  205 + if (success && request.isMember("transitiontime"))
  206 + {
  207 + //Check if success was sent and the value was changed
  208 + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt();
  209 + ++i;
  210 + }
  211 + if (success && request.isMember("on"))
  212 + {
  213 + //Check if success was sent and the value was changed
  214 + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool();
  215 + }
  216 + return success;
217 } 217 }
218 218
219 bool HueLight::OffNoRefresh(uint8_t transition) 219 bool HueLight::OffNoRefresh(uint8_t transition)
220 { 220 {
221 - Json::Value request(Json::objectValue);  
222 - if (transition != 4)  
223 - {  
224 - request["transitiontime"] = transition;  
225 - }  
226 - if (state["state"]["on"].asBool() != false)  
227 - {  
228 - request["on"] = false;  
229 - }  
230 -  
231 - if (!request.isMember("on"))  
232 - {  
233 - //Nothing needs to be changed  
234 - return true;  
235 - }  
236 -  
237 - Json::Value reply = SendPutRequest(request, "/state");  
238 -  
239 - //Check whether request was successful  
240 - std::string path = "/lights/" + std::to_string(id) + "/state/";  
241 - bool success = true;  
242 - int i = 0;  
243 - if (success && request.isMember("transitiontime"))  
244 - {  
245 - //Check if success was sent and the value was changed  
246 - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt();  
247 - ++i;  
248 - }  
249 - if (success && request.isMember("on"))  
250 - {  
251 - //Check if success was sent and the value was changed  
252 - success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool();  
253 - }  
254 - return success; 221 + Json::Value request(Json::objectValue);
  222 + if (transition != 4)
  223 + {
  224 + request["transitiontime"] = transition;
  225 + }
  226 + if (state["state"]["on"].asBool() != false)
  227 + {
  228 + request["on"] = false;
  229 + }
  230 +
  231 + if (!request.isMember("on"))
  232 + {
  233 + //Nothing needs to be changed
  234 + return true;
  235 + }
  236 +
  237 + Json::Value reply = SendPutRequest(request, "/state");
  238 +
  239 + //Check whether request was successful
  240 + std::string path = "/lights/" + std::to_string(id) + "/state/";
  241 + bool success = true;
  242 + int i = 0;
  243 + if (success && request.isMember("transitiontime"))
  244 + {
  245 + //Check if success was sent and the value was changed
  246 + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "transitiontime"].asUInt() == request["transitiontime"].asUInt();
  247 + ++i;
  248 + }
  249 + if (success && request.isMember("on"))
  250 + {
  251 + //Check if success was sent and the value was changed
  252 + success = !reply[i].isNull() && reply[i].isMember("success") && reply[i]["success"][path + "on"].asBool() == request["on"].asBool();
  253 + }
  254 + return success;
255 } 255 }
256 256
257 Json::Value HueLight::SendPutRequest(const Json::Value& request, const std::string& subPath) 257 Json::Value HueLight::SendPutRequest(const Json::Value& request, const std::string& subPath)
258 { 258 {
259 - return http_handler->PUTJson("/api/"+username+"/lights/"+std::to_string(id)+subPath, request, ip); 259 + return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request);
260 } 260 }
261 261
262 void HueLight::refreshState() 262 void HueLight::refreshState()
263 { 263 {
264 - //std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();  
265 - //std::cout << "\tRefreshing lampstate of lamp with id: " << id << ", ip: " << ip << "\n";  
266 - Json::Value answer = http_handler->GETJson("/api/"+username+"/lights/"+std::to_string(id), Json::objectValue, ip);  
267 - if (answer.isObject() && answer.isMember("state"))  
268 - {  
269 - state = answer;  
270 - }  
271 - else  
272 - {  
273 - std::cout << "Answer in HueLight::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl;  
274 - }  
275 - //std::cout << "\tRefresh state took: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl; 264 + //std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
  265 + //std::cout << "\tRefreshing lampstate of lamp with id: " << id << ", ip: " << ip << "\n";
  266 + Json::Value answer = commands.GETRequest("/lights/" + std::to_string(id), Json::objectValue);
  267 + if (answer.isObject() && answer.isMember("state"))
  268 + {
  269 + state = answer;
  270 + }
  271 + else
  272 + {
  273 + std::cout << "Answer in HueLight::refreshState of http_handler->GETJson(...) is not expected!\nAnswer:\n\t" << answer.toStyledString() << std::endl;
  274 + }
  275 + //std::cout << "\tRefresh state took: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl;
276 } 276 }
hueplusplus/include/Hue.h
1 /** 1 /**
2 - \file Hue.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 Hue.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 #ifndef _HUE_H 20 #ifndef _HUE_H
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 #include "BrightnessStrategy.h" 29 #include "BrightnessStrategy.h"
30 #include "ColorHueStrategy.h" 30 #include "ColorHueStrategy.h"
31 #include "ColorTemperatureStrategy.h" 31 #include "ColorTemperatureStrategy.h"
  32 +#include "HueCommandAPI.h"
32 #include "HueLight.h" 33 #include "HueLight.h"
33 #include "IHttpHandler.h" 34 #include "IHttpHandler.h"
34 35
@@ -43,144 +44,145 @@ class Hue; @@ -43,144 +44,145 @@ class Hue;
43 class HueFinder 44 class HueFinder
44 { 45 {
45 public: 46 public:
46 - struct HueIdentification  
47 - {  
48 - std::string ip;  
49 - std::string mac;  
50 - }; 47 + struct HueIdentification
  48 + {
  49 + std::string ip;
  50 + std::string mac;
  51 + };
51 52
52 public: 53 public:
53 54
54 - //! \brief Constructor of HueFinder class  
55 - //!  
56 - //! \param handler HttpHandler of type \ref IHttpHandler for communication 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 on the mac address.  
62 - //! \return vector containing ip and mac of all found bridges  
63 - std::vector<HueIdentification> FindBridges() const;  
64 -  
65 - //! \brief Function that gets a \ref Hue bridge based on its identification  
66 - //!  
67 - //! \param identification \ref HueIdentification that specifies a bridge  
68 - //! \return \ref Hue class object  
69 - Hue GetBridge(const HueIdentification& identification);  
70 -  
71 - //! \brief Function that adds a username to the \ref usernames map  
72 - //!  
73 - //! \param mac MAC address of Hue bridge  
74 - //! \param username Username that is used to control the Hue bridge  
75 - void AddUsername(const std::string& mac, const std::string& username);  
76 -  
77 - //! \brief Function that returns a map of mac addresses and usernames.  
78 - //!  
79 - //! Note these should be saved at the end and re-loaded with \ref AddUsername next time, so only one username is generated per bridge.  
80 - //! \returns A map mapping mac address to username for every bridge  
81 - 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 with the bridge
  58 + HueFinder(std::shared_ptr<const IHttpHandler> handler);
  59 +
  60 + //! \brief Function that finds all bridges in the network and returns them.
  61 + //!
  62 + //! The user should be given the opportunity to select the correct one based on the mac address.
  63 + //! \return vector containing ip and mac of all found 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 next time, so only one username is generated per bridge.
  81 + //! \returns A map mapping mac address to username for every bridge
  82 + const std::map<std::string, std::string>& GetAllUsernames() const;
82 83
83 private: 84 private:
84 - std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref HueFinder::AddUsername  
85 - std::shared_ptr<const IHttpHandler> http_handler; 85 + std::map<std::string, std::string> usernames; //!< Maps all macs to usernames added by \ref HueFinder::AddUsername
  86 + std::shared_ptr<const IHttpHandler> http_handler;
86 }; 87 };
87 88
88 //! Hue class 89 //! Hue class
89 class Hue 90 class Hue
90 { 91 {
91 - friend class HueFinder; 92 + friend class HueFinder;
92 93
93 public: 94 public:
94 - //! \brief Constructor of Hue class  
95 - //!  
96 - //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1"  
97 - //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername  
98 - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge  
99 - Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler);  
100 -  
101 - //! \brief Function to get the ip address of the hue bridge  
102 - //!  
103 - //! \return string containing ip  
104 - std::string getBridgeIP();  
105 -  
106 - //! \brief Function that sends a username request to the Hue bridge.  
107 - //!  
108 - //! It does that for about 30 seconds and you have 5 seconds to prepare  
109 - //! It automatically sets the \ref username variable according to the username received and returns the username received  
110 - //! This function should only be called once to acquire a username to control the bridge and the username should be saved for future use  
111 - //! \param ip String that specifies the ip (in dotted decimal notation like "192.168.2.1") the request is send to  
112 - //! \return String containing username  
113 - std::string requestUsername(const std::string& ip);  
114 -  
115 - //! \brief Function that returns the \ref username  
116 - //!  
117 - //! \return String containing \ref username  
118 - std::string getUsername();  
119 -  
120 - //! \brief Function to set the ip address of this class representing a bridge  
121 - //!  
122 - //! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1"  
123 - void setIP(const std::string ip);  
124 -  
125 - //! \brief Function that returns a \ref Hue::HueLight of specified id  
126 - //!  
127 - //! \param id Integer that specifies the ID of a Hue light  
128 - //! \return \ref HueLight that can be controlled  
129 - HueLight& getLight(int id);  
130 -  
131 - //! \brief Function to remove a light from the bridge  
132 - //!  
133 - //! \attention Any use of the light after it was successfully removed results in undefined behavior  
134 - //! \param id Id of the light to remove  
135 - //! \return Bool that is true on success  
136 - bool removeLight(int id);  
137 -  
138 - //! \brief Function that returns all light types that are associated with this bridge  
139 - //!  
140 - //! \return A map mapping light id's to light types for every light  
141 - //const std::map<uint8_t, ColorType>& getAllLightTypes();  
142 -  
143 - //! \brief Function that returns all lights that are associated with this bridge  
144 - //!  
145 - //! \return A vector containing references to every HueLight  
146 - std::vector<std::reference_wrapper<HueLight>> getAllLights();  
147 -  
148 - //! \brief Function that tells whether a given light id represents an existing light  
149 - //!  
150 - //! Calls refreshState to update the local bridge state  
151 - //! \param id Id of a light to check for existance  
152 - //! \return Bool that is true when a light with the given id exists and false when not  
153 - bool lightExists(int id);  
154 -  
155 - //! \brief Const function that tells whether a given light id represents an existing light  
156 - //!  
157 - //! \note This will not update the local state of the bridge  
158 - //! \param id Id of a light to check for existance  
159 - //! \return Bool that is true when a light with the given id exists and false when not  
160 - bool lightExists(int id) const;  
161 -  
162 - //! \brief Function that sets the HttpHandler.  
163 - //!  
164 - //! The HttpHandler defines how specific commands that deal with bridge communication are executed  
165 - //! \param handler a HttpHandler of type \ref IHttpHandler  
166 - void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) { http_handler = std::move(handler); }; 95 + //! \brief Constructor of Hue class
  96 + //!
  97 + //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1"
  98 + //! \param username String that specifies the username that is used to control the bridge. This needs to be acquired in \ref requestUsername
  99 + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge
  100 + Hue(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> handler);
  101 +
  102 + //! \brief Function to get the ip address of the hue bridge
  103 + //!
  104 + //! \return string containing ip
  105 + std::string getBridgeIP();
  106 +
  107 + //! \brief Function that sends a username request to the Hue bridge.
  108 + //!
  109 + //! It does that for about 30 seconds and you have 5 seconds to prepare
  110 + //! It automatically sets the \ref username variable according to the username received and returns the username received
  111 + //! This function should only be called once to acquire a username to control the bridge and the username should be saved for future use
  112 + //! \param ip String that specifies the ip (in dotted decimal notation like "192.168.2.1") the request is send to
  113 + //! \return String containing username
  114 + std::string requestUsername(const std::string& ip);
  115 +
  116 + //! \brief Function that returns the \ref username
  117 + //!
  118 + //! \return String containing \ref username
  119 + std::string getUsername();
  120 +
  121 + //! \brief Function to set the ip address of this class representing a bridge
  122 + //!
  123 + //! \param ip String that specifies the ip in dotted decimal notation like "192.168.2.1"
  124 + void setIP(const std::string ip);
  125 +
  126 + //! \brief Function that returns a \ref Hue::HueLight of specified id
  127 + //!
  128 + //! \param id Integer that specifies the ID of a Hue light
  129 + //! \return \ref HueLight that can be controlled
  130 + HueLight& getLight(int id);
  131 +
  132 + //! \brief Function to remove a light from the bridge
  133 + //!
  134 + //! \attention Any use of the light after it was successfully removed results in undefined behavior
  135 + //! \param id Id of the light to remove
  136 + //! \return Bool that is true on success
  137 + bool removeLight(int id);
  138 +
  139 + //! \brief Function that returns all light types that are associated with this bridge
  140 + //!
  141 + //! \return A map mapping light id's to light types for every light
  142 + //const std::map<uint8_t, ColorType>& getAllLightTypes();
  143 +
  144 + //! \brief Function that returns all lights that are associated with this bridge
  145 + //!
  146 + //! \return A vector containing references to every HueLight
  147 + std::vector<std::reference_wrapper<HueLight>> getAllLights();
  148 +
  149 + //! \brief Function that tells whether a given light id represents an existing light
  150 + //!
  151 + //! Calls refreshState to update the local bridge state
  152 + //! \param id Id of a light to check for existance
  153 + //! \return Bool that is true when a light with the given id exists and false when not
  154 + bool lightExists(int id);
  155 +
  156 + //! \brief Const function that tells whether a given light id represents an existing light
  157 + //!
  158 + //! \note This will not update the local state of the bridge
  159 + //! \param id Id of a light to check for existance
  160 + //! \return Bool that is true when a light with the given id exists and false when not
  161 + bool lightExists(int id) const;
  162 +
  163 + //! \brief Function that sets the HttpHandler and updates the HueCommandAPI.
  164 + //!
  165 + //! The HttpHandler and HueCommandAPI are used for bridge communication
  166 + //! \param handler a HttpHandler of type \ref IHttpHandler
  167 + void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) { http_handler = std::move(handler); commands = HueCommandAPI(ip, username, http_handler); };
167 168
168 private: 169 private:
169 - //! \brief Function that refreshes the local \ref state of the Hue bridge  
170 - void refreshState(); 170 + //! \brief Function that refreshes the local \ref state of the Hue bridge
  171 + void refreshState();
171 172
172 private: 173 private:
173 - std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation like "192.168.2.1"  
174 - std::string username; //!< Username that is ussed to access the hue bridge  
175 - Json::Value state; //!< The state of the hue bridge as it is returned from it  
176 - std::map< uint8_t, HueLight > lights; //!< Maps ids to HueLights that are controlled by this bridge  
177 -  
178 - std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the brightness of lights  
179 - std::shared_ptr<ColorHueStrategy> simpleColorHueStrategy; //!< Strategy that is used for controlling the color of lights  
180 - std::shared_ptr<ColorHueStrategy> extendedColorHueStrategy; //!< Strategy that is used for controlling the color of lights  
181 - std::shared_ptr<ColorTemperatureStrategy> simpleColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights  
182 - std::shared_ptr<ColorTemperatureStrategy> extendedColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights  
183 - std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the bridge 174 + std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation like "192.168.2.1"
  175 + std::string username; //!< Username that is ussed to access the hue bridge
  176 + Json::Value state; //!< The state of the hue bridge as it is returned from it
  177 + std::map< uint8_t, HueLight > lights; //!< Maps ids to HueLights that are controlled by this bridge
  178 +
  179 + std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the brightness of lights
  180 + std::shared_ptr<ColorHueStrategy> simpleColorHueStrategy; //!< Strategy that is used for controlling the color of lights
  181 + std::shared_ptr<ColorHueStrategy> extendedColorHueStrategy; //!< Strategy that is used for controlling the color of lights
  182 + std::shared_ptr<ColorTemperatureStrategy> simpleColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights
  183 + std::shared_ptr<ColorTemperatureStrategy> extendedColorTemperatureStrategy; //!< Strategy that is used for controlling the color temperature of lights
  184 + std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the bridge
  185 + HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge
184 }; 186 };
185 187
186 #endif 188 #endif
hueplusplus/include/HueCommandAPI.h 0 โ†’ 100644
  1 +/**
  2 + \file HueCommandAPI.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2018 Jan Rogall - developer\n
  5 + Copyright (C) 2018 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 _HUECOMMANDAPI_H
  21 +#define _HUECOMMANDAPI_H
  22 +
  23 +#include <atomic>
  24 +#include <chrono>
  25 +#include <mutex>
  26 +
  27 +#include "IHttpHandler.h"
  28 +
  29 +
  30 +//! Handles communication to the bridge via IHttpHandler and enforces a timeout between each request
  31 +class HueCommandAPI
  32 +{
  33 +public:
  34 + //! \brief Construct from ip, username and HttpHandler
  35 + //!
  36 + //! \param ip String that specifies the ip address of the Hue bridge in dotted decimal notation like "192.168.2.1"
  37 + //! \param username String that specifies the username that is used to control the bridge
  38 + //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge
  39 + HueCommandAPI(const std::string& ip, const std::string& username, std::shared_ptr<const IHttpHandler> httpHandler);
  40 +
  41 + //! \brief Copy construct from other HueCommandAPI
  42 + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
  43 + HueCommandAPI(const HueCommandAPI&) = default;
  44 + //! \brief Move construct from other HueCommandAPI
  45 + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
  46 + HueCommandAPI(HueCommandAPI&&) = default;
  47 +
  48 + //! \brief Copy assign from other HueCommandAPI
  49 + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
  50 + HueCommandAPI& operator=(const HueCommandAPI&) = default;
  51 + //! \brief Move assign from other HueCommandAPI
  52 + //! \note All copies refer to the same timeout data, so even calls from different objects will be delayed
  53 + HueCommandAPI& operator=(HueCommandAPI&&) = default;
  54 +
  55 + //! \brief Sends a HTTP PUT request via the \ref httpHandler to the bridge and returns the response
  56 + //!
  57 + //! This function will block until at least \ref minDelay has passed to any previous request
  58 + //! \param path String that contains the request path (appended after /api/<username>)
  59 + //! \param request Json value containing the request. May be empty
  60 + //! \returns The return value of the underlying \ref IHttpHandler::PUTJson call
  61 + Json::Value PUTRequest(const std::string& path, const Json::Value& request) const;
  62 +
  63 + //! \brief Sends a HTTP GET request via the \ref httpHandler to the bridge and returns the response
  64 + //!
  65 + //! This function will block until at least \ref minDelay has passed to any previous request
  66 + //! \param path String that contains the request path (appended after /api/<username>)
  67 + //! \param request Json value containing the request. May be empty
  68 + //! \returns The return value of the underlying \ref IHttpHandler::GETJson call
  69 + Json::Value GETRequest(const std::string& path, const Json::Value& request) const;
  70 +
  71 + //! \brief Sends a HTTP DELETE request via the \ref httpHandler to the bridge and returns the response
  72 + //!
  73 + //! This function will block until at least \ref minDelay has passed to any previous request
  74 + //! \param path String that contains the request path (appended after /api/<username>)
  75 + //! \param request Json value containing the request. May be empty
  76 + //! \returns The return value of the underlying \ref IHttpHandler::DELETEJson call
  77 + Json::Value DELETERequest(const std::string& path, const Json::Value& request) const;
  78 +private:
  79 + struct TimeoutData
  80 + {
  81 + std::chrono::steady_clock::time_point timeout;
  82 + std::mutex mutex;
  83 + };
  84 +private:
  85 + static constexpr std::chrono::steady_clock::duration minDelay = std::chrono::milliseconds(100);
  86 + std::string ip;
  87 + std::string username;
  88 + std::shared_ptr<const IHttpHandler> httpHandler;
  89 + std::shared_ptr<TimeoutData> timeout;
  90 +};
  91 +
  92 +#endif
0 \ No newline at end of file 93 \ No newline at end of file
hueplusplus/include/HueLight.h
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 #include "BrightnessStrategy.h" 25 #include "BrightnessStrategy.h"
26 #include "ColorHueStrategy.h" 26 #include "ColorHueStrategy.h"
27 #include "ColorTemperatureStrategy.h" 27 #include "ColorTemperatureStrategy.h"
28 -#include "IHttpHandler.h" 28 +#include "HueCommandAPI.h"
29 29
30 #include "json/json.h" 30 #include "json/json.h"
31 31
@@ -557,24 +557,20 @@ public: @@ -557,24 +557,20 @@ public:
557 protected: 557 protected:
558 //! \brief Protected ctor that is used by \ref Hue class. 558 //! \brief Protected ctor that is used by \ref Hue class.
559 //! 559 //!
560 - //! \param ip String that specifies the ip of the Hue bridge  
561 - //! \param username String that specifies the username used to control the bridge  
562 //! \param id Integer that specifies the id of this light 560 //! \param id Integer that specifies the id of this light
563 - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge 561 + //! \param commands HueCommandAPI for communication with the bridge
564 //! 562 //!
565 //! leaves strategies unset 563 //! leaves strategies unset
566 - HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const IHttpHandler> handler); 564 + HueLight(int id, const HueCommandAPI& commands);
567 565
568 //! \brief Protected ctor that is used by \ref Hue class, also sets strategies. 566 //! \brief Protected ctor that is used by \ref Hue class, also sets strategies.
569 //! 567 //!
570 - //! \param ip String that specifies the ip of the Hue bridge  
571 - //! \param username String that specifies the username used to control the bridge  
572 //! \param id Integer that specifies the id of this light 568 //! \param id Integer that specifies the id of this light
  569 + //! \param commands HueCommandAPI for communication with the bridge
573 //! \param brightnessStrategy Strategy for brightness. May be nullptr. 570 //! \param brightnessStrategy Strategy for brightness. May be nullptr.
574 //! \param colorTempStrategy Strategy for color temperature. May be nullptr. 571 //! \param colorTempStrategy Strategy for color temperature. May be nullptr.
575 //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr. 572 //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr.
576 - //! \param handler HttpHandler of type \ref IHttpHandler for communication with the bridge  
577 - HueLight(const std::string& ip, const std::string& username, int id, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::shared_ptr<const IHttpHandler> handler); 573 + HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, std::shared_ptr<const ColorHueStrategy> colorHueStrategy);
578 574
579 //! \brief Protected function that sets the brightness strategy. 575 //! \brief Protected function that sets the brightness strategy.
580 //! 576 //!
@@ -594,11 +590,11 @@ protected: @@ -594,11 +590,11 @@ protected:
594 //! \param strat a strategy of type \ref ColorHueStrategy 590 //! \param strat a strategy of type \ref ColorHueStrategy
595 virtual void setColorHueStrategy(std::shared_ptr<const ColorHueStrategy> strat) { colorHueStrategy = std::move(strat); }; 591 virtual void setColorHueStrategy(std::shared_ptr<const ColorHueStrategy> strat) { colorHueStrategy = std::move(strat); };
596 592
597 - //! \brief Protected function that sets the HttpHandler. 593 + //! \brief Protected function that sets the HueCommandAPI.
598 //! 594 //!
599 - //! The HttpHandler defines how specific commands that deal with bridge communication are executed  
600 - //! \param handler a HttpHandler of type \ref IHttpHandler  
601 - virtual void setHttpHandler(std::shared_ptr<const IHttpHandler> handler) { http_handler = std::move(handler); }; 595 + //! The HueCommandAPI is used for bridge communication
  596 + //! \param commandAPI the new HueCommandAPI
  597 + virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; };
602 598
603 //! \brief Function that turns the light on without refreshing its state. 599 //! \brief Function that turns the light on without refreshing its state.
604 //! 600 //!
@@ -633,7 +629,7 @@ protected: @@ -633,7 +629,7 @@ protected:
633 std::shared_ptr<const BrightnessStrategy> brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands 629 std::shared_ptr<const BrightnessStrategy> brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands
634 std::shared_ptr<const ColorTemperatureStrategy> colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands 630 std::shared_ptr<const ColorTemperatureStrategy> colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands
635 std::shared_ptr<const ColorHueStrategy> colorHueStrategy; //!< holds a reference to the strategy that handles all color commands 631 std::shared_ptr<const ColorHueStrategy> colorHueStrategy; //!< holds a reference to the strategy that handles all color commands
636 - std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the bridge 632 + HueCommandAPI commands; //!< A IHttpHandler that is used to communicate with the bridge
637 }; 633 };
638 634
639 #endif 635 #endif
hueplusplus/test/CMakeLists.txt
@@ -49,8 +49,6 @@ set(TEST_SOURCES @@ -49,8 +49,6 @@ set(TEST_SOURCES
49 # test executable 49 # test executable
50 add_executable(test_HuePlusPlus ${TEST_SOURCES} ${hueplusplus_SOURCES}) 50 add_executable(test_HuePlusPlus ${TEST_SOURCES} ${hueplusplus_SOURCES})
51 target_link_libraries(test_HuePlusPlus gtest gmock) 51 target_link_libraries(test_HuePlusPlus gtest gmock)
52 -# prevent Main.cpp from defining main()  
53 -target_compile_definitions(test_HuePlusPlus PUBLIC MAIN_CPP_NO_MAIN_FUNCTION)  
54 target_include_directories(test_HuePlusPlus PUBLIC ${GTest_INCLUDE_DIRS}) 52 target_include_directories(test_HuePlusPlus PUBLIC ${GTest_INCLUDE_DIRS})
55 target_include_directories(test_HuePlusPlus PUBLIC ${HuePlusPlus_INCLUDE_DIR}) 53 target_include_directories(test_HuePlusPlus PUBLIC ${HuePlusPlus_INCLUDE_DIR})
56 set_property(TARGET test_HuePlusPlus PROPERTY CXX_STANDARD 14) 54 set_property(TARGET test_HuePlusPlus PROPERTY CXX_STANDARD 14)
hueplusplus/test/mocks/mock_HueLight.h
1 /** 1 /**
2 - \file mock_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 mock_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 #ifndef _MOCK_HUE_LIGHT_H 20 #ifndef _MOCK_HUE_LIGHT_H
@@ -33,97 +33,97 @@ @@ -33,97 +33,97 @@
33 class MockHueLight : public HueLight 33 class MockHueLight : public HueLight
34 { 34 {
35 public: 35 public:
36 - MockHueLight(std::shared_ptr<const IHttpHandler> handler) : HueLight(bridge_ip, bridge_username, 1, handler){}; 36 + MockHueLight(std::shared_ptr<const IHttpHandler> handler) : HueLight(1, HueCommandAPI(bridge_ip, bridge_username, handler)) {};
37 37
38 - Json::Value& getState() {return state;}; 38 + Json::Value& getState() { return state; };
39 39
40 - MOCK_METHOD1( On, bool(uint8_t transition) ); 40 + MOCK_METHOD1(On, bool(uint8_t transition));
41 41
42 - MOCK_METHOD1( Off, bool(uint8_t transition) ); 42 + MOCK_METHOD1(Off, bool(uint8_t transition));
43 43
44 - MOCK_METHOD0( isOn, bool() ); 44 + MOCK_METHOD0(isOn, bool());
45 45
46 - MOCK_CONST_METHOD0( isOn, bool() ); 46 + MOCK_CONST_METHOD0(isOn, bool());
47 47
48 - MOCK_CONST_METHOD0( getId, int() ); 48 + MOCK_CONST_METHOD0(getId, int());
49 49
50 - MOCK_CONST_METHOD0( getType, std::string() ); 50 + MOCK_CONST_METHOD0(getType, std::string());
51 51
52 - MOCK_METHOD0( getName, std::string() ); 52 + MOCK_METHOD0(getName, std::string());
53 53
54 - MOCK_CONST_METHOD0( getName, std::string() ); 54 + MOCK_CONST_METHOD0(getName, std::string());
55 55
56 - MOCK_CONST_METHOD0( getModelId, std::string() ); 56 + MOCK_CONST_METHOD0(getModelId, std::string());
57 57
58 - MOCK_CONST_METHOD0( getUId, std::string() ); 58 + MOCK_CONST_METHOD0(getUId, std::string());
59 59
60 - MOCK_CONST_METHOD0( getManufacturername, std::string() ); 60 + MOCK_CONST_METHOD0(getManufacturername, std::string());
61 61
62 - MOCK_CONST_METHOD0( getLuminaireUId, std::string() ); 62 + MOCK_CONST_METHOD0(getLuminaireUId, std::string());
63 63
64 - MOCK_METHOD0( getSwVersion, std::string() ); 64 + MOCK_METHOD0(getSwVersion, std::string());
65 65
66 - MOCK_CONST_METHOD0( getSwVersion, std::string() ); 66 + MOCK_CONST_METHOD0(getSwVersion, std::string());
67 67
68 - MOCK_METHOD1( setName, bool(std::string& name)); 68 + MOCK_METHOD1(setName, bool(std::string& name));
69 69
70 - MOCK_CONST_METHOD0( getColorType, ColorType() ); 70 + MOCK_CONST_METHOD0(getColorType, ColorType());
71 71
72 - MOCK_CONST_METHOD0( hasBrightnessControl, bool() ); 72 + MOCK_CONST_METHOD0(hasBrightnessControl, bool());
73 73
74 - MOCK_CONST_METHOD0( hasTemperatureControl, bool() ); 74 + MOCK_CONST_METHOD0(hasTemperatureControl, bool());
75 75
76 - MOCK_CONST_METHOD0( hasColorControl, bool() ); 76 + MOCK_CONST_METHOD0(hasColorControl, bool());
77 77
78 - MOCK_METHOD2( setBrightness, bool(unsigned int bri, uint8_t transition) ); 78 + MOCK_METHOD2(setBrightness, bool(unsigned int bri, uint8_t transition));
79 79
80 - MOCK_CONST_METHOD0( getBrightness, unsigned int() ); 80 + MOCK_CONST_METHOD0(getBrightness, unsigned int());
81 81
82 - MOCK_METHOD0( getBrightness, unsigned int() ); 82 + MOCK_METHOD0(getBrightness, unsigned int());
83 83
84 - MOCK_METHOD2( setColorTemperature, bool(unsigned int mired, uint8_t transition) ); 84 + MOCK_METHOD2(setColorTemperature, bool(unsigned int mired, uint8_t transition));
85 85
86 - MOCK_CONST_METHOD0( getColorTemperature, unsigned int() ); 86 + MOCK_CONST_METHOD0(getColorTemperature, unsigned int());
87 87
88 - MOCK_METHOD0( getColorTemperature, unsigned int() ); 88 + MOCK_METHOD0(getColorTemperature, unsigned int());
89 89
90 - MOCK_METHOD2( setColorHue, bool(uint16_t hue, uint8_t transition) ); 90 + MOCK_METHOD2(setColorHue, bool(uint16_t hue, uint8_t transition));
91 91
92 - MOCK_METHOD2( setColorSaturation, bool(uint8_t sat, uint8_t transition) ); 92 + MOCK_METHOD2(setColorSaturation, bool(uint8_t sat, uint8_t transition));
93 93
94 - MOCK_METHOD3( setColorHueSaturation, bool(uint16_t hue, uint8_t sat, uint8_t transition) ); 94 + MOCK_METHOD3(setColorHueSaturation, bool(uint16_t hue, uint8_t sat, uint8_t transition));
95 95
96 - MOCK_CONST_METHOD0( getColorHueSaturation, std::pair<uint16_t, uint8_t>() ); 96 + MOCK_CONST_METHOD0(getColorHueSaturation, std::pair<uint16_t, uint8_t>());
97 97
98 - MOCK_METHOD0( getColorHueSaturation, std::pair<uint16_t, uint8_t>() ); 98 + MOCK_METHOD0(getColorHueSaturation, std::pair<uint16_t, uint8_t>());
99 99
100 - MOCK_METHOD3( setColorXY, bool(float x, float y, uint8_t transition) ); 100 + MOCK_METHOD3(setColorXY, bool(float x, float y, uint8_t transition));
101 101
102 - MOCK_CONST_METHOD0( getColorXY, std::pair<float, float>() ); 102 + MOCK_CONST_METHOD0(getColorXY, std::pair<float, float>());
103 103
104 - MOCK_METHOD0( getColorXY, std::pair<float, float>() ); 104 + MOCK_METHOD0(getColorXY, std::pair<float, float>());
105 105
106 - MOCK_METHOD4( setColorRGB, bool(uint8_t r, uint8_t g, uint8_t b, uint8_t transition) ); 106 + MOCK_METHOD4(setColorRGB, bool(uint8_t r, uint8_t g, uint8_t b, uint8_t transition));
107 107
108 - MOCK_METHOD0( alert, bool() ); 108 + MOCK_METHOD0(alert, bool());
109 109
110 - MOCK_METHOD1( alertTemperature, bool(unsigned int mired) ); 110 + MOCK_METHOD1(alertTemperature, bool(unsigned int mired));
111 111
112 - MOCK_METHOD2( alertHueSaturation, bool(uint16_t hue, uint8_t sat) ); 112 + MOCK_METHOD2(alertHueSaturation, bool(uint16_t hue, uint8_t sat));
113 113
114 - MOCK_METHOD2( alertXY, bool(float x, float y) ); 114 + MOCK_METHOD2(alertXY, bool(float x, float y));
115 115
116 - MOCK_METHOD3( alertRGB, bool(uint8_t r, uint8_t g, uint8_t b) ); 116 + MOCK_METHOD3(alertRGB, bool(uint8_t r, uint8_t g, uint8_t b));
117 117
118 - MOCK_METHOD1( setColorLoop, bool(bool on) ); 118 + MOCK_METHOD1(setColorLoop, bool(bool on));
119 119
120 - MOCK_METHOD1( OnNoRefresh, bool(uint8_t transition) ); 120 + MOCK_METHOD1(OnNoRefresh, bool(uint8_t transition));
121 121
122 - MOCK_METHOD1( OffNoRefresh, bool(uint8_t transition) ); 122 + MOCK_METHOD1(OffNoRefresh, bool(uint8_t transition));
123 123
124 - MOCK_METHOD2( SendPutRequest, Json::Value(const Json::Value& request, const std::string& subPath) ); 124 + MOCK_METHOD2(SendPutRequest, Json::Value(const Json::Value& request, const std::string& subPath));
125 125
126 - MOCK_METHOD0( refreshState, void() ); 126 + MOCK_METHOD0(refreshState, void());
127 }; 127 };
128 128
129 #endif 129 #endif
hueplusplus/test/test_ExtendedColorHueStrategy.cpp
@@ -15,15 +15,15 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -15,15 +15,15 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
15 using namespace ::testing; 15 using namespace ::testing;
16 std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>()); 16 std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
17 EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80)) 17 EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80))
18 - .Times(AtLeast(1))  
19 - .WillRepeatedly(Return(Json::Value(Json::objectValue))); 18 + .Times(AtLeast(1))
  19 + .WillRepeatedly(Return(Json::Value(Json::objectValue)));
20 MockHueLight test_light(handler); 20 MockHueLight test_light(handler);
21 EXPECT_CALL(test_light, refreshState()) 21 EXPECT_CALL(test_light, refreshState())
22 .Times(AtLeast(1)) 22 .Times(AtLeast(1))
23 .WillRepeatedly(Return()); 23 .WillRepeatedly(Return());
24 24
25 test_light.getState()["state"]["colormode"] = "invalid"; 25 test_light.getState()["state"]["colormode"] = "invalid";
26 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, test_light) ); 26 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(30000, 128, test_light));
27 27
28 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) 28 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
29 .Times(AtLeast(2)) 29 .Times(AtLeast(2))
@@ -33,21 +33,21 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -33,21 +33,21 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
33 test_light.getState()["state"]["on"] = true; 33 test_light.getState()["state"]["on"] = true;
34 test_light.getState()["state"]["sat"] = 100; 34 test_light.getState()["state"]["sat"] = 100;
35 test_light.getState()["state"]["hue"] = 200; 35 test_light.getState()["state"]["hue"] = 200;
36 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 36 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
37 37
38 EXPECT_CALL(test_light, alert()) 38 EXPECT_CALL(test_light, alert())
39 .Times(AtLeast(2)) 39 .Times(AtLeast(2))
40 .WillOnce(Return(false)) 40 .WillOnce(Return(false))
41 .WillRepeatedly(Return(true)); 41 .WillRepeatedly(Return(true));
42 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 42 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
43 43
44 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 44 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
45 45
46 EXPECT_CALL(test_light, OffNoRefresh(_)) 46 EXPECT_CALL(test_light, OffNoRefresh(_))
47 .Times(AtLeast(1)) 47 .Times(AtLeast(1))
48 .WillRepeatedly(Return(true)); 48 .WillRepeatedly(Return(true));
49 test_light.getState()["state"]["on"] = false; 49 test_light.getState()["state"]["on"] = false;
50 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 50 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
51 51
52 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) 52 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
53 .Times(AtLeast(2)) 53 .Times(AtLeast(2))
@@ -57,24 +57,24 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -57,24 +57,24 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
57 test_light.getState()["state"]["on"] = true; 57 test_light.getState()["state"]["on"] = true;
58 test_light.getState()["state"]["xy"][0] = 0.1; 58 test_light.getState()["state"]["xy"][0] = 0.1;
59 test_light.getState()["state"]["xy"][1] = 0.1; 59 test_light.getState()["state"]["xy"][1] = 0.1;
60 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 60 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
61 61
62 EXPECT_CALL(test_light, alert()) 62 EXPECT_CALL(test_light, alert())
63 .Times(AtLeast(2)) 63 .Times(AtLeast(2))
64 .WillOnce(Return(false)) 64 .WillOnce(Return(false))
65 .WillRepeatedly(Return(true)); 65 .WillRepeatedly(Return(true));
66 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 66 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
67 67
68 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 68 EXPECT_CALL(test_light, setColorXY(_, _, 1))
69 .Times(AtLeast(2)) 69 .Times(AtLeast(2))
70 .WillRepeatedly(Return(true)); 70 .WillRepeatedly(Return(true));
71 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 71 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
72 72
73 EXPECT_CALL(test_light, OffNoRefresh(_)) 73 EXPECT_CALL(test_light, OffNoRefresh(_))
74 .Times(AtLeast(1)) 74 .Times(AtLeast(1))
75 .WillRepeatedly(Return(true)); 75 .WillRepeatedly(Return(true));
76 test_light.getState()["state"]["on"] = false; 76 test_light.getState()["state"]["on"] = false;
77 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 77 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
78 78
79 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) 79 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
80 .Times(AtLeast(2)) 80 .Times(AtLeast(2))
@@ -83,24 +83,24 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -83,24 +83,24 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
83 test_light.getState()["state"]["colormode"] = "ct"; 83 test_light.getState()["state"]["colormode"] = "ct";
84 test_light.getState()["state"]["on"] = true; 84 test_light.getState()["state"]["on"] = true;
85 test_light.getState()["state"]["ct"] = 200; 85 test_light.getState()["state"]["ct"] = 200;
86 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 86 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
87 87
88 EXPECT_CALL(test_light, alert()) 88 EXPECT_CALL(test_light, alert())
89 .Times(AtLeast(2)) 89 .Times(AtLeast(2))
90 .WillOnce(Return(false)) 90 .WillOnce(Return(false))
91 .WillRepeatedly(Return(true)); 91 .WillRepeatedly(Return(true));
92 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 92 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
93 93
94 EXPECT_CALL(test_light, setColorTemperature(_, 1)) 94 EXPECT_CALL(test_light, setColorTemperature(_, 1))
95 .Times(AtLeast(2)) 95 .Times(AtLeast(2))
96 .WillRepeatedly(Return(true)); 96 .WillRepeatedly(Return(true));
97 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 97 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
98 98
99 EXPECT_CALL(test_light, OffNoRefresh(_)) 99 EXPECT_CALL(test_light, OffNoRefresh(_))
100 .Times(AtLeast(1)) 100 .Times(AtLeast(1))
101 .WillRepeatedly(Return(true)); 101 .WillRepeatedly(Return(true));
102 test_light.getState()["state"]["on"] = false; 102 test_light.getState()["state"]["on"] = false;
103 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light) ); 103 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
104 } 104 }
105 105
106 TEST(ExtendedColorHueStrategy, alertXY) 106 TEST(ExtendedColorHueStrategy, alertXY)
@@ -108,15 +108,15 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -108,15 +108,15 @@ TEST(ExtendedColorHueStrategy, alertXY)
108 using namespace ::testing; 108 using namespace ::testing;
109 std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>()); 109 std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
110 EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80)) 110 EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80))
111 - .Times(AtLeast(1))  
112 - .WillRepeatedly(Return(Json::Value(Json::objectValue))); 111 + .Times(AtLeast(1))
  112 + .WillRepeatedly(Return(Json::Value(Json::objectValue)));
113 MockHueLight test_light(handler); 113 MockHueLight test_light(handler);
114 EXPECT_CALL(test_light, refreshState()) 114 EXPECT_CALL(test_light, refreshState())
115 .Times(AtLeast(1)) 115 .Times(AtLeast(1))
116 .WillRepeatedly(Return()); 116 .WillRepeatedly(Return());
117 117
118 test_light.getState()["state"]["colormode"] = "invalid"; 118 test_light.getState()["state"]["colormode"] = "invalid";
119 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 119 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
120 120
121 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 121 EXPECT_CALL(test_light, setColorXY(_, _, 1))
122 .Times(AtLeast(2)) 122 .Times(AtLeast(2))
@@ -128,24 +128,24 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -128,24 +128,24 @@ TEST(ExtendedColorHueStrategy, alertXY)
128 test_light.getState()["state"]["xy"][1] = 0.1; 128 test_light.getState()["state"]["xy"][1] = 0.1;
129 test_light.getState()["state"]["sat"] = 100; 129 test_light.getState()["state"]["sat"] = 100;
130 test_light.getState()["state"]["hue"] = 200; 130 test_light.getState()["state"]["hue"] = 200;
131 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 131 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
132 132
133 EXPECT_CALL(test_light, alert()) 133 EXPECT_CALL(test_light, alert())
134 .Times(AtLeast(2)) 134 .Times(AtLeast(2))
135 .WillOnce(Return(false)) 135 .WillOnce(Return(false))
136 .WillRepeatedly(Return(true)); 136 .WillRepeatedly(Return(true));
137 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 137 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
138 138
139 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) 139 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
140 .Times(AtLeast(2)) 140 .Times(AtLeast(2))
141 .WillRepeatedly(Return(true)); 141 .WillRepeatedly(Return(true));
142 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 142 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
143 143
144 EXPECT_CALL(test_light, OffNoRefresh(_)) 144 EXPECT_CALL(test_light, OffNoRefresh(_))
145 .Times(AtLeast(1)) 145 .Times(AtLeast(1))
146 .WillRepeatedly(Return(true)); 146 .WillRepeatedly(Return(true));
147 test_light.getState()["state"]["on"] = false; 147 test_light.getState()["state"]["on"] = false;
148 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 148 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
149 149
150 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 150 EXPECT_CALL(test_light, setColorXY(_, _, 1))
151 .Times(AtLeast(2)) 151 .Times(AtLeast(2))
@@ -153,21 +153,21 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -153,21 +153,21 @@ TEST(ExtendedColorHueStrategy, alertXY)
153 .WillRepeatedly(Return(true)); 153 .WillRepeatedly(Return(true));
154 test_light.getState()["state"]["colormode"] = "xy"; 154 test_light.getState()["state"]["colormode"] = "xy";
155 test_light.getState()["state"]["on"] = true; 155 test_light.getState()["state"]["on"] = true;
156 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 156 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
157 157
158 EXPECT_CALL(test_light, alert()) 158 EXPECT_CALL(test_light, alert())
159 .Times(AtLeast(2)) 159 .Times(AtLeast(2))
160 .WillOnce(Return(false)) 160 .WillOnce(Return(false))
161 .WillRepeatedly(Return(true)); 161 .WillRepeatedly(Return(true));
162 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 162 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
163 163
164 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 164 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
165 165
166 EXPECT_CALL(test_light, OffNoRefresh(_)) 166 EXPECT_CALL(test_light, OffNoRefresh(_))
167 .Times(AtLeast(1)) 167 .Times(AtLeast(1))
168 .WillRepeatedly(Return(true)); 168 .WillRepeatedly(Return(true));
169 test_light.getState()["state"]["on"] = false; 169 test_light.getState()["state"]["on"] = false;
170 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 170 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
171 171
172 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 172 EXPECT_CALL(test_light, setColorXY(_, _, 1))
173 .Times(AtLeast(2)) 173 .Times(AtLeast(2))
@@ -176,24 +176,24 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -176,24 +176,24 @@ TEST(ExtendedColorHueStrategy, alertXY)
176 test_light.getState()["state"]["colormode"] = "ct"; 176 test_light.getState()["state"]["colormode"] = "ct";
177 test_light.getState()["state"]["on"] = true; 177 test_light.getState()["state"]["on"] = true;
178 test_light.getState()["state"]["ct"] = 200; 178 test_light.getState()["state"]["ct"] = 200;
179 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 179 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
180 180
181 EXPECT_CALL(test_light, alert()) 181 EXPECT_CALL(test_light, alert())
182 .Times(AtLeast(2)) 182 .Times(AtLeast(2))
183 .WillOnce(Return(false)) 183 .WillOnce(Return(false))
184 .WillRepeatedly(Return(true)); 184 .WillRepeatedly(Return(true));
185 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 185 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
186 186
187 EXPECT_CALL(test_light, setColorTemperature(_, 1)) 187 EXPECT_CALL(test_light, setColorTemperature(_, 1))
188 .Times(AtLeast(2)) 188 .Times(AtLeast(2))
189 .WillRepeatedly(Return(true)); 189 .WillRepeatedly(Return(true));
190 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 190 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
191 191
192 EXPECT_CALL(test_light, OffNoRefresh(_)) 192 EXPECT_CALL(test_light, OffNoRefresh(_))
193 .Times(AtLeast(1)) 193 .Times(AtLeast(1))
194 .WillRepeatedly(Return(true)); 194 .WillRepeatedly(Return(true));
195 test_light.getState()["state"]["on"] = false; 195 test_light.getState()["state"]["on"] = false;
196 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 196 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
197 } 197 }
198 198
199 TEST(ExtendedColorHueStrategy, alertRGB) 199 TEST(ExtendedColorHueStrategy, alertRGB)
@@ -201,15 +201,15 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -201,15 +201,15 @@ TEST(ExtendedColorHueStrategy, alertRGB)
201 using namespace ::testing; 201 using namespace ::testing;
202 std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>()); 202 std::shared_ptr<MockHttpHandler> handler(std::make_shared<MockHttpHandler>());
203 EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80)) 203 EXPECT_CALL(*handler, GETJson("/api/" + bridge_username + "/lights/1", Json::Value(Json::objectValue), bridge_ip, 80))
204 - .Times(AtLeast(1))  
205 - .WillRepeatedly(Return(Json::Value(Json::objectValue))); 204 + .Times(AtLeast(1))
  205 + .WillRepeatedly(Return(Json::Value(Json::objectValue)));
206 MockHueLight test_light(handler); 206 MockHueLight test_light(handler);
207 EXPECT_CALL(test_light, refreshState()) 207 EXPECT_CALL(test_light, refreshState())
208 .Times(AtLeast(1)) 208 .Times(AtLeast(1))
209 .WillRepeatedly(Return()); 209 .WillRepeatedly(Return());
210 210
211 test_light.getState()["state"]["colormode"] = "invalid"; 211 test_light.getState()["state"]["colormode"] = "invalid";
212 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 212 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
213 213
214 EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) 214 EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
215 .Times(AtLeast(2)) 215 .Times(AtLeast(2))
@@ -219,24 +219,24 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -219,24 +219,24 @@ TEST(ExtendedColorHueStrategy, alertRGB)
219 test_light.getState()["state"]["on"] = true; 219 test_light.getState()["state"]["on"] = true;
220 test_light.getState()["state"]["sat"] = 100; 220 test_light.getState()["state"]["sat"] = 100;
221 test_light.getState()["state"]["hue"] = 200; 221 test_light.getState()["state"]["hue"] = 200;
222 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 222 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
223 223
224 EXPECT_CALL(test_light, alert()) 224 EXPECT_CALL(test_light, alert())
225 .Times(AtLeast(2)) 225 .Times(AtLeast(2))
226 .WillOnce(Return(false)) 226 .WillOnce(Return(false))
227 .WillRepeatedly(Return(true)); 227 .WillRepeatedly(Return(true));
228 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 228 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
229 229
230 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) 230 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
231 .Times(AtLeast(2)) 231 .Times(AtLeast(2))
232 .WillRepeatedly(Return(true)); 232 .WillRepeatedly(Return(true));
233 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 233 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
234 234
235 EXPECT_CALL(test_light, OffNoRefresh(_)) 235 EXPECT_CALL(test_light, OffNoRefresh(_))
236 .Times(AtLeast(1)) 236 .Times(AtLeast(1))
237 .WillRepeatedly(Return(true)); 237 .WillRepeatedly(Return(true));
238 test_light.getState()["state"]["on"] = false; 238 test_light.getState()["state"]["on"] = false;
239 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 239 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
240 240
241 EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) 241 EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
242 .Times(AtLeast(2)) 242 .Times(AtLeast(2))
@@ -246,24 +246,24 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -246,24 +246,24 @@ TEST(ExtendedColorHueStrategy, alertRGB)
246 test_light.getState()["state"]["on"] = true; 246 test_light.getState()["state"]["on"] = true;
247 test_light.getState()["state"]["xy"][0] = 0.1; 247 test_light.getState()["state"]["xy"][0] = 0.1;
248 test_light.getState()["state"]["xy"][1] = 0.1; 248 test_light.getState()["state"]["xy"][1] = 0.1;
249 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 249 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
250 250
251 EXPECT_CALL(test_light, alert()) 251 EXPECT_CALL(test_light, alert())
252 .Times(AtLeast(2)) 252 .Times(AtLeast(2))
253 .WillOnce(Return(false)) 253 .WillOnce(Return(false))
254 .WillRepeatedly(Return(true)); 254 .WillRepeatedly(Return(true));
255 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 255 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
256 256
257 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 257 EXPECT_CALL(test_light, setColorXY(_, _, 1))
258 .Times(AtLeast(2)) 258 .Times(AtLeast(2))
259 .WillRepeatedly(Return(true)); 259 .WillRepeatedly(Return(true));
260 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 260 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
261 261
262 EXPECT_CALL(test_light, OffNoRefresh(_)) 262 EXPECT_CALL(test_light, OffNoRefresh(_))
263 .Times(AtLeast(1)) 263 .Times(AtLeast(1))
264 .WillRepeatedly(Return(true)); 264 .WillRepeatedly(Return(true));
265 test_light.getState()["state"]["on"] = false; 265 test_light.getState()["state"]["on"] = false;
266 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 266 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
267 267
268 EXPECT_CALL(test_light, setColorRGB(_, _, _, 1)) 268 EXPECT_CALL(test_light, setColorRGB(_, _, _, 1))
269 .Times(AtLeast(2)) 269 .Times(AtLeast(2))
@@ -272,22 +272,22 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -272,22 +272,22 @@ TEST(ExtendedColorHueStrategy, alertRGB)
272 test_light.getState()["state"]["colormode"] = "ct"; 272 test_light.getState()["state"]["colormode"] = "ct";
273 test_light.getState()["state"]["on"] = true; 273 test_light.getState()["state"]["on"] = true;
274 test_light.getState()["state"]["ct"] = 200; 274 test_light.getState()["state"]["ct"] = 200;
275 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 275 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
276 276
277 EXPECT_CALL(test_light, alert()) 277 EXPECT_CALL(test_light, alert())
278 .Times(AtLeast(2)) 278 .Times(AtLeast(2))
279 .WillOnce(Return(false)) 279 .WillOnce(Return(false))
280 .WillRepeatedly(Return(true)); 280 .WillRepeatedly(Return(true));
281 - EXPECT_EQ( false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 281 + EXPECT_EQ(false, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
282 282
283 EXPECT_CALL(test_light, setColorTemperature(_, 1)) 283 EXPECT_CALL(test_light, setColorTemperature(_, 1))
284 .Times(AtLeast(2)) 284 .Times(AtLeast(2))
285 .WillRepeatedly(Return(true)); 285 .WillRepeatedly(Return(true));
286 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 286 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
287 287
288 EXPECT_CALL(test_light, OffNoRefresh(_)) 288 EXPECT_CALL(test_light, OffNoRefresh(_))
289 .Times(AtLeast(1)) 289 .Times(AtLeast(1))
290 .WillRepeatedly(Return(true)); 290 .WillRepeatedly(Return(true));
291 test_light.getState()["state"]["on"] = false; 291 test_light.getState()["state"]["on"] = false;
292 - EXPECT_EQ( true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light) ); 292 + EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
293 } 293 }
hueplusplus/test/test_SimpleColorHueStrategy.cpp
@@ -150,10 +150,10 @@ TEST(SimpleColorHueStrategy, setColorXY) @@ -150,10 +150,10 @@ TEST(SimpleColorHueStrategy, setColorXY)
150 test_light.getState()["state"]["xy"][0] = 0.1; 150 test_light.getState()["state"]["xy"][0] = 0.1;
151 test_light.getState()["state"]["xy"][1] = 0.1; 151 test_light.getState()["state"]["xy"][1] = 0.1;
152 test_light.getState()["state"]["colormode"] = "xy"; 152 test_light.getState()["state"]["colormode"] = "xy";
153 - EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.1, 0.1, 4, test_light) ); 153 + EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.1f, 0.1f, 4, test_light) );
154 154
155 test_light.getState()["state"]["on"] = false; 155 test_light.getState()["state"]["on"] = false;
156 - EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.2355, 0.1234, 6, test_light) ); 156 + EXPECT_EQ( true, SimpleColorHueStrategy().setColorXY(0.2355f, 0.1234f, 6, test_light) );
157 } 157 }
158 158
159 TEST(SimpleColorHueStrategy, setColorRGB) 159 TEST(SimpleColorHueStrategy, setColorRGB)
@@ -290,7 +290,7 @@ TEST(SimpleColorHueStrategy, alertXY) @@ -290,7 +290,7 @@ TEST(SimpleColorHueStrategy, alertXY)
290 .WillRepeatedly(Return()); 290 .WillRepeatedly(Return());
291 291
292 test_light.getState()["state"]["colormode"] = "invalid"; 292 test_light.getState()["state"]["colormode"] = "invalid";
293 - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 293 + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
294 294
295 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 295 EXPECT_CALL(test_light, setColorXY(_, _, 1))
296 .Times(AtLeast(2)) 296 .Times(AtLeast(2))
@@ -302,24 +302,24 @@ TEST(SimpleColorHueStrategy, alertXY) @@ -302,24 +302,24 @@ TEST(SimpleColorHueStrategy, alertXY)
302 test_light.getState()["state"]["xy"][1] = 0.1; 302 test_light.getState()["state"]["xy"][1] = 0.1;
303 test_light.getState()["state"]["sat"] = 100; 303 test_light.getState()["state"]["sat"] = 100;
304 test_light.getState()["state"]["hue"] = 200; 304 test_light.getState()["state"]["hue"] = 200;
305 - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 305 + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
306 306
307 EXPECT_CALL(test_light, alert()) 307 EXPECT_CALL(test_light, alert())
308 .Times(AtLeast(2)) 308 .Times(AtLeast(2))
309 .WillOnce(Return(false)) 309 .WillOnce(Return(false))
310 .WillRepeatedly(Return(true)); 310 .WillRepeatedly(Return(true));
311 - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 311 + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
312 312
313 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)) 313 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1))
314 .Times(AtLeast(2)) 314 .Times(AtLeast(2))
315 .WillRepeatedly(Return(true)); 315 .WillRepeatedly(Return(true));
316 - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 316 + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
317 317
318 EXPECT_CALL(test_light, OffNoRefresh(_)) 318 EXPECT_CALL(test_light, OffNoRefresh(_))
319 .Times(AtLeast(1)) 319 .Times(AtLeast(1))
320 .WillRepeatedly(Return(true)); 320 .WillRepeatedly(Return(true));
321 test_light.getState()["state"]["on"] = false; 321 test_light.getState()["state"]["on"] = false;
322 - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 322 + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
323 323
324 EXPECT_CALL(test_light, setColorXY(_, _, 1)) 324 EXPECT_CALL(test_light, setColorXY(_, _, 1))
325 .Times(AtLeast(2)) 325 .Times(AtLeast(2))
@@ -327,21 +327,21 @@ TEST(SimpleColorHueStrategy, alertXY) @@ -327,21 +327,21 @@ TEST(SimpleColorHueStrategy, alertXY)
327 .WillRepeatedly(Return(true)); 327 .WillRepeatedly(Return(true));
328 test_light.getState()["state"]["colormode"] = "xy"; 328 test_light.getState()["state"]["colormode"] = "xy";
329 test_light.getState()["state"]["on"] = true; 329 test_light.getState()["state"]["on"] = true;
330 - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 330 + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
331 331
332 EXPECT_CALL(test_light, alert()) 332 EXPECT_CALL(test_light, alert())
333 .Times(AtLeast(2)) 333 .Times(AtLeast(2))
334 .WillOnce(Return(false)) 334 .WillOnce(Return(false))
335 .WillRepeatedly(Return(true)); 335 .WillRepeatedly(Return(true));
336 - EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 336 + EXPECT_EQ( false, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
337 337
338 - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 338 + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
339 339
340 EXPECT_CALL(test_light, OffNoRefresh(_)) 340 EXPECT_CALL(test_light, OffNoRefresh(_))
341 .Times(AtLeast(1)) 341 .Times(AtLeast(1))
342 .WillRepeatedly(Return(true)); 342 .WillRepeatedly(Return(true));
343 test_light.getState()["state"]["on"] = false; 343 test_light.getState()["state"]["on"] = false;
344 - EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1, 0.1, test_light) ); 344 + EXPECT_EQ( true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light) );
345 } 345 }
346 346
347 TEST(SimpleColorHueStrategy, alertRGB) 347 TEST(SimpleColorHueStrategy, alertRGB)