Commit ab6b127803cb884c5532bf2670516aab208a12f7

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent 654ab503

Add Config singleton which allows to change the delays.

Setting all delays to zero significantly speeds up test times.
include/hueplusplus/Hue.h
@@ -360,7 +360,6 @@ private: @@ -360,7 +360,6 @@ private:
360 360
361 std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the 361 std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the
362 //!< bridge 362 //!< bridge
363 - std::chrono::steady_clock::duration refreshDuration;  
364 363
365 std::shared_ptr<APICache> stateCache; 364 std::shared_ptr<APICache> stateCache;
366 ResourceList<HueLight, int> lights; 365 ResourceList<HueLight, int> lights;
include/hueplusplus/HueCommandAPI.h
@@ -135,9 +135,6 @@ private: @@ -135,9 +135,6 @@ private:
135 //! \returns "/api/<username>/<path>" 135 //! \returns "/api/<username>/<path>"
136 std::string CombinedPath(const std::string& path) const; 136 std::string CombinedPath(const std::string& path) const;
137 137
138 -public:  
139 - static constexpr std::chrono::steady_clock::duration minDelay = std::chrono::milliseconds(100);  
140 -  
141 private: 138 private:
142 std::string ip; 139 std::string ip;
143 int port; 140 int port;
include/hueplusplus/HueConfig.h
@@ -23,10 +23,53 @@ @@ -23,10 +23,53 @@
23 #ifndef INCLUDE_HUEPLUSPLUS_HUE_CONFIG_H 23 #ifndef INCLUDE_HUEPLUSPLUS_HUE_CONFIG_H
24 #define INCLUDE_HUEPLUSPLUS_HUE_CONFIG_H 24 #define INCLUDE_HUEPLUSPLUS_HUE_CONFIG_H
25 25
  26 +#include <chrono>
  27 +
26 namespace hueplusplus 28 namespace hueplusplus
27 { 29 {
28 -constexpr uint16_t c_PRE_ALERT_DELAY = 120; //!< Delay for advanced alerts before the actual alert  
29 -constexpr uint16_t c_POST_ALERT_DELAY = 1600; //!< Delay for advanced alerts after the actual alert 30 +//! \brief Configurable delays
  31 +//!
  32 +//! Used to set all delays to zero when running tests.
  33 +class Config
  34 +{
  35 +private:
  36 + using duration = std::chrono::steady_clock::duration;
  37 +
  38 +public:
  39 + //! \brief Delay for advanced alerts before the actual alert
  40 + duration getPreAlertDelay() const { return preAlertDelay; }
  41 + //! \brief Delay for advanced alerts after the actual alert
  42 + duration getPostAlertDelay() const { return postAlertDelay; }
  43 +
  44 + //! \brief Timeout for UPnP multicast request
  45 + duration getUPnPTimeout() const { return upnpTimeout; }
  46 +
  47 + //! \brief Delay between bridge requests
  48 + duration getBridgeRequestDelay() const { return bridgeRequestDelay; }
  49 +
  50 + //! \brief Timeout for Hue::requestUsername, waits until link button was pressed
  51 + duration getRequestUsernameTimeout() const { return requestUsernameDelay; }
  52 +
  53 + //! \brief Interval in which username requests are attempted
  54 + duration getRequestUsernameAttemptInterval() const { return requestUsernameAttemptInterval; }
  55 +
  56 + //! \brief Get config instance
  57 + static Config& instance()
  58 + {
  59 + static Config c;
  60 + return c;
  61 + }
  62 +protected:
  63 + Config() = default;
  64 +
  65 +protected:
  66 + duration preAlertDelay = std::chrono::milliseconds(120);
  67 + duration postAlertDelay = std::chrono::milliseconds(1600);
  68 + duration upnpTimeout = std::chrono::seconds(5);
  69 + duration bridgeRequestDelay = std::chrono::milliseconds(100);
  70 + duration requestUsernameDelay = std::chrono::seconds(35);
  71 + duration requestUsernameAttemptInterval = std::chrono::seconds(1);
  72 +};
30 } // namespace hueplusplus 73 } // namespace hueplusplus
31 74
32 #endif 75 #endif
include/hueplusplus/IHttpHandler.h
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 #ifndef INCLUDE_HUEPLUSPLUS_IHTTPHANDLER_H 23 #ifndef INCLUDE_HUEPLUSPLUS_IHTTPHANDLER_H
24 #define INCLUDE_HUEPLUSPLUS_IHTTPHANDLER_H 24 #define INCLUDE_HUEPLUSPLUS_IHTTPHANDLER_H
25 25
  26 +#include <chrono>
26 #include <iostream> 27 #include <iostream>
27 #include <memory> 28 #include <memory>
28 #include <string> 29 #include <string>
@@ -63,14 +64,14 @@ public: @@ -63,14 +64,14 @@ public:
63 //! \param msg The message that should sent to the specified multicast address 64 //! \param msg The message that should sent to the specified multicast address
64 //! \param adr Optional ip or hostname in dotted decimal notation, default is "239.255.255.250" 65 //! \param adr Optional ip or hostname in dotted decimal notation, default is "239.255.255.250"
65 //! \param port Optional port the request is sent to, default is 1900 66 //! \param port Optional port the request is sent to, default is 1900
66 - //! \param timeout Optional time to wait for responses in seconds, default is 5 67 + //! \param timeout Optional time to wait for responses, default is 5 seconds
67 //! 68 //!
68 //! Blocks for the duration of the timeout. 69 //! Blocks for the duration of the timeout.
69 //! 70 //!
70 //! \return vector of strings containing each received answer 71 //! \return vector of strings containing each received answer
71 //! \throws std::system_error when system or socket operations fail 72 //! \throws std::system_error when system or socket operations fail
72 - virtual std::vector<std::string> sendMulticast(  
73 - const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const = 0; 73 + virtual std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250",
  74 + int port = 1900, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)) const = 0;
74 75
75 //! \brief Send a HTTP request with the given method to the specified host and return the body of the response. 76 //! \brief Send a HTTP request with the given method to the specified host and return the body of the response.
76 //! 77 //!
include/hueplusplus/LinHttpHandler.h
@@ -52,11 +52,11 @@ public: @@ -52,11 +52,11 @@ public:
52 //! address \param adr Optional String that contains an ip or hostname in 52 //! address \param adr Optional String that contains an ip or hostname in
53 //! dotted decimal notation, default is "239.255.255.250" \param port Optional 53 //! dotted decimal notation, default is "239.255.255.250" \param port Optional
54 //! integer that specifies the port to which the request is sent. Default is 54 //! integer that specifies the port to which the request is sent. Default is
55 - //! 1900 \param timeout Optional Integer that specifies the timeout of the  
56 - //! request in seconds. Default is 5 \return Vector containing strings of each 55 + //! 1900 \param timeout Optional The timeout of the
  56 + //! request. Default is 5 seconds \return Vector containing strings of each
57 //! answer received 57 //! answer received
58 - virtual std::vector<std::string> sendMulticast(  
59 - const std::string& msg, const std::string& adr = "239.255.255.250", int port = 1900, int timeout = 5) const; 58 + std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250",
  59 + int port = 1900, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)) const override;
60 }; 60 };
61 } // namespace hueplusplus 61 } // namespace hueplusplus
62 62
include/hueplusplus/WinHttpHandler.h
@@ -58,11 +58,11 @@ public: @@ -58,11 +58,11 @@ public:
58 //! address \param adr Optional String that contains an ip or hostname in 58 //! address \param adr Optional String that contains an ip or hostname in
59 //! dotted decimal notation, default is "239.255.255.250" \param port Optional 59 //! dotted decimal notation, default is "239.255.255.250" \param port Optional
60 //! integer that specifies the port to which the request is sent. Default is 60 //! integer that specifies the port to which the request is sent. Default is
61 - //! 1900 \param timeout Optional Integer that specifies the timeout of the  
62 - //! request in seconds. Default is 5 \return Vector containing strings of each 61 + //! 1900 \param timeout Optional The timeout of the
  62 + //! request. Default is 5 seconds \return Vector containing strings of each
63 //! answer received 63 //! answer received
64 std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250", 64 std::vector<std::string> sendMulticast(const std::string& msg, const std::string& adr = "239.255.255.250",
65 - int port = 1900, int timeout = 5) const override; 65 + int port = 1900, std::chrono::steady_clock::duration timeout = std::chrono::seconds(5)) const override;
66 66
67 private: 67 private:
68 WSADATA wsaData; 68 WSADATA wsaData;
src/ExtendedColorHueStrategy.cpp
@@ -44,12 +44,12 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -44,12 +44,12 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
44 { 44 {
45 return false; 45 return false;
46 } 46 }
47 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 47 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
48 if (!light.alert()) 48 if (!light.alert())
49 { 49 {
50 return false; 50 return false;
51 } 51 }
52 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 52 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
53 if (!on) 53 if (!on)
54 { 54 {
55 light.setColorHueSaturation(oldHue, oldSat, 1); 55 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -68,12 +68,12 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -68,12 +68,12 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
68 { 68 {
69 return false; 69 return false;
70 } 70 }
71 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 71 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
72 if (!light.alert()) 72 if (!light.alert())
73 { 73 {
74 return false; 74 return false;
75 } 75 }
76 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 76 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
77 if (!on) 77 if (!on)
78 { 78 {
79 light.setColorXY(oldX, oldY, 1); 79 light.setColorXY(oldX, oldY, 1);
@@ -91,12 +91,12 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -91,12 +91,12 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
91 { 91 {
92 return false; 92 return false;
93 } 93 }
94 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 94 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
95 if (!light.alert()) 95 if (!light.alert())
96 { 96 {
97 return false; 97 return false;
98 } 98 }
99 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 99 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
100 if (!on) 100 if (!on)
101 { 101 {
102 light.setColorTemperature(oldCT, 1); 102 light.setColorTemperature(oldCT, 1);
@@ -127,12 +127,12 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -127,12 +127,12 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
127 { 127 {
128 return false; 128 return false;
129 } 129 }
130 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 130 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
131 if (!light.alert()) 131 if (!light.alert())
132 { 132 {
133 return false; 133 return false;
134 } 134 }
135 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 135 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
136 if (!on) 136 if (!on)
137 { 137 {
138 light.setColorHueSaturation(oldHue, oldSat, 1); 138 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -151,12 +151,12 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -151,12 +151,12 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
151 { 151 {
152 return false; 152 return false;
153 } 153 }
154 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 154 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
155 if (!light.alert()) 155 if (!light.alert())
156 { 156 {
157 return false; 157 return false;
158 } 158 }
159 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 159 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
160 if (!on) 160 if (!on)
161 { 161 {
162 light.setColorXY(oldX, oldY, 1); 162 light.setColorXY(oldX, oldY, 1);
@@ -174,12 +174,12 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -174,12 +174,12 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
174 { 174 {
175 return false; 175 return false;
176 } 176 }
177 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 177 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
178 if (!light.alert()) 178 if (!light.alert())
179 { 179 {
180 return false; 180 return false;
181 } 181 }
182 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 182 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
183 if (!on) 183 if (!on)
184 { 184 {
185 light.setColorTemperature(oldCT, 1); 185 light.setColorTemperature(oldCT, 1);
@@ -210,12 +210,12 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -210,12 +210,12 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
210 { 210 {
211 return false; 211 return false;
212 } 212 }
213 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 213 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
214 if (!light.alert()) 214 if (!light.alert())
215 { 215 {
216 return false; 216 return false;
217 } 217 }
218 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 218 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
219 if (!on) 219 if (!on)
220 { 220 {
221 light.setColorHueSaturation(oldHue, oldSat, 1); 221 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -234,12 +234,12 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -234,12 +234,12 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
234 { 234 {
235 return false; 235 return false;
236 } 236 }
237 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 237 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
238 if (!light.alert()) 238 if (!light.alert())
239 { 239 {
240 return false; 240 return false;
241 } 241 }
242 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 242 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
243 if (!on) 243 if (!on)
244 { 244 {
245 light.setColorXY(oldX, oldY, 1); 245 light.setColorXY(oldX, oldY, 1);
@@ -257,12 +257,12 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -257,12 +257,12 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
257 { 257 {
258 return false; 258 return false;
259 } 259 }
260 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 260 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
261 if (!light.alert()) 261 if (!light.alert())
262 { 262 {
263 return false; 263 return false;
264 } 264 }
265 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 265 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
266 if (!on) 266 if (!on)
267 { 267 {
268 light.setColorTemperature(oldCT, 1); 268 light.setColorTemperature(oldCT, 1);
src/ExtendedColorTemperatureStrategy.cpp
@@ -85,12 +85,12 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -85,12 +85,12 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
85 { 85 {
86 return false; 86 return false;
87 } 87 }
88 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 88 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
89 if (!light.alert()) 89 if (!light.alert())
90 { 90 {
91 return false; 91 return false;
92 } 92 }
93 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 93 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
94 if (!on) 94 if (!on)
95 { 95 {
96 light.setColorHueSaturation(oldHue, oldSat, 1); 96 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -109,12 +109,12 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -109,12 +109,12 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
109 { 109 {
110 return false; 110 return false;
111 } 111 }
112 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 112 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
113 if (!light.alert()) 113 if (!light.alert())
114 { 114 {
115 return false; 115 return false;
116 } 116 }
117 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 117 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
118 if (!on) 118 if (!on)
119 { 119 {
120 light.setColorXY(oldX, oldY, 1); 120 light.setColorXY(oldX, oldY, 1);
@@ -132,12 +132,12 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -132,12 +132,12 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
132 { 132 {
133 return false; 133 return false;
134 } 134 }
135 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 135 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
136 if (!light.alert()) 136 if (!light.alert())
137 { 137 {
138 return false; 138 return false;
139 } 139 }
140 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 140 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
141 if (!on) 141 if (!on)
142 { 142 {
143 light.setColorTemperature(oldCT, 1); 143 light.setColorTemperature(oldCT, 1);
src/Hue.cpp
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 #include <stdexcept> 31 #include <stdexcept>
32 #include <thread> 32 #include <thread>
33 33
  34 +#include "hueplusplus/HueConfig.h"
34 #include "hueplusplus/HueExceptionMacro.h" 35 #include "hueplusplus/HueExceptionMacro.h"
35 #include "hueplusplus/UPnP.h" 36 #include "hueplusplus/UPnP.h"
36 #include "hueplusplus/Utils.h" 37 #include "hueplusplus/Utils.h"
@@ -160,51 +161,44 @@ int Hue::getBridgePort() const @@ -160,51 +161,44 @@ int Hue::getBridgePort() const
160 161
161 std::string Hue::requestUsername() 162 std::string Hue::requestUsername()
162 { 163 {
163 - std::cout << "Please press the link Button! You've got 35 secs!\n"; // when the link  
164 - // button was  
165 - // pressed we  
166 - // got 30  
167 - // seconds to  
168 - // get our  
169 - // username for  
170 - // control 164 + std::chrono::steady_clock::duration timeout = Config::instance().getRequestUsernameTimeout();
  165 + std::chrono::steady_clock::duration checkInterval = Config::instance().getRequestUsernameAttemptInterval();
  166 + std::cout << "Please press the link Button! You've got "
  167 + << std::chrono::duration_cast<std::chrono::seconds>(timeout).count() << " secs!\n";
171 168
  169 + // when the link button was pressed we got 30 seconds to get our username for control
172 nlohmann::json request; 170 nlohmann::json request;
173 request["devicetype"] = "HuePlusPlus#User"; 171 request["devicetype"] = "HuePlusPlus#User";
174 172
175 nlohmann::json answer; 173 nlohmann::json answer;
176 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); 174 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
177 - std::chrono::steady_clock::time_point lastCheck;  
178 - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(35)) 175 + // do-while loop to check at least once when timeout is 0
  176 + do
179 { 177 {
180 - if (std::chrono::steady_clock::now() - lastCheck > std::chrono::seconds(1)) 178 + std::this_thread::sleep_for(checkInterval);
  179 + answer = http_handler->POSTJson("/api", request, ip, port);
  180 + nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username");
  181 + if (jsonUser != nullptr)
181 { 182 {
182 - lastCheck = std::chrono::steady_clock::now();  
183 - answer = http_handler->POSTJson("/api", request, ip, port);  
184 - nlohmann::json jsonUser = utils::safeGetMember(answer, 0, "success", "username");  
185 - if (jsonUser != nullptr)  
186 - {  
187 - // [{"success":{"username": "<username>"}}]  
188 - username = jsonUser.get<std::string>();  
189 - // Update commands with new username and ip  
190 - setHttpHandler(http_handler);  
191 - std::cout << "Success! Link button was pressed!\n";  
192 - std::cout << "Username is \"" << username << "\"\n";  
193 - break;  
194 - }  
195 - else if (answer.size() > 0 && answer[0].count("error")) 183 + // [{"success":{"username": "<username>"}}]
  184 + username = jsonUser.get<std::string>();
  185 + // Update commands with new username and ip
  186 + setHttpHandler(http_handler);
  187 + std::cout << "Success! Link button was pressed!\n";
  188 + std::cout << "Username is \"" << username << "\"\n";
  189 + break;
  190 + }
  191 + else if (answer.size() > 0 && answer[0].count("error"))
  192 + {
  193 + HueAPIResponseException exception = HueAPIResponseException::Create(CURRENT_FILE_INFO, answer[0]);
  194 + // All errors except 101: Link button not pressed
  195 + if (exception.GetErrorNumber() != 101)
196 { 196 {
197 - HueAPIResponseException exception = HueAPIResponseException::Create(CURRENT_FILE_INFO, answer[0]);  
198 - // All errors except 101: Link button not pressed  
199 - if (exception.GetErrorNumber() != 101)  
200 - {  
201 - throw exception;  
202 - } 197 + throw exception;
203 } 198 }
204 -  
205 - std::this_thread::sleep_until(lastCheck + std::chrono::seconds(1));  
206 } 199 }
207 - } 200 + } while (std::chrono::steady_clock::now() - start < timeout);
  201 +
208 return username; 202 return username;
209 } 203 }
210 204
@@ -425,9 +419,10 @@ std::string Hue::getPictureOfModel(const std::string&amp; model_id) const @@ -425,9 +419,10 @@ std::string Hue::getPictureOfModel(const std::string&amp; model_id) const
425 void Hue::setHttpHandler(std::shared_ptr<const IHttpHandler> handler) 419 void Hue::setHttpHandler(std::shared_ptr<const IHttpHandler> handler)
426 { 420 {
427 http_handler = handler; 421 http_handler = handler;
428 - stateCache = std::make_shared<APICache>("", HueCommandAPI(ip, port, username, handler), refreshDuration); 422 + stateCache
  423 + = std::make_shared<APICache>("", HueCommandAPI(ip, port, username, handler), stateCache->getRefreshDuration());
429 lights = ResourceList<HueLight, int>("/lights", stateCache, "lights", 424 lights = ResourceList<HueLight, int>("/lights", stateCache, "lights",
430 - [factory = HueLightFactory(stateCache->getCommandAPI(), refreshDuration)]( 425 + [factory = HueLightFactory(stateCache->getCommandAPI(), stateCache->getRefreshDuration())](
431 int id, const nlohmann::json& state) mutable { return factory.createLight(state, id); }); 426 int id, const nlohmann::json& state) mutable { return factory.createLight(state, id); });
432 groups = CreateableResourceList<Group, int, CreateGroup>("/groups", stateCache, "groups"); 427 groups = CreateableResourceList<Group, int, CreateGroup>("/groups", stateCache, "groups");
433 schedules = CreateableResourceList<Schedule, int, CreateSchedule>("/schedules", stateCache, "schedules"); 428 schedules = CreateableResourceList<Schedule, int, CreateSchedule>("/schedules", stateCache, "schedules");
src/HueCommandAPI.cpp
@@ -24,12 +24,11 @@ @@ -24,12 +24,11 @@
24 24
25 #include <thread> 25 #include <thread>
26 26
  27 +#include "hueplusplus/HueConfig.h"
27 #include "hueplusplus/HueExceptionMacro.h" 28 #include "hueplusplus/HueExceptionMacro.h"
28 29
29 namespace hueplusplus 30 namespace hueplusplus
30 { 31 {
31 -constexpr std::chrono::steady_clock::duration HueCommandAPI::minDelay;  
32 -  
33 namespace 32 namespace
34 { 33 {
35 // Runs functor with appropriate timeout and retries when timed out or connection reset 34 // Runs functor with appropriate timeout and retries when timed out or connection reset
@@ -81,7 +80,7 @@ nlohmann::json HueCommandAPI::PUTRequest(const std::string&amp; path, const nlohmann @@ -81,7 +80,7 @@ nlohmann::json HueCommandAPI::PUTRequest(const std::string&amp; path, const nlohmann
81 nlohmann::json HueCommandAPI::PUTRequest( 80 nlohmann::json HueCommandAPI::PUTRequest(
82 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 81 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
83 { 82 {
84 - return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { 83 + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
85 return httpHandler->PUTJson(CombinedPath(path), request, ip, port); 84 return httpHandler->PUTJson(CombinedPath(path), request, ip, port);
86 })); 85 }));
87 } 86 }
@@ -94,7 +93,7 @@ nlohmann::json HueCommandAPI::GETRequest(const std::string&amp; path, const nlohmann @@ -94,7 +93,7 @@ nlohmann::json HueCommandAPI::GETRequest(const std::string&amp; path, const nlohmann
94 nlohmann::json HueCommandAPI::GETRequest( 93 nlohmann::json HueCommandAPI::GETRequest(
95 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 94 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
96 { 95 {
97 - return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { 96 + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
98 return httpHandler->GETJson(CombinedPath(path), request, ip, port); 97 return httpHandler->GETJson(CombinedPath(path), request, ip, port);
99 })); 98 }));
100 } 99 }
@@ -107,7 +106,7 @@ nlohmann::json HueCommandAPI::DELETERequest(const std::string&amp; path, const nlohm @@ -107,7 +106,7 @@ nlohmann::json HueCommandAPI::DELETERequest(const std::string&amp; path, const nlohm
107 nlohmann::json HueCommandAPI::DELETERequest( 106 nlohmann::json HueCommandAPI::DELETERequest(
108 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 107 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
109 { 108 {
110 - return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { 109 + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
111 return httpHandler->DELETEJson(CombinedPath(path), request, ip, port); 110 return httpHandler->DELETEJson(CombinedPath(path), request, ip, port);
112 })); 111 }));
113 } 112 }
@@ -120,7 +119,7 @@ nlohmann::json HueCommandAPI::POSTRequest(const std::string&amp; path, const nlohman @@ -120,7 +119,7 @@ nlohmann::json HueCommandAPI::POSTRequest(const std::string&amp; path, const nlohman
120 nlohmann::json HueCommandAPI::POSTRequest( 119 nlohmann::json HueCommandAPI::POSTRequest(
121 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 120 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
122 { 121 {
123 - return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { 122 + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, Config::instance().getBridgeRequestDelay(), [&]() {
124 return httpHandler->POSTJson(CombinedPath(path), request, ip, port); 123 return httpHandler->POSTJson(CombinedPath(path), request, ip, port);
125 })); 124 }));
126 } 125 }
src/LinHttpHandler.cpp
@@ -139,7 +139,7 @@ std::string LinHttpHandler::send(const std::string&amp; msg, const std::string&amp; adr, @@ -139,7 +139,7 @@ std::string LinHttpHandler::send(const std::string&amp; msg, const std::string&amp; adr,
139 } 139 }
140 140
141 std::vector<std::string> LinHttpHandler::sendMulticast( 141 std::vector<std::string> LinHttpHandler::sendMulticast(
142 - const std::string& msg, const std::string& adr, int port, int timeout) const 142 + const std::string& msg, const std::string& adr, int port, std::chrono::steady_clock::duration timeout) const
143 { 143 {
144 hostent* server; // host information 144 hostent* server; // host information
145 sockaddr_in server_addr; // server address 145 sockaddr_in server_addr; // server address
@@ -187,7 +187,7 @@ std::vector&lt;std::string&gt; LinHttpHandler::sendMulticast( @@ -187,7 +187,7 @@ std::vector&lt;std::string&gt; LinHttpHandler::sendMulticast(
187 char buffer[2048] = {}; // receive buffer 187 char buffer[2048] = {}; // receive buffer
188 188
189 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); 189 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
190 - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(timeout)) 190 + while (std::chrono::steady_clock::now() - start < timeout)
191 { 191 {
192 ssize_t bytesReceived = recv(socketFD, &buffer, 2048, MSG_DONTWAIT); 192 ssize_t bytesReceived = recv(socketFD, &buffer, 2048, MSG_DONTWAIT);
193 if (bytesReceived < 0) 193 if (bytesReceived < 0)
src/SimpleColorHueStrategy.cpp
@@ -97,12 +97,12 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -97,12 +97,12 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
97 { 97 {
98 return false; 98 return false;
99 } 99 }
100 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 100 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
101 if (!light.alert()) 101 if (!light.alert())
102 { 102 {
103 return false; 103 return false;
104 } 104 }
105 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 105 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
106 if (!on) 106 if (!on)
107 { 107 {
108 light.setColorHueSaturation(oldHue, oldSat, 1); 108 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -121,12 +121,12 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -121,12 +121,12 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
121 { 121 {
122 return false; 122 return false;
123 } 123 }
124 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 124 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
125 if (!light.alert()) 125 if (!light.alert())
126 { 126 {
127 return false; 127 return false;
128 } 128 }
129 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 129 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
130 if (!on) 130 if (!on)
131 { 131 {
132 light.setColorXY(oldX, oldY, 1); 132 light.setColorXY(oldX, oldY, 1);
@@ -157,12 +157,12 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -157,12 +157,12 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
157 { 157 {
158 return false; 158 return false;
159 } 159 }
160 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 160 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
161 if (!light.alert()) 161 if (!light.alert())
162 { 162 {
163 return false; 163 return false;
164 } 164 }
165 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 165 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
166 if (!on) 166 if (!on)
167 { 167 {
168 light.setColorHueSaturation(oldHue, oldSat, 1); 168 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -181,12 +181,12 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -181,12 +181,12 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
181 { 181 {
182 return false; 182 return false;
183 } 183 }
184 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 184 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
185 if (!light.alert()) 185 if (!light.alert())
186 { 186 {
187 return false; 187 return false;
188 } 188 }
189 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 189 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
190 if (!on) 190 if (!on)
191 { 191 {
192 light.setColorXY(oldX, oldY, 1); 192 light.setColorXY(oldX, oldY, 1);
@@ -217,12 +217,12 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -217,12 +217,12 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
217 { 217 {
218 return false; 218 return false;
219 } 219 }
220 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 220 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
221 if (!light.alert()) 221 if (!light.alert())
222 { 222 {
223 return false; 223 return false;
224 } 224 }
225 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 225 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
226 if (!on) 226 if (!on)
227 { 227 {
228 light.setColorHueSaturation(oldHue, oldSat, 1); 228 light.setColorHueSaturation(oldHue, oldSat, 1);
@@ -241,12 +241,12 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -241,12 +241,12 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
241 { 241 {
242 return false; 242 return false;
243 } 243 }
244 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 244 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
245 if (!light.alert()) 245 if (!light.alert())
246 { 246 {
247 return false; 247 return false;
248 } 248 }
249 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 249 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
250 if (!on) 250 if (!on)
251 { 251 {
252 light.setColorXY(oldX, oldY, 1); 252 light.setColorXY(oldX, oldY, 1);
src/SimpleColorTemperatureStrategy.cpp
@@ -50,12 +50,12 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig @@ -50,12 +50,12 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig
50 { 50 {
51 return false; 51 return false;
52 } 52 }
53 - std::this_thread::sleep_for(std::chrono::milliseconds(c_PRE_ALERT_DELAY)); 53 + std::this_thread::sleep_for(Config::instance().getPreAlertDelay());
54 if (!light.alert()) 54 if (!light.alert())
55 { 55 {
56 return false; 56 return false;
57 } 57 }
58 - std::this_thread::sleep_for(std::chrono::milliseconds(c_POST_ALERT_DELAY)); 58 + std::this_thread::sleep_for(Config::instance().getPostAlertDelay());
59 if (!on) 59 if (!on)
60 { 60 {
61 light.setColorTemperature(oldCT, 1); 61 light.setColorTemperature(oldCT, 1);
src/UPnP.cpp
@@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
25 #include <algorithm> 25 #include <algorithm>
26 #include <iostream> 26 #include <iostream>
27 27
  28 +#include "hueplusplus/HueConfig.h"
  29 +
28 namespace hueplusplus 30 namespace hueplusplus
29 { 31 {
30 std::vector<std::pair<std::string, std::string>> UPnP::getDevices(std::shared_ptr<const IHttpHandler> handler) 32 std::vector<std::pair<std::string, std::string>> UPnP::getDevices(std::shared_ptr<const IHttpHandler> handler)
@@ -33,7 +35,7 @@ std::vector&lt;std::pair&lt;std::string, std::string&gt;&gt; UPnP::getDevices(std::shared_pt @@ -33,7 +35,7 @@ std::vector&lt;std::pair&lt;std::string, std::string&gt;&gt; UPnP::getDevices(std::shared_pt
33 std::vector<std::string> foundDevices 35 std::vector<std::string> foundDevices
34 = handler->sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: " 36 = handler->sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
35 "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n", 37 "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
36 - "239.255.255.250", 1900, 5); 38 + "239.255.255.250", 1900, Config::instance().getUPnPTimeout());
37 39
38 std::vector<std::pair<std::string, std::string>> devices; 40 std::vector<std::pair<std::string, std::string>> devices;
39 41
@@ -41,9 +43,19 @@ std::vector&lt;std::pair&lt;std::string, std::string&gt;&gt; UPnP::getDevices(std::shared_pt @@ -41,9 +43,19 @@ std::vector&lt;std::pair&lt;std::string, std::string&gt;&gt; UPnP::getDevices(std::shared_pt
41 for (const std::string& s : foundDevices) 43 for (const std::string& s : foundDevices)
42 { 44 {
43 std::pair<std::string, std::string> device; 45 std::pair<std::string, std::string> device;
44 - int start = s.find("LOCATION:") + 10; 46 + std::size_t start = s.find("LOCATION:");
  47 + if (start == std::string::npos)
  48 + {
  49 + continue;
  50 + }
  51 + start += 10;
45 device.first = s.substr(start, s.find("\r\n", start) - start); 52 device.first = s.substr(start, s.find("\r\n", start) - start);
46 - start = s.find("SERVER:") + 8; 53 + start = s.find("SERVER:");
  54 + if (start == std::string::npos)
  55 + {
  56 + continue;
  57 + }
  58 + start += 8;
47 device.second = s.substr(start, s.find("\r\n", start) - start); 59 device.second = s.substr(start, s.find("\r\n", start) - start);
48 if (std::find_if(devices.begin(), devices.end(), 60 if (std::find_if(devices.begin(), devices.end(),
49 [&](const std::pair<std::string, std::string>& item) { return item.first == device.first; }) 61 [&](const std::pair<std::string, std::string>& item) { return item.first == device.first; })
src/WinHttpHandler.cpp
@@ -174,7 +174,7 @@ std::string WinHttpHandler::send(const std::string&amp; msg, const std::string&amp; adr, @@ -174,7 +174,7 @@ std::string WinHttpHandler::send(const std::string&amp; msg, const std::string&amp; adr,
174 } 174 }
175 175
176 std::vector<std::string> WinHttpHandler::sendMulticast( 176 std::vector<std::string> WinHttpHandler::sendMulticast(
177 - const std::string& msg, const std::string& adr, int port, int timeout) const 177 + const std::string& msg, const std::string& adr, int port, std::chrono::steady_clock::duration timeout) const
178 { 178 {
179 struct addrinfo hints = {}; 179 struct addrinfo hints = {};
180 hints.ai_family = AF_INET; 180 hints.ai_family = AF_INET;
@@ -262,7 +262,7 @@ std::vector&lt;std::string&gt; WinHttpHandler::sendMulticast( @@ -262,7 +262,7 @@ std::vector&lt;std::string&gt; WinHttpHandler::sendMulticast(
262 const int recvbuflen = 2048; 262 const int recvbuflen = 2048;
263 char recvbuf[recvbuflen] = {}; 263 char recvbuf[recvbuflen] = {};
264 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); 264 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
265 - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(timeout)) 265 + while (std::chrono::steady_clock::now() - start < timeout)
266 { 266 {
267 int res = recv(connect_socket, recvbuf, recvbuflen, 0); 267 int res = recv(connect_socket, recvbuf, recvbuflen, 0);
268 if (res > 0) 268 if (res > 0)
test/mocks/mock_BaseHttpHandler.h
@@ -38,7 +38,7 @@ public: @@ -38,7 +38,7 @@ public:
38 MOCK_CONST_METHOD3(send, std::string(const std::string& msg, const std::string& adr, int port)); 38 MOCK_CONST_METHOD3(send, std::string(const std::string& msg, const std::string& adr, int port));
39 39
40 MOCK_CONST_METHOD4( 40 MOCK_CONST_METHOD4(
41 - sendMulticast, std::vector<std::string>(const std::string& msg, const std::string& adr, int port, int timeout)); 41 + sendMulticast, std::vector<std::string>(const std::string& msg, const std::string& adr, int port, std::chrono::steady_clock::duration timeout));
42 }; 42 };
43 43
44 #endif 44 #endif
test/mocks/mock_HttpHandler.h
@@ -39,8 +39,9 @@ public: @@ -39,8 +39,9 @@ public:
39 39
40 MOCK_CONST_METHOD3(sendGetHTTPBody, std::string(const std::string& msg, const std::string& adr, int port)); 40 MOCK_CONST_METHOD3(sendGetHTTPBody, std::string(const std::string& msg, const std::string& adr, int port));
41 41
42 - MOCK_CONST_METHOD4(  
43 - sendMulticast, std::vector<std::string>(const std::string& msg, const std::string& adr, int port, int timeout)); 42 + MOCK_CONST_METHOD4(sendMulticast,
  43 + std::vector<std::string>(
  44 + const std::string& msg, const std::string& adr, int port, std::chrono::steady_clock::duration timeout));
44 45
45 MOCK_CONST_METHOD6(sendHTTPRequest, 46 MOCK_CONST_METHOD6(sendHTTPRequest,
46 std::string(const std::string& method, const std::string& uri, const std::string& content_type, 47 std::string(const std::string& method, const std::string& uri, const std::string& content_type,
test/test_Hue.cpp
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 #include "testhelper.h" 29 #include "testhelper.h"
30 30
31 #include "hueplusplus/Hue.h" 31 #include "hueplusplus/Hue.h"
  32 +#include "hueplusplus/HueConfig.h"
32 #include "json/json.hpp" 33 #include "json/json.hpp"
33 #include "mocks/mock_HttpHandler.h" 34 #include "mocks/mock_HttpHandler.h"
34 35
@@ -47,7 +48,7 @@ protected: @@ -47,7 +48,7 @@ protected:
47 EXPECT_CALL(*handler, 48 EXPECT_CALL(*handler,
48 sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: " 49 sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
49 "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n", 50 "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
50 - "239.255.255.250", 1900, 5)) 51 + "239.255.255.250", 1900, Config::instance().getUPnPTimeout()))
51 .Times(AtLeast(1)) 52 .Times(AtLeast(1))
52 .WillRepeatedly(Return(getMulticastReply())); 53 .WillRepeatedly(Return(getMulticastReply()));
53 54
test/test_HueLight.cpp
@@ -42,73 +42,35 @@ protected: @@ -42,73 +42,35 @@ protected:
42 protected: 42 protected:
43 HueLightTest() 43 HueLightTest()
44 : handler(std::make_shared<MockHttpHandler>()), 44 : handler(std::make_shared<MockHttpHandler>()),
  45 + hue_bridge_state({{"lights",
  46 + {{"1",
  47 + {{"state",
  48 + {{"on", true}, {"bri", 254}, {"ct", 366}, {"alert", "none"}, {"colormode", "ct"},
  49 + {"reachable", true}, {"effect", "none"}}},
  50 + {"swupdate", {{"state", "noupdates"}, {"lastinstall", nullptr}}}, {"type", "Dimmable light"},
  51 + {"name", "Hue lamp 1"}, {"modelid", "LWB004"}, {"manufacturername", "Philips"},
  52 + {"productname", "Hue bloom"}, {"uniqueid", "00:00:00:00:00:00:00:00-00"},
  53 + {"swversion", "5.50.1.19085"}, {"luminaireuniqueid", "0000000"}}},
  54 + {"2",
  55 + {{"state",
  56 + {{"on", false}, {"bri", 0}, {"ct", 366}, {"hue", 12345}, {"sat", 123},
  57 + {"xy", {0.102, 0.102}}, {"alert", "none"}, {"colormode", "ct"}, {"reachable", true},
  58 + {"effect", "none"}}},
  59 + {"swupdate", {{"state", "noupdates"}, {"lastinstall", nullptr}}}, {"type", "Color light"},
  60 + {"name", "Hue lamp 2"}, {"modelid", "LST001"}, {"uniqueid", "11:11:11:11:11:11:11:11-11"},
  61 + {"swversion", "5.50.1.19085"}}},
  62 + {"3",
  63 + {{"state",
  64 + {{"on", false}, {"bri", 254}, {"ct", 366}, {"hue", 12345}, {"sat", 123},
  65 + {"xy", {0.102, 0.102}}, {"alert", "none"}, {"colormode", "ct"}, {"reachable", true},
  66 + {"effect", "none"}}},
  67 + {"swupdate", {{"state", "noupdates"}, {"lastinstall", nullptr}}},
  68 + {"type", "Extended color light"}, {"name", "Hue lamp 3"}, {"modelid", "LCT010"},
  69 + {"manufacturername", "Philips"}, {"productname", "Hue bloom"},
  70 + {"swversion", "5.50.1.19085"}}}}}}),
45 test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler) 71 test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler)
46 { 72 {
47 using namespace ::testing; 73 using namespace ::testing;
48 - hue_bridge_state["lights"] = nlohmann::json::object();  
49 - hue_bridge_state["lights"]["1"] = nlohmann::json::object();  
50 - hue_bridge_state["lights"]["1"]["state"] = nlohmann::json::object();  
51 - hue_bridge_state["lights"]["1"]["state"]["on"] = true;  
52 - hue_bridge_state["lights"]["1"]["state"]["bri"] = 254;  
53 - hue_bridge_state["lights"]["1"]["state"]["ct"] = 366;  
54 - hue_bridge_state["lights"]["1"]["state"]["alert"] = "none";  
55 - hue_bridge_state["lights"]["1"]["state"]["colormode"] = "ct";  
56 - hue_bridge_state["lights"]["1"]["state"]["reachable"] = true;  
57 - hue_bridge_state["lights"]["1"]["state"]["effect"] = "none";  
58 - hue_bridge_state["lights"]["1"]["swupdate"] = nlohmann::json::object();  
59 - hue_bridge_state["lights"]["1"]["swupdate"]["state"] = "noupdates";  
60 - hue_bridge_state["lights"]["1"]["swupdate"]["lastinstall"] = nullptr;  
61 - hue_bridge_state["lights"]["1"]["type"] = "Dimmable light";  
62 - hue_bridge_state["lights"]["1"]["name"] = "Hue lamp 1";  
63 - hue_bridge_state["lights"]["1"]["modelid"] = "LWB004";  
64 - hue_bridge_state["lights"]["1"]["manufacturername"] = "Philips";  
65 - hue_bridge_state["lights"]["1"]["productname"] = "Hue bloom";  
66 - hue_bridge_state["lights"]["1"]["uniqueid"] = "00:00:00:00:00:00:00:00-00";  
67 - hue_bridge_state["lights"]["1"]["swversion"] = "5.50.1.19085";  
68 - hue_bridge_state["lights"]["1"]["luminaireuniqueid"] = "0000000";  
69 - hue_bridge_state["lights"]["2"] = nlohmann::json::object();  
70 - hue_bridge_state["lights"]["2"]["state"] = nlohmann::json::object();  
71 - hue_bridge_state["lights"]["2"]["state"]["on"] = false;  
72 - hue_bridge_state["lights"]["2"]["state"]["bri"] = 0;  
73 - hue_bridge_state["lights"]["2"]["state"]["ct"] = 366;  
74 - hue_bridge_state["lights"]["2"]["state"]["hue"] = 123456;  
75 - hue_bridge_state["lights"]["2"]["state"]["sat"] = 123;  
76 - hue_bridge_state["lights"]["2"]["state"]["xy"][0] = 0.102;  
77 - hue_bridge_state["lights"]["2"]["state"]["xy"][1] = 0.102;  
78 - hue_bridge_state["lights"]["2"]["state"]["alert"] = "none";  
79 - hue_bridge_state["lights"]["2"]["state"]["colormode"] = "ct";  
80 - hue_bridge_state["lights"]["2"]["state"]["reachable"] = true;  
81 - hue_bridge_state["lights"]["2"]["state"]["effect"] = "none";  
82 - hue_bridge_state["lights"]["2"]["swupdate"] = nlohmann::json::object();  
83 - hue_bridge_state["lights"]["2"]["swupdate"]["state"] = "noupdates";  
84 - hue_bridge_state["lights"]["2"]["swupdate"]["lastinstall"] = nullptr;  
85 - hue_bridge_state["lights"]["2"]["type"] = "Color light";  
86 - hue_bridge_state["lights"]["2"]["name"] = "Hue lamp 2";  
87 - hue_bridge_state["lights"]["2"]["modelid"] = "LST001";  
88 - hue_bridge_state["lights"]["2"]["uniqueid"] = "11:11:11:11:11:11:11:11-11";  
89 - hue_bridge_state["lights"]["2"]["swversion"] = "5.50.1.19085";  
90 - hue_bridge_state["lights"]["3"] = nlohmann::json::object();  
91 - hue_bridge_state["lights"]["3"]["state"] = nlohmann::json::object();  
92 - hue_bridge_state["lights"]["3"]["state"]["on"] = false;  
93 - hue_bridge_state["lights"]["3"]["state"]["bri"] = 254;  
94 - hue_bridge_state["lights"]["3"]["state"]["ct"] = 366;  
95 - hue_bridge_state["lights"]["3"]["state"]["hue"] = 123456;  
96 - hue_bridge_state["lights"]["3"]["state"]["sat"] = 123;  
97 - hue_bridge_state["lights"]["3"]["state"]["xy"][0] = 0.102;  
98 - hue_bridge_state["lights"]["3"]["state"]["xy"][1] = 0.102;  
99 - hue_bridge_state["lights"]["3"]["state"]["alert"] = "none";  
100 - hue_bridge_state["lights"]["3"]["state"]["colormode"] = "ct";  
101 - hue_bridge_state["lights"]["3"]["state"]["reachable"] = true;  
102 - hue_bridge_state["lights"]["3"]["state"]["effect"] = "none";  
103 - hue_bridge_state["lights"]["3"]["swupdate"] = nlohmann::json::object();  
104 - hue_bridge_state["lights"]["3"]["swupdate"]["state"] = "noupdates";  
105 - hue_bridge_state["lights"]["3"]["swupdate"]["lastinstall"] = nullptr;  
106 - hue_bridge_state["lights"]["3"]["type"] = "Extended color light";  
107 - hue_bridge_state["lights"]["3"]["name"] = "Hue lamp 3";  
108 - hue_bridge_state["lights"]["3"]["modelid"] = "LCT010";  
109 - hue_bridge_state["lights"]["3"]["manufacturername"] = "Philips";  
110 - hue_bridge_state["lights"]["3"]["productname"] = "Hue bloom";  
111 - hue_bridge_state["lights"]["3"]["swversion"] = "5.50.1.19085";  
112 74
113 EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), 80)) 75 EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), 80))
114 .Times(AtLeast(1)) 76 .Times(AtLeast(1))
@@ -126,7 +88,7 @@ protected: @@ -126,7 +88,7 @@ protected:
126 .Times(AtLeast(1)) 88 .Times(AtLeast(1))
127 .WillRepeatedly(Return(hue_bridge_state["lights"]["3"])); 89 .WillRepeatedly(Return(hue_bridge_state["lights"]["3"]));
128 } 90 }
129 - ~HueLightTest(){}; 91 + ~HueLightTest() {};
130 }; 92 };
131 93
132 TEST_F(HueLightTest, Constructor) 94 TEST_F(HueLightTest, Constructor)
@@ -692,15 +654,15 @@ TEST_F(HueLightTest, getColorHueSaturation) @@ -692,15 +654,15 @@ TEST_F(HueLightTest, getColorHueSaturation)
692 HueLight test_light_3 = test_bridge.getLight(3); 654 HueLight test_light_3 = test_bridge.getLight(3);
693 655
694 EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)), ctest_light_1.getColorHueSaturation()); 656 EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)), ctest_light_1.getColorHueSaturation());
695 - EXPECT_EQ(std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),  
696 - ctest_light_2.getColorHueSaturation());  
697 - EXPECT_EQ(std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)),  
698 - ctest_light_3.getColorHueSaturation()); 657 + EXPECT_EQ(
  658 + std::make_pair(static_cast<uint16_t>(12345), static_cast<uint8_t>(123)), ctest_light_2.getColorHueSaturation());
  659 + EXPECT_EQ(
  660 + std::make_pair(static_cast<uint16_t>(12345), static_cast<uint8_t>(123)), ctest_light_3.getColorHueSaturation());
699 EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)), test_light_1.getColorHueSaturation()); 661 EXPECT_EQ(std::make_pair(static_cast<uint16_t>(0), static_cast<uint8_t>(0)), test_light_1.getColorHueSaturation());
700 EXPECT_EQ( 662 EXPECT_EQ(
701 - std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)), test_light_2.getColorHueSaturation()); 663 + std::make_pair(static_cast<uint16_t>(12345), static_cast<uint8_t>(123)), test_light_2.getColorHueSaturation());
702 EXPECT_EQ( 664 EXPECT_EQ(
703 - std::make_pair(static_cast<uint16_t>(123456), static_cast<uint8_t>(123)), test_light_3.getColorHueSaturation()); 665 + std::make_pair(static_cast<uint16_t>(12345), static_cast<uint8_t>(123)), test_light_3.getColorHueSaturation());
704 } 666 }
705 667
706 TEST_F(HueLightTest, setColorXY) 668 TEST_F(HueLightTest, setColorXY)
test/test_Main.cpp
@@ -21,9 +21,35 @@ @@ -21,9 +21,35 @@
21 **/ 21 **/
22 22
23 #include <gtest/gtest.h> 23 #include <gtest/gtest.h>
  24 +#include <hueplusplus/HueConfig.h>
  25 +
  26 +namespace
  27 +{
  28 +class TestConfig : public hueplusplus::Config
  29 +{
  30 +public:
  31 + TestConfig()
  32 + {
  33 + preAlertDelay = postAlertDelay = upnpTimeout = bridgeRequestDelay = requestUsernameDelay
  34 + = requestUsernameAttemptInterval = std::chrono::seconds(0);
  35 + }
  36 +};
  37 +
  38 +// Environment sets config to disable all delays and speed up tests
  39 +class Environment : public ::testing::Environment
  40 +{
  41 +public:
  42 + ~Environment() override {}
  43 +
  44 + void SetUp() override { hueplusplus::Config::instance() = TestConfig(); }
  45 +
  46 + void TearDown() override {}
  47 +};
  48 +} // namespace
24 49
25 int main(int argc, char** argv) 50 int main(int argc, char** argv)
26 { 51 {
27 ::testing::InitGoogleTest(&argc, argv); 52 ::testing::InitGoogleTest(&argc, argv);
  53 + ::testing::AddGlobalTestEnvironment(new Environment());
28 return RUN_ALL_TESTS(); 54 return RUN_ALL_TESTS();
29 } 55 }
test/test_UPnP.cpp
@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
26 #include "iostream" 26 #include "iostream"
27 #include "testhelper.h" 27 #include "testhelper.h"
28 28
  29 +#include "hueplusplus/HueConfig.h"
29 #include "hueplusplus/UPnP.h" 30 #include "hueplusplus/UPnP.h"
30 #include "json/json.hpp" 31 #include "json/json.hpp"
31 #include "mocks/mock_HttpHandler.h" 32 #include "mocks/mock_HttpHandler.h"
@@ -42,7 +43,7 @@ TEST(UPnP, getDevices) @@ -42,7 +43,7 @@ TEST(UPnP, getDevices)
42 EXPECT_CALL(*handler, 43 EXPECT_CALL(*handler,
43 sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: " 44 sendMulticast("M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: "
44 "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n", 45 "\"ssdp:discover\"\r\nMX: 5\r\nST: ssdp:all\r\n\r\n",
45 - "239.255.255.250", 1900, 5)) 46 + "239.255.255.250", 1900, Config::instance().getUPnPTimeout()))
46 .Times(1) 47 .Times(1)
47 .WillRepeatedly(::testing::Return(getMulticastReply())); 48 .WillRepeatedly(::testing::Return(getMulticastReply()));
48 49