mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 22:48:10 +01:00
Add rgbct and color_temperature light platforms (#2138)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
parent
854f4a8896
commit
d258e06fd7
14 changed files with 254 additions and 4 deletions
|
@ -29,6 +29,7 @@ esphome/components/canbus/* @danielschramm @mvturnho
|
|||
esphome/components/captive_portal/* @OttoWinter
|
||||
esphome/components/climate/* @esphome/core
|
||||
esphome/components/climate_ir/* @glmnet
|
||||
esphome/components/color_temperature/* @jesserockz
|
||||
esphome/components/coolix/* @glmnet
|
||||
esphome/components/cover/* @esphome/core
|
||||
esphome/components/cs5460a/* @balrog-kun
|
||||
|
@ -98,6 +99,7 @@ esphome/components/rc522_i2c/* @glmnet
|
|||
esphome/components/rc522_spi/* @glmnet
|
||||
esphome/components/restart/* @esphome/core
|
||||
esphome/components/rf_bridge/* @jesserockz
|
||||
esphome/components/rgbct/* @jesserockz
|
||||
esphome/components/rtttl/* @glmnet
|
||||
esphome/components/script/* @esphome/core
|
||||
esphome/components/sdm_meter/* @jesserockz @polyfaces
|
||||
|
|
0
esphome/components/color_temperature/__init__.py
Normal file
0
esphome/components/color_temperature/__init__.py
Normal file
38
esphome/components/color_temperature/ct_light_output.h
Normal file
38
esphome/components/color_temperature/ct_light_output.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/light/light_output.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace color_temperature {
|
||||
|
||||
class CTLightOutput : public light::LightOutput {
|
||||
public:
|
||||
void set_color_temperature(output::FloatOutput *color_temperature) { color_temperature_ = color_temperature; }
|
||||
void set_brightness(output::FloatOutput *brightness) { brightness_ = brightness; }
|
||||
void set_cold_white_temperature(float cold_white_temperature) { cold_white_temperature_ = cold_white_temperature; }
|
||||
void set_warm_white_temperature(float warm_white_temperature) { warm_white_temperature_ = warm_white_temperature; }
|
||||
light::LightTraits get_traits() override {
|
||||
auto traits = light::LightTraits();
|
||||
traits.set_supported_color_modes({light::ColorMode::COLOR_TEMPERATURE});
|
||||
traits.set_min_mireds(this->cold_white_temperature_);
|
||||
traits.set_max_mireds(this->warm_white_temperature_);
|
||||
return traits;
|
||||
}
|
||||
void write_state(light::LightState *state) override {
|
||||
float color_temperature, brightness;
|
||||
state->current_values_as_ct(&color_temperature, &brightness);
|
||||
this->color_temperature_->set_level(color_temperature);
|
||||
this->brightness_->set_level(brightness);
|
||||
}
|
||||
|
||||
protected:
|
||||
output::FloatOutput *color_temperature_;
|
||||
output::FloatOutput *brightness_;
|
||||
float cold_white_temperature_;
|
||||
float warm_white_temperature_;
|
||||
};
|
||||
|
||||
} // namespace color_temperature
|
||||
} // namespace esphome
|
42
esphome/components/color_temperature/light.py
Normal file
42
esphome/components/color_temperature/light.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.const import (
|
||||
CONF_BRIGHTNESS,
|
||||
CONF_COLOR_TEMPERATURE,
|
||||
CONF_OUTPUT_ID,
|
||||
CONF_COLD_WHITE_COLOR_TEMPERATURE,
|
||||
CONF_WARM_WHITE_COLOR_TEMPERATURE,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
||||
color_temperature_ns = cg.esphome_ns.namespace("color_temperature")
|
||||
CTLightOutput = color_temperature_ns.class_("CTLightOutput", light.LightOutput)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
light.RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(CTLightOutput),
|
||||
cv.Required(CONF_COLOR_TEMPERATURE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_BRIGHTNESS): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
}
|
||||
),
|
||||
light.validate_color_temperature_channels,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
|
||||
await light.register_light(var, config)
|
||||
|
||||
color_temperature = await cg.get_variable(config[CONF_COLOR_TEMPERATURE])
|
||||
cg.add(var.set_color_temperature(color_temperature))
|
||||
|
||||
brightness = await cg.get_variable(config[CONF_BRIGHTNESS])
|
||||
cg.add(var.set_brightness(brightness))
|
||||
|
||||
cg.add(var.set_cold_white_temperature(config[CONF_COLD_WHITE_COLOR_TEMPERATURE]))
|
||||
cg.add(var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE]))
|
|
@ -2,6 +2,7 @@ import esphome.codegen as cg
|
|||
import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.const import (
|
||||
CONF_CONSTANT_BRIGHTNESS,
|
||||
CONF_OUTPUT_ID,
|
||||
CONF_COLD_WHITE,
|
||||
CONF_WARM_WHITE,
|
||||
|
@ -12,8 +13,6 @@ from esphome.const import (
|
|||
cwww_ns = cg.esphome_ns.namespace("cwww")
|
||||
CWWWLightOutput = cwww_ns.class_("CWWWLightOutput", light.LightOutput)
|
||||
|
||||
CONF_CONSTANT_BRIGHTNESS = "constant_brightness"
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
light.RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
|
|
|
@ -163,6 +163,13 @@ class LightColorValues {
|
|||
this->as_cwww(cold_white, warm_white, gamma, constant_brightness);
|
||||
}
|
||||
|
||||
/// Convert these light color values to an RGB+CT+BR representation with the given parameters.
|
||||
void as_rgbct(float color_temperature_cw, float color_temperature_ww, float *red, float *green, float *blue,
|
||||
float *color_temperature, float *white_brightness, float gamma = 0) const {
|
||||
this->as_rgb(red, green, blue, gamma);
|
||||
this->as_ct(color_temperature_cw, color_temperature_ww, color_temperature, white_brightness, gamma);
|
||||
}
|
||||
|
||||
/// Convert these light color values to an CWWW representation with the given parameters.
|
||||
void as_cwww(float *cold_white, float *warm_white, float gamma = 0, bool constant_brightness = false) const {
|
||||
if (this->color_mode_ & ColorCapability::COLD_WARM_WHITE) {
|
||||
|
@ -187,6 +194,19 @@ class LightColorValues {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert these light color values to a CT+BR representation with the given parameters.
|
||||
void as_ct(float color_temperature_cw, float color_temperature_ww, float *color_temperature, float *white_brightness,
|
||||
float gamma = 0) const {
|
||||
const float white_level = this->color_mode_ & ColorCapability::RGB ? this->white_ : 1;
|
||||
if (this->color_mode_ & ColorCapability::COLOR_TEMPERATURE) {
|
||||
*color_temperature =
|
||||
(this->color_temperature_ - color_temperature_cw) / (color_temperature_ww - color_temperature_cw);
|
||||
*white_brightness = gamma_correct(this->state_ * this->brightness_ * white_level, gamma);
|
||||
} else { // Probably wont get here but put this here anyway.
|
||||
*white_brightness = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Compare this LightColorValues to rhs, return true if and only if all attributes match.
|
||||
bool operator==(const LightColorValues &rhs) const {
|
||||
return color_mode_ == rhs.color_mode_ && state_ == rhs.state_ && brightness_ == rhs.brightness_ &&
|
||||
|
|
|
@ -175,13 +175,23 @@ void LightState::current_values_as_rgbw(float *red, float *green, float *blue, f
|
|||
}
|
||||
void LightState::current_values_as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white,
|
||||
bool constant_brightness) {
|
||||
auto traits = this->get_traits();
|
||||
this->current_values.as_rgbww(red, green, blue, cold_white, warm_white, this->gamma_correct_, constant_brightness);
|
||||
}
|
||||
void LightState::current_values_as_rgbct(float *red, float *green, float *blue, float *color_temperature,
|
||||
float *white_brightness) {
|
||||
auto traits = this->get_traits();
|
||||
this->current_values.as_rgbct(traits.get_min_mireds(), traits.get_max_mireds(), red, green, blue, color_temperature,
|
||||
white_brightness, this->gamma_correct_);
|
||||
}
|
||||
void LightState::current_values_as_cwww(float *cold_white, float *warm_white, bool constant_brightness) {
|
||||
auto traits = this->get_traits();
|
||||
this->current_values.as_cwww(cold_white, warm_white, this->gamma_correct_, constant_brightness);
|
||||
}
|
||||
void LightState::current_values_as_ct(float *color_temperature, float *white_brightness) {
|
||||
auto traits = this->get_traits();
|
||||
this->current_values.as_ct(traits.get_min_mireds(), traits.get_max_mireds(), color_temperature, white_brightness,
|
||||
this->gamma_correct_);
|
||||
}
|
||||
|
||||
void LightState::start_effect_(uint32_t effect_index) {
|
||||
this->stop_effect_();
|
||||
|
|
|
@ -128,8 +128,13 @@ class LightState : public Nameable, public Component {
|
|||
void current_values_as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white,
|
||||
bool constant_brightness = false);
|
||||
|
||||
void current_values_as_rgbct(float *red, float *green, float *blue, float *color_temperature,
|
||||
float *white_brightness);
|
||||
|
||||
void current_values_as_cwww(float *cold_white, float *warm_white, bool constant_brightness = false);
|
||||
|
||||
void current_values_as_ct(float *color_temperature, float *white_brightness);
|
||||
|
||||
protected:
|
||||
friend LightOutput;
|
||||
friend LightCall;
|
||||
|
|
0
esphome/components/rgbct/__init__.py
Normal file
0
esphome/components/rgbct/__init__.py
Normal file
59
esphome/components/rgbct/light.py
Normal file
59
esphome/components/rgbct/light.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.const import (
|
||||
CONF_BLUE,
|
||||
CONF_COLOR_TEMPERATURE,
|
||||
CONF_GREEN,
|
||||
CONF_RED,
|
||||
CONF_OUTPUT_ID,
|
||||
CONF_COLD_WHITE_COLOR_TEMPERATURE,
|
||||
CONF_WARM_WHITE_COLOR_TEMPERATURE,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
||||
rgbct_ns = cg.esphome_ns.namespace("rgbct")
|
||||
RGBCTLightOutput = rgbct_ns.class_("RGBCTLightOutput", light.LightOutput)
|
||||
|
||||
CONF_COLOR_INTERLOCK = "color_interlock"
|
||||
CONF_WHITE_BRIGHTNESS = "white_brightness"
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
light.RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(RGBCTLightOutput),
|
||||
cv.Required(CONF_RED): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_GREEN): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_BLUE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_COLOR_TEMPERATURE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_WHITE_BRIGHTNESS): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Optional(CONF_COLOR_INTERLOCK, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
light.validate_color_temperature_channels,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
|
||||
await light.register_light(var, config)
|
||||
|
||||
red = await cg.get_variable(config[CONF_RED])
|
||||
cg.add(var.set_red(red))
|
||||
green = await cg.get_variable(config[CONF_GREEN])
|
||||
cg.add(var.set_green(green))
|
||||
blue = await cg.get_variable(config[CONF_BLUE])
|
||||
cg.add(var.set_blue(blue))
|
||||
|
||||
color_temp = await cg.get_variable(config[CONF_COLOR_TEMPERATURE])
|
||||
cg.add(var.set_color_temperature(color_temp))
|
||||
white_brightness = await cg.get_variable(config[CONF_WHITE_BRIGHTNESS])
|
||||
cg.add(var.set_white_brightness(white_brightness))
|
||||
|
||||
cg.add(var.set_cold_white_temperature(config[CONF_COLD_WHITE_COLOR_TEMPERATURE]))
|
||||
cg.add(var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE]))
|
||||
|
||||
cg.add(var.set_color_interlock(config[CONF_COLOR_INTERLOCK]))
|
58
esphome/components/rgbct/rgbct_light_output.h
Normal file
58
esphome/components/rgbct/rgbct_light_output.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/light/color_mode.h"
|
||||
#include "esphome/components/light/light_output.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace rgbct {
|
||||
|
||||
class RGBCTLightOutput : public light::LightOutput {
|
||||
public:
|
||||
void set_red(output::FloatOutput *red) { red_ = red; }
|
||||
void set_green(output::FloatOutput *green) { green_ = green; }
|
||||
void set_blue(output::FloatOutput *blue) { blue_ = blue; }
|
||||
|
||||
void set_color_temperature(output::FloatOutput *color_temperature) { color_temperature_ = color_temperature; }
|
||||
void set_white_brightness(output::FloatOutput *white_brightness) { white_brightness_ = white_brightness; }
|
||||
|
||||
void set_cold_white_temperature(float cold_white_temperature) { cold_white_temperature_ = cold_white_temperature; }
|
||||
void set_warm_white_temperature(float warm_white_temperature) { warm_white_temperature_ = warm_white_temperature; }
|
||||
void set_color_interlock(bool color_interlock) { color_interlock_ = color_interlock; }
|
||||
|
||||
light::LightTraits get_traits() override {
|
||||
auto traits = light::LightTraits();
|
||||
if (this->color_interlock_)
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB, light::ColorMode::COLOR_TEMPERATURE});
|
||||
else
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB_COLOR_TEMPERATURE, light::ColorMode::COLOR_TEMPERATURE});
|
||||
traits.set_min_mireds(this->cold_white_temperature_);
|
||||
traits.set_max_mireds(this->warm_white_temperature_);
|
||||
return traits;
|
||||
}
|
||||
void write_state(light::LightState *state) override {
|
||||
float red, green, blue, color_temperature, white_brightness;
|
||||
|
||||
state->current_values_as_rgbct(&red, &green, &blue, &color_temperature, &white_brightness);
|
||||
|
||||
this->red_->set_level(red);
|
||||
this->green_->set_level(green);
|
||||
this->blue_->set_level(blue);
|
||||
this->color_temperature_->set_level(color_temperature);
|
||||
this->white_brightness_->set_level(white_brightness);
|
||||
}
|
||||
|
||||
protected:
|
||||
output::FloatOutput *red_;
|
||||
output::FloatOutput *green_;
|
||||
output::FloatOutput *blue_;
|
||||
output::FloatOutput *color_temperature_;
|
||||
output::FloatOutput *white_brightness_;
|
||||
float cold_white_temperature_;
|
||||
float warm_white_temperature_;
|
||||
bool color_interlock_{true};
|
||||
};
|
||||
|
||||
} // namespace rgbct
|
||||
} // namespace esphome
|
|
@ -3,6 +3,7 @@ import esphome.config_validation as cv
|
|||
from esphome.components import light, output
|
||||
from esphome.const import (
|
||||
CONF_BLUE,
|
||||
CONF_CONSTANT_BRIGHTNESS,
|
||||
CONF_GREEN,
|
||||
CONF_RED,
|
||||
CONF_OUTPUT_ID,
|
||||
|
@ -15,7 +16,6 @@ from esphome.const import (
|
|||
rgbww_ns = cg.esphome_ns.namespace("rgbww")
|
||||
RGBWWLightOutput = rgbww_ns.class_("RGBWWLightOutput", light.LightOutput)
|
||||
|
||||
CONF_CONSTANT_BRIGHTNESS = "constant_brightness"
|
||||
CONF_COLOR_INTERLOCK = "color_interlock"
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
|
|
|
@ -134,6 +134,7 @@ CONF_COMPONENTS = "components"
|
|||
CONF_CONDITION = "condition"
|
||||
CONF_CONDITION_ID = "condition_id"
|
||||
CONF_CONDUCTIVITY = "conductivity"
|
||||
CONF_CONSTANT_BRIGHTNESS = "constant_brightness"
|
||||
CONF_CONTRAST = "contrast"
|
||||
CONF_COOL_ACTION = "cool_action"
|
||||
CONF_COOL_DEADBAND = "cool_deadband"
|
||||
|
|
|
@ -1429,6 +1429,16 @@ light:
|
|||
cold_white_color_temperature: 153 mireds
|
||||
warm_white_color_temperature: 500 mireds
|
||||
color_interlock: true
|
||||
- platform: rgbct
|
||||
name: 'Living Room Lights 2'
|
||||
red: pca_3
|
||||
green: pca_4
|
||||
blue: pca_5
|
||||
color_temperature: pca_6
|
||||
white_brightness: pca_6
|
||||
cold_white_color_temperature: 153 mireds
|
||||
warm_white_color_temperature: 500 mireds
|
||||
color_interlock: true
|
||||
- platform: cwww
|
||||
name: 'Living Room Lights 2'
|
||||
cold_white: pca_6
|
||||
|
@ -1436,6 +1446,12 @@ light:
|
|||
cold_white_color_temperature: 153 mireds
|
||||
warm_white_color_temperature: 500 mireds
|
||||
constant_brightness: true
|
||||
- platform: color_temperature
|
||||
name: 'Living Room Lights 2'
|
||||
color_temperature: pca_6
|
||||
brightness: pca_6
|
||||
cold_white_color_temperature: 153 mireds
|
||||
warm_white_color_temperature: 500 mireds
|
||||
- platform: fastled_clockless
|
||||
id: addr1
|
||||
chipset: WS2811
|
||||
|
|
Loading…
Reference in a new issue