substitutions: device_name: toiletlight friendly_name: "Toilet Light" esphome: name: ${device_name} friendly_name: ${friendly_name} area: Toilet esp32: variant: esp32c3 cpu_frequency: 80MHz framework: type: esp-idf sdkconfig_options: CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON: y CONFIG_BOOTLOADER_LOG_LEVEL_NONE: y CONFIG_LOG_DEFAULT_LEVEL_NONE: y preferences: flash_write_interval: 30s # Enable logging logger: # disable logging for much faster startup level: NONE # make RXD / TXD available baud_rate: 0 # Enable Home Assistant API api: encryption: key: !secret api_encryption_key # OTA ota: - platform: esphome password: !secret ota_password # WiFi Credentials wifi: domain: .lan ssid: !secret wifi_ssid password: !secret wifi_password # enabling power saves causes jitter! power_save_mode: NONE # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "${device_name} Fallback Hotspot" password: !secret wifi_ap_password captive_portal: light: - id: toilet platform: color_temperature name: "Toilet" color_temperature: pwm_warm_cold # we are using pwm_dim_mapped to transform between min+max-power # otherwise one can use: #brightness: pwm_dim #gamma_correct: 1.0 brightness: pwm_dim_mapped cold_white_color_temperature: 6500 K warm_white_color_temperature: 3000 K default_transition_length: 300ms initial_state: state: true brightness: 100% color_temperature: 4500 K restore_mode: RESTORE_DEFAULT_ON output: - id: pwm_dim platform: ledc pin: GPIO1 frequency: 3900 Hz channel: 0 min_power: 0.04 zero_means_zero: true - id: pwm_warm platform: ledc pin: GPIO3 # original mcu uses 3900Hz frequency: 24000 Hz channel: 2 - id: pwm_cold platform: ledc pin: GPIO4 # original mcu uses 3900Hz frequency: 24000 Hz channel: 3 phase_angle: 180° - platform: template id: pwm_warm_cold type: float write_action: - lambda: |- auto warm = id(pwm_warm), cold = id(pwm_cold); ESP_LOGD("cal", "warm: %f, cold: %f, phase: %f", state, 1-state, state*360.0); warm->set_level(state); cold->set_level(1 - state); cold->set_phase_angle(state * 360.0); # map output to range (min_power, max_power) - platform: template id: pwm_dim_mapped type: float write_action: - lambda: |- auto output = id(pwm_dim); float min = output->get_min_power(), max = output->get_max_power(); float newlvl = (state) ? state * (max - min) + min : 0; ESP_LOGD("cal", "dim: %f -> %f", state, newlvl); output->set_level(newlvl); if (newlvl == 0) { id(pwm_warm).set_level(0); id(pwm_cold).set_level(0); } # closed loop not implemented #sensor: # - id: adc_cs # platform: adc # pin: GPIO0 # accuracy_decimals: 2 # attenuation: auto # update_interval: 1s globals: - id: saved_brightness type: float restore_value: yes initial_value: '1.0' - id: saved_color_temp type: float restore_value: yes initial_value: '222.0' # 4500K binary_sensor: - platform: homeassistant name: "Nightlight enabled from Home Assistant" entity_id: input_boolean.toilet_light_nightlight on_state_change: then: - if: condition: lambda: 'return x.has_value() && x.value();' then: - globals.set: id: saved_brightness value: !lambda 'return id(toilet).current_values.get_brightness();' - globals.set: id: saved_color_temp value: !lambda 'return id(toilet).current_values.get_color_temperature();' - light.turn_on: id: toilet brightness: 1% color_temperature: 3000 K else: - light.turn_on: id: toilet brightness: !lambda 'return id(saved_brightness);' color_temperature: !lambda 'return id(saved_color_temp);'