From 8bfb374147baa3244aa40045dc2d7a46c0ec1275 Mon Sep 17 00:00:00 2001 From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com> Date: Mon, 20 Apr 2020 21:49:35 +0200 Subject: [PATCH] Implement HueLightFactory::getColorType, fix tests. --- include/hueplusplus/HueDeviceTypes.h | 6 +++++- include/hueplusplus/HueLight.h | 6 ++++++ src/Hue.cpp | 8 +++----- src/HueDeviceTypes.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ test/test_Hue.cpp | 7 ++++--- test/test_HueLight.cpp | 10 +++++----- 6 files changed, 79 insertions(+), 44 deletions(-) diff --git a/include/hueplusplus/HueDeviceTypes.h b/include/hueplusplus/HueDeviceTypes.h index 48e64d6..1f77e07 100644 --- a/include/hueplusplus/HueDeviceTypes.h +++ b/include/hueplusplus/HueDeviceTypes.h @@ -33,12 +33,16 @@ namespace hueplusplus class HueLightFactory { public: - HueLightFactory(const HueCommandAPI& commands); + HueLightFactory(const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration); HueLight createLight(const nlohmann::json& lightState, int id); private: + ColorType getColorType(const nlohmann::json& lightState, bool hasCt) const; + +private: HueCommandAPI commands; + std::chrono::steady_clock::duration refreshDuration; std::shared_ptr simpleBrightness; std::shared_ptr simpleColorTemperature; std::shared_ptr extendedColorTemperature; diff --git a/include/hueplusplus/HueLight.h b/include/hueplusplus/HueLight.h index ecaee77..8c0bfb7 100644 --- a/include/hueplusplus/HueLight.h +++ b/include/hueplusplus/HueLight.h @@ -118,7 +118,13 @@ public: //! \brief Const function that returns the light type //! + //! The type determines which functions the light has. //! \return String containing the type + //! - "On/Off light": on/off + //! - "Dimmable light": on/off, brightness + //! - "Color light": on/off, brightness, color hue/sat/xy + //! - "Color temperature light": on/off, brightness, color temperature + //! - "Extended color light": on/off, brightness, color temperature, color hue/sat/xy virtual std::string getType() const; //! \brief Function that returns the name of the light. diff --git a/src/Hue.cpp b/src/Hue.cpp index 56d11ec..ee5e9c9 100644 --- a/src/Hue.cpp +++ b/src/Hue.cpp @@ -137,7 +137,7 @@ Hue::Hue(const std::string& ip, const int port, const std::string& username, http_handler(std::move(handler)), commands(ip, port, username, http_handler), stateCache("", commands, refreshDuration), - lightFactory(commands) + lightFactory(commands, refreshDuration) {} std::string Hue::getBridgeIP() @@ -179,9 +179,7 @@ std::string Hue::requestUsername() // [{"success":{"username": ""}}] username = jsonUser.get(); // Update commands with new username and ip - commands = HueCommandAPI(ip, port, username, http_handler); - stateCache = APICache("", commands, stateCache.getRefreshDuration()); - lightFactory = HueLightFactory(commands); + setHttpHandler(http_handler); std::cout << "Success! Link button was pressed!\n"; std::cout << "Username is \"" << username << "\"\n"; break; @@ -523,6 +521,6 @@ void Hue::setHttpHandler(std::shared_ptr handler) http_handler = handler; commands = HueCommandAPI(ip, port, username, handler); stateCache = APICache("", commands, stateCache.getRefreshDuration()); - lightFactory = HueLightFactory(commands); + lightFactory = HueLightFactory(commands, stateCache.getRefreshDuration()); } } // namespace hueplusplus diff --git a/src/HueDeviceTypes.cpp b/src/HueDeviceTypes.cpp index b411c01..f9df60c 100644 --- a/src/HueDeviceTypes.cpp +++ b/src/HueDeviceTypes.cpp @@ -31,6 +31,7 @@ #include "hueplusplus/SimpleBrightnessStrategy.h" #include "hueplusplus/SimpleColorHueStrategy.h" #include "hueplusplus/SimpleColorTemperatureStrategy.h" +#include "hueplusplus/Utils.h" namespace hueplusplus { @@ -56,32 +57,11 @@ const std::set& getGamutATypes() = {"LST001", "LLC005", "LLC006", "LLC007", "LLC010", "LLC011", "LLC012", "LLC013", "LLC014"}; return c_EXTENDEDCOLORLIGHT_GAMUTA_TYPES; } - -const std::set& getNoColorTypes() -{ - static const std::set c_DIMMABLELIGHT_NO_COLOR_TYPES - = {"LWB004", "LWB006", "LWB007", "LWB010", "LWB014", "LDF001", "LDF002", "LDD001", "LDD002", "MWM001"}; - return c_DIMMABLELIGHT_NO_COLOR_TYPES; -} - -const std::set& getNonDimmableTypes() -{ - static const std::set c_NON_DIMMABLE_TYPES = {"Plug 01"}; - return c_NON_DIMMABLE_TYPES; -} - -const std::set& getTemperatureLightTypes() -{ - static const std::set c_TEMPERATURELIGHT_TYPES - = {"LLM010", "LLM011", "LLM012", "LTW001", "LTW004", "LTW010", "LTW011", "LTW012", "LTW013", "LTW014", "LTW015", - "LTP001", "LTP002", "LTP003", "LTP004", "LTP005", "LTD003", "LTF001", "LTF002", "LTC001", "LTC002", - "LTC003", "LTC004", "LTC011", "LTC012", "LTD001", "LTD002", "LFF001", "LTT001", "LDT001"}; - return c_TEMPERATURELIGHT_TYPES; -} } // namespace -HueLightFactory::HueLightFactory(const HueCommandAPI& commands) +HueLightFactory::HueLightFactory(const HueCommandAPI& commands, std::chrono::steady_clock::duration refreshDuration) : commands(commands), + refreshDuration(refreshDuration), simpleBrightness(std::make_shared()), simpleColorHue(std::make_shared()), extendedColorHue(std::make_shared()), @@ -97,35 +77,81 @@ HueLight HueLightFactory::createLight(const nlohmann::json& lightState, int id) if (type == "on/off light") { - HueLight light(id, commands, nullptr, nullptr, nullptr); + HueLight light(id, commands, nullptr, nullptr, nullptr, refreshDuration); light.colorType = ColorType::NONE; return light; } else if (type == "dimmable light") { - HueLight light(id, commands, simpleBrightness, nullptr, nullptr); + HueLight light(id, commands, simpleBrightness, nullptr, nullptr, refreshDuration); light.colorType = ColorType::NONE; return light; } else if (type == "color temperature light") { - HueLight light(id, commands, simpleBrightness, simpleColorTemperature, nullptr); + HueLight light(id, commands, simpleBrightness, simpleColorTemperature, nullptr, refreshDuration); light.colorType = ColorType::TEMPERATURE; return light; } else if (type == "color light") { - HueLight light(id, commands, simpleBrightness, nullptr, simpleColorHue); - light.colorType = ColorType::GAMUT_A; // getColorType(state); + HueLight light(id, commands, simpleBrightness, nullptr, simpleColorHue, refreshDuration); + light.colorType = getColorType(lightState, false); return light; } else if (type == "extended color light") { - HueLight light(id, commands, simpleBrightness, extendedColorTemperature, extendedColorHue); - light.colorType = ColorType::GAMUT_B_TEMPERATURE; // getColorType(state); + HueLight light(id, commands, simpleBrightness, extendedColorTemperature, extendedColorHue, refreshDuration); + light.colorType = getColorType(lightState, true); return light; } std::cerr << "Could not determine HueLight type:" << type << "!\n"; throw HueException(CURRENT_FILE_INFO, "Could not determine HueLight type!"); } + +ColorType HueLightFactory::getColorType(const nlohmann::json& lightState, bool hasCt) const +{ + // Try to get color type via capabilities + const nlohmann::json& gamuttype = utils::safeGetMember(lightState, "capabilities", "control", "colorgamuttype"); + if (gamuttype.is_string()) + { + const std::string gamut = gamuttype.get(); + if (gamut == "A") + { + return hasCt ? ColorType::GAMUT_A_TEMPERATURE : ColorType::GAMUT_A; + } + else if (gamut == "B") + { + return hasCt ? ColorType::GAMUT_B_TEMPERATURE : ColorType::GAMUT_B; + } + else if (gamut == "C") + { + return hasCt ? ColorType::GAMUT_C_TEMPERATURE : ColorType::GAMUT_C; + } + else + { + // Only other type is "Other" which does not have an enum value + return ColorType::UNDEFINED; + } + } + else + { + // Old version without capabilities, fall back to hardcoded types + std::string modelid = lightState.at("modelid").get(); + if (getGamutATypes().count(modelid)) + { + return hasCt ? ColorType::GAMUT_A_TEMPERATURE : ColorType::GAMUT_A; + } + else if (getGamutBTypes().count(modelid)) + { + return hasCt ? ColorType::GAMUT_B_TEMPERATURE : ColorType::GAMUT_B; + } + else if (getGamutCTypes().count(modelid)) + { + return hasCt ? ColorType::GAMUT_C_TEMPERATURE : ColorType::GAMUT_C; + } + std::cerr << "Could not determine HueLight color type:" << modelid << "!\n"; + throw HueException(CURRENT_FILE_INFO, "Could not determine HueLight color type!"); + } +} } // namespace hueplusplus diff --git a/test/test_Hue.cpp b/test/test_Hue.cpp index 147c730..b4e5c9a 100644 --- a/test/test_Hue.cpp +++ b/test/test_Hue.cpp @@ -298,6 +298,7 @@ TEST(Hue, getLight) EXPECT_EQ(test_light_1.getColorType(), ColorType::TEMPERATURE); // more coverage stuff + hue_bridge_state["lights"]["1"]["type"] = "Color light"; hue_bridge_state["lights"]["1"]["modelid"] = "LCT001"; EXPECT_CALL( *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) @@ -349,7 +350,7 @@ TEST(Hue, getLight) EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); EXPECT_EQ(test_light_1.getColorType(), ColorType::GAMUT_A); - hue_bridge_state["lights"]["1"]["modelid"] = "LWB004"; + hue_bridge_state["lights"]["1"]["type"] = "Dimmable light"; EXPECT_CALL( *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) .Times(1) @@ -366,7 +367,7 @@ TEST(Hue, getLight) EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE); - hue_bridge_state["lights"]["1"]["modelid"] = "Plug 01"; + hue_bridge_state["lights"]["1"]["type"] = "On/Off light"; EXPECT_CALL( *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) .Times(1) @@ -383,7 +384,7 @@ TEST(Hue, getLight) EXPECT_EQ(test_light_1.getName(), "Hue ambiance lamp 1"); EXPECT_EQ(test_light_1.getColorType(), ColorType::NONE); - hue_bridge_state["lights"]["1"]["modelid"] = "ABC000"; + hue_bridge_state["lights"]["1"]["type"] = "unknown light type"; EXPECT_CALL( *handler, GETJson("/api/" + getBridgeUsername(), nlohmann::json::object(), getBridgeIp(), getBridgePort())) .Times(1) diff --git a/test/test_HueLight.cpp b/test/test_HueLight.cpp index d38ef48..64acb33 100644 --- a/test/test_HueLight.cpp +++ b/test/test_HueLight.cpp @@ -103,7 +103,7 @@ protected: hue_bridge_state["lights"]["3"]["swupdate"] = nlohmann::json::object(); hue_bridge_state["lights"]["3"]["swupdate"]["state"] = "noupdates"; hue_bridge_state["lights"]["3"]["swupdate"]["lastinstall"] = nullptr; - hue_bridge_state["lights"]["3"]["type"] = "Color extended light"; + hue_bridge_state["lights"]["3"]["type"] = "Extended color light"; hue_bridge_state["lights"]["3"]["name"] = "Hue lamp 3"; hue_bridge_state["lights"]["3"]["modelid"] = "LCT010"; hue_bridge_state["lights"]["3"]["manufacturername"] = "Philips"; @@ -236,10 +236,10 @@ TEST_F(HueLightTest, getType) EXPECT_EQ("Dimmable light", ctest_light_1.getType()); EXPECT_EQ("Color light", ctest_light_2.getType()); - EXPECT_EQ("Color extended light", ctest_light_3.getType()); + EXPECT_EQ("Extended color light", ctest_light_3.getType()); EXPECT_EQ("Dimmable light", test_light_1.getType()); EXPECT_EQ("Color light", test_light_2.getType()); - EXPECT_EQ("Color extended light", test_light_3.getType()); + EXPECT_EQ("Extended color light", test_light_3.getType()); } TEST_F(HueLightTest, getName) @@ -406,10 +406,10 @@ TEST_F(HueLightTest, getColorType) EXPECT_EQ(ColorType::NONE, ctest_light_1.getColorType()); EXPECT_EQ(ColorType::GAMUT_A, ctest_light_2.getColorType()); - EXPECT_EQ(ColorType::GAMUT_C, ctest_light_3.getColorType()); + EXPECT_EQ(ColorType::GAMUT_C_TEMPERATURE, ctest_light_3.getColorType()); EXPECT_EQ(ColorType::NONE, test_light_1.getColorType()); EXPECT_EQ(ColorType::GAMUT_A, test_light_2.getColorType()); - EXPECT_EQ(ColorType::GAMUT_C, test_light_3.getColorType()); + EXPECT_EQ(ColorType::GAMUT_C_TEMPERATURE, test_light_3.getColorType()); } TEST_F(HueLightTest, KelvinToMired) -- libgit2 0.21.4