diff --git a/include/hueplusplus/HueConfig.h b/include/hueplusplus/APIConfig.h index 3a592e8..3a592e8 100644 --- a/include/hueplusplus/HueConfig.h +++ b/include/hueplusplus/APIConfig.h diff --git a/include/hueplusplus/BridgeConfig.h b/include/hueplusplus/BridgeConfig.h new file mode 100644 index 0000000..65596c3 --- /dev/null +++ b/include/hueplusplus/BridgeConfig.h @@ -0,0 +1,73 @@ +/** + \file BridgeConfig.h + Copyright Notice\n + Copyright (C) 2020 Jan Rogall - 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 . +**/ + +#include +#include + +#include "APICache.h" +#include "TimePattern.h" + +namespace hueplusplus +{ +struct Version +{ + int major; + int minor; + int patch; +}; + +struct WhitelistedUser +{ + std::string key; + std::string name; + time::AbsoluteTime lastUsed; + time::AbsoluteTime created; +}; + +class BridgeConfig +{ +public: + BridgeConfig(std::shared_ptr baseCache, std::chrono::steady_clock::duration refreshDuration); + + void refresh(); + + std::vector getWhitelistedUsers() const; + void removeUser(const std::string& userKey); + + bool getLinkButton() const; + void pressLinkButton(); + + void touchLink(); + + std::string getMACAddress() const; + time::AbsoluteTime getUTCTime() const; + std::string getTimezone() const; + +protected: + BridgeConfig(const BridgeConfig&) = default; + BridgeConfig(BridgeConfig&&) = default; + BridgeConfig& operator=(const BridgeConfig&) = default; + BridgeConfig& operator=(BridgeConfig&&) = default; + +private: + APICache cache; +}; +} // namespace hueplusplus \ No newline at end of file diff --git a/include/hueplusplus/Hue.h b/include/hueplusplus/Hue.h index d652387..b644d60 100644 --- a/include/hueplusplus/Hue.h +++ b/include/hueplusplus/Hue.h @@ -30,6 +30,7 @@ #include #include "APICache.h" +#include "BridgeConfig.h" #include "BrightnessStrategy.h" #include "ColorHueStrategy.h" #include "ColorTemperatureStrategy.h" @@ -117,6 +118,14 @@ private: std::shared_ptr http_handler; }; +template +class MakeCopyable : public T +{ +public: + using T::T; + using T::operator=; +}; + //! \brief Hue class for a bridge. //! //! This is the main class used to interact with the Hue bridge. @@ -184,6 +193,8 @@ public: //! \param handler a HttpHandler of type \ref IHttpHandler void setHttpHandler(std::shared_ptr handler); + BridgeConfig& config(); + const BridgeConfig& config() const; ///@} //! \name Lights ///@{ @@ -353,7 +364,6 @@ public: //! \throws nlohmann::json::parse_error when response could not be parsed Scene& getScene(const std::string& id); - //! \brief Checks whether a scene exists. //! \param id ID of the scene. //! \returns true when the scene exists. @@ -381,10 +391,11 @@ private: //!< bridge std::chrono::steady_clock::duration refreshDuration; std::shared_ptr stateCache; - ResourceList lights; - GroupResourceList groups; - CreateableResourceList schedules; - CreateableResourceList scenes; + MakeCopyable> lights; + MakeCopyable> groups; + MakeCopyable> schedules; + MakeCopyable> scenes; + MakeCopyable bridgeConfig; }; } // namespace hueplusplus diff --git a/include/hueplusplus/ResourceList.h b/include/hueplusplus/ResourceList.h index 952b0a8..3e0d933 100644 --- a/include/hueplusplus/ResourceList.h +++ b/include/hueplusplus/ResourceList.h @@ -57,7 +57,7 @@ public: std::chrono::steady_clock::duration refreshDuration, const std::function& factory = nullptr) : stateCache(baseCache, cacheEntry, refreshDuration), factory(factory), path(stateCache.getRequestPath() + '/') - {} + { } //! \brief Construct ResourceList with a separate cache and optional factory function //! \param commands HueCommandAPI for requests //! \param path Path of the resource list @@ -68,16 +68,12 @@ public: std::chrono::steady_clock::duration refreshDuration, const std::function& factory = nullptr) : stateCache(path, commands, refreshDuration), factory(factory), path(path + '/') - {} + { } //! \brief Deleted copy constructor ResourceList(const ResourceList&) = delete; - //! \brief Defaulted move constructor - ResourceList(ResourceList&&) = default; //! \brief Deleted copy assignment ResourceList& operator=(const ResourceList&) = delete; - //! \brief Defaulted move assignment - ResourceList& operator=(ResourceList&&) = default; //! \brief Refreshes internal state now void refresh() { stateCache.refresh(); } @@ -198,6 +194,11 @@ protected: id, state, std::is_constructible {}); } + //! \brief Protected defaulted move constructor + ResourceList(ResourceList&&) = default; + //! \brief Protected defaulted move assignment + ResourceList& operator=(ResourceList&&) = default; + private: // Resource is constructable Resource construct(const IdType& id, const nlohmann::json& state, std::true_type) @@ -274,6 +275,11 @@ public: } return IdType {}; } +protected: + //! \brief Protected defaulted move constructor + CreateableResourceList(CreateableResourceList&&) = default; + //! \brief Protected defaulted move assignment + CreateableResourceList& operator=(CreateableResourceList&&) = default; }; //! \brief Handles a group list with the special group 0 @@ -306,6 +312,12 @@ public: //! \brief Get group, specially handles group 0 //! \see ResourceList::exists bool exists(int id) const { return id == 0 || CreateableResourceList::exists(id); } + +protected: + //! \brief Protected defaulted move constructor + GroupResourceList(GroupResourceList&&) = default; + //! \brief Protected defaulted move assignment + GroupResourceList& operator=(GroupResourceList&&) = default; }; } // namespace hueplusplus diff --git a/src/BridgeConfig.cpp b/src/BridgeConfig.cpp new file mode 100644 index 0000000..4f0296e --- /dev/null +++ b/src/BridgeConfig.cpp @@ -0,0 +1,74 @@ +/** + \file BridgeConfig.cpp + Copyright Notice\n + Copyright (C) 2020 Jan Rogall - 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 . +**/ + +#include +#include + +namespace hueplusplus +{ +BridgeConfig::BridgeConfig(std::shared_ptr baseCache, std::chrono::steady_clock::duration refreshDuration) + : cache(std::move(baseCache), "config", refreshDuration) +{ } +void BridgeConfig::refresh() +{ + cache.refresh(); +} +std::vector BridgeConfig::getWhitelistedUsers() const +{ + const nlohmann::json& whitelist = cache.getValue().at("whitelist"); + std::vector users; + for (auto it = whitelist.begin(); it != whitelist.end(); ++it) + { + users.push_back({it.key(), it->at("name").get(), + time::AbsoluteTime::parseUTC(it->at("last use date").get()), + time::AbsoluteTime::parseUTC(it->at("create date").get())}); + } + return users; +} +void BridgeConfig::removeUser(const std::string& userKey) +{ + cache.getCommandAPI().DELETERequest("/config/whitelist/" + userKey, nlohmann::json::object()); +} +bool BridgeConfig::getLinkButton() const +{ + return cache.getValue().at("linkbutton").get(); +} +void BridgeConfig::pressLinkButton() +{ + cache.getCommandAPI().PUTRequest("/config", {{"linkbutton", true}}, CURRENT_FILE_INFO); +} +void BridgeConfig::touchLink() +{ + cache.getCommandAPI().PUTRequest("/config", {{"touchlink", true}}, CURRENT_FILE_INFO); +} +std::string BridgeConfig::getMACAddress() const +{ + return cache.getValue().at("mac").get(); +} +time::AbsoluteTime BridgeConfig::getUTCTime() const +{ + return time::AbsoluteTime::parseUTC(cache.getValue().at("UTC").get()); +} +std::string BridgeConfig::getTimezone() const +{ + return cache.getValue().at("timezone").get(); +} +} // namespace hueplusplus \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 14a975d..ef94e2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,7 @@ set(hueplusplus_SOURCES StateTransaction.cpp TimePattern.cpp UPnP.cpp - Utils.cpp) + Utils.cpp "BridgeConfig.cpp") # on windows we want to compile the WinHttpHandler if(WIN32) diff --git a/src/ExtendedColorHueStrategy.cpp b/src/ExtendedColorHueStrategy.cpp index 456125d..f16036d 100644 --- a/src/ExtendedColorHueStrategy.cpp +++ b/src/ExtendedColorHueStrategy.cpp @@ -26,7 +26,7 @@ #include #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" namespace hueplusplus { diff --git a/src/ExtendedColorTemperatureStrategy.cpp b/src/ExtendedColorTemperatureStrategy.cpp index 24e6564..d179ce1 100644 --- a/src/ExtendedColorTemperatureStrategy.cpp +++ b/src/ExtendedColorTemperatureStrategy.cpp @@ -26,7 +26,7 @@ #include #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/HueExceptionMacro.h" #include "hueplusplus/Utils.h" diff --git a/src/Hue.cpp b/src/Hue.cpp index 316f2a2..dcf4541 100644 --- a/src/Hue.cpp +++ b/src/Hue.cpp @@ -31,14 +31,14 @@ #include #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/HueExceptionMacro.h" #include "hueplusplus/UPnP.h" #include "hueplusplus/Utils.h" namespace hueplusplus { -HueFinder::HueFinder(std::shared_ptr handler) : http_handler(std::move(handler)) {} +HueFinder::HueFinder(std::shared_ptr handler) : http_handler(std::move(handler)) { } std::vector HueFinder::FindBridges() const { @@ -144,8 +144,9 @@ Hue::Hue(const std::string& ip, const int port, const std::string& username, int id, const nlohmann::json& state) mutable { return factory.createLight(state, id); }), groups(stateCache, "groups", refreshDuration), schedules(stateCache, "schedules", refreshDuration), - scenes(stateCache, "scenes", refreshDuration) -{} + scenes(stateCache, "scenes", refreshDuration), + bridgeConfig(stateCache, refreshDuration) +{ } void Hue::refresh() { @@ -220,6 +221,16 @@ void Hue::setPort(const int port) this->port = port; } +BridgeConfig& Hue::config() +{ + return bridgeConfig; +} + +const BridgeConfig& Hue::config() const +{ + return bridgeConfig; +} + HueLight& Hue::getLight(int id) { return lights.get(id); @@ -315,5 +326,6 @@ void Hue::setHttpHandler(std::shared_ptr handler) groups = GroupResourceList(stateCache, "groups", refreshDuration); schedules = CreateableResourceList(stateCache, "schedules", refreshDuration); scenes = CreateableResourceList(stateCache, "scenes", refreshDuration); + bridgeConfig = BridgeConfig(stateCache, refreshDuration); } } // namespace hueplusplus diff --git a/src/HueCommandAPI.cpp b/src/HueCommandAPI.cpp index f5d80e5..13e0727 100644 --- a/src/HueCommandAPI.cpp +++ b/src/HueCommandAPI.cpp @@ -24,7 +24,7 @@ #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/HueExceptionMacro.h" namespace hueplusplus diff --git a/src/SimpleColorHueStrategy.cpp b/src/SimpleColorHueStrategy.cpp index 2ec4e78..a9c3114 100644 --- a/src/SimpleColorHueStrategy.cpp +++ b/src/SimpleColorHueStrategy.cpp @@ -26,7 +26,7 @@ #include #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/HueExceptionMacro.h" #include "hueplusplus/Utils.h" diff --git a/src/SimpleColorTemperatureStrategy.cpp b/src/SimpleColorTemperatureStrategy.cpp index bbb3045..fa51c7e 100644 --- a/src/SimpleColorTemperatureStrategy.cpp +++ b/src/SimpleColorTemperatureStrategy.cpp @@ -26,7 +26,7 @@ #include #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/HueExceptionMacro.h" #include "hueplusplus/Utils.h" diff --git a/src/UPnP.cpp b/src/UPnP.cpp index f691155..056b5ad 100644 --- a/src/UPnP.cpp +++ b/src/UPnP.cpp @@ -25,7 +25,7 @@ #include #include -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" namespace hueplusplus { diff --git a/test/test_Hue.cpp b/test/test_Hue.cpp index 2f8798a..37d1725 100644 --- a/test/test_Hue.cpp +++ b/test/test_Hue.cpp @@ -28,8 +28,8 @@ #include "testhelper.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/Hue.h" -#include "hueplusplus/HueConfig.h" #include "json/json.hpp" #include "mocks/mock_HttpHandler.h" diff --git a/test/test_Main.cpp b/test/test_Main.cpp index 98526bb..896d1d2 100644 --- a/test/test_Main.cpp +++ b/test/test_Main.cpp @@ -21,7 +21,7 @@ **/ #include -#include +#include namespace { diff --git a/test/test_UPnP.cpp b/test/test_UPnP.cpp index 17f5feb..5faba5a 100644 --- a/test/test_UPnP.cpp +++ b/test/test_UPnP.cpp @@ -26,7 +26,7 @@ #include "iostream" #include "testhelper.h" -#include "hueplusplus/HueConfig.h" +#include "hueplusplus/APIConfig.h" #include "hueplusplus/UPnP.h" #include "json/json.hpp" #include "mocks/mock_HttpHandler.h"