/** \file Light.h Copyright Notice\n Copyright (C) 2017 Jan Rogall - developer\n Copyright (C) 2017 Moritz Wirger - developer\n This file is part of hueplusplus. hueplusplus is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. hueplusplus is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with hueplusplus. If not, see . **/ #ifndef INCLUDE_HUEPLUSPLUS_HUE_LIGHT_H #define INCLUDE_HUEPLUSPLUS_HUE_LIGHT_H #include #include "APICache.h" #include "BaseDevice.h" #include "BrightnessStrategy.h" #include "ColorHueStrategy.h" #include "ColorTemperatureStrategy.h" #include "HueCommandAPI.h" #include "StateTransaction.h" #include namespace hueplusplus { //! enum that specifies the color type of all HueLights enum class ColorType { UNDEFINED, //!< ColorType for this light is unknown or undefined NONE, //!< light has no specific ColorType GAMUT_A, //!< light uses Gamut A GAMUT_B, //!< light uses Gamut B GAMUT_C, //!< light uses Gamut C TEMPERATURE, //!< light has color temperature control GAMUT_A_TEMPERATURE, //!< light uses Gamut A and has color temperature control GAMUT_B_TEMPERATURE, //!< light uses Gamut B and has color temperature control GAMUT_C_TEMPERATURE, //!< light uses Gamut C and has color temperature control GAMUT_OTHER, //!< light uses capabilities to specify a different gamut GAMUT_OTHER_TEMPERATURE //!< light uses capabilities to specify a different gamut and has color temperature control }; //! \brief Class for Hue Light fixtures //! //! Provides methods to query and control lights. class Light : public BaseDevice { friend class LightFactory; friend class SimpleBrightnessStrategy; friend class SimpleColorHueStrategy; friend class ExtendedColorHueStrategy; friend class SimpleColorTemperatureStrategy; friend class ExtendedColorTemperatureStrategy; public: //! \name General information ///@{ //! \brief Const function that returns the luminaireuniqueid of the light //! //! \note Only working on bridges with versions starting at 1.9 //! \return String containing the luminaireuniqueid or an empty string when the function is not supported virtual std::string getLuminaireUId() const; //! \brief Const function that returns the color type of the light. //! //! \return ColorType containig the color type of the light virtual ColorType getColorType() const; //! \brief Get gamut space of possible light colors //! \returns Used gamut, or \ref gamut::maxGamut when unknown. ColorGamut getColorGamut() const; ///@} //! \name Light state ///@{ //! \brief Function that turns the light on. //! //! \param transition Optional parameter to set the transition from current state to new, standard is 4 = 400ms //! \return 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 on(uint8_t transition = 4); //! \brief Function that turns the light off. //! //! \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 off(uint8_t transition = 4); //! \brief Function to check whether a light is on or off //! //! \return Bool that is true, when the light is on and false, when off //! \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 isOn(); //! \brief Const function to check whether a light is on or off //! //! \note This will not refresh the light state //! \return Bool that is true, when the light is on and false, when off virtual bool isOn() const; //! \brief Const function to check whether this light has brightness control //! //! \return Bool that is true when the light has specified abilities and false //! when not virtual bool hasBrightnessControl() const { return brightnessStrategy != nullptr; }; //! \brief Const function to check whether this light has color temperature //! control //! //! \return Bool that is true when the light has specified abilities and false //! when not virtual bool hasTemperatureControl() const { return colorTemperatureStrategy != nullptr; }; //! \brief Connst function to check whether this light has full color control //! //! \return Bool that is true when the light has specified abilities and false //! when not virtual bool hasColorControl() const { return colorHueStrategy != nullptr; }; //! \brief Function that sets the brightness of this light. //! //! \note The brightness will only be set if the light has a reference to a //! specific \ref BrightnessStrategy. The brightness can range from 0 = off to //! 254 = fully lit. //! \param bri Unsigned int that specifies the brightness //! \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 setBrightness(unsigned int bri, uint8_t transition = 4) { if (brightnessStrategy) { return brightnessStrategy->setBrightness(bri, transition, *this); } return false; }; //! \brief Const function that returns the brightness of this light. //! //! \note The brightness will only be returned if the light has a reference to //! a specific \ref BrightnessStrategy. \note This will not refresh the light //! state The brightness can range from 0 = off to 254 = fully lit. \return //! Unsigned int that is 0 when function failed virtual unsigned int getBrightness() const { if (brightnessStrategy) { return brightnessStrategy->getBrightness(*this); } return 0; }; //! \brief Function that returns the brightness of this light. //! //! \note The brightness will only be returned if the light has a reference to //! a specific \ref BrightnessStrategy. The brightness can range from 0 = off //! to 254 = fully lit. //! \return Unsigned int that is 0 when function failed //! \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 unsigned int getBrightness() { if (brightnessStrategy) { return brightnessStrategy->getBrightness(*this); } return 0; }; //! \brief Function that sets the color temperature of this light in mired. //! //! \note The color temperature will only be set if the light has a reference //! to a specific \ref ColorTemperatureStrategy. The color temperature can //! range from 153 to 500. //! \param mired Unsigned int that specifies the color temperature in Mired //! \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 setColorTemperature(unsigned int mired, uint8_t transition = 4) { if (colorTemperatureStrategy) { return colorTemperatureStrategy->setColorTemperature(mired, transition, *this); } return false; }; //! \brief Const function that returns the current color temperature of the //! light //! //! \note The color temperature will only be returned when the light has a //! reference to a specific \ref ColorTemperatureStrategy. //! \note This will not refresh the light state //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold //! and 500 is warm. //! \return Unsigned int representing the color temperature in mired or 0 when failed virtual unsigned int getColorTemperature() const { if (colorTemperatureStrategy) { return colorTemperatureStrategy->getColorTemperature(*this); } return 0; }; //! \brief Function that returns the current color temperature of the light //! //! \note The color temperature will only be returned when the light has a //! reference to a specific \ref ColorTemperatureStrategy. //! Updates the lights state by calling refreshState() //! The color temperature in mired ranges from 153 to 500 whereas 153 is cold //! and 500 is warm. //! \return Unsigned int representing the color temperature in mired or 0 when failed //! \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 unsigned int getColorTemperature() { if (colorTemperatureStrategy) { return colorTemperatureStrategy->getColorTemperature(*this); } return 0; }; //! \brief Function to set the color of this light with specified hue. //! //! \note The color will only be set if the light has a reference to a //! specific \ref ColorHueStrategy. The hue can range from 0 to 65535, whereas //! 65535 and 0 are red, 25500 is green and 46920 is blue. //! \param hue uint16_t that specifies the hue //! \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 setColorHue(uint16_t hue, uint8_t transition = 4) { if (colorHueStrategy) { return colorHueStrategy->setColorHue(hue, transition, *this); } return false; }; //! \brief Function to set the color of this light with specified saturation. //! //! \note The color will only be set if the light has a reference to a //! specific \ref ColorHueStrategy. The saturation can range from 0 to 254, //! whereas 0 is least saturated (white) and 254 is most saturated. //! \param sat uint8_t that specifies the saturation //! \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 setColorSaturation(uint8_t sat, uint8_t transition = 4) { if (colorHueStrategy) { return colorHueStrategy->setColorSaturation(sat, transition, *this); } return false; }; //! \brief Function to set the color of this light with specified hue and //! saturation. //! //! \note The color will only be set if the light has a reference to a //! specific \ref ColorHueStrategy. //! \param hueSat Color in hue and satuation. //! \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 setColorHueSaturation(const HueSaturation& hueSat, uint8_t transition = 4) { if (colorHueStrategy) { return colorHueStrategy->setColorHueSaturation(hueSat, transition, *this); } return false; }; //! \brief Const function that returns the current color of the light as hue //! and saturation //! //! \note The color hue and saturation will only be returned when the light //! has a reference to a specific \ref ColorHueStrategy. //! \note This will not refresh the light state //! \return Current hue and saturation or {0,0} when failed //! \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 HueSaturation getColorHueSaturation() const { if (colorHueStrategy) { return colorHueStrategy->getColorHueSaturation(*this); } return {}; }; //! \brief Function that returns the current color of the light as hue and //! saturation //! //! \note The color hue and saturation will only be returned when the light //! has a reference to a specific \ref ColorHueStrategy. Updates the lights //! state by calling refreshState() //! \return Current hue and saturation or {0,0} when failed //! \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 HueSaturation getColorHueSaturation() { if (colorHueStrategy) { return colorHueStrategy->getColorHueSaturation(*this); } return {}; }; //! \brief Function to set the color of this light in CIE with specified x y. //! //! \note The color will only be set if the light has a reference to a //! specific \ref ColorHueStrategy. The values of x and y are ranging from 0 to 1. //! \param xy The color in XY and brightness //! \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 setColorXY(const XYBrightness& xy, uint8_t transition = 4) { if (colorHueStrategy) { return colorHueStrategy->setColorXY(xy, transition, *this); } return false; }; //! \brief Const function that returns the current color of the light as xy //! //! \note The color x and y will only be returned when the light has a //! reference to a specific \ref ColorHueStrategy. //! \note This does not update the lights state //! \return XYBrightness with x, y and brightness or an empty one (all 0) when failed virtual XYBrightness getColorXY() const { if (colorHueStrategy) { return colorHueStrategy->getColorXY(*this); } return {}; }; //! \brief Function that returns the current color of the light as xy //! //! \note The color x and y will only be returned when the light has a //! reference to a specific \ref ColorHueStrategy. //! Updates the lights state by calling refreshState() //! \return XYBrightness with x, y and brightness or an empty one (all 0) when failed //! \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 XYBrightness getColorXY() { if (colorHueStrategy) { return colorHueStrategy->getColorXY(*this); } return {}; } //! \brief Function to set the color of this light with red green and blue //! values. //! //! \note The color will only be set if the light has a reference to a //! specific \ref ColorHueStrategy. The values of red, green and blue are //! ranging from 0 to 255. //! \param rgb RGB color that will be mapped to the available color space //! \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 setColorRGB(const RGB& rgb, uint8_t transition = 4) { if (colorHueStrategy) { return colorHueStrategy->setColorXY(rgb.toXY(getColorGamut()), transition, *this); } return false; } //! \brief Function that lets the light perform one breath cycle. //! //! Can be used for locating a light. //! \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 alert(); //! \brief Function that lets the light perform one breath cycle in specified //! color temperature. //! //! \note The breath cylce will only be performed if the light has a reference //! to a specific \ref ColorTemperatureStrategy. //! \param mired Color temperature in mired //! \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 alertTemperature(unsigned int mired) { if (colorTemperatureStrategy) { return colorTemperatureStrategy->alertTemperature(mired, *this); } return false; } //! \brief Function that lets the light perform one breath cycle in specified //! color. //! //! \note The breath cylce will only be performed if the light has a reference //! to a specific \ref ColorHueStrategy. //! \param hueSat Color in hue and saturation //! \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 alertHueSaturation(const HueSaturation& hueSat) { if (colorHueStrategy) { return colorHueStrategy->alertHueSaturation(hueSat, *this); } return false; } //! \brief Function that lets the light perform one breath cycle in specified //! color. //! //! \note The breath cylce will only be performed if the light has a reference //! to a specific \ref ColorHueStrategy. //! \param xy The x,y coordinates in CIE and brightness //! \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 alertXY(const XYBrightness& xy) { if (colorHueStrategy) { return colorHueStrategy->alertXY(xy, *this); } return false; } //! \brief Function to turn colorloop effect on/off. //! //! Notice this function will only be performed light has a reference to a //! specific \ref ColorHueStrategy. The colorloop effect will loop through all //! colors on current hue and saturation levels. Notice that none of the //! setter functions check whether this feature is enabled and the colorloop //! can only be disabled with this function or by simply calling //! off() and then on(), so you could //! alternatively call off() and then use any of the setter functions. //! \param on bool that enables this feature when true and disables it when false //! \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 setColorLoop(bool on) { if (colorHueStrategy) { return colorHueStrategy->setColorLoop(on, *this); } return false; } //! \brief Create a transaction for this light. //! //! The transaction can be used to change more than one value in one request. //! Only use the functions supported by the current light type. //! //! Example usage: \code //! light.transaction().setBrightness(240).setColorHue(5000).commit(); //! \endcode virtual StateTransaction transaction(); ///@} protected: //! \brief Protected ctor that is used by \ref LightFactory. //! //! \param id Integer that specifies the id of this light //! \param commands HueCommandAPI for communication with the bridge //! //! leaves strategies unset Light(int id, const HueCommandAPI& commands); //! \brief Protected ctor that is used by \ref LightFactory. //! //! \param id Integer that specifies the id of this light //! \param baseCache Cache of the light list (must not be null). //! //! leaves strategies unset Light(int id, const std::shared_ptr& baseCache); //! \brief Protected ctor that is used by \ref LightFactory, also sets //! strategies. //! //! \param id Integer that specifies the id of this light //! \param commands HueCommandAPI for communication with the bridge //! \param brightnessStrategy Strategy for brightness. May be nullptr. //! \param colorTempStrategy Strategy for color temperature. May be nullptr. //! \param colorHueStrategy Strategy for color hue/saturation. May be nullptr. //! \param refreshDuration Time between refreshing the cached state. //! Can be 0 to always refresh, or steady_clock::duration::max() to never refresh. //! \param currentState The current light state, may be null. //! \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 Light(int id, const HueCommandAPI& commands, std::shared_ptr brightnessStrategy, std::shared_ptr colorTempStrategy, std::shared_ptr colorHueStrategy, std::chrono::steady_clock::duration refreshDuration, const nlohmann::json& currentState); //! \brief Protected function that sets the brightness strategy. //! //! The strategy defines how specific commands that deal with brightness //! control are executed \param strat a strategy of type \ref //! BrightnessStrategy virtual void setBrightnessStrategy(std::shared_ptr strat) { brightnessStrategy = std::move(strat); }; //! \brief Protected function that sets the colorTemperature strategy. //! //! The strategy defines how specific commands that deal with colortemperature //! control are executed \param strat a strategy of type \ref //! ColorTemperatureStrategy virtual void setColorTemperatureStrategy(std::shared_ptr strat) { colorTemperatureStrategy = std::move(strat); }; //! \brief Protected function that sets the colorHue strategy. //! //! The strategy defines how specific commands that deal with color control //! are executed \param strat a strategy of type \ref ColorHueStrategy virtual void setColorHueStrategy(std::shared_ptr strat) { colorHueStrategy = std::move(strat); }; protected: ColorType colorType; //!< holds the \ref ColorType of the light std::shared_ptr brightnessStrategy; //!< holds a reference to the strategy that handles brightness commands std::shared_ptr colorTemperatureStrategy; //!< holds a reference to the strategy that handles colortemperature commands std::shared_ptr colorHueStrategy; //!< holds a reference to the strategy that handles all color commands }; } // namespace hueplusplus #endif