From cd30bc7443f7fede4fce158b792397f44962b39c Mon Sep 17 00:00:00 2001 From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com> Date: Sun, 12 Apr 2020 22:06:48 +0200 Subject: [PATCH] Implement APICache to cache json values returned by the Hue API. --- include/hueplusplus/APICache.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/hueplusplus/Hue.h | 15 ++++----------- include/hueplusplus/HueLight.h | 33 ++++----------------------------- src/APICache.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/ExtendedColorHueStrategy.cpp | 69 ++++++++++++++++++++++++++++++++++++--------------------------------- src/ExtendedColorTemperatureStrategy.cpp | 30 ++++++++++++++++-------------- src/Hue.cpp | 48 ++++++++++++++---------------------------------- src/HueCommandAPI.cpp | 6 +++--- src/HueLight.cpp | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------------------- src/SimpleBrightnessStrategy.cpp | 16 ++++++++-------- src/SimpleColorHueStrategy.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------- src/SimpleColorTemperatureStrategy.cpp | 23 ++++++++++++----------- test/mocks/mock_HueLight.h | 14 ++++++-------- test/test_ExtendedColorHueStrategy.cpp | 21 +++++++++------------ test/test_ExtendedColorTemperatureStrategy.cpp | 5 ++--- test/test_Hue.cpp | 13 ++----------- test/test_HueLight.cpp | 16 ---------------- test/test_SimpleBrightnessStrategy.cpp | 5 ++--- test/test_SimpleColorHueStrategy.cpp | 29 ++++++++++++----------------- test/test_SimpleColorTemperatureStrategy.cpp | 6 ++---- 21 files changed, 395 insertions(+), 394 deletions(-) create mode 100644 include/hueplusplus/APICache.h create mode 100644 src/APICache.cpp diff --git a/include/hueplusplus/APICache.h b/include/hueplusplus/APICache.h new file mode 100644 index 0000000..55c9766 --- /dev/null +++ b/include/hueplusplus/APICache.h @@ -0,0 +1,71 @@ +/** + \file APICache.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_API_CACHE_H +#define INCLUDE_API_CACHE_H + +#include +#include + +#include "HueCommandAPI.h" + +namespace hueplusplus +{ +//! \brief Caches API GET requests and refreshes regularly. +class APICache +{ +public: + //! \brief Constructs APICache + //! \param path URL appended after username, may be empty. + //! \param commands HueCommandAPI for making API requests. + //! \param refresh Interval between cache refreshing. May be 0 to always refresh. + APICache(const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh); + + //! \brief Refresh cache now. + //! \throws std::system_error when system or socket operations fail + //! \throws HueException when response contained no body + //! \throws HueAPIResponseException when response contains an error + //! \throws nlohmann::json::parse_error when response could not be parsed + void Refresh(); + + //! \brief Get cached value, refresh if necessary. + //! \throws std::system_error when system or socket operations fail + //! \throws HueException when response contained no body + //! \throws HueAPIResponseException when response contains an error + //! \throws nlohmann::json::parse_error when response could not be parsed + nlohmann::json& GetValue(); + //! \brief Get cached value, does not refresh. + const nlohmann::json& GetValue() const; + + //! \brief Get duration between refreshes. + std::chrono::steady_clock::duration GetRefreshDuration() const; + +private: + std::string path; + HueCommandAPI commands; + std::chrono::steady_clock::duration refreshDuration; + std::chrono::steady_clock::time_point lastRefresh; + nlohmann::json value; +}; +} // namespace hueplusplus + +#endif diff --git a/include/hueplusplus/Hue.h b/include/hueplusplus/Hue.h index 57f5e65..277dfb7 100644 --- a/include/hueplusplus/Hue.h +++ b/include/hueplusplus/Hue.h @@ -29,6 +29,7 @@ #include #include +#include "APICache.h" #include "BrightnessStrategy.h" #include "ColorHueStrategy.h" #include "ColorTemperatureStrategy.h" @@ -123,8 +124,8 @@ public: //! \param username String that specifies the username that is used to control //! the bridge. This needs to be acquired in \ref requestUsername //! \param handler HttpHandler for communication with the bridge - Hue(const std::string& ip, const int port, const std::string& username, - std::shared_ptr handler); + Hue(const std::string& ip, const int port, const std::string& username, std::shared_ptr handler, + std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10)); //! \brief Function to get the ip address of the hue bridge //! @@ -249,19 +250,10 @@ public: } private: - //! \brief Function that refreshes the local \ref state of the Hue bridge - //! \throws std::system_error when system or socket operations fail - //! \throws HueException when response contained no body - //! \throws HueAPIResponseException when response contains an error - //! \throws nlohmann::json::parse_error when response could not be parsed - void refreshState(); - -private: std::string ip; //!< IP-Address of the hue bridge in dotted decimal notation //!< like "192.168.2.1" std::string username; //!< Username that is ussed to access the hue bridge int port; - nlohmann::json state; //!< The state of the hue bridge as it is returned from it std::map lights; //!< Maps ids to HueLights that are controlled by this bridge std::shared_ptr simpleBrightnessStrategy; //!< Strategy that is used for controlling the @@ -278,6 +270,7 @@ private: std::shared_ptr http_handler; //!< A IHttpHandler that is used to communicate with the //!< bridge HueCommandAPI commands; //!< A HueCommandAPI that is used to communicate with the bridge + APICache stateCache; //!< The state of the hue bridge as it is returned from it }; } // namespace hueplusplus diff --git a/include/hueplusplus/HueLight.h b/include/hueplusplus/HueLight.h index 3fd778d..6531241 100644 --- a/include/hueplusplus/HueLight.h +++ b/include/hueplusplus/HueLight.h @@ -25,6 +25,7 @@ #include +#include "APICache.h" #include "BrightnessStrategy.h" #include "ColorHueStrategy.h" #include "ColorTemperatureStrategy.h" @@ -698,7 +699,8 @@ protected: //! \throws nlohmann::json::parse_error when response could not be parsed HueLight(int id, const HueCommandAPI& commands, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, - std::shared_ptr colorHueStrategy); + std::shared_ptr colorHueStrategy, + std::chrono::steady_clock::duration refreshDuration = std::chrono::seconds(10)); //! \brief Protected function that sets the brightness strategy. //! @@ -735,26 +737,6 @@ protected: //! \param commandAPI the new HueCommandAPI virtual void setCommandAPI(const HueCommandAPI& commandAPI) { commands = commandAPI; }; - //! \brief Function that turns the light on without refreshing its state. - //! - //! \param transition Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - //! \throws std::system_error when system or socket operations fail - //! \throws HueException when response contained no body - //! \throws HueAPIResponseException when response contains an error - //! \throws nlohmann::json::parse_error when response could not be parsed - virtual bool OnNoRefresh(uint8_t transition = 4); - - //! \brief Function that turns the light off without refreshing its state. - //! - //! \param transition Optional parameter to set the transition from current state to new standard is 4 = 400ms - //! \return Bool that is true on success - //! \throws std::system_error when system or socket operations fail - //! \throws HueException when response contained no body - //! \throws HueAPIResponseException when response contains an error - //! \throws nlohmann::json::parse_error when response could not be parsed - virtual bool OffNoRefresh(uint8_t transition = 4); - //! \brief Utility function to send a put request to the light. //! //! \throws nlohmann::json::parse_error if the reply could not be parsed @@ -768,16 +750,9 @@ protected: //! \throws nlohmann::json::parse_error when response could not be parsed virtual nlohmann::json SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo); - //! \brief Virtual function that refreshes the \ref state of the light. - //! \throws std::system_error when system or socket operations fail - //! \throws HueException when response contained no body - //! \throws HueAPIResponseException when response contains an error - //! \throws nlohmann::json::parse_error when response could not be parsed - virtual void refreshState(); - protected: int id; //!< holds the id of the light - nlohmann::json state; //!< holds the current state of the light updated by \ref refreshState + APICache state; //!< holds the current state of the light updated by \ref refreshState ColorType colorType; //!< holds the \ref ColorType of the light std::shared_ptr diff --git a/src/APICache.cpp b/src/APICache.cpp new file mode 100644 index 0000000..ebd8653 --- /dev/null +++ b/src/APICache.cpp @@ -0,0 +1,55 @@ +#include "hueplusplus/APICache.h" +/** + \file BaseHttpHandler.cpp + 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 . +**/ + +#include "hueplusplus/HueExceptionMacro.h" + +hueplusplus::APICache::APICache( + const std::string& path, const HueCommandAPI& commands, std::chrono::steady_clock::duration refresh) + : path(path), + commands(commands), + refreshDuration(refresh), + lastRefresh(std::chrono::steady_clock::duration::zero()) +{} + +void hueplusplus::APICache::Refresh() { + value = commands.GETRequest(path, nlohmann::json::object(), CURRENT_FILE_INFO); +} + +nlohmann::json& hueplusplus::APICache::GetValue() +{ + if (std::chrono::steady_clock::now() >= lastRefresh + refreshDuration) + { + Refresh(); + } + return value; +} + +const nlohmann::json& hueplusplus::APICache::GetValue() const +{ + return value; +} + +std::chrono::steady_clock::duration hueplusplus::APICache::GetRefreshDuration() const +{ + return refreshDuration; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5be5ba9..655ce42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ set(hueplusplus_SOURCES + APICache.cpp BaseHttpHandler.cpp ExtendedColorHueStrategy.cpp ExtendedColorTemperatureStrategy.cpp diff --git a/src/ExtendedColorHueStrategy.cpp b/src/ExtendedColorHueStrategy.cpp index 9546cf7..169bf63 100644 --- a/src/ExtendedColorHueStrategy.cpp +++ b/src/ExtendedColorHueStrategy.cpp @@ -32,13 +32,14 @@ namespace hueplusplus { bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorHueSaturation(hue, sat, 1)) { return false; @@ -52,7 +53,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -61,8 +62,8 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorHueSaturation(hue, sat, 1)) { return false; @@ -76,7 +77,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -85,7 +86,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"].get(); + uint16_t oldCT = state["ct"].get(); if (!light.setColorHueSaturation(hue, sat, 1)) { return false; @@ -99,7 +100,7 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue if (!on) { light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -114,13 +115,14 @@ bool ExtendedColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, Hue bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorXY(x, y, 1)) { return false; @@ -134,7 +136,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -143,8 +145,8 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorXY(x, y, 1)) { return false; @@ -158,7 +160,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -167,7 +169,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"].get(); + uint16_t oldCT = state["ct"].get(); if (!light.setColorXY(x, y, 1)) { return false; @@ -181,7 +183,7 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const if (!on) { light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -196,13 +198,14 @@ bool ExtendedColorHueStrategy::alertXY(float x, float y, HueLight& light) const bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"]; + bool on = state["on"]; if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorRGB(r, g, b, 1)) { return false; @@ -216,7 +219,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -225,8 +228,8 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorRGB(r, g, b, 1)) { return false; @@ -240,7 +243,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -249,7 +252,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"].get(); + uint16_t oldCT = state["ct"].get(); if (!light.setColorRGB(r, g, b, 1)) { return false; @@ -263,7 +266,7 @@ bool ExtendedColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLigh if (!on) { light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { diff --git a/src/ExtendedColorTemperatureStrategy.cpp b/src/ExtendedColorTemperatureStrategy.cpp index 151ddd6..edaf804 100644 --- a/src/ExtendedColorTemperatureStrategy.cpp +++ b/src/ExtendedColorTemperatureStrategy.cpp @@ -35,17 +35,18 @@ namespace hueplusplus bool ExtendedColorTemperatureStrategy::setColorTemperature( unsigned int mired, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); if (transition != 4) { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (light.state["state"]["ct"] != mired || light.state["state"]["colormode"] != "ct") + if (state["ct"] != mired || state["colormode"] != "ct") { if (mired > 500) { @@ -72,13 +73,14 @@ bool ExtendedColorTemperatureStrategy::setColorTemperature( bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorTemperature(mired, 1)) { return false; @@ -92,7 +94,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -101,8 +103,8 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorTemperature(mired, 1)) { return false; @@ -116,7 +118,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -125,7 +127,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL } else if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"].get(); + uint16_t oldCT = state["ct"].get(); if (!light.setColorTemperature(mired, 1)) { return false; @@ -139,7 +141,7 @@ bool ExtendedColorTemperatureStrategy::alertTemperature(unsigned int mired, HueL if (!on) { light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { diff --git a/src/Hue.cpp b/src/Hue.cpp index 6d825b9..5d5d54b 100644 --- a/src/Hue.cpp +++ b/src/Hue.cpp @@ -135,8 +135,8 @@ std::string HueFinder::ParseDescription(const std::string& description) return std::string(); } -Hue::Hue( - const std::string& ip, const int port, const std::string& username, std::shared_ptr handler) +Hue::Hue(const std::string& ip, const int port, const std::string& username, + std::shared_ptr handler, std::chrono::steady_clock::duration refreshDuration) : ip(ip), port(port), username(username), @@ -146,7 +146,8 @@ Hue::Hue( simpleColorTemperatureStrategy(std::make_shared()), extendedColorTemperatureStrategy(std::make_shared()), http_handler(std::move(handler)), - commands(ip, port, username, http_handler) + commands(ip, port, username, http_handler), + stateCache("", commands, refreshDuration) {} std::string Hue::getBridgeIP() @@ -189,6 +190,7 @@ std::string Hue::requestUsername() username = jsonUser.get(); // Update commands with new username and ip commands = HueCommandAPI(ip, port, username, http_handler); + stateCache = APICache("", commands, stateCache.GetRefreshDuration()); std::cout << "Success! Link button was pressed!\n"; std::cout << "Username is \"" << username << "\"\n"; break; @@ -228,18 +230,16 @@ HueLight& Hue::getLight(int id) auto pos = lights.find(id); if (pos != lights.end()) { - pos->second.refreshState(); + pos->second.state.Refresh(); return pos->second; } - refreshState(); - if (!state["lights"].count(std::to_string(id))) + const nlohmann::json& lightsCache = stateCache.GetValue()["lights"]; + if (!lightsCache.count(std::to_string(id))) { std::cerr << "Error in Hue getLight(): light with id " << id << " is not valid\n"; throw HueException(CURRENT_FILE_INFO, "Light id is not valid"); } - // std::cout << state["lights"][std::to_string(id)] << std::endl; - std::string type = state["lights"][std::to_string(id)]["modelid"].get(); - // std::cout << type << std::endl; + std::string type = lightsCache[std::to_string(id)]["modelid"].get(); auto light = MakeHueLight()(type, id, commands, simpleBrightnessStrategy, extendedColorTemperatureStrategy, simpleColorTemperatureStrategy, extendedColorHueStrategy, simpleColorHueStrategy); lights.emplace(id, light); @@ -260,9 +260,9 @@ bool Hue::removeLight(int id) std::vector> Hue::getAllLights() { - refreshState(); - nlohmann::json lightsState = state["lights"]; - for (nlohmann::json::iterator it = lightsState.begin(); it != lightsState.end(); ++it) + // No reference because getLight may invalidate it + nlohmann::json lightsState = stateCache.GetValue()["lights"]; + for (auto it = lightsState.begin(); it != lightsState.end(); ++it) { getLight(std::stoi(it.key())); } @@ -276,13 +276,12 @@ std::vector> Hue::getAllLights() bool Hue::lightExists(int id) { - refreshState(); auto pos = lights.find(id); if (pos != lights.end()) { return true; } - if (state["lights"].count(std::to_string(id))) + if (stateCache.GetValue()["lights"].count(std::to_string(id))) { return true; } @@ -296,7 +295,7 @@ bool Hue::lightExists(int id) const { return true; } - if (state["lights"].count(std::to_string(id))) + if (stateCache.GetValue()["lights"].count(std::to_string(id))) { return true; } @@ -437,23 +436,4 @@ std::string Hue::getPictureOfModel(const std::string& model_id) const } return ret; } - -void Hue::refreshState() -{ - if (username.empty()) - { - return; - } - nlohmann::json answer = commands.GETRequest("", nlohmann::json::object(), CURRENT_FILE_INFO); - if (answer.is_object() && answer.count("lights")) - { - state = answer; - } - else - { - std::cout << "Answer in Hue::refreshState of http_handler->GETJson(...) is " - "not expected!\nAnswer:\n\t" - << answer.dump() << std::endl; - } -} } // namespace hueplusplus diff --git a/src/HueCommandAPI.cpp b/src/HueCommandAPI.cpp index 3fb79f6..738ff30 100644 --- a/src/HueCommandAPI.cpp +++ b/src/HueCommandAPI.cpp @@ -81,7 +81,7 @@ nlohmann::json HueCommandAPI::PUTRequest(const std::string& path, const nlohmann nlohmann::json HueCommandAPI::PUTRequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { - return HandleError(fileInfo, + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->PUTJson(CombinedPath(path), request, ip); })); } @@ -93,7 +93,7 @@ nlohmann::json HueCommandAPI::GETRequest(const std::string& path, const nlohmann nlohmann::json HueCommandAPI::GETRequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { - return HandleError(fileInfo, + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->GETJson(CombinedPath(path), request, ip); })); } @@ -105,7 +105,7 @@ nlohmann::json HueCommandAPI::DELETERequest(const std::string& path, const nlohm nlohmann::json HueCommandAPI::DELETERequest( const std::string& path, const nlohmann::json& request, FileInfo fileInfo) const { - return HandleError(fileInfo, + return HandleError(std::move(fileInfo), RunWithTimeout(timeout, minDelay, [&]() { return httpHandler->DELETEJson(CombinedPath(path), request, ip); })); } diff --git a/src/HueLight.cpp b/src/HueLight.cpp index 5aa1375..fafc7a2 100644 --- a/src/HueLight.cpp +++ b/src/HueLight.cpp @@ -1,23 +1,23 @@ /** - \file HueLight.cpp - Copyright Notice\n - Copyright (C) 2017 Jan Rogall - developer\n - Copyright (C) 2017 Moritz Wirger - developer\n + \file HueLight.cpp + Copyright Notice\n + Copyright (C) 2017 Jan Rogall - developer\n + Copyright (C) 2017 Moritz Wirger - developer\n - This file is part of hueplusplus. + 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 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. + 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 . + You should have received a copy of the GNU Lesser General Public License + along with hueplusplus. If not, see . **/ #include "hueplusplus/HueLight.h" @@ -34,25 +34,60 @@ namespace hueplusplus { bool HueLight::On(uint8_t transition) { - refreshState(); - return OnNoRefresh(transition); + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (state.GetValue()["state"]["on"] != true) + { + request["on"] = true; + } + + if (!request.count("on")) + { + // Nothing needs to be changed + return true; + } + + nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, id); } bool HueLight::Off(uint8_t transition) { - refreshState(); - return OffNoRefresh(transition); + nlohmann::json request = nlohmann::json::object(); + if (transition != 4) + { + request["transitiontime"] = transition; + } + if (state.GetValue()["state"]["on"] != false) + { + request["on"] = false; + } + + if (!request.count("on")) + { + // Nothing needs to be changed + return true; + } + + nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO); + + // Check whether request was successful + return utils::validateReplyForLight(request, reply, id); } bool HueLight::isOn() { - refreshState(); - return state["state"]["on"].get(); + return state.GetValue()["state"]["on"].get(); } bool HueLight::isOn() const { - return state["state"]["on"].get(); + return state.GetValue()["state"]["on"].get(); } int HueLight::getId() const @@ -62,70 +97,52 @@ int HueLight::getId() const std::string HueLight::getType() const { - return state["type"].get(); + return state.GetValue()["type"].get(); } std::string HueLight::getName() { - refreshState(); - return state["name"].get(); + return state.GetValue()["name"].get(); } std::string HueLight::getName() const { - return state["name"].get(); + return state.GetValue()["name"].get(); } std::string HueLight::getModelId() const { - return state["modelid"].get(); + return state.GetValue()["modelid"].get(); } std::string HueLight::getUId() const { - if (state.count("uniqueid")) - { - return state["uniqueid"].get(); - } - return std::string(); + return state.GetValue().value("uniqueid", std::string()); } std::string HueLight::getManufacturername() const { - if (state.count("manufacturername")) - { - return state["manufacturername"].get(); - } - return std::string(); + return state.GetValue().value("manufacturername", std::string()); } std::string HueLight::getProductname() const { - if (state.count("productname")) - { - return state["productname"].get(); - } - return std::string(); + return state.GetValue().value("productname", std::string()); } std::string HueLight::getLuminaireUId() const { - if (state.count("luminaireuniqueid")) - { - return state["luminaireuniqueid"].get(); - } - return std::string(); + return state.GetValue().value("luminaireuniqueid", std::string()); } std::string HueLight::getSwVersion() { - refreshState(); - return state["swversion"].get(); + return state.GetValue()["swversion"].get(); } std::string HueLight::getSwVersion() const { - return state["swversion"].get(); + return state.GetValue()["swversion"].get(); } bool HueLight::setName(const std::string& name) @@ -134,8 +151,9 @@ bool HueLight::setName(const std::string& name) request["name"] = name; nlohmann::json reply = SendPutRequest(request, "/name", CURRENT_FILE_INFO); - // Check whether request was successful - return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name") == name; + // Check whether request was successful (returned name is not necessarily the actually set name) + // If it already exists, a number is added, if it is too long to be returned, "Updated" is returned + return utils::safeGetMember(reply, 0, "success", "/lights/" + std::to_string(id) + "/name").is_string(); } ColorType HueLight::getColorType() const @@ -167,89 +185,20 @@ HueLight::HueLight(int id, const HueCommandAPI& commands) : HueLight(id, command HueLight::HueLight(int id, const HueCommandAPI& commands, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, - std::shared_ptr colorHueStrategy) + std::shared_ptr colorHueStrategy, std::chrono::steady_clock::duration refreshDuration) : id(id), brightnessStrategy(std::move(brightnessStrategy)), colorTemperatureStrategy(std::move(colorTempStrategy)), colorHueStrategy(std::move(colorHueStrategy)), - commands(commands) - -{ - refreshState(); -} + commands(commands), + state("/lights/" + std::to_string(id), commands, refreshDuration) -bool HueLight::OnNoRefresh(uint8_t transition) { - nlohmann::json request = nlohmann::json::object(); - if (transition != 4) - { - request["transitiontime"] = transition; - } - if (state["state"]["on"] != true) - { - request["on"] = true; - } - - if (!request.count("on")) - { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO); - - // Check whether request was successful - return utils::validateReplyForLight(request, reply, id); -} - -bool HueLight::OffNoRefresh(uint8_t transition) -{ - nlohmann::json request = nlohmann::json::object(); - if (transition != 4) - { - request["transitiontime"] = transition; - } - if (state["state"]["on"] != false) - { - request["on"] = false; - } - - if (!request.count("on")) - { - // Nothing needs to be changed - return true; - } - - nlohmann::json reply = SendPutRequest(request, "/state", CURRENT_FILE_INFO); - - // Check whether request was successful - return utils::validateReplyForLight(request, reply, id); + state.Refresh(); } nlohmann::json HueLight::SendPutRequest(const nlohmann::json& request, const std::string& subPath, FileInfo fileInfo) { return commands.PUTRequest("/lights/" + std::to_string(id) + subPath, request, std::move(fileInfo)); } - -void HueLight::refreshState() -{ - // std::chrono::steady_clock::time_point start = - // std::chrono::steady_clock::now(); std::cout << "\tRefreshing lampstate of - // lamp with id: " << id << ", ip: " << ip << "\n"; - nlohmann::json answer - = commands.GETRequest("/lights/" + std::to_string(id), nlohmann::json::object(), CURRENT_FILE_INFO); - if (answer.count("state")) - { - state = answer; - } - else - { - std::cout << "Answer in HueLight::refreshState of " - "http_handler->GETJson(...) is not expected!\nAnswer:\n\t" - << answer.dump() << std::endl; - } - // std::cout << "\tRefresh state took: " << - // std::chrono::duration_cast(std::chrono::steady_clock::now() - // - start).count() << "ms" << std::endl; -} } // namespace hueplusplus diff --git a/src/SimpleBrightnessStrategy.cpp b/src/SimpleBrightnessStrategy.cpp index a2aaf73..185d7ce 100644 --- a/src/SimpleBrightnessStrategy.cpp +++ b/src/SimpleBrightnessStrategy.cpp @@ -33,12 +33,13 @@ namespace hueplusplus { bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; if (bri == 0) { - if (light.state["state"]["on"] == true) + if (state["on"] == true) { - return light.OffNoRefresh(transition); + return light.Off(transition); } else { @@ -52,11 +53,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (light.state["state"]["bri"] != bri) + if (state["bri"] != bri) { if (bri > 254) { @@ -80,12 +81,11 @@ bool SimpleBrightnessStrategy::setBrightness(unsigned int bri, uint8_t transitio unsigned int SimpleBrightnessStrategy::getBrightness(HueLight& light) const { - light.refreshState(); - return light.state["state"]["bri"].get(); + return light.state.GetValue()["state"]["bri"].get(); } unsigned int SimpleBrightnessStrategy::getBrightness(const HueLight& light) const { - return light.state["state"]["bri"].get(); + return light.state.GetValue()["state"]["bri"].get(); } } // namespace hueplusplus diff --git a/src/SimpleColorHueStrategy.cpp b/src/SimpleColorHueStrategy.cpp index 220cb77..fb85a95 100644 --- a/src/SimpleColorHueStrategy.cpp +++ b/src/SimpleColorHueStrategy.cpp @@ -34,17 +34,18 @@ namespace hueplusplus { bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); if (transition != 4) { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs") + if (state["hue"] != hue || state["colormode"] != "hs") { hue = hue % 65535; request["hue"] = hue; @@ -64,17 +65,18 @@ bool SimpleColorHueStrategy::setColorHue(uint16_t hue, uint8_t transition, HueLi bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); if (transition != 4) { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (light.state["state"]["sat"] != sat) + if (state["sat"] != sat) { if (sat > 254) { @@ -97,23 +99,24 @@ bool SimpleColorHueStrategy::setColorSaturation(uint8_t sat, uint8_t transition, bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); if (transition != 4) { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (light.state["state"]["hue"] != hue || light.state["state"]["colormode"] != "hs") + if (state["hue"] != hue || state["colormode"] != "hs") { hue = hue % 65535; request["hue"] = hue; } - if (light.state["state"]["sat"] != sat || light.state["state"]["colormode"] != "hs") + if (state["sat"] != sat || state["colormode"] != "hs") { if (sat > 254) { @@ -136,20 +139,21 @@ bool SimpleColorHueStrategy::setColorHueSaturation(uint16_t hue, uint8_t sat, ui bool SimpleColorHueStrategy::setColorXY(float x, float y, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); if (transition != 4) { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (std::abs(light.state["state"]["xy"][0].get() - x) > 1E-4f - || std::abs(light.state["state"]["xy"][1].get() - y) > 1E-4f - || light.state["state"]["colormode"] != "xy") + if (std::abs(state["xy"][0].get() - x) > 1E-4f + || std::abs(state["xy"][1].get() - y) > 1E-4f + || state["colormode"] != "xy") { request["xy"][0] = x; request["xy"][1] = y; @@ -171,7 +175,7 @@ bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_ { if ((r == 0) && (g == 0) && (b == 0)) { - return light.OffNoRefresh(); + return light.Off(); } const float red = float(r) / 255; @@ -196,15 +200,16 @@ bool SimpleColorHueStrategy::setColorRGB(uint8_t r, uint8_t g, uint8_t b, uint8_ bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight& light) const { // colorloop - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } std::string effect; - if ((effect = on ? "colorloop" : "none") != light.state["state"]["effect"]) + if ((effect = on ? "colorloop" : "none") != state["effect"]) { request["effect"] = effect; } @@ -222,13 +227,14 @@ bool SimpleColorHueStrategy::setColorLoop(bool on, HueLight& light) const bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorHueSaturation(hue, sat, 1)) { return false; @@ -242,7 +248,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -251,8 +257,8 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorHueSaturation(hue, sat, 1)) { return false; @@ -266,7 +272,7 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -281,13 +287,14 @@ bool SimpleColorHueStrategy::alertHueSaturation(uint16_t hue, uint8_t sat, HueLi bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorXY(x, y, 1)) { return false; @@ -301,7 +308,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -310,8 +317,8 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorXY(x, y, 1)) { return false; @@ -325,7 +332,7 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -340,13 +347,14 @@ bool SimpleColorHueStrategy::alertXY(float x, float y, HueLight& light) const bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "hs") { - uint16_t oldHue = light.state["state"]["hue"].get(); - uint8_t oldSat = light.state["state"]["sat"].get(); + uint16_t oldHue = state["hue"].get(); + uint8_t oldSat = state["sat"].get(); if (!light.setColorRGB(r, g, b, 1)) { return false; @@ -360,7 +368,7 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& if (!on) { light.setColorHueSaturation(oldHue, oldSat, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -369,8 +377,8 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& } else if (cType == "xy") { - float oldX = light.state["state"]["xy"][0].get(); - float oldY = light.state["state"]["xy"][1].get(); + float oldX = state["xy"][0].get(); + float oldY = state["xy"][1].get(); if (!light.setColorRGB(r, g, b, 1)) { return false; @@ -384,7 +392,7 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& if (!on) { light.setColorXY(oldX, oldY, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -399,24 +407,26 @@ bool SimpleColorHueStrategy::alertRGB(uint8_t r, uint8_t g, uint8_t b, HueLight& std::pair SimpleColorHueStrategy::getColorHueSaturation(HueLight& light) const { - light.refreshState(); - return std::make_pair(light.state["state"]["hue"].get(), light.state["state"]["sat"].get()); + // Save value, so there are no inconsistent results if it is refreshed between two calls + const nlohmann::json& state = light.state.GetValue()["state"]; + return std::make_pair(state["hue"].get(), state["sat"].get()); } std::pair SimpleColorHueStrategy::getColorHueSaturation(const HueLight& light) const { - return std::make_pair(light.state["state"]["hue"].get(), light.state["state"]["sat"].get()); + return std::make_pair(light.state.GetValue()["state"]["hue"].get(), light.state.GetValue()["state"]["sat"].get()); } std::pair SimpleColorHueStrategy::getColorXY(HueLight& light) const { - light.refreshState(); - return std::make_pair(light.state["state"]["xy"][0].get(), light.state["state"]["xy"][1].get()); + // Save value, so there are no inconsistent results if it is refreshed between two calls + const nlohmann::json& state = light.state.GetValue()["state"]; + return std::make_pair(state["xy"][0].get(), state["xy"][1].get()); } std::pair SimpleColorHueStrategy::getColorXY(const HueLight& light) const { - return std::make_pair(light.state["state"]["xy"][0].get(), light.state["state"]["xy"][1].get()); + return std::make_pair(light.state.GetValue()["state"]["xy"][0].get(), light.state.GetValue()["state"]["xy"][1].get()); } /*bool SimpleColorHueStrategy::pointInTriangle(float pointx, float pointy, float x0, float y0, float x1, float y1, float x2, float y2) diff --git a/src/SimpleColorTemperatureStrategy.cpp b/src/SimpleColorTemperatureStrategy.cpp index c28aed0..02c96b5 100644 --- a/src/SimpleColorTemperatureStrategy.cpp +++ b/src/SimpleColorTemperatureStrategy.cpp @@ -34,17 +34,18 @@ namespace hueplusplus { bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uint8_t transition, HueLight& light) const { - light.refreshState(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; nlohmann::json request = nlohmann::json::object(); if (transition != 4) { request["transitiontime"] = transition; } - if (light.state["state"]["on"] != true) + if (state["on"] != true) { request["on"] = true; } - if (light.state["state"]["ct"] != mired) + if (state["ct"] != mired) { if (mired > 500) { @@ -71,12 +72,13 @@ bool SimpleColorTemperatureStrategy::setColorTemperature(unsigned int mired, uin bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLight& light) const { - light.refreshState(); - std::string cType = light.state["state"]["colormode"].get(); - bool on = light.state["state"]["on"].get(); + // Careful, only use state until any light function might refresh the value and invalidate the reference + const nlohmann::json& state = light.state.GetValue()["state"]; + std::string cType = state["colormode"].get(); + bool on = state["on"].get(); if (cType == "ct") { - uint16_t oldCT = light.state["state"]["ct"].get(); + uint16_t oldCT = state["ct"].get(); if (!light.setColorTemperature(mired, 1)) { return false; @@ -90,7 +92,7 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig if (!on) { light.setColorTemperature(oldCT, 1); - return light.OffNoRefresh(1); + return light.Off(1); } else { @@ -105,12 +107,11 @@ bool SimpleColorTemperatureStrategy::alertTemperature(unsigned int mired, HueLig unsigned int SimpleColorTemperatureStrategy::getColorTemperature(HueLight& light) const { - light.refreshState(); - return light.state["state"]["ct"].get(); + return light.state.GetValue()["state"]["ct"].get(); } unsigned int SimpleColorTemperatureStrategy::getColorTemperature(const HueLight& light) const { - return light.state["state"]["ct"].get(); + return light.state.GetValue()["state"]["ct"].get(); } } // namespace hueplusplus diff --git a/test/mocks/mock_HueLight.h b/test/mocks/mock_HueLight.h index 6db85fe..63f35f5 100644 --- a/test/mocks/mock_HueLight.h +++ b/test/mocks/mock_HueLight.h @@ -37,9 +37,13 @@ class MockHueLight : public hueplusplus::HueLight { public: MockHueLight(std::shared_ptr handler) - : HueLight(1, hueplusplus::HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler)){}; + : HueLight(1, hueplusplus::HueCommandAPI(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler), nullptr, + nullptr, nullptr, std::chrono::steady_clock::duration::max()) + { + // Set refresh duration to max, so random refreshes do not hinder the test setups + } - nlohmann::json& getState() { return state; }; + nlohmann::json& getState() { return state.GetValue(); } MOCK_METHOD1(On, bool(uint8_t transition)); @@ -121,14 +125,8 @@ public: MOCK_METHOD1(setColorLoop, bool(bool on)); - MOCK_METHOD1(OnNoRefresh, bool(uint8_t transition)); - - MOCK_METHOD1(OffNoRefresh, bool(uint8_t transition)); - MOCK_METHOD3(SendPutRequest, nlohmann::json(const nlohmann::json& request, const std::string& subPath, hueplusplus::FileInfo fileInfo)); - - MOCK_METHOD0(refreshState, void()); }; #endif diff --git a/test/test_ExtendedColorHueStrategy.cpp b/test/test_ExtendedColorHueStrategy.cpp index 97fac0f..ab52cf2 100644 --- a/test/test_ExtendedColorHueStrategy.cpp +++ b/test/test_ExtendedColorHueStrategy.cpp @@ -44,7 +44,6 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -65,7 +64,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); @@ -85,7 +84,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); @@ -104,7 +103,7 @@ TEST(ExtendedColorHueStrategy, alertHueSaturation) EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertHueSaturation(200, 100, test_light)); } @@ -118,7 +117,6 @@ TEST(ExtendedColorHueStrategy, alertXY) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -139,7 +137,7 @@ TEST(ExtendedColorHueStrategy, alertXY) EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); @@ -153,7 +151,7 @@ TEST(ExtendedColorHueStrategy, alertXY) EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); @@ -169,7 +167,7 @@ TEST(ExtendedColorHueStrategy, alertXY) EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); } @@ -183,7 +181,6 @@ TEST(ExtendedColorHueStrategy, alertRGB) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -205,7 +202,7 @@ TEST(ExtendedColorHueStrategy, alertRGB) EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); @@ -225,7 +222,7 @@ TEST(ExtendedColorHueStrategy, alertRGB) EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); @@ -244,7 +241,7 @@ TEST(ExtendedColorHueStrategy, alertRGB) EXPECT_CALL(test_light, setColorTemperature(_, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorHueStrategy().alertRGB(128, 128, 128, test_light)); } diff --git a/test/test_ExtendedColorTemperatureStrategy.cpp b/test/test_ExtendedColorTemperatureStrategy.cpp index 4379b4c..e0bf3f9 100644 --- a/test/test_ExtendedColorTemperatureStrategy.cpp +++ b/test/test_ExtendedColorTemperatureStrategy.cpp @@ -44,7 +44,7 @@ TEST(ExtendedColorTemperatureStrategy, setColorTemperature) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -84,7 +84,6 @@ TEST(ExtendedColorTemperatureStrategy, alertTemperature) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -107,7 +106,7 @@ TEST(ExtendedColorTemperatureStrategy, alertTemperature) EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, ExtendedColorTemperatureStrategy().alertTemperature(400, test_light)); diff --git a/test/test_Hue.cpp b/test/test_Hue.cpp index e519a3c..f7976fd 100644 --- a/test/test_Hue.cpp +++ b/test/test_Hue.cpp @@ -449,12 +449,12 @@ TEST(Hue, getAllLights) EXPECT_CALL( *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) - .Times(2) + .Times(AtLeast(1)) .WillRepeatedly(Return(hue_bridge_state)); EXPECT_CALL(*handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), getBridgePort())) - .Times(2) + .Times(AtLeast(1)) .WillRepeatedly(Return(hue_bridge_state["lights"]["1"])); Hue test_bridge(getBridgeIp(), getBridgePort(), getBridgeUsername(), handler); @@ -531,12 +531,3 @@ TEST(Hue, getPictureOfLight) EXPECT_EQ("e27_waca", test_bridge.getPictureOfLight(1)); } - -TEST(Hue, refreshState) -{ - std::shared_ptr handler = std::make_shared(); - Hue test_bridge(getBridgeIp(), getBridgePort(), "", handler); // NULL as username leads to segfault - - std::vector> test_lights = test_bridge.getAllLights(); - EXPECT_EQ(test_lights.size(), 0); -} diff --git a/test/test_HueLight.cpp b/test/test_HueLight.cpp index 59902a6..ea23894 100644 --- a/test/test_HueLight.cpp +++ b/test/test_HueLight.cpp @@ -888,19 +888,3 @@ TEST_F(HueLightTest, setColorLoop) EXPECT_EQ(false, test_light_2.setColorLoop(false)); EXPECT_EQ(false, test_light_3.setColorLoop(true)); } - -TEST_F(HueLightTest, refreshState) -{ - using namespace ::testing; - test_bridge.getLight(1); - test_bridge.getLight(2); - test_bridge.getLight(3); - - EXPECT_CALL( - *handler, GETJson("/api/" + getBridgeUsername() + "/lights/1", nlohmann::json::object(), getBridgeIp(), 80)) - .Times(2) - .WillRepeatedly(Return(nlohmann::json::object())); - - const HueLight ctest_light_1 = test_bridge.getLight(1); - HueLight test_light_1 = test_bridge.getLight(1); -} diff --git a/test/test_SimpleBrightnessStrategy.cpp b/test/test_SimpleBrightnessStrategy.cpp index 9e08a9b..38179ad 100644 --- a/test/test_SimpleBrightnessStrategy.cpp +++ b/test/test_SimpleBrightnessStrategy.cpp @@ -45,8 +45,8 @@ TEST(SimpleBrightnessStrategy, setBrightness) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -86,7 +86,6 @@ TEST(SimpleBrightnessStrategy, getBrightness) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["bri"] = 200; EXPECT_EQ(200, SimpleBrightnessStrategy().getBrightness(test_light)); diff --git a/test/test_SimpleColorHueStrategy.cpp b/test/test_SimpleColorHueStrategy.cpp index ea0c36e..2216d81 100644 --- a/test/test_SimpleColorHueStrategy.cpp +++ b/test/test_SimpleColorHueStrategy.cpp @@ -44,7 +44,7 @@ TEST(SimpleColorHueStrategy, setColorHue) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -76,7 +76,7 @@ TEST(SimpleColorHueStrategy, setColorSaturation) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -108,7 +108,7 @@ TEST(SimpleColorHueStrategy, setColorHueSaturation) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -144,7 +144,7 @@ TEST(SimpleColorHueStrategy, setColorXY) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -184,7 +184,7 @@ TEST(SimpleColorHueStrategy, setColorRGB) EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(255, 255, 255, 4, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(4)).Times(1).WillOnce(Return(true)); + EXPECT_CALL(test_light, Off(4)).Times(1).WillOnce(Return(true)); EXPECT_EQ(true, SimpleColorHueStrategy().setColorRGB(0, 0, 0, 4, test_light)); } @@ -197,7 +197,7 @@ TEST(SimpleColorHueStrategy, setColorLoop) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -226,7 +226,6 @@ TEST(SimpleColorHueStrategy, alertHueSaturation) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -247,7 +246,7 @@ TEST(SimpleColorHueStrategy, alertHueSaturation) EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); @@ -267,7 +266,7 @@ TEST(SimpleColorHueStrategy, alertHueSaturation) EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorHueStrategy().alertHueSaturation(200, 100, test_light)); } @@ -281,7 +280,6 @@ TEST(SimpleColorHueStrategy, alertXY) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -302,7 +300,7 @@ TEST(SimpleColorHueStrategy, alertXY) EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); @@ -316,7 +314,7 @@ TEST(SimpleColorHueStrategy, alertXY) EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorHueStrategy().alertXY(0.1f, 0.1f, test_light)); } @@ -330,7 +328,6 @@ TEST(SimpleColorHueStrategy, alertRGB) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -352,7 +349,7 @@ TEST(SimpleColorHueStrategy, alertRGB) EXPECT_CALL(test_light, setColorHueSaturation(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); @@ -372,7 +369,7 @@ TEST(SimpleColorHueStrategy, alertRGB) EXPECT_CALL(test_light, setColorXY(_, _, 1)).Times(AtLeast(2)).WillRepeatedly(Return(true)); EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorHueStrategy().alertRGB(128, 128, 128, test_light)); } @@ -386,7 +383,6 @@ TEST(SimpleColorHueStrategy, getColorHueSaturation) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["hue"] = 5000; test_light.getState()["state"]["sat"] = 128; @@ -407,7 +403,6 @@ TEST(SimpleColorHueStrategy, getColorXY) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["xy"][0] = 0.1234; test_light.getState()["state"]["xy"][1] = 0.1234; diff --git a/test/test_SimpleColorTemperatureStrategy.cpp b/test/test_SimpleColorTemperatureStrategy.cpp index b00803d..3385870 100644 --- a/test/test_SimpleColorTemperatureStrategy.cpp +++ b/test/test_SimpleColorTemperatureStrategy.cpp @@ -45,7 +45,7 @@ TEST(SimpleColorTemperatureStrategy, setColorTemperature) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); + nlohmann::json prep_ret; prep_ret = nlohmann::json::array(); prep_ret[0] = nlohmann::json::object(); @@ -84,7 +84,6 @@ TEST(SimpleColorTemperatureStrategy, alertTemperature) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["colormode"] = "invalid"; test_light.getState()["state"]["on"] = false; @@ -104,7 +103,7 @@ TEST(SimpleColorTemperatureStrategy, alertTemperature) EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); - EXPECT_CALL(test_light, OffNoRefresh(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(test_light, Off(_)).Times(AtLeast(1)).WillRepeatedly(Return(true)); test_light.getState()["state"]["on"] = false; EXPECT_EQ(true, SimpleColorTemperatureStrategy().alertTemperature(400, test_light)); } @@ -118,7 +117,6 @@ TEST(SimpleColorTemperatureStrategy, getColorTemperature) .Times(AtLeast(1)) .WillRepeatedly(Return(nlohmann::json::object())); MockHueLight test_light(handler); - EXPECT_CALL(test_light, refreshState()).Times(AtLeast(1)).WillRepeatedly(Return()); test_light.getState()["state"]["ct"] = 200; EXPECT_EQ(200, SimpleColorTemperatureStrategy().getColorTemperature(test_light)); -- libgit2 0.21.4