Commit 59d03c52dd4eee0f30b7064b58e4bb9eb5117d5a
Committed by
Moritz Wirger
1 parent
4a7edd72
Add group class for groups of HueLight.
Showing
4 changed files
with
324 additions
and
2 deletions
include/hueplusplus/Group.h
0 → 100644
| 1 | +/** | |
| 2 | + \file Group.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_HUEPLUSPLUS_GROUP_H | |
| 24 | +#define INCLUDE_HUEPLUSPLUS_GROUP_H | |
| 25 | + | |
| 26 | +#include <string> | |
| 27 | +#include <vector> | |
| 28 | + | |
| 29 | +#include "APICache.h" | |
| 30 | +#include "HueCommandAPI.h" | |
| 31 | + | |
| 32 | +#include "json/json.hpp" | |
| 33 | + | |
| 34 | +namespace hueplusplus | |
| 35 | +{ | |
| 36 | + class Group | |
| 37 | + { | |
| 38 | + public: | |
| 39 | + Group(int id, const HueCommandAPI& commands); | |
| 40 | + | |
| 41 | + virtual ~Group() = default; | |
| 42 | + | |
| 43 | + int getId() const; | |
| 44 | + std::string getName() const; | |
| 45 | + std::string getType() const; | |
| 46 | + std::vector<int> getLightIds() const; | |
| 47 | + | |
| 48 | + void setName(const std::string& name); | |
| 49 | + void setLights(const std::vector<int>& ids); | |
| 50 | + | |
| 51 | + std::string getRoomType() const; | |
| 52 | + void setRoomType(const std::string& type); | |
| 53 | + | |
| 54 | + bool getAllOn() const; | |
| 55 | + bool getAnyOn() const; | |
| 56 | + | |
| 57 | + bool getActionOn() const; | |
| 58 | + std::pair<uint16_t, uint8_t> getActionHueSaturation() const; | |
| 59 | + unsigned int getActionBrightness() const; | |
| 60 | + unsigned int getActionColorTemperature() const; | |
| 61 | + std::pair<float, float> getActionColorXY() const; | |
| 62 | + std::string getActionColorMode() const; | |
| 63 | + | |
| 64 | + void setOn(bool on, uint8_t transition = 4); | |
| 65 | + void setBrightness(uint8_t brightness, uint8_t transition = 4); | |
| 66 | + void setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition = 4); | |
| 67 | + void setColorXY(float x, float y, uint8_t transition = 4); | |
| 68 | + void setColorTemperature(unsigned int mired, uint8_t transition = 4); | |
| 69 | + void setColorLoop(bool on, uint8_t transition = 4); | |
| 70 | + void incrementBrightness(int increment, uint8_t transition = 4); | |
| 71 | + void incrementSaturation(int increment, uint8_t transition = 4); | |
| 72 | + void incrementHue(int increment, uint8_t transition = 4); | |
| 73 | + void incrementColorTemperature(int increment, uint8_t transition = 4); | |
| 74 | + void incrementColorXY(float increment, uint8_t transition = 4); | |
| 75 | + void setScene(const std::string& scene, uint8_t transition = 4); | |
| 76 | + protected: | |
| 77 | + nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo); | |
| 78 | + | |
| 79 | + protected: | |
| 80 | + int id; | |
| 81 | + APICache state; | |
| 82 | + HueCommandAPI commands; | |
| 83 | + }; | |
| 84 | +} // namespace hueplusplus | |
| 85 | + | |
| 86 | +#endif | |
| 0 | 87 | \ No newline at end of file | ... | ... |
src/CMakeLists.txt
src/Group.cpp
0 → 100644
| 1 | +#include "hueplusplus/Group.h" | |
| 2 | + | |
| 3 | +#include "hueplusplus/HueExceptionMacro.h" | |
| 4 | + | |
| 5 | +hueplusplus::Group::Group(int id, const HueCommandAPI& commands) | |
| 6 | + : id(id), state("/groups/" + std::to_string(id), commands, std::chrono::seconds(10)), commands(commands) | |
| 7 | +{} | |
| 8 | + | |
| 9 | +int hueplusplus::Group::getId() const | |
| 10 | +{ | |
| 11 | + return id; | |
| 12 | +} | |
| 13 | + | |
| 14 | +std::string hueplusplus::Group::getName() const | |
| 15 | +{ | |
| 16 | + return state.GetValue().at("name").get<std::string>(); | |
| 17 | +} | |
| 18 | + | |
| 19 | +std::string hueplusplus::Group::getType() const | |
| 20 | +{ | |
| 21 | + return state.GetValue().at("type").get<std::string>(); | |
| 22 | +} | |
| 23 | + | |
| 24 | +std::vector<int> hueplusplus::Group::getLightIds() const | |
| 25 | +{ | |
| 26 | + const nlohmann::json& lights = state.GetValue().at("lights"); | |
| 27 | + std::vector<int> ids(lights.size()); | |
| 28 | + for (const nlohmann::json& id : lights) | |
| 29 | + { | |
| 30 | + ids.push_back(std::stoi(id.get<std::string>())); | |
| 31 | + } | |
| 32 | + return ids; | |
| 33 | +} | |
| 34 | + | |
| 35 | +void hueplusplus::Group::setName(const std::string& name) | |
| 36 | +{ | |
| 37 | + nlohmann::json request = {{"name", name}}; | |
| 38 | + SendPutRequest(request, "", CURRENT_FILE_INFO); | |
| 39 | +} | |
| 40 | + | |
| 41 | +void hueplusplus::Group::setLights(const std::vector<int>& ids) | |
| 42 | +{ | |
| 43 | + nlohmann::json lights = nlohmann::json::array(); | |
| 44 | + for (int id : ids) | |
| 45 | + { | |
| 46 | + lights.push_back(std::to_string(id)); | |
| 47 | + } | |
| 48 | + SendPutRequest({{"lights", lights}}, "", CURRENT_FILE_INFO); | |
| 49 | +} | |
| 50 | + | |
| 51 | +bool hueplusplus::Group::getAllOn() const | |
| 52 | +{ | |
| 53 | + return state.GetValue().at("state").at("all_on").get<bool>(); | |
| 54 | +} | |
| 55 | + | |
| 56 | +bool hueplusplus::Group::getAnyOn() const | |
| 57 | +{ | |
| 58 | + return state.GetValue().at("state").at("any_on").get<bool>(); | |
| 59 | +} | |
| 60 | + | |
| 61 | +bool hueplusplus::Group::getActionOn() const | |
| 62 | +{ | |
| 63 | + return state.GetValue().at("action").at("on").get<bool>(); | |
| 64 | +} | |
| 65 | + | |
| 66 | +std::pair<uint16_t, uint8_t> hueplusplus::Group::getActionHueSaturation() const | |
| 67 | +{ | |
| 68 | + const nlohmann::json& action = state.GetValue().at("action"); | |
| 69 | + | |
| 70 | + return std::make_pair(action.at("hue").get<int>(), action.at("sat").get<int>()); | |
| 71 | +} | |
| 72 | + | |
| 73 | +unsigned int hueplusplus::Group::getActionBrightness() const | |
| 74 | +{ | |
| 75 | + return state.GetValue().at("action").at("bri").get<int>(); | |
| 76 | +} | |
| 77 | + | |
| 78 | +unsigned int hueplusplus::Group::getActionColorTemperature() const | |
| 79 | +{ | |
| 80 | + return state.GetValue().at("action").at("ct").get<int>(); | |
| 81 | +} | |
| 82 | + | |
| 83 | +std::pair<float, float> hueplusplus::Group::getActionColorXY() const | |
| 84 | +{ | |
| 85 | + const nlohmann::json& xy = state.GetValue().at("action").at("xy"); | |
| 86 | + return std::pair<float, float>(xy[0].get<float>(), xy[1].get<float>()); | |
| 87 | +} | |
| 88 | + | |
| 89 | +std::string hueplusplus::Group::getActionColorMode() const | |
| 90 | +{ | |
| 91 | + return state.GetValue().at("action").at("colormode").get<std::string>(); | |
| 92 | +} | |
| 93 | + | |
| 94 | +void hueplusplus::Group::setOn(bool on, uint8_t transition) | |
| 95 | +{ | |
| 96 | + nlohmann::json request = {{"on", on}}; | |
| 97 | + if (transition != 4) | |
| 98 | + { | |
| 99 | + request["transition"] = transition; | |
| 100 | + } | |
| 101 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 102 | +} | |
| 103 | + | |
| 104 | +void hueplusplus::Group::setBrightness(uint8_t brightness, uint8_t transition) | |
| 105 | +{ | |
| 106 | + // TODO: turn on/off | |
| 107 | + nlohmann::json request = {{"bri", brightness}}; | |
| 108 | + if (transition != 4) | |
| 109 | + { | |
| 110 | + request["transition"] = transition; | |
| 111 | + } | |
| 112 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 113 | +} | |
| 114 | + | |
| 115 | +void hueplusplus::Group::setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition) | |
| 116 | +{ | |
| 117 | + nlohmann::json request = {{"hue", hue}, {"sat", saturation}}; | |
| 118 | + if (transition != 4) | |
| 119 | + { | |
| 120 | + request["transition"] = transition; | |
| 121 | + } | |
| 122 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 123 | +} | |
| 124 | + | |
| 125 | +void hueplusplus::Group::setColorXY(float x, float y, uint8_t transition) | |
| 126 | +{ | |
| 127 | + nlohmann::json request = {{"xy", {x, y}}}; | |
| 128 | + if (transition != 4) | |
| 129 | + { | |
| 130 | + request["transition"] = transition; | |
| 131 | + } | |
| 132 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 133 | +} | |
| 134 | + | |
| 135 | +void hueplusplus::Group::setColorTemperature(unsigned int mired, uint8_t transition) | |
| 136 | +{ | |
| 137 | + nlohmann::json request = {{"ct", mired}}; | |
| 138 | + if (transition != 4) | |
| 139 | + { | |
| 140 | + request["transition"] = transition; | |
| 141 | + } | |
| 142 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 143 | +} | |
| 144 | + | |
| 145 | +void hueplusplus::Group::setColorLoop(bool on, uint8_t transition) | |
| 146 | +{ | |
| 147 | + nlohmann::json request = {{"effect", on ? "colorloop" : "none"}}; | |
| 148 | + if (transition != 4) | |
| 149 | + { | |
| 150 | + request["transition"] = transition; | |
| 151 | + } | |
| 152 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 153 | +} | |
| 154 | + | |
| 155 | +void hueplusplus::Group::incrementBrightness(int increment, uint8_t transition) | |
| 156 | +{ | |
| 157 | + nlohmann::json request = {{"bri_inc", increment}}; | |
| 158 | + if (transition != 4) | |
| 159 | + { | |
| 160 | + request["transition"] = transition; | |
| 161 | + } | |
| 162 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 163 | +} | |
| 164 | + | |
| 165 | +void hueplusplus::Group::incrementSaturation(int increment, uint8_t transition) | |
| 166 | +{ | |
| 167 | + nlohmann::json request = {{"sat_inc", increment}}; | |
| 168 | + if (transition != 4) | |
| 169 | + { | |
| 170 | + request["transition"] = transition; | |
| 171 | + } | |
| 172 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 173 | +} | |
| 174 | + | |
| 175 | +void hueplusplus::Group::incrementHue(int increment, uint8_t transition) | |
| 176 | +{ | |
| 177 | + nlohmann::json request = {{"hue_inc", increment}}; | |
| 178 | + if (transition != 4) | |
| 179 | + { | |
| 180 | + request["transition"] = transition; | |
| 181 | + } | |
| 182 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 183 | +} | |
| 184 | + | |
| 185 | +void hueplusplus::Group::incrementColorTemperature(int increment, uint8_t transition) | |
| 186 | +{ | |
| 187 | + nlohmann::json request = {{"ct_inc", increment}}; | |
| 188 | + if (transition != 4) | |
| 189 | + { | |
| 190 | + request["transition"] = transition; | |
| 191 | + } | |
| 192 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 193 | +} | |
| 194 | + | |
| 195 | +void hueplusplus::Group::incrementColorXY(float increment, uint8_t transition) | |
| 196 | +{ | |
| 197 | + nlohmann::json request = {{"xy_inc", increment}}; | |
| 198 | + if (transition != 4) | |
| 199 | + { | |
| 200 | + request["transition"] = transition; | |
| 201 | + } | |
| 202 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 203 | +} | |
| 204 | + | |
| 205 | +void hueplusplus::Group::setScene(const std::string& scene, uint8_t transition) | |
| 206 | +{ | |
| 207 | + nlohmann::json request = {{"scene", scene}}; | |
| 208 | + if (transition != 4) | |
| 209 | + { | |
| 210 | + request["transition"] = transition; | |
| 211 | + } | |
| 212 | + SendPutRequest(request, "/action", CURRENT_FILE_INFO); | |
| 213 | +} | |
| 214 | + | |
| 215 | +nlohmann::json hueplusplus::Group::SendPutRequest( | |
| 216 | + const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo) | |
| 217 | +{ | |
| 218 | + return commands.PUTRequest("/groups/" + std::to_string(id) + subPath, request, std::move(fileInfo)); | |
| 219 | +} | |
| 220 | + | |
| 221 | +std::string hueplusplus::Group::getRoomType() const | |
| 222 | +{ | |
| 223 | + return state.GetValue().at("class").get<std::string>(); | |
| 224 | +} | |
| 225 | + | |
| 226 | +void hueplusplus::Group::setRoomType(const std::string& type) | |
| 227 | +{ | |
| 228 | + SendPutRequest({{"class", type}}, "", CURRENT_FILE_INFO); | |
| 229 | +} | ... | ... |
src/HueCommandAPI.cpp
| ... | ... | @@ -115,9 +115,15 @@ nlohmann::json HueCommandAPI::HandleError(FileInfo fileInfo, const nlohmann::jso |
| 115 | 115 | { |
| 116 | 116 | throw HueAPIResponseException::Create(std::move(fileInfo), response); |
| 117 | 117 | } |
| 118 | - else if (response.is_array() && response.size() > 0 && response[0].count("error")) | |
| 118 | + else if (response.is_array()) | |
| 119 | 119 | { |
| 120 | - throw HueAPIResponseException::Create(std::move(fileInfo), response[0]); | |
| 120 | + // Check if array contains error response | |
| 121 | + auto it | |
| 122 | + = std::find_if(response.begin(), response.end(), [](const nlohmann::json& v) { return v.count("error"); }); | |
| 123 | + if (it != response.end()) | |
| 124 | + { | |
| 125 | + throw HueAPIResponseException::Create(std::move(fileInfo), it.value()); | |
| 126 | + } | |
| 121 | 127 | } |
| 122 | 128 | return response; |
| 123 | 129 | } | ... | ... |