Commit cd30bc7443f7fede4fce158b792397f44962b39c

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

Implement APICache to cache json values returned by the Hue API.

include/hueplusplus/APICache.h 0 → 100644
  1 +/**
  2 + \file APICache.h
  3 + Copyright Notice\n
  4 + Copyright (C) 2020 Jan Rogall - developer\n
  5 + Copyright (C) 2020 Moritz Wirger - developer\n
  6 +
  7 + This file is part of hueplusplus.
  8 +
  9 + hueplusplus is free software: you can redistribute it and/or modify
  10 + it under the terms of the GNU Lesser General Public License as published by
  11 + the Free Software Foundation, either version 3 of the License, or
  12 + (at your option) any later version.
  13 +
  14 + hueplusplus is distributed in the hope that it will be useful,
  15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + GNU Lesser General Public License for more details.
  18 +
  19 + You should have received a copy of the GNU Lesser General Public License
  20 + along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
  21 +**/
  22 +
  23 +#ifndef INCLUDE_API_CACHE_H
  24 +#define INCLUDE_API_CACHE_H
  25 +
  26 +#include <chrono>
  27 +#include <string>
  28 +
  29 +#include "HueCommandAPI.h"
  30 +
  31 +namespace hueplusplus
  32 +{
  33 +//! \brief Caches API GET requests and refreshes regularly.
  34 +class APICache
  35 +{
  36 +public:
  37 + //! \brief Constructs APICache
  38 + //! \param path URL appended after username, may be empty.
  39 + //! \param commands HueCommandAPI for making API requests.
  40 + //! \param refresh Interval between cache refreshing. May be 0 to always refresh.
  41 + APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh);
  42 +
  43 + //! \brief Refresh cache now.
  44 + //! \throws std::system_error when system or socket operations fail
  45 + //! \throws HueException when response contained no body
  46 + //! \throws HueAPIResponseException when response contains an error
  47 + //! \throws nlohmann::json::parse_error when response could not be parsed
  48 + void Refresh();
  49 +
  50 + //! \brief Get cached value, refresh if necessary.
  51 + //! \throws std::system_error when system or socket operations fail
  52 + //! \throws HueException when response contained no body
  53 + //! \throws HueAPIResponseException when response contains an error
  54 + //! \throws nlohmann::json::parse_error when response could not be parsed
  55 + nlohmann::json& GetValue();
  56 + //! \brief Get cached value, does not refresh.
  57 + const nlohmann::json& GetValue() const;
  58 +
  59 + //! \brief Get duration between refreshes.
  60 + std::chrono::steady_clock::duration GetRefreshDuration() const;
  61 +
  62 +private:
  63 + std::string path;
  64 + HueCommandAPI commands;
  65 + std::chrono::steady_clock::duration refreshDuration;
  66 + std::chrono::steady_clock::time_point lastRefresh;
  67 + nlohmann::json value;
  68 +};
  69 +} // namespace hueplusplus
  70 +
  71 +#endif
include/hueplusplus/Hue.h
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 #include <utility> 29 #include <utility>
30 #include <vector> 30 #include <vector>
31 31
  32 +#include "APICache.h"
32 #include "BrightnessStrategy.h" 33 #include "BrightnessStrategy.h"
33 #include "ColorHueStrategy.h" 34 #include "ColorHueStrategy.h"
34 #include "ColorTemperatureStrategy.h" 35 #include "ColorTemperatureStrategy.h"
@@ -123,8 +124,8 @@ public: @@ -123,8 +124,8 @@ public:
123 //! \param username String that specifies the username that is used to control 124 //! \param username String that specifies the username that is used to control
124 //! the bridge. This needs to be acquired in \ref requestUsername 125 //! the bridge. This needs to be acquired in \ref requestUsername
125 //! \param handler HttpHandler for communication with the bridge 126 //! \param handler HttpHandler for communication with the bridge
126 - Hue(const std::string& ip, const int port, const std::string& username,  
127 - std::shared_ptr<const IHttpHandler> handler); 127 + Hue(const std::string& ip, const int port, const std::string& username, std::shared_ptr<const IHttpHandler> handler,
  128 + std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10));
128 129
129 //! \brief Function to get the ip address of the hue bridge 130 //! \brief Function to get the ip address of the hue bridge
130 //! 131 //!
@@ -249,19 +250,10 @@ public: @@ -249,19 +250,10 @@ public:
249 } 250 }
250 251
251 private: 252 private:
252 - //! \brief Function that refreshes the local \ref state of the Hue bridge  
253 - //! \throws std::system_error when system or socket operations fail  
254 - //! \throws HueException when response contained no body  
255 - //! \throws HueAPIResponseException when response contains an error  
256 - //! \throws nlohmann::json::parse_error when response could not be parsed  
257 - void refreshState();  
258 -  
259 -private:  
260 std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation 253 std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation
261 //!< like "192.168.2.1" 254 //!< like "192.168.2.1"
262 std::string username; //!< Username that is ussed to access the hue bridge 255 std::string username; //!< Username that is ussed to access the hue bridge
263 int port; 256 int port;
264 - nlohmann::json state; //!< The state of the hue bridge as it is returned from it  
265 std::map<uint8_t, HueLight> lights; //!< Maps ids to HueLights that are controlled by this bridge 257 std::map<uint8_t, HueLight> lights; //!< Maps ids to HueLights that are controlled by this bridge
266 258
267 std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the 259 std::shared_ptr<BrightnessStrategy> simpleBrightnessStrategy; //!< Strategy that is used for controlling the
@@ -278,6 +270,7 @@ private: @@ -278,6 +270,7 @@ private:
278 std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the 270 std::shared_ptr<const IHttpHandler> http_handler; //!< A IHttpHandler that is used to communicate with the
279 //!< bridge 271 //!< bridge
280 HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge 272 HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge
  273 + APICache stateCache; //!< The state of the hue bridge as it is returned from it
281 }; 274 };
282 } // namespace hueplusplus 275 } // namespace hueplusplus
283 276
include/hueplusplus/HueLight.h
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
25 25
26 #include <memory> 26 #include <memory>
27 27
  28 +#include "APICache.h"
28 #include "BrightnessStrategy.h" 29 #include "BrightnessStrategy.h"
29 #include "ColorHueStrategy.h" 30 #include "ColorHueStrategy.h"
30 #include "ColorTemperatureStrategy.h" 31 #include "ColorTemperatureStrategy.h"
@@ -698,7 +699,8 @@ protected: @@ -698,7 +699,8 @@ protected:
698 //! \throws nlohmann::json::parse_error when response could not be parsed 699 //! \throws nlohmann::json::parse_error when response could not be parsed
699 HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, 700 HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
700 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, 701 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
701 - std::shared_ptr<const ColorHueStrategy> colorHueStrategy); 702 + std::shared_ptr<const ColorHueStrategy> colorHueStrategy,
  703 + std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10));
702 704
703 //! \brief Protected function that sets the brightness strategy. 705 //! \brief Protected function that sets the brightness strategy.
704 //! 706 //!
@@ -735,26 +737,6 @@ protected: @@ -735,26 +737,6 @@ protected:
735 //! \param commandAPI the new HueCommandAPI 737 //! \param commandAPI the new HueCommandAPI
736 virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; }; 738 virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; };
737 739
738 - //! \brief Function that turns the light on without refreshing its state.  
739 - //!  
740 - //! \param transition Optional parameter to set the transition from current state to new standard is 4 = 400ms  
741 - //! \return Bool that is true on success  
742 - //! \throws std::system_error when system or socket operations fail  
743 - //! \throws HueException when response contained no body  
744 - //! \throws HueAPIResponseException when response contains an error  
745 - //! \throws nlohmann::json::parse_error when response could not be parsed  
746 - virtual bool OnNoRefresh(uint8_t transition = 4);  
747 -  
748 - //! \brief Function that turns the light off without refreshing its state.  
749 - //!  
750 - //! \param transition Optional parameter to set the transition from current state to new standard is 4 = 400ms  
751 - //! \return Bool that is true on success  
752 - //! \throws std::system_error when system or socket operations fail  
753 - //! \throws HueException when response contained no body  
754 - //! \throws HueAPIResponseException when response contains an error  
755 - //! \throws nlohmann::json::parse_error when response could not be parsed  
756 - virtual bool OffNoRefresh(uint8_t transition = 4);  
757 -  
758 //! \brief Utility function to send a put request to the light. 740 //! \brief Utility function to send a put request to the light.
759 //! 741 //!
760 //! \throws nlohmann::json::parse_error if the reply could not be parsed 742 //! \throws nlohmann::json::parse_error if the reply could not be parsed
@@ -768,16 +750,9 @@ protected: @@ -768,16 +750,9 @@ protected:
768 //! \throws nlohmann::json::parse_error when response could not be parsed 750 //! \throws nlohmann::json::parse_error when response could not be parsed
769 virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo); 751 virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo);
770 752
771 - //! \brief Virtual function that refreshes the \ref state of the light.  
772 - //! \throws std::system_error when system or socket operations fail  
773 - //! \throws HueException when response contained no body  
774 - //! \throws HueAPIResponseException when response contains an error  
775 - //! \throws nlohmann::json::parse_error when response could not be parsed  
776 - virtual void refreshState();  
777 -  
778 protected: 753 protected:
779 int id; //!< holds the id of the light 754 int id; //!< holds the id of the light
780 - nlohmann::json state; //!< holds the current state of the light updated by \ref refreshState 755 + APICache state; //!< holds the current state of the light updated by \ref refreshState
781 ColorType colorType; //!< holds the \ref ColorType of the light 756 ColorType colorType; //!< holds the \ref ColorType of the light
782 757
783 std::shared_ptr<const BrightnessStrategy> 758 std::shared_ptr<const BrightnessStrategy>
src/APICache.cpp 0 → 100644
  1 +#include "hueplusplus/APICache.h"
  2 +/**
  3 + \file BaseHttpHandler.cpp
  4 + Copyright Notice\n
  5 + Copyright (C) 2020 Jan Rogall - developer\n
  6 + Copyright (C) 2020 Moritz Wirger - developer\n
  7 +
  8 + This file is part of hueplusplus.
  9 +
  10 + hueplusplus is free software: you can redistribute it and/or modify
  11 + it under the terms of the GNU Lesser General Public License as published by
  12 + the Free Software Foundation, either version 3 of the License, or
  13 + (at your option) any later version.
  14 +
  15 + hueplusplus is distributed in the hope that it will be useful,
  16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + GNU Lesser General Public License for more details.
  19 +
  20 + You should have received a copy of the GNU Lesser General Public License
  21 + along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
  22 +**/
  23 +
  24 +#include "hueplusplus/HueExceptionMacro.h"
  25 +
  26 +hueplusplus::APICache::APICache(
  27 + const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh)
  28 + : path(path),
  29 + commands(commands),
  30 + refreshDuration(refresh),
  31 + lastRefresh(std::chrono::steady_clock::duration::zero())
  32 +{}
  33 +
  34 +void hueplusplus::APICache::Refresh() {
  35 + value = commands.GETRequest(path, nlohmann::json::object(), CURRENT_FILE_INFO);
  36 +}
  37 +
  38 +nlohmann::json& hueplusplus::APICache::GetValue()
  39 +{
  40 + if (std::chrono::steady_clock::now() >= lastRefresh + refreshDuration)
  41 + {
  42 + Refresh();
  43 + }
  44 + return value;
  45 +}
  46 +
  47 +const nlohmann::json& hueplusplus::APICache::GetValue() const
  48 +{
  49 + return value;
  50 +}
  51 +
  52 +std::chrono::steady_clock::duration hueplusplus::APICache::GetRefreshDuration() const
  53 +{
  54 + return refreshDuration;
  55 +}
src/CMakeLists.txt
1 set(hueplusplus_SOURCES 1 set(hueplusplus_SOURCES
  2 + APICache.cpp
2 BaseHttpHandler.cpp 3 BaseHttpHandler.cpp
3 ExtendedColorHueStrategy.cpp 4 ExtendedColorHueStrategy.cpp
4 ExtendedColorTemperatureStrategy.cpp 5 ExtendedColorTemperatureStrategy.cpp
src/ExtendedColorHueStrategy.cpp
@@ -32,13 +32,14 @@ namespace hueplusplus @@ -32,13 +32,14 @@ namespace hueplusplus
32 { 32 {
33 bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const 33 bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const
34 { 34 {
35 - light.refreshState();  
36 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
37 - bool on = light.state["state"]["on"].get<bool>(); 35 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  36 + const nlohmann::json& state = light.state.GetValue()["state"];
  37 + std::string cType = state["colormode"].get<std::string>();
  38 + bool on = state["on"].get<bool>();
38 if (cType == "hs") 39 if (cType == "hs")
39 { 40 {
40 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
41 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 41 + uint16_t oldHue = state["hue"].get<uint16_t>();
  42 + uint8_t oldSat = state["sat"].get<uint8_t>();
42 if (!light.setColorHueSaturation(hue, sat, 1)) 43 if (!light.setColorHueSaturation(hue, sat, 1))
43 { 44 {
44 return false; 45 return false;
@@ -52,7 +53,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -52,7 +53,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
52 if (!on) 53 if (!on)
53 { 54 {
54 light.setColorHueSaturation(oldHue, oldSat, 1); 55 light.setColorHueSaturation(oldHue, oldSat, 1);
55 - return light.OffNoRefresh(1); 56 + return light.Off(1);
56 } 57 }
57 else 58 else
58 { 59 {
@@ -61,8 +62,8 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -61,8 +62,8 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
61 } 62 }
62 else if (cType == "xy") 63 else if (cType == "xy")
63 { 64 {
64 - float oldX = light.state["state"]["xy"][0].get<float>();  
65 - float oldY = light.state["state"]["xy"][1].get<float>(); 65 + float oldX = state["xy"][0].get<float>();
  66 + float oldY = state["xy"][1].get<float>();
66 if (!light.setColorHueSaturation(hue, sat, 1)) 67 if (!light.setColorHueSaturation(hue, sat, 1))
67 { 68 {
68 return false; 69 return false;
@@ -76,7 +77,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -76,7 +77,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
76 if (!on) 77 if (!on)
77 { 78 {
78 light.setColorXY(oldX, oldY, 1); 79 light.setColorXY(oldX, oldY, 1);
79 - return light.OffNoRefresh(1); 80 + return light.Off(1);
80 } 81 }
81 else 82 else
82 { 83 {
@@ -85,7 +86,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -85,7 +86,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
85 } 86 }
86 else if (cType == "ct") 87 else if (cType == "ct")
87 { 88 {
88 - uint16_t oldCT = light.state["state"]["ct"].get<uint16_t>(); 89 + uint16_t oldCT = state["ct"].get<uint16_t>();
89 if (!light.setColorHueSaturation(hue, sat, 1)) 90 if (!light.setColorHueSaturation(hue, sat, 1))
90 { 91 {
91 return false; 92 return false;
@@ -99,7 +100,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -99,7 +100,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
99 if (!on) 100 if (!on)
100 { 101 {
101 light.setColorTemperature(oldCT, 1); 102 light.setColorTemperature(oldCT, 1);
102 - return light.OffNoRefresh(1); 103 + return light.Off(1);
103 } 104 }
104 else 105 else
105 { 106 {
@@ -114,13 +115,14 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue @@ -114,13 +115,14 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue
114 115
115 bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const 116 bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const
116 { 117 {
117 - light.refreshState();  
118 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
119 - bool on = light.state["state"]["on"].get<bool>(); 118 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  119 + const nlohmann::json& state = light.state.GetValue()["state"];
  120 + std::string cType = state["colormode"].get<std::string>();
  121 + bool on = state["on"].get<bool>();
120 if (cType == "hs") 122 if (cType == "hs")
121 { 123 {
122 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
123 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 124 + uint16_t oldHue = state["hue"].get<uint16_t>();
  125 + uint8_t oldSat = state["sat"].get<uint8_t>();
124 if (!light.setColorXY(x, y, 1)) 126 if (!light.setColorXY(x, y, 1))
125 { 127 {
126 return false; 128 return false;
@@ -134,7 +136,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -134,7 +136,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
134 if (!on) 136 if (!on)
135 { 137 {
136 light.setColorHueSaturation(oldHue, oldSat, 1); 138 light.setColorHueSaturation(oldHue, oldSat, 1);
137 - return light.OffNoRefresh(1); 139 + return light.Off(1);
138 } 140 }
139 else 141 else
140 { 142 {
@@ -143,8 +145,8 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -143,8 +145,8 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
143 } 145 }
144 else if (cType == "xy") 146 else if (cType == "xy")
145 { 147 {
146 - float oldX = light.state["state"]["xy"][0].get<float>();  
147 - float oldY = light.state["state"]["xy"][1].get<float>(); 148 + float oldX = state["xy"][0].get<float>();
  149 + float oldY = state["xy"][1].get<float>();
148 if (!light.setColorXY(x, y, 1)) 150 if (!light.setColorXY(x, y, 1))
149 { 151 {
150 return false; 152 return false;
@@ -158,7 +160,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -158,7 +160,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
158 if (!on) 160 if (!on)
159 { 161 {
160 light.setColorXY(oldX, oldY, 1); 162 light.setColorXY(oldX, oldY, 1);
161 - return light.OffNoRefresh(1); 163 + return light.Off(1);
162 } 164 }
163 else 165 else
164 { 166 {
@@ -167,7 +169,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -167,7 +169,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
167 } 169 }
168 else if (cType == "ct") 170 else if (cType == "ct")
169 { 171 {
170 - uint16_t oldCT = light.state["state"]["ct"].get<uint16_t>(); 172 + uint16_t oldCT = state["ct"].get<uint16_t>();
171 if (!light.setColorXY(x, y, 1)) 173 if (!light.setColorXY(x, y, 1))
172 { 174 {
173 return false; 175 return false;
@@ -181,7 +183,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -181,7 +183,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
181 if (!on) 183 if (!on)
182 { 184 {
183 light.setColorTemperature(oldCT, 1); 185 light.setColorTemperature(oldCT, 1);
184 - return light.OffNoRefresh(1); 186 + return light.Off(1);
185 } 187 }
186 else 188 else
187 { 189 {
@@ -196,13 +198,14 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -196,13 +198,14 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
196 198
197 bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const 199 bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const
198 { 200 {
199 - light.refreshState();  
200 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
201 - bool on = light.state["state"]["on"].get<bool>(); 201 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  202 + const nlohmann::json& state = light.state.GetValue()["state"];
  203 + std::string cType = state["colormode"];
  204 + bool on = state["on"];
202 if (cType == "hs") 205 if (cType == "hs")
203 { 206 {
204 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
205 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 207 + uint16_t oldHue = state["hue"].get<uint16_t>();
  208 + uint8_t oldSat = state["sat"].get<uint8_t>();
206 if (!light.setColorRGB(r, g, b, 1)) 209 if (!light.setColorRGB(r, g, b, 1))
207 { 210 {
208 return false; 211 return false;
@@ -216,7 +219,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -216,7 +219,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
216 if (!on) 219 if (!on)
217 { 220 {
218 light.setColorHueSaturation(oldHue, oldSat, 1); 221 light.setColorHueSaturation(oldHue, oldSat, 1);
219 - return light.OffNoRefresh(1); 222 + return light.Off(1);
220 } 223 }
221 else 224 else
222 { 225 {
@@ -225,8 +228,8 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -225,8 +228,8 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
225 } 228 }
226 else if (cType == "xy") 229 else if (cType == "xy")
227 { 230 {
228 - float oldX = light.state["state"]["xy"][0].get<float>();  
229 - float oldY = light.state["state"]["xy"][1].get<float>(); 231 + float oldX = state["xy"][0].get<float>();
  232 + float oldY = state["xy"][1].get<float>();
230 if (!light.setColorRGB(r, g, b, 1)) 233 if (!light.setColorRGB(r, g, b, 1))
231 { 234 {
232 return false; 235 return false;
@@ -240,7 +243,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -240,7 +243,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
240 if (!on) 243 if (!on)
241 { 244 {
242 light.setColorXY(oldX, oldY, 1); 245 light.setColorXY(oldX, oldY, 1);
243 - return light.OffNoRefresh(1); 246 + return light.Off(1);
244 } 247 }
245 else 248 else
246 { 249 {
@@ -249,7 +252,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -249,7 +252,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
249 } 252 }
250 else if (cType == "ct") 253 else if (cType == "ct")
251 { 254 {
252 - uint16_t oldCT = light.state["state"]["ct"].get<uint16_t>(); 255 + uint16_t oldCT = state["ct"].get<uint16_t>();
253 if (!light.setColorRGB(r, g, b, 1)) 256 if (!light.setColorRGB(r, g, b, 1))
254 { 257 {
255 return false; 258 return false;
@@ -263,7 +266,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh @@ -263,7 +266,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh
263 if (!on) 266 if (!on)
264 { 267 {
265 light.setColorTemperature(oldCT, 1); 268 light.setColorTemperature(oldCT, 1);
266 - return light.OffNoRefresh(1); 269 + return light.Off(1);
267 } 270 }
268 else 271 else
269 { 272 {
src/ExtendedColorTemperatureStrategy.cpp
@@ -35,17 +35,18 @@ namespace hueplusplus @@ -35,17 +35,18 @@ namespace hueplusplus
35 bool ExtendedColorTemperatureStrategy::setColorTemperature( 35 bool ExtendedColorTemperatureStrategy::setColorTemperature(
36 unsigned int mired, uint8_t transition, HueLight& light) const 36 unsigned int mired, uint8_t transition, HueLight& light) const
37 { 37 {
38 - light.refreshState(); 38 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  39 + const nlohmann::json& state = light.state.GetValue()["state"];
39 nlohmann::json request = nlohmann::json::object(); 40 nlohmann::json request = nlohmann::json::object();
40 if (transition != 4) 41 if (transition != 4)
41 { 42 {
42 request["transitiontime"] = transition; 43 request["transitiontime"] = transition;
43 } 44 }
44 - if (light.state["state"]["on"] != true) 45 + if (state["on"] != true)
45 { 46 {
46 request["on"] = true; 47 request["on"] = true;
47 } 48 }
48 - if (light.state["state"]["ct"] != mired || light.state["state"]["colormode"] != "ct") 49 + if (state["ct"] != mired || state["colormode"] != "ct")
49 { 50 {
50 if (mired > 500) 51 if (mired > 500)
51 { 52 {
@@ -72,13 +73,14 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature( @@ -72,13 +73,14 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature(
72 73
73 bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const 74 bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const
74 { 75 {
75 - light.refreshState();  
76 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
77 - bool on = light.state["state"]["on"].get<bool>(); 76 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  77 + const nlohmann::json& state = light.state.GetValue()["state"];
  78 + std::string cType = state["colormode"].get<std::string>();
  79 + bool on = state["on"].get<bool>();
78 if (cType == "hs") 80 if (cType == "hs")
79 { 81 {
80 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
81 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 82 + uint16_t oldHue = state["hue"].get<uint16_t>();
  83 + uint8_t oldSat = state["sat"].get<uint8_t>();
82 if (!light.setColorTemperature(mired, 1)) 84 if (!light.setColorTemperature(mired, 1))
83 { 85 {
84 return false; 86 return false;
@@ -92,7 +94,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -92,7 +94,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
92 if (!on) 94 if (!on)
93 { 95 {
94 light.setColorHueSaturation(oldHue, oldSat, 1); 96 light.setColorHueSaturation(oldHue, oldSat, 1);
95 - return light.OffNoRefresh(1); 97 + return light.Off(1);
96 } 98 }
97 else 99 else
98 { 100 {
@@ -101,8 +103,8 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -101,8 +103,8 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
101 } 103 }
102 else if (cType == "xy") 104 else if (cType == "xy")
103 { 105 {
104 - float oldX = light.state["state"]["xy"][0].get<float>();  
105 - float oldY = light.state["state"]["xy"][1].get<float>(); 106 + float oldX = state["xy"][0].get<float>();
  107 + float oldY = state["xy"][1].get<float>();
106 if (!light.setColorTemperature(mired, 1)) 108 if (!light.setColorTemperature(mired, 1))
107 { 109 {
108 return false; 110 return false;
@@ -116,7 +118,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -116,7 +118,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
116 if (!on) 118 if (!on)
117 { 119 {
118 light.setColorXY(oldX, oldY, 1); 120 light.setColorXY(oldX, oldY, 1);
119 - return light.OffNoRefresh(1); 121 + return light.Off(1);
120 } 122 }
121 else 123 else
122 { 124 {
@@ -125,7 +127,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -125,7 +127,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
125 } 127 }
126 else if (cType == "ct") 128 else if (cType == "ct")
127 { 129 {
128 - uint16_t oldCT = light.state["state"]["ct"].get<uint16_t>(); 130 + uint16_t oldCT = state["ct"].get<uint16_t>();
129 if (!light.setColorTemperature(mired, 1)) 131 if (!light.setColorTemperature(mired, 1))
130 { 132 {
131 return false; 133 return false;
@@ -139,7 +141,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL @@ -139,7 +141,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL
139 if (!on) 141 if (!on)
140 { 142 {
141 light.setColorTemperature(oldCT, 1); 143 light.setColorTemperature(oldCT, 1);
142 - return light.OffNoRefresh(1); 144 + return light.Off(1);
143 } 145 }
144 else 146 else
145 { 147 {
src/Hue.cpp
@@ -135,8 +135,8 @@ std::string HueFinder::ParseDescription(const std::string&amp; description) @@ -135,8 +135,8 @@ std::string HueFinder::ParseDescription(const std::string&amp; description)
135 return std::string(); 135 return std::string();
136 } 136 }
137 137
138 -Hue::Hue(  
139 - const std::string& ip, const int port, const std::string& username, std::shared_ptr<const IHttpHandler> handler) 138 +Hue::Hue(const std::string& ip, const int port, const std::string& username,
  139 + std::shared_ptr<const IHttpHandler> handler, std::chrono::steady_clock::duration refreshDuration)
140 : ip(ip), 140 : ip(ip),
141 port(port), 141 port(port),
142 username(username), 142 username(username),
@@ -146,7 +146,8 @@ Hue::Hue( @@ -146,7 +146,8 @@ Hue::Hue(
146 simpleColorTemperatureStrategy(std::make_shared<SimpleColorTemperatureStrategy>()), 146 simpleColorTemperatureStrategy(std::make_shared<SimpleColorTemperatureStrategy>()),
147 extendedColorTemperatureStrategy(std::make_shared<ExtendedColorTemperatureStrategy>()), 147 extendedColorTemperatureStrategy(std::make_shared<ExtendedColorTemperatureStrategy>()),
148 http_handler(std::move(handler)), 148 http_handler(std::move(handler)),
149 - commands(ip, port, username, http_handler) 149 + commands(ip, port, username, http_handler),
  150 + stateCache("", commands, refreshDuration)
150 {} 151 {}
151 152
152 std::string Hue::getBridgeIP() 153 std::string Hue::getBridgeIP()
@@ -189,6 +190,7 @@ std::string Hue::requestUsername() @@ -189,6 +190,7 @@ std::string Hue::requestUsername()
189 username = jsonUser.get<std::string>(); 190 username = jsonUser.get<std::string>();
190 // Update commands with new username and ip 191 // Update commands with new username and ip
191 commands = HueCommandAPI(ip, port, username, http_handler); 192 commands = HueCommandAPI(ip, port, username, http_handler);
  193 + stateCache = APICache("", commands, stateCache.GetRefreshDuration());
192 std::cout << "Success! Link button was pressed!\n"; 194 std::cout << "Success! Link button was pressed!\n";
193 std::cout << "Username is \"" << username << "\"\n"; 195 std::cout << "Username is \"" << username << "\"\n";
194 break; 196 break;
@@ -228,18 +230,16 @@ HueLight&amp; Hue::getLight(int id) @@ -228,18 +230,16 @@ HueLight&amp; Hue::getLight(int id)
228 auto pos = lights.find(id); 230 auto pos = lights.find(id);
229 if (pos != lights.end()) 231 if (pos != lights.end())
230 { 232 {
231 - pos->second.refreshState(); 233 + pos->second.state.Refresh();
232 return pos->second; 234 return pos->second;
233 } 235 }
234 - refreshState();  
235 - if (!state["lights"].count(std::to_string(id))) 236 + const nlohmann::json& lightsCache = stateCache.GetValue()["lights"];
  237 + if (!lightsCache.count(std::to_string(id)))
236 { 238 {
237 std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n"; 239 std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n";
238 throw HueException(CURRENT_FILE_INFO, "Light id is not valid"); 240 throw HueException(CURRENT_FILE_INFO, "Light id is not valid");
239 } 241 }
240 - // std::cout << state["lights"][std::to_string(id)] << std::endl;  
241 - std::string type = state["lights"][std::to_string(id)]["modelid"].get<std::string>();  
242 - // std::cout << type << std::endl; 242 + std::string type = lightsCache[std::to_string(id)]["modelid"].get<std::string>();
243 auto light = MakeHueLight()(type, id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, 243 auto light = MakeHueLight()(type, id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy,
244 simpleColorTemperatureStrategy, extendedColorHueStrategy, simpleColorHueStrategy); 244 simpleColorTemperatureStrategy, extendedColorHueStrategy, simpleColorHueStrategy);
245 lights.emplace(id, light); 245 lights.emplace(id, light);
@@ -260,9 +260,9 @@ bool Hue::removeLight(int id) @@ -260,9 +260,9 @@ bool Hue::removeLight(int id)
260 260
261 std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights() 261 std::vector<std::reference_wrapper<HueLight>> Hue::getAllLights()
262 { 262 {
263 - refreshState();  
264 - nlohmann::json lightsState = state["lights"];  
265 - for (nlohmann::json::iterator it = lightsState.begin(); it != lightsState.end(); ++it) 263 + // No reference because getLight may invalidate it
  264 + nlohmann::json lightsState = stateCache.GetValue()["lights"];
  265 + for (auto it = lightsState.begin(); it != lightsState.end(); ++it)
266 { 266 {
267 getLight(std::stoi(it.key())); 267 getLight(std::stoi(it.key()));
268 } 268 }
@@ -276,13 +276,12 @@ std::vector&lt;std::reference_wrapper&lt;HueLight&gt;&gt; Hue::getAllLights() @@ -276,13 +276,12 @@ std::vector&lt;std::reference_wrapper&lt;HueLight&gt;&gt; Hue::getAllLights()
276 276
277 bool Hue::lightExists(int id) 277 bool Hue::lightExists(int id)
278 { 278 {
279 - refreshState();  
280 auto pos = lights.find(id); 279 auto pos = lights.find(id);
281 if (pos != lights.end()) 280 if (pos != lights.end())
282 { 281 {
283 return true; 282 return true;
284 } 283 }
285 - if (state["lights"].count(std::to_string(id))) 284 + if (stateCache.GetValue()["lights"].count(std::to_string(id)))
286 { 285 {
287 return true; 286 return true;
288 } 287 }
@@ -296,7 +295,7 @@ bool Hue::lightExists(int id) const @@ -296,7 +295,7 @@ bool Hue::lightExists(int id) const
296 { 295 {
297 return true; 296 return true;
298 } 297 }
299 - if (state["lights"].count(std::to_string(id))) 298 + if (stateCache.GetValue()["lights"].count(std::to_string(id)))
300 { 299 {
301 return true; 300 return true;
302 } 301 }
@@ -437,23 +436,4 @@ std::string Hue::getPictureOfModel(const std::string&amp; model_id) const @@ -437,23 +436,4 @@ std::string Hue::getPictureOfModel(const std::string&amp; model_id) const
437 } 436 }
438 return ret; 437 return ret;
439 } 438 }
440 -  
441 -void Hue::refreshState()  
442 -{  
443 - if (username.empty())  
444 - {  
445 - return;  
446 - }  
447 - nlohmann::json answer = commands.GETRequest("", nlohmann::json::object(), CURRENT_FILE_INFO);  
448 - if (answer.is_object() && answer.count("lights"))  
449 - {  
450 - state = answer;  
451 - }  
452 - else  
453 - {  
454 - std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is "  
455 - "not expected!\nAnswer:\n\t"  
456 - << answer.dump() << std::endl;  
457 - }  
458 -}  
459 } // namespace hueplusplus 439 } // namespace hueplusplus
src/HueCommandAPI.cpp
@@ -81,7 +81,7 @@ nlohmann::json HueCommandAPI::PUTRequest(const std::string&amp; path, const nlohmann @@ -81,7 +81,7 @@ nlohmann::json HueCommandAPI::PUTRequest(const std::string&amp; path, const nlohmann
81 nlohmann::json HueCommandAPI::PUTRequest( 81 nlohmann::json HueCommandAPI::PUTRequest(
82 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 82 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
83 { 83 {
84 - return HandleError(fileInfo, 84 + return HandleError(std::move(fileInfo),
85 RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->PUTJson(CombinedPath(path), request, ip); })); 85 RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->PUTJson(CombinedPath(path), request, ip); }));
86 } 86 }
87 87
@@ -93,7 +93,7 @@ nlohmann::json HueCommandAPI::GETRequest(const std::string&amp; path, const nlohmann @@ -93,7 +93,7 @@ nlohmann::json HueCommandAPI::GETRequest(const std::string&amp; path, const nlohmann
93 nlohmann::json HueCommandAPI::GETRequest( 93 nlohmann::json HueCommandAPI::GETRequest(
94 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 94 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
95 { 95 {
96 - return HandleError(fileInfo, 96 + return HandleError(std::move(fileInfo),
97 RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->GETJson(CombinedPath(path), request, ip); })); 97 RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->GETJson(CombinedPath(path), request, ip); }));
98 } 98 }
99 99
@@ -105,7 +105,7 @@ nlohmann::json HueCommandAPI::DELETERequest(const std::string&amp; path, const nlohm @@ -105,7 +105,7 @@ nlohmann::json HueCommandAPI::DELETERequest(const std::string&amp; path, const nlohm
105 nlohmann::json HueCommandAPI::DELETERequest( 105 nlohmann::json HueCommandAPI::DELETERequest(
106 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const 106 const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const
107 { 107 {
108 - return HandleError(fileInfo, 108 + return HandleError(std::move(fileInfo),
109 RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->DELETEJson(CombinedPath(path), request, ip); })); 109 RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->DELETEJson(CombinedPath(path), request, ip); }));
110 } 110 }
111 111
src/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 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 6
7 - This file is part of hueplusplus. 7 + This file is part of hueplusplus.
8 8
9 - hueplusplus is free software: you can redistribute it and/or modify  
10 - it under the terms of the GNU Lesser General Public License as published by  
11 - the Free Software Foundation, either version 3 of the License, or  
12 - (at your option) any later version. 9 + hueplusplus is free software: you can redistribute it and/or modify
  10 + it under the terms of the GNU Lesser General Public License as published by
  11 + the Free Software Foundation, either version 3 of the License, or
  12 + (at your option) any later version.
13 13
14 - hueplusplus is distributed in the hope that it will be useful,  
15 - but WITHOUT ANY WARRANTY; without even the implied warranty of  
16 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
17 - GNU Lesser General Public License for more details. 14 + hueplusplus is distributed in the hope that it will be useful,
  15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + GNU Lesser General Public License for more details.
18 18
19 - You should have received a copy of the GNU Lesser General Public License  
20 - along with hueplusplus. If not, see <http://www.gnu.org/licenses/>. 19 + You should have received a copy of the GNU Lesser General Public License
  20 + along with hueplusplus. If not, see <http://www.gnu.org/licenses/>.
21 **/ 21 **/
22 22
23 #include "hueplusplus/HueLight.h" 23 #include "hueplusplus/HueLight.h"
@@ -34,25 +34,60 @@ namespace hueplusplus @@ -34,25 +34,60 @@ namespace hueplusplus
34 { 34 {
35 bool HueLight::On(uint8_t transition) 35 bool HueLight::On(uint8_t transition)
36 { 36 {
37 - refreshState();  
38 - return OnNoRefresh(transition); 37 + nlohmann::json request = nlohmann::json::object();
  38 + if (transition != 4)
  39 + {
  40 + request["transitiontime"] = transition;
  41 + }
  42 + if (state.GetValue()["state"]["on"] != true)
  43 + {
  44 + request["on"] = true;
  45 + }
  46 +
  47 + if (!request.count("on"))
  48 + {
  49 + // Nothing needs to be changed
  50 + return true;
  51 + }
  52 +
  53 + nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO);
  54 +
  55 + // Check whether request was successful
  56 + return utils::validateReplyForLight(request, reply, id);
39 } 57 }
40 58
41 bool HueLight::Off(uint8_t transition) 59 bool HueLight::Off(uint8_t transition)
42 { 60 {
43 - refreshState();  
44 - return OffNoRefresh(transition); 61 + nlohmann::json request = nlohmann::json::object();
  62 + if (transition != 4)
  63 + {
  64 + request["transitiontime"] = transition;
  65 + }
  66 + if (state.GetValue()["state"]["on"] != false)
  67 + {
  68 + request["on"] = false;
  69 + }
  70 +
  71 + if (!request.count("on"))
  72 + {
  73 + // Nothing needs to be changed
  74 + return true;
  75 + }
  76 +
  77 + nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO);
  78 +
  79 + // Check whether request was successful
  80 + return utils::validateReplyForLight(request, reply, id);
45 } 81 }
46 82
47 bool HueLight::isOn() 83 bool HueLight::isOn()
48 { 84 {
49 - refreshState();  
50 - return state["state"]["on"].get<bool>(); 85 + return state.GetValue()["state"]["on"].get<bool>();
51 } 86 }
52 87
53 bool HueLight::isOn() const 88 bool HueLight::isOn() const
54 { 89 {
55 - return state["state"]["on"].get<bool>(); 90 + return state.GetValue()["state"]["on"].get<bool>();
56 } 91 }
57 92
58 int HueLight::getId() const 93 int HueLight::getId() const
@@ -62,70 +97,52 @@ int HueLight::getId() const @@ -62,70 +97,52 @@ int HueLight::getId() const
62 97
63 std::string HueLight::getType() const 98 std::string HueLight::getType() const
64 { 99 {
65 - return state["type"].get<std::string>(); 100 + return state.GetValue()["type"].get<std::string>();
66 } 101 }
67 102
68 std::string HueLight::getName() 103 std::string HueLight::getName()
69 { 104 {
70 - refreshState();  
71 - return state["name"].get<std::string>(); 105 + return state.GetValue()["name"].get<std::string>();
72 } 106 }
73 107
74 std::string HueLight::getName() const 108 std::string HueLight::getName() const
75 { 109 {
76 - return state["name"].get<std::string>(); 110 + return state.GetValue()["name"].get<std::string>();
77 } 111 }
78 112
79 std::string HueLight::getModelId() const 113 std::string HueLight::getModelId() const
80 { 114 {
81 - return state["modelid"].get<std::string>(); 115 + return state.GetValue()["modelid"].get<std::string>();
82 } 116 }
83 117
84 std::string HueLight::getUId() const 118 std::string HueLight::getUId() const
85 { 119 {
86 - if (state.count("uniqueid"))  
87 - {  
88 - return state["uniqueid"].get<std::string>();  
89 - }  
90 - return std::string(); 120 + return state.GetValue().value("uniqueid", std::string());
91 } 121 }
92 122
93 std::string HueLight::getManufacturername() const 123 std::string HueLight::getManufacturername() const
94 { 124 {
95 - if (state.count("manufacturername"))  
96 - {  
97 - return state["manufacturername"].get<std::string>();  
98 - }  
99 - return std::string(); 125 + return state.GetValue().value("manufacturername", std::string());
100 } 126 }
101 127
102 std::string HueLight::getProductname() const 128 std::string HueLight::getProductname() const
103 { 129 {
104 - if (state.count("productname"))  
105 - {  
106 - return state["productname"].get<std::string>();  
107 - }  
108 - return std::string(); 130 + return state.GetValue().value("productname", std::string());
109 } 131 }
110 132
111 std::string HueLight::getLuminaireUId() const 133 std::string HueLight::getLuminaireUId() const
112 { 134 {
113 - if (state.count("luminaireuniqueid"))  
114 - {  
115 - return state["luminaireuniqueid"].get<std::string>();  
116 - }  
117 - return std::string(); 135 + return state.GetValue().value("luminaireuniqueid", std::string());
118 } 136 }
119 137
120 std::string HueLight::getSwVersion() 138 std::string HueLight::getSwVersion()
121 { 139 {
122 - refreshState();  
123 - return state["swversion"].get<std::string>(); 140 + return state.GetValue()["swversion"].get<std::string>();
124 } 141 }
125 142
126 std::string HueLight::getSwVersion() const 143 std::string HueLight::getSwVersion() const
127 { 144 {
128 - return state["swversion"].get<std::string>(); 145 + return state.GetValue()["swversion"].get<std::string>();
129 } 146 }
130 147
131 bool HueLight::setName(const std::string& name) 148 bool HueLight::setName(const std::string& name)
@@ -134,8 +151,9 @@ bool HueLight::setName(const std::string&amp; name) @@ -134,8 +151,9 @@ bool HueLight::setName(const std::string&amp; name)
134 request["name"] = name; 151 request["name"] = name;
135 nlohmann::json reply = SendPutRequest(request, "/name", CURRENT_FILE_INFO); 152 nlohmann::json reply = SendPutRequest(request, "/name", CURRENT_FILE_INFO);
136 153
137 - // Check whether request was successful  
138 - return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name") == name; 154 + // Check whether request was successful (returned name is not necessarily the actually set name)
  155 + // If it already exists, a number is added, if it is too long to be returned, "Updated" is returned
  156 + return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name").is_string();
139 } 157 }
140 158
141 ColorType HueLight::getColorType() const 159 ColorType HueLight::getColorType() const
@@ -167,89 +185,20 @@ HueLight::HueLight(int id, const HueCommandAPI&amp; commands) : HueLight(id, command @@ -167,89 +185,20 @@ HueLight::HueLight(int id, const HueCommandAPI&amp; commands) : HueLight(id, command
167 185
168 HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy, 186 HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr<const BrightnessStrategy> brightnessStrategy,
169 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy, 187 std::shared_ptr<const ColorTemperatureStrategy> colorTempStrategy,
170 - std::shared_ptr<const ColorHueStrategy> colorHueStrategy) 188 + std::shared_ptr<const ColorHueStrategy> colorHueStrategy, std::chrono::steady_clock::duration refreshDuration)
171 : id(id), 189 : id(id),
172 brightnessStrategy(std::move(brightnessStrategy)), 190 brightnessStrategy(std::move(brightnessStrategy)),
173 colorTemperatureStrategy(std::move(colorTempStrategy)), 191 colorTemperatureStrategy(std::move(colorTempStrategy)),
174 colorHueStrategy(std::move(colorHueStrategy)), 192 colorHueStrategy(std::move(colorHueStrategy)),
175 - commands(commands)  
176 -  
177 -{  
178 - refreshState();  
179 -} 193 + commands(commands),
  194 + state("/lights/" + std::to_string(id), commands, refreshDuration)
180 195
181 -bool HueLight::OnNoRefresh(uint8_t transition)  
182 { 196 {
183 - nlohmann::json request = nlohmann::json::object();  
184 - if (transition != 4)  
185 - {  
186 - request["transitiontime"] = transition;  
187 - }  
188 - if (state["state"]["on"] != true)  
189 - {  
190 - request["on"] = true;  
191 - }  
192 -  
193 - if (!request.count("on"))  
194 - {  
195 - // Nothing needs to be changed  
196 - return true;  
197 - }  
198 -  
199 - nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO);  
200 -  
201 - // Check whether request was successful  
202 - return utils::validateReplyForLight(request, reply, id);  
203 -}  
204 -  
205 -bool HueLight::OffNoRefresh(uint8_t transition)  
206 -{  
207 - nlohmann::json request = nlohmann::json::object();  
208 - if (transition != 4)  
209 - {  
210 - request["transitiontime"] = transition;  
211 - }  
212 - if (state["state"]["on"] != false)  
213 - {  
214 - request["on"] = false;  
215 - }  
216 -  
217 - if (!request.count("on"))  
218 - {  
219 - // Nothing needs to be changed  
220 - return true;  
221 - }  
222 -  
223 - nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO);  
224 -  
225 - // Check whether request was successful  
226 - return utils::validateReplyForLight(request, reply, id); 197 + state.Refresh();
227 } 198 }
228 199
229 nlohmann::json HueLight::SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo) 200 nlohmann::json HueLight::SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo)
230 { 201 {
231 return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request, std::move(fileInfo)); 202 return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request, std::move(fileInfo));
232 } 203 }
233 -  
234 -void HueLight::refreshState()  
235 -{  
236 - // std::chrono::steady_clock::time_point start =  
237 - // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of  
238 - // lamp with id: " << id << ", ip: " << ip << "\n";  
239 - nlohmann::json answer  
240 - = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object(), CURRENT_FILE_INFO);  
241 - if (answer.count("state"))  
242 - {  
243 - state = answer;  
244 - }  
245 - else  
246 - {  
247 - std::cout << "Answer in HueLight::refreshState of "  
248 - "http_handler->GETJson(...) is not expected!\nAnswer:\n\t"  
249 - << answer.dump() << std::endl;  
250 - }  
251 - // std::cout << "\tRefresh state took: " <<  
252 - // std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()  
253 - // - start).count() << "ms" << std::endl;  
254 -}  
255 } // namespace hueplusplus 204 } // namespace hueplusplus
src/SimpleBrightnessStrategy.cpp
@@ -33,12 +33,13 @@ namespace hueplusplus @@ -33,12 +33,13 @@ namespace hueplusplus
33 { 33 {
34 bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const 34 bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const
35 { 35 {
36 - light.refreshState(); 36 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  37 + const nlohmann::json& state = light.state.GetValue()["state"];
37 if (bri == 0) 38 if (bri == 0)
38 { 39 {
39 - if (light.state["state"]["on"] == true) 40 + if (state["on"] == true)
40 { 41 {
41 - return light.OffNoRefresh(transition); 42 + return light.Off(transition);
42 } 43 }
43 else 44 else
44 { 45 {
@@ -52,11 +53,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio @@ -52,11 +53,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio
52 { 53 {
53 request["transitiontime"] = transition; 54 request["transitiontime"] = transition;
54 } 55 }
55 - if (light.state["state"]["on"] != true) 56 + if (state["on"] != true)
56 { 57 {
57 request["on"] = true; 58 request["on"] = true;
58 } 59 }
59 - if (light.state["state"]["bri"] != bri) 60 + if (state["bri"] != bri)
60 { 61 {
61 if (bri > 254) 62 if (bri > 254)
62 { 63 {
@@ -80,12 +81,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio @@ -80,12 +81,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio
80 81
81 unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const 82 unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const
82 { 83 {
83 - light.refreshState();  
84 - return light.state["state"]["bri"].get<unsigned int>(); 84 + return light.state.GetValue()["state"]["bri"].get<unsigned int>();
85 } 85 }
86 86
87 unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const 87 unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const
88 { 88 {
89 - return light.state["state"]["bri"].get<unsigned int>(); 89 + return light.state.GetValue()["state"]["bri"].get<unsigned int>();
90 } 90 }
91 } // namespace hueplusplus 91 } // namespace hueplusplus
src/SimpleColorHueStrategy.cpp
@@ -34,17 +34,18 @@ namespace hueplusplus @@ -34,17 +34,18 @@ namespace hueplusplus
34 { 34 {
35 bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const 35 bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const
36 { 36 {
37 - light.refreshState(); 37 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  38 + const nlohmann::json& state = light.state.GetValue()["state"];
38 nlohmann::json request = nlohmann::json::object(); 39 nlohmann::json request = nlohmann::json::object();
39 if (transition != 4) 40 if (transition != 4)
40 { 41 {
41 request["transitiontime"] = transition; 42 request["transitiontime"] = transition;
42 } 43 }
43 - if (light.state["state"]["on"] != true) 44 + if (state["on"] != true)
44 { 45 {
45 request["on"] = true; 46 request["on"] = true;
46 } 47 }
47 - if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs") 48 + if (state["hue"] != hue || state["colormode"] != "hs")
48 { 49 {
49 hue = hue % 65535; 50 hue = hue % 65535;
50 request["hue"] = hue; 51 request["hue"] = hue;
@@ -64,17 +65,18 @@ bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLi @@ -64,17 +65,18 @@ bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLi
64 65
65 bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const 66 bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const
66 { 67 {
67 - light.refreshState(); 68 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  69 + const nlohmann::json& state = light.state.GetValue()["state"];
68 nlohmann::json request = nlohmann::json::object(); 70 nlohmann::json request = nlohmann::json::object();
69 if (transition != 4) 71 if (transition != 4)
70 { 72 {
71 request["transitiontime"] = transition; 73 request["transitiontime"] = transition;
72 } 74 }
73 - if (light.state["state"]["on"] != true) 75 + if (state["on"] != true)
74 { 76 {
75 request["on"] = true; 77 request["on"] = true;
76 } 78 }
77 - if (light.state["state"]["sat"] != sat) 79 + if (state["sat"] != sat)
78 { 80 {
79 if (sat > 254) 81 if (sat > 254)
80 { 82 {
@@ -97,23 +99,24 @@ bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, @@ -97,23 +99,24 @@ bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition,
97 99
98 bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const 100 bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const
99 { 101 {
100 - light.refreshState(); 102 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  103 + const nlohmann::json& state = light.state.GetValue()["state"];
101 nlohmann::json request = nlohmann::json::object(); 104 nlohmann::json request = nlohmann::json::object();
102 105
103 if (transition != 4) 106 if (transition != 4)
104 { 107 {
105 request["transitiontime"] = transition; 108 request["transitiontime"] = transition;
106 } 109 }
107 - if (light.state["state"]["on"] != true) 110 + if (state["on"] != true)
108 { 111 {
109 request["on"] = true; 112 request["on"] = true;
110 } 113 }
111 - if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs") 114 + if (state["hue"] != hue || state["colormode"] != "hs")
112 { 115 {
113 hue = hue % 65535; 116 hue = hue % 65535;
114 request["hue"] = hue; 117 request["hue"] = hue;
115 } 118 }
116 - if (light.state["state"]["sat"] != sat || light.state["state"]["colormode"] != "hs") 119 + if (state["sat"] != sat || state["colormode"] != "hs")
117 { 120 {
118 if (sat > 254) 121 if (sat > 254)
119 { 122 {
@@ -136,20 +139,21 @@ bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, ui @@ -136,20 +139,21 @@ bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, ui
136 139
137 bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition, HueLight& light) const 140 bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition, HueLight& light) const
138 { 141 {
139 - light.refreshState(); 142 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  143 + const nlohmann::json& state = light.state.GetValue()["state"];
140 nlohmann::json request = nlohmann::json::object(); 144 nlohmann::json request = nlohmann::json::object();
141 145
142 if (transition != 4) 146 if (transition != 4)
143 { 147 {
144 request["transitiontime"] = transition; 148 request["transitiontime"] = transition;
145 } 149 }
146 - if (light.state["state"]["on"] != true) 150 + if (state["on"] != true)
147 { 151 {
148 request["on"] = true; 152 request["on"] = true;
149 } 153 }
150 - if (std::abs(light.state["state"]["xy"][0].get<float>() - x) > 1E-4f  
151 - || std::abs(light.state["state"]["xy"][1].get<float>() - y) > 1E-4f  
152 - || light.state["state"]["colormode"] != "xy") 154 + if (std::abs(state["xy"][0].get<float>() - x) > 1E-4f
  155 + || std::abs(state["xy"][1].get<float>() - y) > 1E-4f
  156 + || state["colormode"] != "xy")
153 { 157 {
154 request["xy"][0] = x; 158 request["xy"][0] = x;
155 request["xy"][1] = y; 159 request["xy"][1] = y;
@@ -171,7 +175,7 @@ bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_ @@ -171,7 +175,7 @@ bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_
171 { 175 {
172 if ((r == 0) && (g == 0) && (b == 0)) 176 if ((r == 0) && (g == 0) && (b == 0))
173 { 177 {
174 - return light.OffNoRefresh(); 178 + return light.Off();
175 } 179 }
176 180
177 const float red = float(r) / 255; 181 const float red = float(r) / 255;
@@ -196,15 +200,16 @@ bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_ @@ -196,15 +200,16 @@ bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_
196 bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight& light) const 200 bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight& light) const
197 { 201 {
198 // colorloop 202 // colorloop
199 - light.refreshState(); 203 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  204 + const nlohmann::json& state = light.state.GetValue()["state"];
200 nlohmann::json request = nlohmann::json::object(); 205 nlohmann::json request = nlohmann::json::object();
201 206
202 - if (light.state["state"]["on"] != true) 207 + if (state["on"] != true)
203 { 208 {
204 request["on"] = true; 209 request["on"] = true;
205 } 210 }
206 std::string effect; 211 std::string effect;
207 - if ((effect = on ? "colorloop" : "none") != light.state["state"]["effect"]) 212 + if ((effect = on ? "colorloop" : "none") != state["effect"])
208 { 213 {
209 request["effect"] = effect; 214 request["effect"] = effect;
210 } 215 }
@@ -222,13 +227,14 @@ bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight&amp; light) const @@ -222,13 +227,14 @@ bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight&amp; light) const
222 227
223 bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const 228 bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const
224 { 229 {
225 - light.refreshState();  
226 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
227 - bool on = light.state["state"]["on"].get<bool>(); 230 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  231 + const nlohmann::json& state = light.state.GetValue()["state"];
  232 + std::string cType = state["colormode"].get<std::string>();
  233 + bool on = state["on"].get<bool>();
228 if (cType == "hs") 234 if (cType == "hs")
229 { 235 {
230 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
231 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 236 + uint16_t oldHue = state["hue"].get<uint16_t>();
  237 + uint8_t oldSat = state["sat"].get<uint8_t>();
232 if (!light.setColorHueSaturation(hue, sat, 1)) 238 if (!light.setColorHueSaturation(hue, sat, 1))
233 { 239 {
234 return false; 240 return false;
@@ -242,7 +248,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -242,7 +248,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
242 if (!on) 248 if (!on)
243 { 249 {
244 light.setColorHueSaturation(oldHue, oldSat, 1); 250 light.setColorHueSaturation(oldHue, oldSat, 1);
245 - return light.OffNoRefresh(1); 251 + return light.Off(1);
246 } 252 }
247 else 253 else
248 { 254 {
@@ -251,8 +257,8 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -251,8 +257,8 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
251 } 257 }
252 else if (cType == "xy") 258 else if (cType == "xy")
253 { 259 {
254 - float oldX = light.state["state"]["xy"][0].get<float>();  
255 - float oldY = light.state["state"]["xy"][1].get<float>(); 260 + float oldX = state["xy"][0].get<float>();
  261 + float oldY = state["xy"][1].get<float>();
256 if (!light.setColorHueSaturation(hue, sat, 1)) 262 if (!light.setColorHueSaturation(hue, sat, 1))
257 { 263 {
258 return false; 264 return false;
@@ -266,7 +272,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -266,7 +272,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
266 if (!on) 272 if (!on)
267 { 273 {
268 light.setColorXY(oldX, oldY, 1); 274 light.setColorXY(oldX, oldY, 1);
269 - return light.OffNoRefresh(1); 275 + return light.Off(1);
270 } 276 }
271 else 277 else
272 { 278 {
@@ -281,13 +287,14 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi @@ -281,13 +287,14 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi
281 287
282 bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const 288 bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const
283 { 289 {
284 - light.refreshState();  
285 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
286 - bool on = light.state["state"]["on"].get<bool>(); 290 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  291 + const nlohmann::json& state = light.state.GetValue()["state"];
  292 + std::string cType = state["colormode"].get<std::string>();
  293 + bool on = state["on"].get<bool>();
287 if (cType == "hs") 294 if (cType == "hs")
288 { 295 {
289 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
290 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 296 + uint16_t oldHue = state["hue"].get<uint16_t>();
  297 + uint8_t oldSat = state["sat"].get<uint8_t>();
291 if (!light.setColorXY(x, y, 1)) 298 if (!light.setColorXY(x, y, 1))
292 { 299 {
293 return false; 300 return false;
@@ -301,7 +308,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -301,7 +308,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
301 if (!on) 308 if (!on)
302 { 309 {
303 light.setColorHueSaturation(oldHue, oldSat, 1); 310 light.setColorHueSaturation(oldHue, oldSat, 1);
304 - return light.OffNoRefresh(1); 311 + return light.Off(1);
305 } 312 }
306 else 313 else
307 { 314 {
@@ -310,8 +317,8 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -310,8 +317,8 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
310 } 317 }
311 else if (cType == "xy") 318 else if (cType == "xy")
312 { 319 {
313 - float oldX = light.state["state"]["xy"][0].get<float>();  
314 - float oldY = light.state["state"]["xy"][1].get<float>(); 320 + float oldX = state["xy"][0].get<float>();
  321 + float oldY = state["xy"][1].get<float>();
315 if (!light.setColorXY(x, y, 1)) 322 if (!light.setColorXY(x, y, 1))
316 { 323 {
317 return false; 324 return false;
@@ -325,7 +332,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -325,7 +332,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
325 if (!on) 332 if (!on)
326 { 333 {
327 light.setColorXY(oldX, oldY, 1); 334 light.setColorXY(oldX, oldY, 1);
328 - return light.OffNoRefresh(1); 335 + return light.Off(1);
329 } 336 }
330 else 337 else
331 { 338 {
@@ -340,13 +347,14 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const @@ -340,13 +347,14 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight&amp; light) const
340 347
341 bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const 348 bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const
342 { 349 {
343 - light.refreshState();  
344 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
345 - bool on = light.state["state"]["on"].get<bool>(); 350 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  351 + const nlohmann::json& state = light.state.GetValue()["state"];
  352 + std::string cType = state["colormode"].get<std::string>();
  353 + bool on = state["on"].get<bool>();
346 if (cType == "hs") 354 if (cType == "hs")
347 { 355 {
348 - uint16_t oldHue = light.state["state"]["hue"].get<uint16_t>();  
349 - uint8_t oldSat = light.state["state"]["sat"].get<uint8_t>(); 356 + uint16_t oldHue = state["hue"].get<uint16_t>();
  357 + uint8_t oldSat = state["sat"].get<uint8_t>();
350 if (!light.setColorRGB(r, g, b, 1)) 358 if (!light.setColorRGB(r, g, b, 1))
351 { 359 {
352 return false; 360 return false;
@@ -360,7 +368,7 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -360,7 +368,7 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
360 if (!on) 368 if (!on)
361 { 369 {
362 light.setColorHueSaturation(oldHue, oldSat, 1); 370 light.setColorHueSaturation(oldHue, oldSat, 1);
363 - return light.OffNoRefresh(1); 371 + return light.Off(1);
364 } 372 }
365 else 373 else
366 { 374 {
@@ -369,8 +377,8 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -369,8 +377,8 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
369 } 377 }
370 else if (cType == "xy") 378 else if (cType == "xy")
371 { 379 {
372 - float oldX = light.state["state"]["xy"][0].get<float>();  
373 - float oldY = light.state["state"]["xy"][1].get<float>(); 380 + float oldX = state["xy"][0].get<float>();
  381 + float oldY = state["xy"][1].get<float>();
374 if (!light.setColorRGB(r, g, b, 1)) 382 if (!light.setColorRGB(r, g, b, 1))
375 { 383 {
376 return false; 384 return false;
@@ -384,7 +392,7 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -384,7 +392,7 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
384 if (!on) 392 if (!on)
385 { 393 {
386 light.setColorXY(oldX, oldY, 1); 394 light.setColorXY(oldX, oldY, 1);
387 - return light.OffNoRefresh(1); 395 + return light.Off(1);
388 } 396 }
389 else 397 else
390 { 398 {
@@ -399,24 +407,26 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp; @@ -399,24 +407,26 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight&amp;
399 407
400 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const 408 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const
401 { 409 {
402 - light.refreshState();  
403 - return std::make_pair(light.state["state"]["hue"].get<uint16_t>(), light.state["state"]["sat"].get<uint8_t>()); 410 + // Save value, so there are no inconsistent results if it is refreshed between two calls
  411 + const nlohmann::json& state = light.state.GetValue()["state"];
  412 + return std::make_pair(state["hue"].get<uint16_t>(), state["sat"].get<uint8_t>());
404 } 413 }
405 414
406 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const 415 std::pair<uint16_t, uint8_t> SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const
407 { 416 {
408 - return std::make_pair(light.state["state"]["hue"].get<uint16_t>(), light.state["state"]["sat"].get<uint8_t>()); 417 + return std::make_pair(light.state.GetValue()["state"]["hue"].get<uint16_t>(), light.state.GetValue()["state"]["sat"].get<uint8_t>());
409 } 418 }
410 419
411 std::pair<float, float> SimpleColorHueStrategy::getColorXY(HueLight& light) const 420 std::pair<float, float> SimpleColorHueStrategy::getColorXY(HueLight& light) const
412 { 421 {
413 - light.refreshState();  
414 - return std::make_pair(light.state["state"]["xy"][0].get<float>(), light.state["state"]["xy"][1].get<float>()); 422 + // Save value, so there are no inconsistent results if it is refreshed between two calls
  423 + const nlohmann::json& state = light.state.GetValue()["state"];
  424 + return std::make_pair(state["xy"][0].get<float>(), state["xy"][1].get<float>());
415 } 425 }
416 426
417 std::pair<float, float> SimpleColorHueStrategy::getColorXY(const HueLight& light) const 427 std::pair<float, float> SimpleColorHueStrategy::getColorXY(const HueLight& light) const
418 { 428 {
419 - return std::make_pair(light.state["state"]["xy"][0].get<float>(), light.state["state"]["xy"][1].get<float>()); 429 + return std::make_pair(light.state.GetValue()["state"]["xy"][0].get<float>(), light.state.GetValue()["state"]["xy"][1].get<float>());
420 } 430 }
421 /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float 431 /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float
422 x0, float y0, float x1, float y1, float x2, float y2) 432 x0, float y0, float x1, float y1, float x2, float y2)
src/SimpleColorTemperatureStrategy.cpp
@@ -34,17 +34,18 @@ namespace hueplusplus @@ -34,17 +34,18 @@ namespace hueplusplus
34 { 34 {
35 bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const 35 bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const
36 { 36 {
37 - light.refreshState(); 37 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  38 + const nlohmann::json& state = light.state.GetValue()["state"];
38 nlohmann::json request = nlohmann::json::object(); 39 nlohmann::json request = nlohmann::json::object();
39 if (transition != 4) 40 if (transition != 4)
40 { 41 {
41 request["transitiontime"] = transition; 42 request["transitiontime"] = transition;
42 } 43 }
43 - if (light.state["state"]["on"] != true) 44 + if (state["on"] != true)
44 { 45 {
45 request["on"] = true; 46 request["on"] = true;
46 } 47 }
47 - if (light.state["state"]["ct"] != mired) 48 + if (state["ct"] != mired)
48 { 49 {
49 if (mired > 500) 50 if (mired > 500)
50 { 51 {
@@ -71,12 +72,13 @@ bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uin @@ -71,12 +72,13 @@ bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uin
71 72
72 bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const 73 bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const
73 { 74 {
74 - light.refreshState();  
75 - std::string cType = light.state["state"]["colormode"].get<std::string>();  
76 - bool on = light.state["state"]["on"].get<bool>(); 75 + // Careful, only use state until any light function might refresh the value and invalidate the reference
  76 + const nlohmann::json& state = light.state.GetValue()["state"];
  77 + std::string cType = state["colormode"].get<std::string>();
  78 + bool on = state["on"].get<bool>();
77 if (cType == "ct") 79 if (cType == "ct")
78 { 80 {
79 - uint16_t oldCT = light.state["state"]["ct"].get<uint16_t>(); 81 + uint16_t oldCT = state["ct"].get<uint16_t>();
80 if (!light.setColorTemperature(mired, 1)) 82 if (!light.setColorTemperature(mired, 1))
81 { 83 {
82 return false; 84 return false;
@@ -90,7 +92,7 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig @@ -90,7 +92,7 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig
90 if (!on) 92 if (!on)
91 { 93 {
92 light.setColorTemperature(oldCT, 1); 94 light.setColorTemperature(oldCT, 1);
93 - return light.OffNoRefresh(1); 95 + return light.Off(1);
94 } 96 }
95 else 97 else
96 { 98 {
@@ -105,12 +107,11 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig @@ -105,12 +107,11 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig
105 107
106 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const 108 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const
107 { 109 {
108 - light.refreshState();  
109 - return light.state["state"]["ct"].get<unsigned int>(); 110 + return light.state.GetValue()["state"]["ct"].get<unsigned int>();
110 } 111 }
111 112
112 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const 113 unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const
113 { 114 {
114 - return light.state["state"]["ct"].get<unsigned int>(); 115 + return light.state.GetValue()["state"]["ct"].get<unsigned int>();
115 } 116 }
116 } // namespace hueplusplus 117 } // namespace hueplusplus
test/mocks/mock_HueLight.h
@@ -37,9 +37,13 @@ class MockHueLight : public hueplusplus::HueLight @@ -37,9 +37,13 @@ class MockHueLight : public hueplusplus::HueLight
37 { 37 {
38 public: 38 public:
39 MockHueLight(std::shared_ptr<const hueplusplus::IHttpHandler> handler) 39 MockHueLight(std::shared_ptr<const hueplusplus::IHttpHandler> handler)
40 - : HueLight(1, hueplusplus::HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler)){}; 40 + : HueLight(1, hueplusplus::HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler), nullptr,
  41 + nullptr, nullptr, std::chrono::steady_clock::duration::max())
  42 + {
  43 + // Set refresh duration to max, so random refreshes do not hinder the test setups
  44 + }
41 45
42 - nlohmann::json& getState() { return state; }; 46 + nlohmann::json& getState() { return state.GetValue(); }
43 47
44 MOCK_METHOD1(On, bool(uint8_t transition)); 48 MOCK_METHOD1(On, bool(uint8_t transition));
45 49
@@ -121,14 +125,8 @@ public: @@ -121,14 +125,8 @@ public:
121 125
122 MOCK_METHOD1(setColorLoop, bool(bool on)); 126 MOCK_METHOD1(setColorLoop, bool(bool on));
123 127
124 - MOCK_METHOD1(OnNoRefresh, bool(uint8_t transition));  
125 -  
126 - MOCK_METHOD1(OffNoRefresh, bool(uint8_t transition));  
127 -  
128 MOCK_METHOD3(SendPutRequest, 128 MOCK_METHOD3(SendPutRequest,
129 nlohmann::json(const nlohmann::json& request, const std::string& subPath, hueplusplus::FileInfo fileInfo)); 129 nlohmann::json(const nlohmann::json& request, const std::string& subPath, hueplusplus::FileInfo fileInfo));
130 -  
131 - MOCK_METHOD0(refreshState, void());  
132 }; 130 };
133 131
134 #endif 132 #endif
test/test_ExtendedColorHueStrategy.cpp
@@ -44,7 +44,6 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -44,7 +44,6 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
44 .Times(AtLeast(1)) 44 .Times(AtLeast(1))
45 .WillRepeatedly(Return(nlohmann::json::object())); 45 .WillRepeatedly(Return(nlohmann::json::object()));
46 MockHueLight test_light(handler); 46 MockHueLight test_light(handler);
47 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
48 47
49 test_light.getState()["state"]["colormode"] = "invalid"; 48 test_light.getState()["state"]["colormode"] = "invalid";
50 test_light.getState()["state"]["on"] = false; 49 test_light.getState()["state"]["on"] = false;
@@ -65,7 +64,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -65,7 +64,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
65 64
66 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); 65 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
67 66
68 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 67 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
69 test_light.getState()["state"]["on"] = false; 68 test_light.getState()["state"]["on"] = false;
70 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); 69 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
71 70
@@ -85,7 +84,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -85,7 +84,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
85 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 84 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
86 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); 85 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
87 86
88 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 87 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
89 test_light.getState()["state"]["on"] = false; 88 test_light.getState()["state"]["on"] = false;
90 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); 89 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
91 90
@@ -104,7 +103,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) @@ -104,7 +103,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation)
104 EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 103 EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
105 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); 104 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
106 105
107 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 106 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
108 test_light.getState()["state"]["on"] = false; 107 test_light.getState()["state"]["on"] = false;
109 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); 108 EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light));
110 } 109 }
@@ -118,7 +117,6 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -118,7 +117,6 @@ TEST(ExtendedColorHueStrategy, alertXY)
118 .Times(AtLeast(1)) 117 .Times(AtLeast(1))
119 .WillRepeatedly(Return(nlohmann::json::object())); 118 .WillRepeatedly(Return(nlohmann::json::object()));
120 MockHueLight test_light(handler); 119 MockHueLight test_light(handler);
121 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
122 120
123 test_light.getState()["state"]["colormode"] = "invalid"; 121 test_light.getState()["state"]["colormode"] = "invalid";
124 test_light.getState()["state"]["on"] = false; 122 test_light.getState()["state"]["on"] = false;
@@ -139,7 +137,7 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -139,7 +137,7 @@ TEST(ExtendedColorHueStrategy, alertXY)
139 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 137 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
140 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 138 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
141 139
142 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 140 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
143 test_light.getState()["state"]["on"] = false; 141 test_light.getState()["state"]["on"] = false;
144 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 142 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
145 143
@@ -153,7 +151,7 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -153,7 +151,7 @@ TEST(ExtendedColorHueStrategy, alertXY)
153 151
154 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 152 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
155 153
156 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 154 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
157 test_light.getState()["state"]["on"] = false; 155 test_light.getState()["state"]["on"] = false;
158 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 156 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
159 157
@@ -169,7 +167,7 @@ TEST(ExtendedColorHueStrategy, alertXY) @@ -169,7 +167,7 @@ TEST(ExtendedColorHueStrategy, alertXY)
169 EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 167 EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
170 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 168 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
171 169
172 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 170 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
173 test_light.getState()["state"]["on"] = false; 171 test_light.getState()["state"]["on"] = false;
174 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 172 EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
175 } 173 }
@@ -183,7 +181,6 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -183,7 +181,6 @@ TEST(ExtendedColorHueStrategy, alertRGB)
183 .Times(AtLeast(1)) 181 .Times(AtLeast(1))
184 .WillRepeatedly(Return(nlohmann::json::object())); 182 .WillRepeatedly(Return(nlohmann::json::object()));
185 MockHueLight test_light(handler); 183 MockHueLight test_light(handler);
186 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
187 184
188 test_light.getState()["state"]["colormode"] = "invalid"; 185 test_light.getState()["state"]["colormode"] = "invalid";
189 test_light.getState()["state"]["on"] = false; 186 test_light.getState()["state"]["on"] = false;
@@ -205,7 +202,7 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -205,7 +202,7 @@ TEST(ExtendedColorHueStrategy, alertRGB)
205 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 202 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
206 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); 203 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
207 204
208 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 205 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
209 test_light.getState()["state"]["on"] = false; 206 test_light.getState()["state"]["on"] = false;
210 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); 207 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
211 208
@@ -225,7 +222,7 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -225,7 +222,7 @@ TEST(ExtendedColorHueStrategy, alertRGB)
225 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 222 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
226 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); 223 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
227 224
228 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 225 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
229 test_light.getState()["state"]["on"] = false; 226 test_light.getState()["state"]["on"] = false;
230 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); 227 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
231 228
@@ -244,7 +241,7 @@ TEST(ExtendedColorHueStrategy, alertRGB) @@ -244,7 +241,7 @@ TEST(ExtendedColorHueStrategy, alertRGB)
244 EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 241 EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
245 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); 242 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
246 243
247 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 244 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
248 test_light.getState()["state"]["on"] = false; 245 test_light.getState()["state"]["on"] = false;
249 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); 246 EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light));
250 } 247 }
test/test_ExtendedColorTemperatureStrategy.cpp
@@ -44,7 +44,7 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature) @@ -44,7 +44,7 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature)
44 .Times(AtLeast(1)) 44 .Times(AtLeast(1))
45 .WillRepeatedly(Return(nlohmann::json::object())); 45 .WillRepeatedly(Return(nlohmann::json::object()));
46 MockHueLight test_light(handler); 46 MockHueLight test_light(handler);
47 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 47 +
48 nlohmann::json prep_ret; 48 nlohmann::json prep_ret;
49 prep_ret = nlohmann::json::array(); 49 prep_ret = nlohmann::json::array();
50 prep_ret[0] = nlohmann::json::object(); 50 prep_ret[0] = nlohmann::json::object();
@@ -84,7 +84,6 @@ TEST(ExtendedColorTemperatureStrategy, alertTemperature) @@ -84,7 +84,6 @@ TEST(ExtendedColorTemperatureStrategy, alertTemperature)
84 .Times(AtLeast(1)) 84 .Times(AtLeast(1))
85 .WillRepeatedly(Return(nlohmann::json::object())); 85 .WillRepeatedly(Return(nlohmann::json::object()));
86 MockHueLight test_light(handler); 86 MockHueLight test_light(handler);
87 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
88 87
89 test_light.getState()["state"]["colormode"] = "invalid"; 88 test_light.getState()["state"]["colormode"] = "invalid";
90 test_light.getState()["state"]["on"] = false; 89 test_light.getState()["state"]["on"] = false;
@@ -107,7 +106,7 @@ TEST(ExtendedColorTemperatureStrategy, alertTemperature) @@ -107,7 +106,7 @@ TEST(ExtendedColorTemperatureStrategy, alertTemperature)
107 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 106 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
108 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); 107 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
109 108
110 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 109 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
111 test_light.getState()["state"]["on"] = false; 110 test_light.getState()["state"]["on"] = false;
112 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); 111 EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light));
113 112
test/test_Hue.cpp
@@ -449,12 +449,12 @@ TEST(Hue, getAllLights) @@ -449,12 +449,12 @@ TEST(Hue, getAllLights)
449 449
450 EXPECT_CALL( 450 EXPECT_CALL(
451 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) 451 *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort()))
452 - .Times(2) 452 + .Times(AtLeast(1))
453 .WillRepeatedly(Return(hue_bridge_state)); 453 .WillRepeatedly(Return(hue_bridge_state));
454 454
455 EXPECT_CALL(*handler, 455 EXPECT_CALL(*handler,
456 GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) 456 GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort()))
457 - .Times(2) 457 + .Times(AtLeast(1))
458 .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); 458 .WillRepeatedly(Return(hue_bridge_state["lights"]["1"]));
459 459
460 Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); 460 Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler);
@@ -531,12 +531,3 @@ TEST(Hue, getPictureOfLight) @@ -531,12 +531,3 @@ TEST(Hue, getPictureOfLight)
531 531
532 EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1)); 532 EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1));
533 } 533 }
534 -  
535 -TEST(Hue, refreshState)  
536 -{  
537 - std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>();  
538 - Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); // NULL as username leads to segfault  
539 -  
540 - std::vector<std::reference_wrapper<HueLight>> test_lights = test_bridge.getAllLights();  
541 - EXPECT_EQ(test_lights.size(), 0);  
542 -}  
test/test_HueLight.cpp
@@ -888,19 +888,3 @@ TEST_F(HueLightTest, setColorLoop) @@ -888,19 +888,3 @@ TEST_F(HueLightTest, setColorLoop)
888 EXPECT_EQ(false, test_light_2.setColorLoop(false)); 888 EXPECT_EQ(false, test_light_2.setColorLoop(false));
889 EXPECT_EQ(false, test_light_3.setColorLoop(true)); 889 EXPECT_EQ(false, test_light_3.setColorLoop(true));
890 } 890 }
891 -  
892 -TEST_F(HueLightTest, refreshState)  
893 -{  
894 - using namespace ::testing;  
895 - test_bridge.getLight(1);  
896 - test_bridge.getLight(2);  
897 - test_bridge.getLight(3);  
898 -  
899 - EXPECT_CALL(  
900 - *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80))  
901 - .Times(2)  
902 - .WillRepeatedly(Return(nlohmann::json::object()));  
903 -  
904 - const HueLight ctest_light_1 = test_bridge.getLight(1);  
905 - HueLight test_light_1 = test_bridge.getLight(1);  
906 -}  
test/test_SimpleBrightnessStrategy.cpp
@@ -45,8 +45,8 @@ TEST(SimpleBrightnessStrategy, setBrightness) @@ -45,8 +45,8 @@ TEST(SimpleBrightnessStrategy, setBrightness)
45 .Times(AtLeast(1)) 45 .Times(AtLeast(1))
46 .WillRepeatedly(Return(nlohmann::json::object())); 46 .WillRepeatedly(Return(nlohmann::json::object()));
47 MockHueLight test_light(handler); 47 MockHueLight test_light(handler);
48 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
49 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 48 +
  49 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
50 nlohmann::json prep_ret; 50 nlohmann::json prep_ret;
51 prep_ret = nlohmann::json::array(); 51 prep_ret = nlohmann::json::array();
52 prep_ret[0] = nlohmann::json::object(); 52 prep_ret[0] = nlohmann::json::object();
@@ -86,7 +86,6 @@ TEST(SimpleBrightnessStrategy, getBrightness) @@ -86,7 +86,6 @@ TEST(SimpleBrightnessStrategy, getBrightness)
86 .Times(AtLeast(1)) 86 .Times(AtLeast(1))
87 .WillRepeatedly(Return(nlohmann::json::object())); 87 .WillRepeatedly(Return(nlohmann::json::object()));
88 MockHueLight test_light(handler); 88 MockHueLight test_light(handler);
89 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
90 89
91 test_light.getState()["state"]["bri"] = 200; 90 test_light.getState()["state"]["bri"] = 200;
92 EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light)); 91 EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light));
test/test_SimpleColorHueStrategy.cpp
@@ -44,7 +44,7 @@ TEST(SimpleColorHueStrategy, setColorHue) @@ -44,7 +44,7 @@ TEST(SimpleColorHueStrategy, setColorHue)
44 .Times(AtLeast(1)) 44 .Times(AtLeast(1))
45 .WillRepeatedly(Return(nlohmann::json::object())); 45 .WillRepeatedly(Return(nlohmann::json::object()));
46 MockHueLight test_light(handler); 46 MockHueLight test_light(handler);
47 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 47 +
48 nlohmann::json prep_ret; 48 nlohmann::json prep_ret;
49 prep_ret = nlohmann::json::array(); 49 prep_ret = nlohmann::json::array();
50 prep_ret[0] = nlohmann::json::object(); 50 prep_ret[0] = nlohmann::json::object();
@@ -76,7 +76,7 @@ TEST(SimpleColorHueStrategy, setColorSaturation) @@ -76,7 +76,7 @@ TEST(SimpleColorHueStrategy, setColorSaturation)
76 .Times(AtLeast(1)) 76 .Times(AtLeast(1))
77 .WillRepeatedly(Return(nlohmann::json::object())); 77 .WillRepeatedly(Return(nlohmann::json::object()));
78 MockHueLight test_light(handler); 78 MockHueLight test_light(handler);
79 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 79 +
80 nlohmann::json prep_ret; 80 nlohmann::json prep_ret;
81 prep_ret = nlohmann::json::array(); 81 prep_ret = nlohmann::json::array();
82 prep_ret[0] = nlohmann::json::object(); 82 prep_ret[0] = nlohmann::json::object();
@@ -108,7 +108,7 @@ TEST(SimpleColorHueStrategy, setColorHueSaturation) @@ -108,7 +108,7 @@ TEST(SimpleColorHueStrategy, setColorHueSaturation)
108 .Times(AtLeast(1)) 108 .Times(AtLeast(1))
109 .WillRepeatedly(Return(nlohmann::json::object())); 109 .WillRepeatedly(Return(nlohmann::json::object()));
110 MockHueLight test_light(handler); 110 MockHueLight test_light(handler);
111 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 111 +
112 nlohmann::json prep_ret; 112 nlohmann::json prep_ret;
113 prep_ret = nlohmann::json::array(); 113 prep_ret = nlohmann::json::array();
114 prep_ret[0] = nlohmann::json::object(); 114 prep_ret[0] = nlohmann::json::object();
@@ -144,7 +144,7 @@ TEST(SimpleColorHueStrategy, setColorXY) @@ -144,7 +144,7 @@ TEST(SimpleColorHueStrategy, setColorXY)
144 .Times(AtLeast(1)) 144 .Times(AtLeast(1))
145 .WillRepeatedly(Return(nlohmann::json::object())); 145 .WillRepeatedly(Return(nlohmann::json::object()));
146 MockHueLight test_light(handler); 146 MockHueLight test_light(handler);
147 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 147 +
148 nlohmann::json prep_ret; 148 nlohmann::json prep_ret;
149 prep_ret = nlohmann::json::array(); 149 prep_ret = nlohmann::json::array();
150 prep_ret[0] = nlohmann::json::object(); 150 prep_ret[0] = nlohmann::json::object();
@@ -184,7 +184,7 @@ TEST(SimpleColorHueStrategy, setColorRGB) @@ -184,7 +184,7 @@ TEST(SimpleColorHueStrategy, setColorRGB)
184 184
185 EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light)); 185 EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light));
186 186
187 - EXPECT_CALL(test_light, OffNoRefresh(4)).Times(1).WillOnce(Return(true)); 187 + EXPECT_CALL(test_light, Off(4)).Times(1).WillOnce(Return(true));
188 EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light)); 188 EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light));
189 } 189 }
190 190
@@ -197,7 +197,7 @@ TEST(SimpleColorHueStrategy, setColorLoop) @@ -197,7 +197,7 @@ TEST(SimpleColorHueStrategy, setColorLoop)
197 .Times(AtLeast(1)) 197 .Times(AtLeast(1))
198 .WillRepeatedly(Return(nlohmann::json::object())); 198 .WillRepeatedly(Return(nlohmann::json::object()));
199 MockHueLight test_light(handler); 199 MockHueLight test_light(handler);
200 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 200 +
201 nlohmann::json prep_ret; 201 nlohmann::json prep_ret;
202 prep_ret = nlohmann::json::array(); 202 prep_ret = nlohmann::json::array();
203 prep_ret[0] = nlohmann::json::object(); 203 prep_ret[0] = nlohmann::json::object();
@@ -226,7 +226,6 @@ TEST(SimpleColorHueStrategy, alertHueSaturation) @@ -226,7 +226,6 @@ TEST(SimpleColorHueStrategy, alertHueSaturation)
226 .Times(AtLeast(1)) 226 .Times(AtLeast(1))
227 .WillRepeatedly(Return(nlohmann::json::object())); 227 .WillRepeatedly(Return(nlohmann::json::object()));
228 MockHueLight test_light(handler); 228 MockHueLight test_light(handler);
229 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
230 229
231 test_light.getState()["state"]["colormode"] = "invalid"; 230 test_light.getState()["state"]["colormode"] = "invalid";
232 test_light.getState()["state"]["on"] = false; 231 test_light.getState()["state"]["on"] = false;
@@ -247,7 +246,7 @@ TEST(SimpleColorHueStrategy, alertHueSaturation) @@ -247,7 +246,7 @@ TEST(SimpleColorHueStrategy, alertHueSaturation)
247 246
248 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); 247 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
249 248
250 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 249 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
251 test_light.getState()["state"]["on"] = false; 250 test_light.getState()["state"]["on"] = false;
252 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); 251 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
253 252
@@ -267,7 +266,7 @@ TEST(SimpleColorHueStrategy, alertHueSaturation) @@ -267,7 +266,7 @@ TEST(SimpleColorHueStrategy, alertHueSaturation)
267 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 266 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
268 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); 267 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
269 268
270 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 269 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
271 test_light.getState()["state"]["on"] = false; 270 test_light.getState()["state"]["on"] = false;
272 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); 271 EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light));
273 } 272 }
@@ -281,7 +280,6 @@ TEST(SimpleColorHueStrategy, alertXY) @@ -281,7 +280,6 @@ TEST(SimpleColorHueStrategy, alertXY)
281 .Times(AtLeast(1)) 280 .Times(AtLeast(1))
282 .WillRepeatedly(Return(nlohmann::json::object())); 281 .WillRepeatedly(Return(nlohmann::json::object()));
283 MockHueLight test_light(handler); 282 MockHueLight test_light(handler);
284 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
285 283
286 test_light.getState()["state"]["colormode"] = "invalid"; 284 test_light.getState()["state"]["colormode"] = "invalid";
287 test_light.getState()["state"]["on"] = false; 285 test_light.getState()["state"]["on"] = false;
@@ -302,7 +300,7 @@ TEST(SimpleColorHueStrategy, alertXY) @@ -302,7 +300,7 @@ TEST(SimpleColorHueStrategy, alertXY)
302 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 300 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
303 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 301 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
304 302
305 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 303 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
306 test_light.getState()["state"]["on"] = false; 304 test_light.getState()["state"]["on"] = false;
307 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 305 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
308 306
@@ -316,7 +314,7 @@ TEST(SimpleColorHueStrategy, alertXY) @@ -316,7 +314,7 @@ TEST(SimpleColorHueStrategy, alertXY)
316 314
317 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 315 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
318 316
319 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 317 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
320 test_light.getState()["state"]["on"] = false; 318 test_light.getState()["state"]["on"] = false;
321 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); 319 EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light));
322 } 320 }
@@ -330,7 +328,6 @@ TEST(SimpleColorHueStrategy, alertRGB) @@ -330,7 +328,6 @@ TEST(SimpleColorHueStrategy, alertRGB)
330 .Times(AtLeast(1)) 328 .Times(AtLeast(1))
331 .WillRepeatedly(Return(nlohmann::json::object())); 329 .WillRepeatedly(Return(nlohmann::json::object()));
332 MockHueLight test_light(handler); 330 MockHueLight test_light(handler);
333 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
334 331
335 test_light.getState()["state"]["colormode"] = "invalid"; 332 test_light.getState()["state"]["colormode"] = "invalid";
336 test_light.getState()["state"]["on"] = false; 333 test_light.getState()["state"]["on"] = false;
@@ -352,7 +349,7 @@ TEST(SimpleColorHueStrategy, alertRGB) @@ -352,7 +349,7 @@ TEST(SimpleColorHueStrategy, alertRGB)
352 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 349 EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
353 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); 350 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
354 351
355 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 352 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
356 test_light.getState()["state"]["on"] = false; 353 test_light.getState()["state"]["on"] = false;
357 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); 354 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
358 355
@@ -372,7 +369,7 @@ TEST(SimpleColorHueStrategy, alertRGB) @@ -372,7 +369,7 @@ TEST(SimpleColorHueStrategy, alertRGB)
372 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); 369 EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true));
373 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); 370 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
374 371
375 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 372 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
376 test_light.getState()["state"]["on"] = false; 373 test_light.getState()["state"]["on"] = false;
377 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); 374 EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light));
378 } 375 }
@@ -386,7 +383,6 @@ TEST(SimpleColorHueStrategy, getColorHueSaturation) @@ -386,7 +383,6 @@ TEST(SimpleColorHueStrategy, getColorHueSaturation)
386 .Times(AtLeast(1)) 383 .Times(AtLeast(1))
387 .WillRepeatedly(Return(nlohmann::json::object())); 384 .WillRepeatedly(Return(nlohmann::json::object()));
388 MockHueLight test_light(handler); 385 MockHueLight test_light(handler);
389 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
390 386
391 test_light.getState()["state"]["hue"] = 5000; 387 test_light.getState()["state"]["hue"] = 5000;
392 test_light.getState()["state"]["sat"] = 128; 388 test_light.getState()["state"]["sat"] = 128;
@@ -407,7 +403,6 @@ TEST(SimpleColorHueStrategy, getColorXY) @@ -407,7 +403,6 @@ TEST(SimpleColorHueStrategy, getColorXY)
407 .Times(AtLeast(1)) 403 .Times(AtLeast(1))
408 .WillRepeatedly(Return(nlohmann::json::object())); 404 .WillRepeatedly(Return(nlohmann::json::object()));
409 MockHueLight test_light(handler); 405 MockHueLight test_light(handler);
410 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
411 406
412 test_light.getState()["state"]["xy"][0] = 0.1234; 407 test_light.getState()["state"]["xy"][0] = 0.1234;
413 test_light.getState()["state"]["xy"][1] = 0.1234; 408 test_light.getState()["state"]["xy"][1] = 0.1234;
test/test_SimpleColorTemperatureStrategy.cpp
@@ -45,7 +45,7 @@ TEST(SimpleColorTemperatureStrategy, setColorTemperature) @@ -45,7 +45,7 @@ TEST(SimpleColorTemperatureStrategy, setColorTemperature)
45 .Times(AtLeast(1)) 45 .Times(AtLeast(1))
46 .WillRepeatedly(Return(nlohmann::json::object())); 46 .WillRepeatedly(Return(nlohmann::json::object()));
47 MockHueLight test_light(handler); 47 MockHueLight test_light(handler);
48 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); 48 +
49 nlohmann::json prep_ret; 49 nlohmann::json prep_ret;
50 prep_ret = nlohmann::json::array(); 50 prep_ret = nlohmann::json::array();
51 prep_ret[0] = nlohmann::json::object(); 51 prep_ret[0] = nlohmann::json::object();
@@ -84,7 +84,6 @@ TEST(SimpleColorTemperatureStrategy, alertTemperature) @@ -84,7 +84,6 @@ TEST(SimpleColorTemperatureStrategy, alertTemperature)
84 .Times(AtLeast(1)) 84 .Times(AtLeast(1))
85 .WillRepeatedly(Return(nlohmann::json::object())); 85 .WillRepeatedly(Return(nlohmann::json::object()));
86 MockHueLight test_light(handler); 86 MockHueLight test_light(handler);
87 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
88 87
89 test_light.getState()["state"]["colormode"] = "invalid"; 88 test_light.getState()["state"]["colormode"] = "invalid";
90 test_light.getState()["state"]["on"] = false; 89 test_light.getState()["state"]["on"] = false;
@@ -104,7 +103,7 @@ TEST(SimpleColorTemperatureStrategy, alertTemperature) @@ -104,7 +103,7 @@ TEST(SimpleColorTemperatureStrategy, alertTemperature)
104 103
105 EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); 104 EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
106 105
107 - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); 106 + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true));
108 test_light.getState()["state"]["on"] = false; 107 test_light.getState()["state"]["on"] = false;
109 EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); 108 EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light));
110 } 109 }
@@ -118,7 +117,6 @@ TEST(SimpleColorTemperatureStrategy, getColorTemperature) @@ -118,7 +117,6 @@ TEST(SimpleColorTemperatureStrategy, getColorTemperature)
118 .Times(AtLeast(1)) 117 .Times(AtLeast(1))
119 .WillRepeatedly(Return(nlohmann::json::object())); 118 .WillRepeatedly(Return(nlohmann::json::object()));
120 MockHueLight test_light(handler); 119 MockHueLight test_light(handler);
121 - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return());  
122 120
123 test_light.getState()["state"]["ct"] = 200; 121 test_light.getState()["state"]["ct"] = 200;
124 EXPECT_EQ(200, SimpleColorTemperatureStrategy().getColorTemperature(test_light)); 122 EXPECT_EQ(200, SimpleColorTemperatureStrategy().getColorTemperature(test_light));