It took me a few days to get this project to this point. I think I can now call it “finished” but who knows. I benefited greatly from searching threads when trying to figure out how to write the config, but there doesn’t seem to be a lot of content pertaining to these cheap yellow displays. I would like to post my yaml so others might benefit from my work.
The cheap yellow display does the following:
- Shows a blue “closed” garage door mdi icon when the garage is closed, with the word CLOSED at the bottom of the screen
- Shows a yellow “open” garage door mdi icon when the garage is open, with the word OPEN at the bottom of the screen
- Shows a yellow mdi icon of a person inside the garage when there is motion detected inside the open garage, and a black icon when the garage is closed (because the door of the closed garage icon is blue)
- Shows a red “open” garage door mdi icon when the garage is open AND there has been no motion detected inside the garage for ten minutes, with the amount of time the open garage has been unoccupied (“stagnant”) displayed at the bottom of the screen (10 Minutes, 11 Minutes, etc.)
- Triggers the garage door button when the screen is touched for 500ms and slowly flashes the rear blue LED one time
- Shows not only the states OPEN and CLOSED, but also OPENING and CLOSING, based on the amount of time the door travels
I’m not an expert, so feel free to offer any advice. The display is working as I’d planned, so I am not seeking any advice, though.
captive_portal:
spi:
- id: tft
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO12
- id: touch
clk_pin: GPIO25
mosi_pin: GPIO32
miso_pin: GPIO39
color:
- id: my_red
red: 100%
green: 0%
blue: 0%
- id: my_blue
red: 33%
green: 47%
blue: 61%
- id: my_yellow
red: 95%
green: 97%
blue: 8%
- id: my_black
red: 0%
green: 0%
blue: 0%
image:
- file: mdi:garage
id: garage
resize: 220x220
- file: mdi:garage-open
id: garage_open
resize: 220x220
- file: mdi:walk
id: person
resize: 50x50
number:
- platform: template
name: "Timer Number"
id: timer_garage_is_unoccupied
optimistic: true
min_value: 9
max_value: 1430
step: 1
internal: false
script:
- id: timer
mode: restart
then:
- number.increment: timer_garage_is_unoccupied
- delay: 1min
- script.execute: timer
binary_sensor:
- platform: homeassistant
name: "Garage Door Open"
id: garage_door_open
entity_id: binary_sensor.garage_door_sensor ### My door open/closed sensor
internal: true
on_state:
then:
if:
condition:
binary_sensor.is_off: garage_door_open
then:
- binary_sensor.template.publish:
id: garage_door_open_for_10_minutes
state: off
- binary_sensor.template.publish:
id: garage_motion_is_stagnant
state: off
else:
- delay: 10min
- if:
condition:
for:
time: 10min
condition:
binary_sensor.is_on: garage_door_open
then:
- binary_sensor.template.publish:
id: garage_door_open_for_10_minutes
state: on
- platform: homeassistant
name: "Garage Motion"
id: garage_motion
entity_id: binary_sensor.motion_inside_garage
internal: true
on_state:
then:
if:
condition:
binary_sensor.is_on: garage_motion
then:
- binary_sensor.template.publish:
id: no_motion_for_10_minutes
state: off
- binary_sensor.template.publish:
id: garage_motion_is_stagnant
state: off
else:
- delay: 10min
- if:
condition:
for:
time: 10min
condition:
binary_sensor.is_off: garage_motion
then:
- binary_sensor.template.publish:
id: no_motion_for_10_minutes
state: on
else:
- binary_sensor.template.publish:
id: no_motion_for_10_minutes
state: off
- platform: template
name: "Garage Door Button"
id: garage_door_button_binary_sensor
- platform: template
name: "Garage Motion Is Stagnant"
id: garage_motion_is_stagnant
internal: false
on_state:
then:
if:
condition:
binary_sensor.is_on: garage_motion_is_stagnant
then:
- script.execute: timer
else:
- script.stop: timer
- number.set:
id: timer_garage_is_unoccupied
value: 9
- platform: template
name: "Garage Door Open For 10 Minutes"
id: garage_door_open_for_10_minutes
internal: true
on_state:
then:
if:
condition:
binary_sensor.is_on: no_motion_for_10_minutes
then:
- binary_sensor.template.publish:
id: garage_motion_is_stagnant
state: on
- platform: template
name: "No Motion For 10 Minutes"
id: no_motion_for_10_minutes
internal: true
on_state:
then:
if:
condition:
binary_sensor.is_on: garage_door_open_for_10_minutes
then:
- binary_sensor.template.publish:
id: garage_motion_is_stagnant
state: on
- platform: template
name: Screen_Touch
id: screen_touch
internal: False
lambda: |-
auto touch = id(my_touchscreen)->get_touch();
if (id(touch).state > 0) {
return true;
} else {
return false;
}
text_sensor:
- platform: homeassistant
id: garage_door_status
entity_id: sensor.garage_door_esp32_garage_door_opening_open_closing_closed
internal: true
button:
- platform: template
name: Garage Door Touchscreen ESP32 Button
id: garage_door_touchscreen_esp32_button
internal: true
on_press:
then:
- lambda: |-
id(garage_door_button_binary_sensor).publish_state(true);
- delay: 0.5s
- lambda: |-
id(garage_door_button_binary_sensor).publish_state(false);
font:
- file: "https://github.com/pjobson/Microsoft-365-Fonts/raw/main/S/Segoe%20UI%20Black.ttf"
id: segoe_ui_black_font
size: 40
display:
- platform: ili9xxx
model: tft 2.4
spi_id: tft
cs_pin: GPIO15
dc_pin: GPIO2
rotation: 90
id: cyd
lambda: |-
if (id(garage_door_open).state) {{{
if (id(garage_motion_is_stagnant).state) {{
it.image(50, 0, id(garage_open), id(my_red));
it.printf(160, 210, (segoe_ui_black_font), my_red, TextAlign::CENTER, "%.0f Minutes", id(timer_garage_is_unoccupied).state);
}} else {{
it.image(50, 0, id(garage_open), id(my_yellow));
it.print(160, 210, (segoe_ui_black_font), my_yellow, TextAlign::CENTER, id(garage_door_status).state.c_str());
if (id(garage_motion).state) {
it.image(140, 140, id(person), id(my_yellow));
} else {
;
}
}}
}}} else {{{
it.image(50, 0, id(garage), id(my_blue));
it.print(160, 210, (segoe_ui_black_font), my_blue, TextAlign::CENTER, "CLOSED");
if (id(garage_motion).state) {
it.image(140, 140, id(person), id(my_black));
} else {
;
}
}}}
touchscreen:
- platform: xpt2046
id: my_touchscreen
display: cyd
spi_id: touch
cs_pin: GPIO33
interrupt_pin: GPIO36
update_interval: 50ms
transform:
mirror_x: false
mirror_y: false
swap_xy: false
calibration:
x_max: 320
y_max: 240
on_touch:
then:
- light.turn_on:
id: backlight
brightness: 100%
- delay: 0.5s
- if:
condition:
- binary_sensor.is_on: screen_touch
then:
- light.turn_on:
id: garage_door_touchscreen_esp32_rear_led
red: 0%
green: 75%
blue: 100%
- button.press: garage_door_touchscreen_esp32_button
- delay: 1.5s
- light.dim_relative:
id: garage_door_touchscreen_esp32_rear_led
relative_brightness: -100%
transition_length: 1s
on_release:
then:
- light.turn_on:
id: backlight
brightness: 75%
output:
- platform: ledc
pin: GPIO21
id: backlight_pwm
- platform: ledc
pin: GPIO4
id: led_red
inverted: true
- platform: ledc
pin: GPIO16
id: led_green
inverted: true
- platform: ledc
pin: GPIO17
id: led_blue
inverted: true
light:
- platform: monochromatic
output: backlight_pwm
name: "Display Backlight"
id: backlight
restore_mode: ALWAYS_ON
internal: True
on_turn_on:
then:
- light.turn_on:
id: backlight
brightness: 75%
red: 100%
green: 100%
blue: 1.0
- platform: rgb
name: "Rear LED"
id: garage_door_touchscreen_esp32_rear_led
restore_mode: ALWAYS_OFF
red: led_red
green: led_green
blue: led_blue
internal: True
Edit:
Here is the yaml for the Open, Opening, Closing, Closed sensor, taken from the ESP32 that controls the relays for the garage door opener inside the garage. There might be an easier way to do this with lambda, but I’m not a lambda expert.
binary_sensor:
- platform: homeassistant
name: "Garage Door Sensor"
id: garage_door_sensor
entity_id: binary_sensor.garage_door_sensor ### My door open/closed sensor
internal: true
- platform: template
name: "Garage Door Malfunction"
id: garage_door_malfunction
### When this is On HA will notify me that the door has malfunctioned
button:
- platform: template
name: Garage Door Button
id: garage_door_button
icon: "mdi:garage"
on_press:
then:
- switch.turn_on: garage_door_button_switch
- if:
condition:
- binary_sensor.is_off: garage_door_sensor
then:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: OPENING
- delay: 9s
- if:
condition:
- binary_sensor.is_on: garage_door_sensor
then:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: OPEN
else:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: CLOSED
- delay: 9s
- if:
condition:
- binary_sensor.is_on: garage_door_sensor
then:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: OPEN
else:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: CLOSED
- binary_sensor.template.publish:
id: garage_door_malfunction
state: On
- delay: 60s
- binary_sensor.template.publish:
id: garage_door_malfunction
state: Off
else:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: CLOSING
- wait_until:
condition:
binary_sensor.is_off: garage_door_sensor
timeout: 11s
- if:
condition:
- binary_sensor.is_off: garage_door_sensor
then:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: CLOSED
else:
- text_sensor.template.publish:
id: garage_door_opening_open_closing_closed
state: OPEN
- binary_sensor.template.publish:
id: garage_door_malfunction
state: On
- delay: 60s
- binary_sensor.template.publish:
id: garage_door_malfunction
state: Off