// ----------------------------------------------------------------------------- // Lights // ----------------------------------------------------------------------------- #pragma once #include "espurna.h" #define MQTT_TOPIC_LIGHT "light" #define MQTT_TOPIC_LIGHT_JSON "light_json" #define MQTT_TOPIC_CHANNEL "channel" #define MQTT_TOPIC_COLOR_RGB "rgb" #define MQTT_TOPIC_COLOR_HEX "hex" #define MQTT_TOPIC_COLOR_HSV "hsv" #define MQTT_TOPIC_ANIM_MODE "anim_mode" #define MQTT_TOPIC_ANIM_SPEED "anim_speed" #define MQTT_TOPIC_BRIGHTNESS "brightness" #define MQTT_TOPIC_MIRED "mired" #define MQTT_TOPIC_KELVIN "kelvin" #define MQTT_TOPIC_TRANSITION "transition" // TODO: lowercase namespace Light { constexpr size_t ChannelsMax = 5; constexpr long ValueMin = LIGHT_MIN_VALUE; constexpr long ValueMax = LIGHT_MAX_VALUE; constexpr long BrightnessMin = LIGHT_MIN_BRIGHTNESS; constexpr long BrightnessMax = LIGHT_MAX_BRIGHTNESS; constexpr long MiredsCold = LIGHT_COLDWHITE_MIRED; constexpr long MiredsWarm = LIGHT_WARMWHITE_MIRED; constexpr long PwmMin = LIGHT_MIN_PWM; constexpr long PwmMax = LIGHT_MAX_PWM; constexpr long PwmLimit = LIGHT_LIMIT_PWM; enum class Report { None = 0, Web = 1 << 0, Mqtt = 1 << 1, MqttGroup = 1 << 2 }; constexpr int operator|(Report lhs, int rhs) { return static_cast(lhs) | rhs; } constexpr int operator|(int lhs, Report rhs) { return lhs | static_cast(rhs); } constexpr int operator|(Report lhs, Report rhs) { return static_cast(lhs) | static_cast(rhs); } constexpr int operator&(int lhs, Report rhs) { return lhs & static_cast(rhs); } constexpr int operator&(Report lhs, int rhs) { return static_cast(lhs) & rhs; } constexpr int DefaultReport { Report::Web | Report::Mqtt | Report::MqttGroup }; struct Hsv { static constexpr long HueMin { 0 }; static constexpr long HueMax { 360 }; static constexpr long SaturationMin { 0 }; static constexpr long SaturationMax { 100 }; static constexpr long ValueMin { 0 }; static constexpr long ValueMax { 100 }; Hsv() = default; Hsv(long hue, long saturation, long value) : _hue(std::clamp(hue, HueMin, HueMax)), _saturation(std::clamp(saturation, SaturationMin, SaturationMax)), _value(std::clamp(value, ValueMin, ValueMax)) {} long hue() const { return _hue; } long saturation() const { return _saturation; } long value() const { return _value; } private: long _hue { HueMin }; long _saturation { SaturationMin }; long _value { ValueMin }; }; struct Rgb { static constexpr long Min { 0 }; static constexpr long Max { 255 }; Rgb() = default; Rgb(long red, long green, long blue) : _red(std::clamp(red, Min, Max)), _green(std::clamp(green, Min, Max)), _blue(std::clamp(blue, Min, Max)) {} long red() const { return _red; } long green() const { return _green; } long blue() const { return _blue; } unsigned long asUlong() const; private: long _red { Min }; long _green { Min }; long _blue { Min }; }; struct MiredsRange { constexpr MiredsRange() = default; MiredsRange(long cold, long warm) : _cold(cold), _warm(warm) {} long cold() const { return _cold; } long warm() const { return _warm; } private: long _cold { MiredsCold }; long _warm { MiredsWarm }; }; } // namespace Light using LightStateListener = std::function; using LightReportListener = void(*)(); class LightProvider { public: virtual void update() = 0; virtual void state(bool) = 0; virtual void channel(size_t ch, float value) = 0; }; struct LightTransition { unsigned long time; unsigned long step; }; size_t lightChannels(); LightTransition lightTransition(); unsigned long lightTransitionTime(); unsigned long lightTransitionStep(); void lightTransition(unsigned long time, unsigned long step); void lightTransition(LightTransition transition); void lightColor(const char* color, bool rgb); void lightColor(const String& color, bool rgb); void lightColor(const char* color); void lightColor(const String& color); void lightColor(unsigned long color); String lightRgbPayload(); String lightHsvPayload(); String lightColor(); bool lightSave(); void lightSave(bool save); Light::Rgb lightRgb(); void lightRgb(Light::Rgb); Light::Hsv lightHsv(); void lightHs(long hue, long saturation); void lightHsv(Light::Hsv); void lightMireds(long mireds); Light::MiredsRange lightMiredsRange(); void lightRed(long value); long lightRed(); void lightGreen(long value); long lightGreen(); void lightBlue(long value); long lightBlue(); void lightColdWhite(long value); long lightColdWhite(); void lightWarmWhite(long value); long lightWarmWhite(); void lightState(size_t id, bool state); bool lightState(size_t id); void lightState(bool state); bool lightState(); void lightBrightness(long brightness); long lightBrightness(); long lightChannel(size_t id); void lightChannel(size_t id, long value); void lightBrightnessStep(long steps, long multiplier = LIGHT_STEP); void lightChannelStep(size_t id, long steps, long multiplier = LIGHT_STEP); void lightUpdate(bool save, LightTransition transition, Light::Report report); void lightUpdate(bool save, LightTransition transition, int report); void lightUpdate(LightTransition transition); void lightUpdate(bool save); void lightUpdate(); bool lightHasColor(); bool lightUseRGB(); bool lightUseCCT(); void lightMQTT(); void lightSetReportListener(LightReportListener); void lightSetStateListener(LightStateListener); void lightSetProvider(std::unique_ptr&&); bool lightAdd(); void lightSetup();