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 | \ No newline at end of file | 87 | \ No newline at end of file |
src/CMakeLists.txt
| @@ -3,6 +3,7 @@ set(hueplusplus_SOURCES | @@ -3,6 +3,7 @@ set(hueplusplus_SOURCES | ||
| 3 | BaseHttpHandler.cpp | 3 | BaseHttpHandler.cpp |
| 4 | ExtendedColorHueStrategy.cpp | 4 | ExtendedColorHueStrategy.cpp |
| 5 | ExtendedColorTemperatureStrategy.cpp | 5 | ExtendedColorTemperatureStrategy.cpp |
| 6 | + Group.cpp | ||
| 6 | Hue.cpp | 7 | Hue.cpp |
| 7 | HueCommandAPI.cpp | 8 | HueCommandAPI.cpp |
| 8 | HueDeviceTypes.cpp | 9 | HueDeviceTypes.cpp |
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,9 +115,15 @@ nlohmann::json HueCommandAPI::HandleError(FileInfo fileInfo, const nlohmann::jso | ||
| 115 | { | 115 | { |
| 116 | throw HueAPIResponseException::Create(std::move(fileInfo), response); | 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 | return response; | 128 | return response; |
| 123 | } | 129 | } |