Commit 67145ea0aa0723d6e3f6ce96038bf4a883feda98
Committed by
Moritz Wirger
1 parent
91594d47
Implement StateTransaction to combine more than one state change into one request.
Showing
2 changed files
with
179 additions
and
69 deletions
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( | ... | ... |