Color temperature incorrect with low main brightness and warm_rgb on
Opened this issue · 9 comments
Summary
When setting the brightness of the main bulb to low values (<20%) with warm_rgb turned on, the actual color is incorrect, and sometimes even flickers (17% is especially bad). This wouldn't really be an issue except when using these bulbs with the flicker effect to simulate a candle, the drastic change in color temperature whenever the brightness drops too low is not good. And there's not a great way to get the correct color without using the warm_rbg.
More details:
- color temperature on main bulb set to 350mireds
- warm_rbg bulb turned on and set to reddish orange (white: 40%, red: 100%, green: 73%, blue: 0%)
- Version 1.845 of kauf_bulb.yaml (with a few custom additions). Full yaml copied below
- Added the effect->apply() code to light_state.cpp so effects will work.
- I'm pretty sure this color issue also happens without any of this custom code, but I haven't had a chance to try lately.
- I started digging into the color math that happens, but that was looking like a deeper dive than I had the time for.
Full yaml:
# esphome upload desk.yaml --device <orignal ip address>
# https://esphome.io/guides/configuration-types.html#substitutions
substitutions:
# substitutions can be changed here if you are using this file directly in the ESPHome dashboard. The better approach is
# to incorporate this file as a package using the following lines, and then overwrite these substitutions in your local
# yaml file by redefining them.
#
# packages:
# kauf.rgbww: github://KaufHA/kauf-rgbww-bulbs/kauf-bulb.yaml
#
name: kauf-bulb # **** CHANGE DEVICE NAME TO SOMETHING UNIQUE PER DEVICE. RENAME YAML FILE TO SAME NAME. ****
# **** USE DASHES (-) INSTEAD OF SPACES OR UNDERSCORE (_). USE ONLY LOWER CASE LETTERS. ****
friendly_name: Kauf Bulb # **** CHANGE FRIENDLY NAME TO SOMETHING UNIQUE PER DEVICE ****
disable_entities: "true" # set to "false" to have all entities show up in Home Assistant automatically
# https://esphome.io/components/light/index.html#base-light-configuration
light_restore_mode: RESTORE_DEFAULT_OFF # change power-on action for main light entity - NAT CHANGED
default_power_on_state: "Restore Power Off State"
wifi_ap_timeout: 2min # default to 2 minute timeout for yaml file as package.
# https://esphome.io/components/esphome.html#esphome-creators-project
project_name: Kauf.RGBWW
project_ver_num: "1.845"
project_ver_let: y
sub_on_turn_on: script_do_nothing
sub_on_turn_off: script_do_nothing
# https://esphome.io/components/esp8266.html
esp8266:
board: esp01_1m
restore_from_flash: true
start_free: 76
global_addr: global_forced_addr
# https://esphome.io/components/external_components.html
external_components:
- source:
type: git
url: https://github.com/KaufHA/common
refresh: 0s
- source:
type: git
url: https://github.com/KaufHA/kauf-rgbww-bulbs
refresh: 0s
- source:
type: local
path: copied_components
# https://esphome.io/guides/automations.html#global-variables
globals:
- id: global_forced_addr
type: int
restore_value: no
initial_value: '12345'
# https://esphome.io/components/esphome.html
esphome:
name: $name
name_add_mac_suffix: true
project:
name: $project_name
version: $project_ver_num($project_ver_let)
on_boot:
priority: 799.5 # after numbers/selects/switches being setup (800) and before lights being setup (799).
then: # restore settings
- script.execute: script_set_boot_mode
- script.execute: script_set_wled
# https://esphome.io/components/button/index.html
# https://esphome.io/components/button/restart.html
button:
- platform: restart
id: restart_button
name: $friendly_name Restart Firmware
entity_category: diagnostic
disabled_by_default: $disable_entities
# https://esphome.io/components/wifi.html
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Uncomment below to set a static IP
manual_ip:
static_ip: !secret ip_address
gateway: !secret gateway
subnet: !secret subnet
# default is 20, 17 is recommended.
output_power: 17
# using fast_connect as default since it is required for hidden networks.
fast_connect: true
forced_addr: 0
global_addr: global_forced_addr
ap:
ap_timeout: $wifi_ap_timeout
# https://esphome.io/components/captive_portal.html
captive_portal:
# https://esphome.io/components/logger.html
logger:
# https://esphome.io/components/api.html
api:
id: kauf_api
# https://esphome.io/components/ota.html
ota:
on_error:
then:
- button.press: restart_button
# https://esphome.io/components/web_server.html
web_server:
local: true
# PWM outputs for each LED channel
# https://esphome.io/components/output/esp8266_pwm.html
output:
- platform: esp8266_pwm
pin: GPIO4
frequency: 1000 Hz
id: pwm_red
max_power: .85
- platform: esp8266_pwm
pin: GPIO12
frequency: 1000 Hz
id: pwm_green
max_power: .85
- platform: esp8266_pwm
pin: GPIO14
frequency: 1000 Hz
id: pwm_blue
max_power: .85
- platform: esp8266_pwm
pin: GPIO5
frequency: 1000 Hz
id: pwm_cw
max_power: .85
- platform: esp8266_pwm
pin: GPIO13
frequency: 1000 Hz
id: pwm_ww
max_power: .85
# https://esphome.io/components/light/index.html
light:
# Additive RGB light for Warm White
- platform: kauf_rgbww
id: warm_rgb
entity_category: config
default_transition_length: 0ms
icon: mdi:store-cog
aux: true
name: $friendly_name Warm RGB
forced_hash: 4077116474
forced_addr: 28
global_addr: global_forced_addr
disabled_by_default: $disable_entities
# Additive RGB light for Cold White
- platform: kauf_rgbww
id: cold_rgb
entity_category: config
default_transition_length: 0ms
icon: mdi:store-cog-outline
aux: true
name: $friendly_name Cold RGB
forced_hash: 301094535
forced_addr: 40
global_addr: global_forced_addr
disabled_by_default: $disable_entities
# Main RGBWW light
- platform: kauf_rgbww
id: kauf_light
default_transition_length: 250ms
name: $friendly_name
red: pwm_red
green: pwm_green
blue: pwm_blue
warm_white: pwm_ww
cold_white: pwm_cw
warm_rgb: warm_rgb
cold_rgb: cold_rgb
forced_hash: 2723974766
forced_addr: 52
global_addr: global_forced_addr
restore_mode: $light_restore_mode
on_turn_on:
- script.execute: $sub_on_turn_on
on_turn_off:
- script.execute: $sub_on_turn_off
- switch.turn_off: kauf_light_candle
effects:
- flicker:
name: Candle
alpha: 95%
intensity: 3%
# https://esphome.io/components/select/index.html
# https://esphome.io/components/select/template.html
select:
- platform: template
name: $friendly_name Effect
id: effect
optimistic: true
options:
- "None"
- "WLED / DDP"
initial_option: "None"
restore_value: true
icon: mdi:string-lights
set_action:
- delay: 1ms
- script.execute: script_set_wled
- script.execute: script_save_changes
entity_category: config
forced_hash: 5841966
forced_addr: 66
global_addr: global_forced_addr
- platform: template
name: $friendly_name DDP Debug
id: select_ddp_debug
optimistic: true
options:
- "Print no packets"
- "Print imperfect packets"
- "Print all packets"
initial_option: "Print no packets"
restore_value: false
icon: mdi:play-network
entity_category: diagnostic
disabled_by_default: $disable_entities
set_action:
- lambda: |-
if ( x == "Print no packets" ) { id(kauf_light)->set_ddp_debug(0); }
else if ( x == "Print imperfect packets" ) { id(kauf_light)->set_ddp_debug(1); }
else if ( x == "Print all packets" ) { id(kauf_light)->set_ddp_debug(2); }
# default light state on boot
- platform: template
name: $friendly_name Power On State
id: select_boot_state
optimistic: true
options:
- "Restore Power Off State"
- "Always On - Last Value"
- "Always On - Bright White"
- "Always Off"
- "YAML Configured ($light_restore_mode)"
# defaulting to always on is nice so you know new bulbs are working
initial_option: $default_power_on_state
restore_value: true
icon: mdi:restart-alert
set_action:
- delay: 1ms
- script.execute: script_save_changes
- script.execute: script_set_boot_mode
- lambda: kauf_light->save_remote_values_();
entity_category: config
forced_hash: 3524332562
forced_addr: 64
global_addr: global_forced_addr
# https://esphome.io/components/number/index.html
# https://esphome.io/components/number/template.html
number: # set max power output for PWMs
- platform: template
name: ${friendly_name} Max Power
min_value: 1
max_value: 100
step: 1
initial_value: 85
id: number_max_power
entity_category: config
disabled_by_default: $disable_entities
icon: mdi:brightness-percent
optimistic: true
restore_value: true
unit_of_measurement: "%"
mode: box
forced_hash: 4189052763
forced_addr: 74
global_addr: global_forced_addr
on_value:
- lambda: |-
float new_power = ((float)x)/100.0f;
id(pwm_red).set_max_power(new_power);
id(pwm_green).set_max_power(new_power);
id(pwm_blue).set_max_power(new_power);
id(pwm_ww).set_max_power(new_power);
id(pwm_cw).set_max_power(new_power);
id(kauf_light)->set_next_write();
- script.execute: script_save_changes
- platform: template
name: ${friendly_name} Default Fade
min_value: 0
max_value: 5000
step: 50
initial_value: 250
id: number_default_fade
entity_category: config
icon: mdi:timer-outline
optimistic: true
restore_value: true
unit_of_measurement: "ms"
mode: box
forced_hash: 3133748577
forced_addr: 72
global_addr: global_forced_addr
on_value:
- lambda: 'id(kauf_light)->set_default_transition_length(x);'
- script.execute: script_save_changes
# https://esphome.io/components/switch/index.html
# https://esphome.io/components/switch/template.html
switch:
- platform: template
icon: mdi:candle
id: kauf_light_candle
name: $friendly_name Candle
optimistic: true
restore_state: true
disabled_by_default: $disable_entities
global_addr: global_forced_addr
on_turn_on:
# We shouldn't be using this one so just leave it out for now
# - light.turn_off:
# id: kauf_light
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.circadian_lighting_dining_table_light
- delay: 1ms
# originally it was [255, 188, 0]
# but that felt just a smidge too green so trying adjusting
# [232, 170, 0]
- light.turn_on:
id: warm_rgb
white: 40%
red: 100%
green: 73%
blue: 0%
transition_length: 0ms
- delay: 1ms
# Something about turning the light on first and then setting the effect
# seems to be more reliable. It's also a nicer fade in
- light.turn_on:
id: kauf_light
brightness: 35%
color_temperature: 350mireds
transition_length: 250ms
- delay: 300ms
- light.turn_on:
id: kauf_light
brightness: 35%
color_temperature: 350mireds
effect: Candle
# Can't do transition length and candle
# transition_length: 200ms
on_turn_off:
- light.turn_off:
id: kauf_light
transition_length: 250ms
- delay: 300ms
- light.control:
id: warm_rgb
white: 100%
red: 100%
green: 74%
blue: 0%
- delay: 100ms
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.circadian_lighting_dining_table_light
- platform: template
id: switch_no_hass
name: $friendly_name No HASS
optimistic: true
restore_state: true
entity_category: config
disabled_by_default: $disable_entities
icon: mdi:toggle-switch-off-outline
forced_hash: 706743398
forced_addr: 70
global_addr: global_forced_addr
on_turn_on:
- lambda: id(kauf_api)->set_reboot_timeout(0);
- script.execute: script_save_changes
on_turn_off:
- lambda: id(kauf_api)->set_reboot_timeout(900000);
- script.execute: script_save_changes
# https://esphome.io/components/sensor/uptime.html
sensor:
- platform: uptime
name: $friendly_name Uptime
update_interval: 60s
entity_category: diagnostic
disabled_by_default: $disable_entities
# Send IP Address to HA.
# https://esphome.io/components/text_sensor/wifi_info.html
text_sensor:
- platform: wifi_info
ip_address:
name: $friendly_name IP Address
entity_category: diagnostic
disabled_by_default: $disable_entities
# https://esphome.io/guides/automations.html#script-component
script:
- id: script_save_changes
mode: restart
then:
- delay: 3s
- lambda: 'global_preferences->sync();'
- id: script_set_wled
then:
- lambda: |-
if ( id(effect).state == "WLED / DDP" ) { id(kauf_light)->set_use_wled(true); }
else { id(kauf_light)->set_use_wled(false); }
- id: script_set_boot_mode
then:
lambda: |-
if ( id(select_boot_state).state == "Restore Power Off State")
kauf_light->set_restore_mode(LIGHT_RESTORE_DEFAULT_OFF);
else if ( id(select_boot_state).state == "Always On - Last Value")
kauf_light->set_restore_mode(LIGHT_RESTORE_AND_ON);
else if ( id(select_boot_state).state == "Always On - Bright White")
kauf_light->set_restore_mode(LIGHT_ALWAYS_ON);
else if ( id(select_boot_state).state == "Always Off")
kauf_light->set_restore_mode(LIGHT_RESTORE_AND_OFF);
else
kauf_light->set_restore_mode(LIGHT_$light_restore_mode);
- id: script_do_nothing
then:
lambda: return;
# Current reserved flash memory:
# 00-25: Wi-Fi Credentials
# 28-39: Warm RGB
# 40-51: Cold RGB
# 52-63: Main Light
# 64-65: Power On State select
# 66-67: Effect select
# 70-71: No HASS switch
# 72-73: Default Fade Length
# 74-75: Max Power
Thanks adding so many details. I'll check it out this weekend.
Did the flicker effect work for you with the main light set to 350 mireds?
In addition to adding the effect->apply() code back in I had to add in a line to base_light_effect.h to copy the color temperature from remote to out (Line 222: out.set_color_temperature(remote.get_color_temperature());
). Otherwise it would always flicker with the cold white LEDs and never warm white. Meaning, turning the Candle effect on would change the light's display from warm white to cold white even though it still showed warm white in Home Assistant.
BTW I'll add the effect->apply() code back in so you don't need your own custom components. Still looking at the flickering issue, I have a couple of ideas.
Try turning down the frequency on the PWM outputs. I think I'm doing too much on the ESP8266 to be able to also have 5 channels of software PWM running at 1000Hz, so it causes inaccuracies in timing. I used the following and it seemed to improve. I used 400Hz for the white channels and 200Hz for the colors. I'll probably play around with it more and find new values for the release firmware.
Lowering the PWM rate also increases resolution at low brightness so should help with accuracy that way as well.
# PWM outputs for each LED channel
# https://esphome.io/components/output/esp8266_pwm.html
output:
- platform: esp8266_pwm
pin: GPIO4
frequency: 200 Hz
id: pwm_red
max_power: .85
- platform: esp8266_pwm
pin: GPIO12
frequency: 200 Hz
id: pwm_green
max_power: .85
- platform: esp8266_pwm
pin: GPIO14
frequency: 200 Hz
id: pwm_blue
max_power: .85
- platform: esp8266_pwm
pin: GPIO5
frequency: 400 Hz
id: pwm_cw
max_power: .85
- platform: esp8266_pwm
pin: GPIO13
frequency: 400 Hz
id: pwm_ww
max_power: .85
Finally got a chance to come back to this. I copied over the latest version (1.863) from kauf_bulb.yaml and this seems to have fixed it! Thanks for adding back the effects piece too!
Ah spoke too soon. It's definitely better, but still flickers around 10% brightness and below.
Hmmm. Can you reply with complete exact settings of main light and cold/warm rgb lights? color and brightness. If you go to the states tab under developer tools it will show you the exact rgb values etc.
I'm having a similar issue with color temperatures: at their warmest settings, the bulbs are still relatively cool. Looking at the States tab, I see the bulbs have min_color_temp_kelvin: 2857
, where for other of my bulbs, that's 2000
(allowing for much warmer light like I'm looking for).
Can I change that value to enable warmer light? If so, how?
EDIT: Reviewing the docs again, it sounds like what I actually want is to use the Kauf Bulb Warm RGB entity. I'll have to take a look tomorrow to figure out how to do that.
I'm having a similar issue with color temperatures: at their warmest settings, the bulbs are still relatively cool. Looking at the States tab, I see the bulbs have
min_color_temp_kelvin: 2857
, where for other of my bulbs, that's2000
(allowing for much warmer light like I'm looking for).
Not necessarily related to the main issue, but the color temperature of the bulbs definitely shifts towards cool as the bulbs warm up from being on. Apparently this is common with LEDs, but I wonder if the color temperature of these bulbs is the steady state, or the initial on temp...
Hmmm. Can you reply with complete exact settings of main light and cold/warm rgb lights? color and brightness. If you go to the states tab under developer tools it will show you the exact rgb values etc.
main_light:
min_mireds: 150
max_mireds: 350
effect_list: None, Candle
supported_color_modes: color_temp, rgb
friendly_name: Kauf Bulb
supported_features: 44
color_mode: color_temp
brightness: 26
color_temp: 350
hs_color: 28.077, 60.925
rgb_color: 255, 172, 99
xy_color: 0.51, 0.386
effect: None
cold rgb off
warm rgb
supported_color_modes: rgbw
icon: mdi:store-cog
friendly_name: Kauf Bulb Warm RGB
supported_features: 40
color_mode: rgbw
brightness: 255
hs_color: 44.409, 49.804
rgb_color: 255, 222, 128
rgbw_color: 255, 189, 0, 255
xy_color: 0.437, 0.421