Created
September 10, 2021 11:21
-
-
Save mikezter/31fb35f5d1cfe66a2b888121c9bca995 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
esphome: | |
name: qs-wifi-ds02-2c | |
platform: ESP8266 | |
board: esp01_1m | |
wifi: | |
ssid: "MyWiFi_SSID" | |
password: "MyWiFi_pw" | |
# Enable fallback hotspot (captive portal) in case wifi connection fails | |
ap: | |
ssid: "Qs-Wifi-Ds02-2C" | |
password: "MyFallBack_pw" | |
captive_portal: | |
# Enable Home Assistant API | |
api: | |
password: "my-ha-api-password" | |
ota: | |
# Example configuration entry (optional web server) | |
web_server: | |
port: 80 | |
# Make sure logging is not using the serial port | |
logger: | |
baud_rate: 0 | |
logs: | |
sensor: ERROR | |
duty_cycle: ERROR | |
binary_sensor: ERROR | |
light: ERROR | |
# level: VERBOSE | |
time: | |
- platform: homeassistant | |
substitutions: | |
switch_id: "dim_2ch_01" | |
# globals: | |
# Dummy light brightness tracker Global | |
globals: | |
# Dim direction for Switch 1: 0=Up (brighten) 1=down (dim) | |
- id: g_direction_1 | |
type: int | |
restore_value: no | |
initial_value: "1" | |
# Counter for time pressed for switch 1 | |
- id: g_counter_1 | |
type: int | |
restore_value: no | |
initial_value: "0" | |
# initial brightness | |
# Dim direction for Switch 2: 0=Up (brighten) 1=down (dim) | |
- id: g_direction_2 | |
type: int | |
restore_value: no | |
initial_value: "1" | |
# Counter for time pressed for switch 2 | |
- id: g_counter_2 | |
type: int | |
restore_value: no | |
initial_value: "0" | |
# initial brightness | |
# Uart definition to talk to MCU dimmer | |
uart: | |
tx_pin: GPIO1 | |
rx_pin: GPIO3 | |
stop_bits: 1 | |
baud_rate: 9600 | |
sensor: | |
- platform: wifi_signal | |
name: "${switch_id} WiFi Signal Sensor" | |
update_interval: 60s | |
# Primary template sensor to track Brightness of light object for "on_value" sending to MCU dimmer | |
# CH1 | |
- platform: template | |
name: "${switch_id} Brightness Sensor CH1" | |
id: sensor_g_bright_1 | |
internal: true | |
update_interval: 20ms | |
# Ensure on_value only triggered when brightness (0-255) changes | |
filters: | |
delta: 0.8 | |
# Read brightness (0 - 1) from light , convert to (0-255) for MCU | |
lambda: |- | |
if (id(light_main_1).remote_values.is_on()) { | |
return (int(id(light_main_1).remote_values.get_brightness() * 255)); | |
} | |
else { | |
return 0; | |
} | |
# On Change send to MCU via UART | |
on_value: | |
then: | |
- uart.write: !lambda |- | |
return {0xFF, 0x55, 0x01, (char) id(sensor_g_bright_1).state, 0x00, 0x00, 0x00, 0x0A}; | |
- logger.log: | |
level: INFO | |
format: "CH1 Sensor Value Change sent to UART %3.1f" | |
args: ["id(sensor_g_bright_1).state"] | |
# Sensor to detect button push (via duty_cycle of 50hz mains signal) | |
- platform: template | |
name: "${switch_id} Brightness Sensor CH2" | |
id: sensor_g_bright_2 | |
internal: true | |
update_interval: 20ms | |
# Ensure on_value only triggered when brightness (0-255) changes | |
filters: | |
delta: 0.8 | |
# Read brightness (0 - 1) from light , convert to (0-255) for MCU | |
lambda: |- | |
if (id(light_main_2).remote_values.is_on()) { | |
return (int(id(light_main_2).remote_values.get_brightness() * 255)); | |
} | |
else { | |
return 0; | |
} | |
# On Change send to MCU via UART | |
on_value: | |
then: | |
- uart.write: !lambda |- | |
return {0xFF, 0x55, 0x02, 0x00, (char) id(sensor_g_bright_2).state, 0x00, 0x00, 0x0A}; | |
- logger.log: | |
level: INFO | |
format: "CH2 Sensor Value Change sent to UART %3.1f" | |
args: ["id(sensor_g_bright_2).state"] | |
# Sensor to detect button push (via duty_cycle of 50hz mains signal) | |
- platform: duty_cycle | |
pin: GPIO13 | |
internal: true | |
id: sensor_push_switch_1 | |
name: "${switch_id} Sensor Push Switch 1" | |
update_interval: 20ms | |
- platform: duty_cycle | |
pin: GPIO5 | |
internal: true | |
id: sensor_push_switch_2 | |
name: "${switch_id} Sensor Push Switch 2" | |
update_interval: 20ms | |
binary_sensor: | |
#Binary sensor (on/off) which reads duty_cyle sensor readings. CH1 | |
- platform: template | |
id: switch1 | |
internal: true | |
name: "${switch_id} Switch Binary Sensor 1" | |
# read duty_cycle, convert to on/off | |
lambda: |- | |
if (id(sensor_push_switch_1).state < 95.0) { | |
return true; | |
} else { | |
return false; | |
} | |
# Short Click - toggle light only | |
on_click: | |
max_length: 300ms | |
then: | |
light.toggle: light_main_1 | |
# Generic On_Press - log press, toggle DIM Direction and reset press interval counter | |
on_press: | |
then: | |
- logger.log: "Switch 1 Press" | |
- lambda: |- | |
if (id(g_direction_1) == 0) { | |
id(g_direction_1) = 1; | |
} else { | |
id(g_direction_1) = 0; | |
} | |
id(g_counter_1) = 0; | |
#Binary sensor (on/off) which reads duty_cyle sensor readings. CH2 | |
- platform: template | |
id: switch2 | |
internal: true | |
name: "${switch_id} Switch Binary Sensor 2" | |
# read duty_cycle, convert to on/off | |
lambda: |- | |
if (id(sensor_push_switch_2).state < 95.0) { | |
return true; | |
} else { | |
return false; | |
} | |
# Short Click - toggle light only | |
on_click: | |
max_length: 300ms | |
then: | |
light.toggle: light_main_2 | |
# Generic On_Press - log press, toggle DIM Direction and reset press interval counter | |
on_press: | |
then: | |
- logger.log: "Switch 2 Press" | |
- lambda: |- | |
if (id(g_direction_2) == 0) { | |
id(g_direction_2) = 1; | |
} else { | |
id(g_direction_2) = 0; | |
} | |
id(g_counter_2) = 0; | |
# Dummy light output to allow creation of light object | |
output: | |
- platform: esp8266_pwm | |
pin: GPIO14 | |
frequency: 800 Hz | |
id: dummy_pwm1 | |
- platform: esp8266_pwm | |
pin: GPIO16 | |
frequency: 800 Hz | |
id: dummy_pwm2 | |
# Primary Light object exposed to HA | |
light: | |
- platform: monochromatic | |
default_transition_length: 20ms | |
name: "${switch_id} Light 1" | |
output: dummy_pwm1 | |
id: light_main_1 | |
- platform: monochromatic | |
default_transition_length: 20ms | |
name: "${switch_id} Light 2" | |
output: dummy_pwm2 | |
id: light_main_2 | |
switch: | |
- platform: restart | |
name: "${switch_id} Restart" | |
# Polling object for long press handling of switch for dim/brighten cycle | |
interval: | |
- interval: 20ms | |
then: | |
- if: | |
condition: | |
binary_sensor.is_on: switch1 | |
then: | |
# Ramp rate for dim is product of interval (20ms) * number of intervals | |
# Every 20ms Dimmer is increased/decreased by 2/255 | |
# Lower limit = 10% | |
# Upper limit = 100% | |
# 100% - 10% = 90% = 230/255. Therefore 230/2 * 20ms = 2.3 seconds for full range | |
# At full/min brightness - further 16x20ms = 0.32 Seconds "dwell" by resetting counter to 0 | |
# Initial pause for 16x20ms = 0.32s to allow "on_click" to be discounted 1st | |
# g_direction_1 = 0 (Increasing brightness) | |
# g_direction_1 = 1 (decreasing brightness) | |
# g_counter_1 = Interval pulse counter | |
lambda: |- | |
float curr_bright = id(light_main_1).remote_values.get_brightness(); | |
id(g_counter_1) += 1; | |
// If max bright, change direction | |
if (curr_bright >= 0.999 && id(g_direction_1) == 0) { | |
id(g_direction_1) = 1; | |
id(g_counter_1) = 0; | |
} | |
// If below min_bright, change direction | |
if (curr_bright < 0.1 && id(g_direction_1) == 1) { | |
id(g_direction_1) = 0; | |
id(g_counter_1) = 0; | |
} | |
if (id(g_direction_1) == 0 && id(g_counter_1) > 15) { | |
// Increase Bright | |
auto call = id(light_main_1).turn_on(); | |
call.set_brightness(curr_bright + (2.0/255.0)); | |
call.perform(); | |
} | |
else if(id(g_direction_1) == 1 && id(g_counter_1) > 15) { | |
// Decrease Bright | |
auto call = id(light_main_1).turn_on(); | |
call.set_brightness(curr_bright - (2.0/255.0)); | |
call.perform(); | |
} | |
- if: | |
condition: | |
binary_sensor.is_on: switch2 | |
then: | |
# Ramp rate for dim is product of interval (20ms) * number of intervals | |
# Every 20ms Dimmer is increased/decreased by 2/255 | |
# Lower limit = 10% | |
# Upper limit = 100% | |
# 100% - 10% = 90% = 230/255. Therefore 230/2 * 20ms = 2.3 seconds for full range | |
# At full/min brightness - further 16x20ms = 0.32 Seconds "dwell" by resetting counter to 0 | |
# Initial pause for 16x20ms = 0.32s to allow "on_click" to be discounted 1st | |
# g_direction_1 = 0 (Increasing brightness) | |
# g_direction_1 = 1 (decreasing brightness) | |
# g_counter_1 = Interval pulse counter | |
lambda: |- | |
float curr_bright = id(light_main_2).remote_values.get_brightness(); | |
id(g_counter_2) += 1; | |
// If max bright, change direction | |
if (curr_bright >= 0.999 && id(g_direction_2) == 0) { | |
id(g_direction_2) = 1; | |
id(g_counter_2) = 0; | |
} | |
// If below min_bright, change direction | |
if (curr_bright < 0.1 && id(g_direction_2) == 1) { | |
id(g_direction_2) = 0; | |
id(g_counter_2) = 0; | |
} | |
if (id(g_direction_2) == 0 && id(g_counter_2) > 15) { | |
// Increase Bright | |
auto call = id(light_main_2).turn_on(); | |
call.set_brightness(curr_bright + (2.0/255.0)); | |
call.perform(); | |
} | |
else if(id(g_direction_2) == 1 && id(g_counter_2) > 15) { | |
// Decrease Bright | |
auto call = id(light_main_2).turn_on(); | |
call.set_brightness(curr_bright - (2.0/255.0)); | |
call.perform(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment