Commit 67145ea0aa0723d6e3f6ce96038bf4a883feda98

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent 91594d47

Implement StateTransaction to combine more than one state change into one request.

include/hueplusplus/Group.h
... ... @@ -33,6 +33,39 @@
33 33  
34 34 namespace hueplusplus
35 35 {
  36 +class StateTransaction
  37 +{
  38 +public:
  39 + StateTransaction(const HueCommandAPI& commands, const std::string& path, const nlohmann::json& currentState);
  40 +
  41 + StateTransaction(const StateTransaction&) = delete;
  42 + StateTransaction(StateTransaction&&) = default;
  43 +
  44 + bool commit() &&;
  45 +
  46 + StateTransaction&& setOn(bool on) &&;
  47 + StateTransaction&& setBrightness(uint8_t brightness) &&;
  48 + StateTransaction&& setColorHue(uint16_t hue) &&;
  49 + StateTransaction&& setColorSaturation(uint8_t saturation) &&;
  50 + StateTransaction&& setColorHueSaturation(uint16_t hue, uint8_t saturation) &&;
  51 + StateTransaction&& setColorXY(float x, float y) &&;
  52 + StateTransaction&& setColorTemperature(unsigned int mired) &&;
  53 + StateTransaction&& setColorLoop(bool on) &&;
  54 + StateTransaction&& incrementBrightness(int increment) &&;
  55 + StateTransaction&& incrementSaturation(int increment) &&;
  56 + StateTransaction&& incrementHue(int increment) &&;
  57 + StateTransaction&& incrementColorTemperature(int increment) &&;
  58 + StateTransaction&& incrementColorXY(float xInc, float yInc) &&;
  59 + StateTransaction&& setScene(const std::string& scene) &&;
  60 + StateTransaction&& setTransition(uint16_t transition) &&;
  61 +
  62 +private:
  63 + const HueCommandAPI& commands;
  64 + std::string path;
  65 + nlohmann::json state;
  66 + nlohmann::json request;
  67 +};
  68 +
36 69 class Group
37 70 {
38 71 public:
... ... @@ -77,6 +110,8 @@ public:
77 110 std::string getActionColorMode();
78 111 std::string getActionColorMode() const;
79 112  
  113 + StateTransaction transaction();
  114 +
80 115 void setOn(bool on, uint8_t transition = 4);
81 116 void setBrightness(uint8_t brightness, uint8_t transition = 4);
82 117 void setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition = 4);
... ... @@ -87,7 +122,7 @@ public:
87 122 void incrementSaturation(int increment, uint8_t transition = 4);
88 123 void incrementHue(int increment, uint8_t transition = 4);
89 124 void incrementColorTemperature(int increment, uint8_t transition = 4);
90   - void incrementColorXY(float increment, uint8_t transition = 4);
  125 + void incrementColorXY(float incX, float incY, uint8_t transition = 4);
91 126 void setScene(const std::string& scene, uint8_t transition = 4);
92 127  
93 128 protected:
... ...
src/Group.cpp
... ... @@ -2,6 +2,132 @@
2 2  
3 3 #include "hueplusplus/HueExceptionMacro.h"
4 4  
  5 +hueplusplus::StateTransaction::StateTransaction(
  6 + const HueCommandAPI& commands, const std::string& path, const nlohmann::json& currentState)
  7 + : commands(commands), path(path), state(state), request(nlohmann::json::object())
  8 +{}
  9 +
  10 +bool hueplusplus::StateTransaction::commit() &&
  11 +{
  12 + // Empty request or request with only transition makes no sense
  13 + if (!request.empty() || (request.size() == 1 && request.count("transition")))
  14 + {
  15 + if (!request.count("on"))
  16 + {
  17 + if (request.value("bri", 254) == 0)
  18 + {
  19 + // Turn off if brightness is 0
  20 + request["on"] = false;
  21 + }
  22 + else if (request.value("bri", 0) != 0 || request.count("colorloop") || request.count("hue")
  23 + || request.count("sat") || request.count("xy"))
  24 + {
  25 + // Turn on if it was turned off
  26 + request["on"] = true;
  27 + }
  28 + }
  29 +
  30 + commands.PUTRequest(path, request, CURRENT_FILE_INFO);
  31 + return true;
  32 + }
  33 + return false;
  34 +}
  35 +
  36 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setOn(bool on) &&
  37 +{
  38 + request["on"] = on;
  39 + return std::move(*this);
  40 +}
  41 +
  42 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setBrightness(uint8_t brightness) &&
  43 +{
  44 + request["bri"] = std::min<uint8_t>(brightness, 254);
  45 + return std::move(*this);
  46 +}
  47 +
  48 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setColorSaturation(uint8_t saturation) &&
  49 +{
  50 + request["sat"] = std::min<uint8_t>(saturation, 254);
  51 + return std::move(*this);
  52 +}
  53 +
  54 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setColorHue(uint16_t hue) &&
  55 +{
  56 + request["hue"] = hue;
  57 + return std::move(*this);
  58 +}
  59 +
  60 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setColorHueSaturation(
  61 + uint16_t hue, uint8_t saturation) &&
  62 +{
  63 + request["hue"] = hue;
  64 + request["sat"] = std::min<uint8_t>(saturation, 254);
  65 + return std::move(*this);
  66 +}
  67 +
  68 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setColorXY(float x, float y) &&
  69 +{
  70 + request["xy"] = {x, y};
  71 + return std::move(*this);
  72 +}
  73 +
  74 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setColorTemperature(unsigned int mired) &&
  75 +{
  76 + request["ct"] = mired;
  77 + return std::move(*this);
  78 +}
  79 +
  80 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setColorLoop(bool on) &&
  81 +{
  82 + request["effect"] = on ? "colorloop" : "none";
  83 + return std::move(*this);
  84 +}
  85 +
  86 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::incrementBrightness(int increment) &&
  87 +{
  88 + request["bri_inc"] = std::max(-254, std::min(increment, 254));
  89 + return std::move(*this);
  90 +}
  91 +
  92 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::incrementSaturation(int increment) &&
  93 +{
  94 + request["sat_inc"] = std::max(-254, std::min(increment, 254));
  95 + return std::move(*this);
  96 +}
  97 +
  98 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::incrementHue(int increment) &&
  99 +{
  100 + request["hue_inc"] = std::max(-65534, std::min(increment, 65534));
  101 + return std::move(*this);
  102 +}
  103 +
  104 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::incrementColorTemperature(int increment) &&
  105 +{
  106 + request["ct_inc"] = std::max(-65534, std::min(increment, 65534));
  107 + return std::move(*this);
  108 +}
  109 +
  110 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::incrementColorXY(float xInc, float yInc) &&
  111 +{
  112 + request["xy_inc"] = {std::min(-0.5f, std::max(xInc, 0.5f)), std::min(-0.5f, std::max(yInc, 0.5f))};
  113 + return std::move(*this);
  114 +}
  115 +
  116 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setScene(const std::string& scene) &&
  117 +{
  118 + request["scene"] = scene;
  119 + return std::move(*this);
  120 +}
  121 +
  122 +hueplusplus::StateTransaction&& hueplusplus::StateTransaction::setTransition(uint16_t transition) &&
  123 +{
  124 + if (transition != 4)
  125 + {
  126 + request["transitiontime"] = transition;
  127 + }
  128 + return std::move(*this);
  129 +}
  130 +
5 131 hueplusplus::Group::Group(int id, const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration)
6 132 : id(id), state("/groups/" + std::to_string(id), commands, refreshDuration), commands(commands)
7 133 {
... ... @@ -134,6 +260,11 @@ std::string hueplusplus::Group::getActionColorMode() const
134 260 return state.GetValue().at("action").at("colormode").get<std::string>();
135 261 }
136 262  
  263 +hueplusplus::StateTransaction hueplusplus::Group::transaction()
  264 +{
  265 + return StateTransaction(commands, "/groups/" + std::to_string(id) + "/action", state.GetValue());
  266 +}
  267 +
137 268 void hueplusplus::Group::setOn(bool on, uint8_t transition)
138 269 {
139 270 nlohmann::json request = {{"on", on}};
... ... @@ -146,113 +277,57 @@ void hueplusplus::Group::setOn(bool on, uint8_t transition)
146 277  
147 278 void hueplusplus::Group::setBrightness(uint8_t brightness, uint8_t transition)
148 279 {
149   - // TODO: turn on/off
150   - nlohmann::json request = {{"bri", brightness}};
151   - if (transition != 4)
152   - {
153   - request["transition"] = transition;
154   - }
155   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  280 + transaction().setBrightness(brightness).setTransition(transition).commit();
156 281 }
157 282  
158 283 void hueplusplus::Group::setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition)
159 284 {
160   - nlohmann::json request = {{"hue", hue}, {"sat", saturation}};
161   - if (transition != 4)
162   - {
163   - request["transition"] = transition;
164   - }
165   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  285 + transaction().setColorHueSaturation(hue, saturation).setTransition(transition).commit();
166 286 }
167 287  
168 288 void hueplusplus::Group::setColorXY(float x, float y, uint8_t transition)
169 289 {
170   - nlohmann::json request = {{"xy", {x, y}}};
171   - if (transition != 4)
172   - {
173   - request["transition"] = transition;
174   - }
175   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  290 + transaction().setColorXY(x, y).setTransition(transition).commit();
176 291 }
177 292  
178 293 void hueplusplus::Group::setColorTemperature(unsigned int mired, uint8_t transition)
179 294 {
180   - nlohmann::json request = {{"ct", mired}};
181   - if (transition != 4)
182   - {
183   - request["transition"] = transition;
184   - }
185   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  295 + transaction().setColorTemperature(mired).setTransition(transition).commit();
186 296 }
187 297  
188 298 void hueplusplus::Group::setColorLoop(bool on, uint8_t transition)
189 299 {
190   - nlohmann::json request = {{"effect", on ? "colorloop" : "none"}};
191   - if (transition != 4)
192   - {
193   - request["transition"] = transition;
194   - }
195   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  300 + transaction().setColorLoop(on).setTransition(transition);
196 301 }
197 302  
198 303 void hueplusplus::Group::incrementBrightness(int increment, uint8_t transition)
199 304 {
200   - nlohmann::json request = {{"bri_inc", increment}};
201   - if (transition != 4)
202   - {
203   - request["transition"] = transition;
204   - }
205   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  305 + transaction().incrementBrightness(increment).setTransition(transition).commit();
206 306 }
207 307  
208 308 void hueplusplus::Group::incrementSaturation(int increment, uint8_t transition)
209 309 {
210   - nlohmann::json request = {{"sat_inc", increment}};
211   - if (transition != 4)
212   - {
213   - request["transition"] = transition;
214   - }
215   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  310 + transaction().incrementSaturation(increment).setTransition(transition).commit();
216 311 }
217 312  
218 313 void hueplusplus::Group::incrementHue(int increment, uint8_t transition)
219 314 {
220   - nlohmann::json request = {{"hue_inc", increment}};
221   - if (transition != 4)
222   - {
223   - request["transition"] = transition;
224   - }
225   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  315 + transaction().incrementHue(increment).setTransition(transition).commit();
226 316 }
227 317  
228 318 void hueplusplus::Group::incrementColorTemperature(int increment, uint8_t transition)
229 319 {
230   - nlohmann::json request = {{"ct_inc", increment}};
231   - if (transition != 4)
232   - {
233   - request["transition"] = transition;
234   - }
235   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  320 + transaction().incrementColorTemperature(increment).setTransition(transition).commit();
236 321 }
237 322  
238   -void hueplusplus::Group::incrementColorXY(float increment, uint8_t transition)
  323 +void hueplusplus::Group::incrementColorXY(float incX, float incY, uint8_t transition)
239 324 {
240   - nlohmann::json request = {{"xy_inc", increment}};
241   - if (transition != 4)
242   - {
243   - request["transition"] = transition;
244   - }
245   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  325 + transaction().incrementColorXY(incX, incY).setTransition(transition).commit();
246 326 }
247 327  
248 328 void hueplusplus::Group::setScene(const std::string& scene, uint8_t transition)
249 329 {
250   - nlohmann::json request = {{"scene", scene}};
251   - if (transition != 4)
252   - {
253   - request["transition"] = transition;
254   - }
255   - SendPutRequest(request, "/action", CURRENT_FILE_INFO);
  330 + transaction().setScene(scene).setTransition(transition).commit();
256 331 }
257 332  
258 333 nlohmann::json hueplusplus::Group::SendPutRequest(
... ...