mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Merge pull request #12072 from emontnemery/light_retain_ratio
Allow retaining ratio between white and color channels
This commit is contained in:
commit
6f79deae73
@ -171,7 +171,8 @@ void (* const LightCommand[])(void) PROGMEM = {
|
|||||||
|
|
||||||
// Light color mode, either RGB alone, or white-CT alone, or both only available if ct_rgb_linked is false
|
// Light color mode, either RGB alone, or white-CT alone, or both only available if ct_rgb_linked is false
|
||||||
enum LightColorModes {
|
enum LightColorModes {
|
||||||
LCM_RGB = 1, LCM_CT = 2, LCM_BOTH = 3 };
|
LCM_RGB = 1, LCM_CT = 2, LCM_BOTH = 3
|
||||||
|
};
|
||||||
|
|
||||||
struct LRgbColor {
|
struct LRgbColor {
|
||||||
uint8_t R, G, B;
|
uint8_t R, G, B;
|
||||||
@ -321,6 +322,7 @@ class LightStateClass {
|
|||||||
uint16_t _hue = 0; // 0..359
|
uint16_t _hue = 0; // 0..359
|
||||||
uint8_t _sat = 255; // 0..255
|
uint8_t _sat = 255; // 0..255
|
||||||
uint8_t _briRGB = 255; // 0..255
|
uint8_t _briRGB = 255; // 0..255
|
||||||
|
uint8_t _briRGB_orig = 255; // 0..255
|
||||||
// dimmer is same as _bri but with a range of 0%-100%
|
// dimmer is same as _bri but with a range of 0%-100%
|
||||||
uint8_t _r = 255; // 0..255
|
uint8_t _r = 255; // 0..255
|
||||||
uint8_t _g = 255; // 0..255
|
uint8_t _g = 255; // 0..255
|
||||||
@ -331,6 +333,7 @@ class LightStateClass {
|
|||||||
uint8_t _wc = 255; // white cold channel
|
uint8_t _wc = 255; // white cold channel
|
||||||
uint8_t _ww = 0; // white warm channel
|
uint8_t _ww = 0; // white warm channel
|
||||||
uint8_t _briCT = 255;
|
uint8_t _briCT = 255;
|
||||||
|
uint8_t _briCT_orig = 255;
|
||||||
|
|
||||||
uint8_t _color_mode = LCM_RGB; // RGB by default
|
uint8_t _color_mode = LCM_RGB; // RGB by default
|
||||||
|
|
||||||
@ -343,7 +346,7 @@ class LightStateClass {
|
|||||||
_subtype = sub_type; // set sub_type at initialization, shoudln't be changed afterwards
|
_subtype = sub_type; // set sub_type at initialization, shoudln't be changed afterwards
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is a bit hairy, it will try to match the rerquired
|
// This function is a bit hairy, it will try to match the required
|
||||||
// colormode with the features of the device:
|
// colormode with the features of the device:
|
||||||
// LST_NONE: LCM_RGB
|
// LST_NONE: LCM_RGB
|
||||||
// LST_SINGLE: LCM_RGB
|
// LST_SINGLE: LCM_RGB
|
||||||
@ -455,6 +458,10 @@ class LightStateClass {
|
|||||||
return _briCT;
|
return _briCT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint8_t getBriCTOrig() {
|
||||||
|
return _briCT_orig;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint8_t DimmerToBri(uint8_t dimmer) {
|
static inline uint8_t DimmerToBri(uint8_t dimmer) {
|
||||||
return changeUIntScale(dimmer, 0, 100, 0, 255); // 0..255
|
return changeUIntScale(dimmer, 0, 100, 0, 255); // 0..255
|
||||||
}
|
}
|
||||||
@ -520,6 +527,10 @@ class LightStateClass {
|
|||||||
return _briRGB;
|
return _briRGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint8_t getBriRGBOrig() {
|
||||||
|
return _briRGB_orig;
|
||||||
|
}
|
||||||
|
|
||||||
void setDimmer(uint8_t dimmer) {
|
void setDimmer(uint8_t dimmer) {
|
||||||
setBri(DimmerToBri(dimmer));
|
setBri(DimmerToBri(dimmer));
|
||||||
}
|
}
|
||||||
@ -649,6 +660,13 @@ class LightStateClass {
|
|||||||
void setChannels(uint8_t *channels) {
|
void setChannels(uint8_t *channels) {
|
||||||
setRGB(channels[0], channels[1], channels[2]);
|
setRGB(channels[0], channels[1], channels[2]);
|
||||||
setCW(channels[3], channels[4], true); // free range for WC and WW
|
setCW(channels[3], channels[4], true); // free range for WC and WW
|
||||||
|
uint8_t r = channels[0];
|
||||||
|
uint8_t g = channels[1];
|
||||||
|
uint8_t b = channels[2];
|
||||||
|
uint8_t cw = channels[3];
|
||||||
|
uint8_t ww = channels[4];
|
||||||
|
_briRGB_orig = (r > g && r > b) ? r : (g > b) ? g : b;
|
||||||
|
_briCT_orig = (cw > ww) ? cw : ww;
|
||||||
#ifdef DEBUG_LIGHT
|
#ifdef DEBUG_LIGHT
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, "LightStateClass::setChannels (%d %d %d %d %d)",
|
AddLog(LOG_LEVEL_DEBUG_MORE, "LightStateClass::setChannels (%d %d %d %d %d)",
|
||||||
channels[0], channels[1], channels[2], channels[3], channels[4]);
|
channels[0], channels[1], channels[2], channels[3], channels[4]);
|
||||||
@ -1257,6 +1275,28 @@ void LightSetBri(uint8_t device, uint8_t bri) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightSetBriScaled(uint8_t bri) {
|
||||||
|
// change both dimmers, retain ratio between white and color channels
|
||||||
|
uint32_t bri_rgb = light_state.getBriRGBOrig();
|
||||||
|
uint32_t bri_ct = light_state.getBriCTOrig();
|
||||||
|
#ifdef DEBUG_LIGHT
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, "LightSetBri bri:%d, bri_rgb:%d, bri_ct: %d", bri, bri_rgb, bri_ct);
|
||||||
|
#endif
|
||||||
|
uint32_t max_bri = bri_rgb > bri_ct ? bri_rgb : bri_ct;
|
||||||
|
if (max_bri == 0) {
|
||||||
|
bri_rgb = bri;
|
||||||
|
bri_ct = bri;
|
||||||
|
} else {
|
||||||
|
bri_rgb = changeUIntScale(bri_rgb, 0, max_bri, 0, bri);
|
||||||
|
bri_ct = changeUIntScale(bri_ct, 0, max_bri, 0, bri);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_LIGHT
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, "LightSetBri new bri_rgb:%d, new bri_ct: %d", bri_rgb, bri_ct);
|
||||||
|
#endif
|
||||||
|
light_controller.changeBriRGB(bri_rgb);
|
||||||
|
light_controller.changeBriCT(bri_ct);
|
||||||
|
}
|
||||||
|
|
||||||
void LightColorOffset(int32_t offset) {
|
void LightColorOffset(int32_t offset) {
|
||||||
uint16_t hue;
|
uint16_t hue;
|
||||||
uint8_t sat;
|
uint8_t sat;
|
||||||
@ -2461,7 +2501,7 @@ void CmndSupportColor(void)
|
|||||||
light_controller.changeChannels(Light.entry_color);
|
light_controller.changeChannels(Light.entry_color);
|
||||||
if (2 == XdrvMailbox.index) {
|
if (2 == XdrvMailbox.index) {
|
||||||
// If Color2, set back old brightness
|
// If Color2, set back old brightness
|
||||||
light_controller.changeBri(old_bri);
|
LightSetBriScaled(old_bri);
|
||||||
}
|
}
|
||||||
#ifdef USE_LIGHT_PALETTE
|
#ifdef USE_LIGHT_PALETTE
|
||||||
}
|
}
|
||||||
@ -2713,7 +2753,7 @@ void CmndDimmer(void)
|
|||||||
TasmotaGlobal.skip_light_fade = true;
|
TasmotaGlobal.skip_light_fade = true;
|
||||||
XdrvMailbox.index = 0;
|
XdrvMailbox.index = 0;
|
||||||
}
|
}
|
||||||
else if (XdrvMailbox.index > 2) {
|
else if (XdrvMailbox.index > 4) {
|
||||||
XdrvMailbox.index = 1;
|
XdrvMailbox.index = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2740,7 +2780,14 @@ void CmndDimmer(void)
|
|||||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
||||||
if (light_controller.isCTRGBLinked()) {
|
if (light_controller.isCTRGBLinked()) {
|
||||||
// normal state, linked RGB and CW
|
// normal state, linked RGB and CW
|
||||||
light_controller.changeDimmer(XdrvMailbox.payload);
|
if (4 == XdrvMailbox.index) {
|
||||||
|
// change both dimmers, retain ratio between white and color channels
|
||||||
|
uint32_t new_bri = changeUIntScale(XdrvMailbox.payload, 0, 100, 0, 255);
|
||||||
|
LightSetBriScaled(new_bri);
|
||||||
|
} else {
|
||||||
|
// change both dimmers
|
||||||
|
light_controller.changeDimmer(XdrvMailbox.payload);
|
||||||
|
}
|
||||||
LightPreparePower();
|
LightPreparePower();
|
||||||
} else {
|
} else {
|
||||||
if (0 != XdrvMailbox.index) {
|
if (0 != XdrvMailbox.index) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user