From 59d03c52dd4eee0f30b7064b58e4bb9eb5117d5a Mon Sep 17 00:00:00 2001
From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com>
Date: Mon, 13 Apr 2020 14:34:19 +0200
Subject: [PATCH] Add group class for groups of HueLight.
---
include/hueplusplus/Group.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/CMakeLists.txt | 1 +
src/Group.cpp | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/HueCommandAPI.cpp | 10 ++++++++--
4 files changed, 324 insertions(+), 2 deletions(-)
create mode 100644 include/hueplusplus/Group.h
create mode 100644 src/Group.cpp
diff --git a/include/hueplusplus/Group.h b/include/hueplusplus/Group.h
new file mode 100644
index 0000000..c4e65ae
--- /dev/null
+++ b/include/hueplusplus/Group.h
@@ -0,0 +1,86 @@
+/**
+ \file Group.h
+ Copyright Notice\n
+ Copyright (C) 2020 Jan Rogall - developer\n
+ Copyright (C) 2020 Moritz Wirger - developer\n
+
+ This file is part of hueplusplus.
+
+ hueplusplus is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ hueplusplus is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with hueplusplus. If not, see .
+**/
+
+#ifndef INCLUDE_HUEPLUSPLUS_GROUP_H
+#define INCLUDE_HUEPLUSPLUS_GROUP_H
+
+#include
+#include
+
+#include "APICache.h"
+#include "HueCommandAPI.h"
+
+#include "json/json.hpp"
+
+namespace hueplusplus
+{
+ class Group
+ {
+ public:
+ Group(int id, const HueCommandAPI& commands);
+
+ virtual ~Group() = default;
+
+ int getId() const;
+ std::string getName() const;
+ std::string getType() const;
+ std::vector getLightIds() const;
+
+ void setName(const std::string& name);
+ void setLights(const std::vector& ids);
+
+ std::string getRoomType() const;
+ void setRoomType(const std::string& type);
+
+ bool getAllOn() const;
+ bool getAnyOn() const;
+
+ bool getActionOn() const;
+ std::pair getActionHueSaturation() const;
+ unsigned int getActionBrightness() const;
+ unsigned int getActionColorTemperature() const;
+ std::pair getActionColorXY() const;
+ std::string getActionColorMode() const;
+
+ void setOn(bool on, uint8_t transition = 4);
+ void setBrightness(uint8_t brightness, uint8_t transition = 4);
+ void setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition = 4);
+ void setColorXY(float x, float y, uint8_t transition = 4);
+ void setColorTemperature(unsigned int mired, uint8_t transition = 4);
+ void setColorLoop(bool on, uint8_t transition = 4);
+ void incrementBrightness(int increment, uint8_t transition = 4);
+ void incrementSaturation(int increment, uint8_t transition = 4);
+ void incrementHue(int increment, uint8_t transition = 4);
+ void incrementColorTemperature(int increment, uint8_t transition = 4);
+ void incrementColorXY(float increment, uint8_t transition = 4);
+ void setScene(const std::string& scene, uint8_t transition = 4);
+ protected:
+ nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo);
+
+ protected:
+ int id;
+ APICache state;
+ HueCommandAPI commands;
+ };
+} // namespace hueplusplus
+
+#endif
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 655ce42..c7d1f74 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,6 +3,7 @@ set(hueplusplus_SOURCES
BaseHttpHandler.cpp
ExtendedColorHueStrategy.cpp
ExtendedColorTemperatureStrategy.cpp
+ Group.cpp
Hue.cpp
HueCommandAPI.cpp
HueDeviceTypes.cpp
diff --git a/src/Group.cpp b/src/Group.cpp
new file mode 100644
index 0000000..ae677b5
--- /dev/null
+++ b/src/Group.cpp
@@ -0,0 +1,229 @@
+#include "hueplusplus/Group.h"
+
+#include "hueplusplus/HueExceptionMacro.h"
+
+hueplusplus::Group::Group(int id, const HueCommandAPI& commands)
+ : id(id), state("/groups/" + std::to_string(id), commands, std::chrono::seconds(10)), commands(commands)
+{}
+
+int hueplusplus::Group::getId() const
+{
+ return id;
+}
+
+std::string hueplusplus::Group::getName() const
+{
+ return state.GetValue().at("name").get();
+}
+
+std::string hueplusplus::Group::getType() const
+{
+ return state.GetValue().at("type").get();
+}
+
+std::vector hueplusplus::Group::getLightIds() const
+{
+ const nlohmann::json& lights = state.GetValue().at("lights");
+ std::vector ids(lights.size());
+ for (const nlohmann::json& id : lights)
+ {
+ ids.push_back(std::stoi(id.get()));
+ }
+ return ids;
+}
+
+void hueplusplus::Group::setName(const std::string& name)
+{
+ nlohmann::json request = {{"name", name}};
+ SendPutRequest(request, "", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setLights(const std::vector& ids)
+{
+ nlohmann::json lights = nlohmann::json::array();
+ for (int id : ids)
+ {
+ lights.push_back(std::to_string(id));
+ }
+ SendPutRequest({{"lights", lights}}, "", CURRENT_FILE_INFO);
+}
+
+bool hueplusplus::Group::getAllOn() const
+{
+ return state.GetValue().at("state").at("all_on").get();
+}
+
+bool hueplusplus::Group::getAnyOn() const
+{
+ return state.GetValue().at("state").at("any_on").get();
+}
+
+bool hueplusplus::Group::getActionOn() const
+{
+ return state.GetValue().at("action").at("on").get();
+}
+
+std::pair hueplusplus::Group::getActionHueSaturation() const
+{
+ const nlohmann::json& action = state.GetValue().at("action");
+
+ return std::make_pair(action.at("hue").get(), action.at("sat").get());
+}
+
+unsigned int hueplusplus::Group::getActionBrightness() const
+{
+ return state.GetValue().at("action").at("bri").get();
+}
+
+unsigned int hueplusplus::Group::getActionColorTemperature() const
+{
+ return state.GetValue().at("action").at("ct").get();
+}
+
+std::pair hueplusplus::Group::getActionColorXY() const
+{
+ const nlohmann::json& xy = state.GetValue().at("action").at("xy");
+ return std::pair(xy[0].get(), xy[1].get());
+}
+
+std::string hueplusplus::Group::getActionColorMode() const
+{
+ return state.GetValue().at("action").at("colormode").get();
+}
+
+void hueplusplus::Group::setOn(bool on, uint8_t transition)
+{
+ nlohmann::json request = {{"on", on}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setBrightness(uint8_t brightness, uint8_t transition)
+{
+ // TODO: turn on/off
+ nlohmann::json request = {{"bri", brightness}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setColorHueSaturation(uint16_t hue, uint8_t saturation, uint8_t transition)
+{
+ nlohmann::json request = {{"hue", hue}, {"sat", saturation}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setColorXY(float x, float y, uint8_t transition)
+{
+ nlohmann::json request = {{"xy", {x, y}}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setColorTemperature(unsigned int mired, uint8_t transition)
+{
+ nlohmann::json request = {{"ct", mired}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setColorLoop(bool on, uint8_t transition)
+{
+ nlohmann::json request = {{"effect", on ? "colorloop" : "none"}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::incrementBrightness(int increment, uint8_t transition)
+{
+ nlohmann::json request = {{"bri_inc", increment}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::incrementSaturation(int increment, uint8_t transition)
+{
+ nlohmann::json request = {{"sat_inc", increment}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::incrementHue(int increment, uint8_t transition)
+{
+ nlohmann::json request = {{"hue_inc", increment}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::incrementColorTemperature(int increment, uint8_t transition)
+{
+ nlohmann::json request = {{"ct_inc", increment}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::incrementColorXY(float increment, uint8_t transition)
+{
+ nlohmann::json request = {{"xy_inc", increment}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+void hueplusplus::Group::setScene(const std::string& scene, uint8_t transition)
+{
+ nlohmann::json request = {{"scene", scene}};
+ if (transition != 4)
+ {
+ request["transition"] = transition;
+ }
+ SendPutRequest(request, "/action", CURRENT_FILE_INFO);
+}
+
+nlohmann::json hueplusplus::Group::SendPutRequest(
+ const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo)
+{
+ return commands.PUTRequest("/groups/" + std::to_string(id) + subPath, request, std::move(fileInfo));
+}
+
+std::string hueplusplus::Group::getRoomType() const
+{
+ return state.GetValue().at("class").get();
+}
+
+void hueplusplus::Group::setRoomType(const std::string& type)
+{
+ SendPutRequest({{"class", type}}, "", CURRENT_FILE_INFO);
+}
diff --git a/src/HueCommandAPI.cpp b/src/HueCommandAPI.cpp
index 738ff30..7562c1c 100644
--- a/src/HueCommandAPI.cpp
+++ b/src/HueCommandAPI.cpp
@@ -115,9 +115,15 @@ nlohmann::json HueCommandAPI::HandleError(FileInfo fileInfo, const nlohmann::jso
{
throw HueAPIResponseException::Create(std::move(fileInfo), response);
}
- else if (response.is_array() && response.size() > 0 && response[0].count("error"))
+ else if (response.is_array())
{
- throw HueAPIResponseException::Create(std::move(fileInfo), response[0]);
+ // Check if array contains error response
+ auto it
+ = std::find_if(response.begin(), response.end(), [](const nlohmann::json& v) { return v.count("error"); });
+ if (it != response.end())
+ {
+ throw HueAPIResponseException::Create(std::move(fileInfo), it.value());
+ }
}
return response;
}
--
libgit2 0.21.4