Files
camera-jpg/doorbell-display.yaml
T

284 lines
7.0 KiB
YAML

# Waveshare ESP32-S3-Touch-LCD-4B — doorbell JPEG viewer
# Copy this file AND the components/ folder into your ESPHome config directory.
# Pair with the resizer proxy in this repo.
#
# Touch cycles: stream A (default) -> stream B -> off -> stream A ...
#
# Uses a custom fast_jpeg component (RGB565 block decode + DMA blit).
# Stock online_image JPEG is too slow for ~5 fps.
substitutions:
name: doorbell-display
friendly_name: Doorbell Display
stream_a_url: "http://10.0.1.195:8080/doorbell/?size=480"
stream_b_url: "http://10.0.1.195:8080/oprit/?size=480"
external_components:
- source:
type: local
path: components
esphome:
name: ${name}
friendly_name: ${friendly_name}
min_version: "2025.2.0"
on_boot:
- priority: 800
then:
- lambda: |-
auto *io = id(ext_io);
io->pin_mode(0, esphome::gpio::FLAG_OUTPUT);
io->pin_mode(1, esphome::gpio::FLAG_OUTPUT);
io->pin_mode(2, esphome::gpio::FLAG_OUTPUT);
io->pin_mode(7, esphome::gpio::FLAG_OUTPUT);
io->digital_write(0, true);
io->digital_write(1, false);
io->digital_write(2, false);
io->digital_write(7, false);
- delay: 120ms
- lambda: |-
id(ext_io)->digital_write(7, true);
- priority: 600
then:
- script.execute: activate_stream_a
- light.turn_on:
id: backlight
brightness: 100%
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
flash_size: 16MB
framework:
type: esp-idf
sdkconfig_options:
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: "y"
CONFIG_SPIRAM_RODATA: "y"
advanced:
include_builtin_idf_components:
- esp_http_client
psram:
mode: octal
speed: 80MHz
logger:
logs:
fast_jpeg: INFO
api:
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
i2c:
sda: GPIO47
scl: GPIO48
frequency: 400kHz
scan: true
pca9554:
- id: ext_io
address: 0x20
pin_count: 8
globals:
- id: touch_state
type: int
restore_value: false
initial_value: "0"
script:
- id: activate_stream_a
then:
- lambda: |-
id(touch_state) = 0;
id(doorbell_jpg).set_url("${stream_a_url}");
id(doorbell_jpg).set_enabled(true);
- id: deactivate_stream
then:
- lambda: |-
id(touch_state) = 2;
id(doorbell_jpg).set_enabled(false);
- id: cycle_stream
mode: restart
then:
- lambda: |-
id(touch_state) = (id(touch_state) + 1) % 3;
- if:
condition:
lambda: "return id(touch_state) == 0;"
then:
- script.execute: activate_stream_a
- light.turn_on:
id: backlight
brightness: 100%
- if:
condition:
lambda: "return id(touch_state) == 1;"
then:
- lambda: |-
id(doorbell_jpg).set_url("${stream_b_url}");
id(doorbell_jpg).set_enabled(true);
- light.turn_on:
id: backlight
brightness: 100%
- if:
condition:
lambda: "return id(touch_state) == 2;"
then:
- light.turn_off: backlight
spi:
- id: disp_spi
interface: software
clk_pin:
pca9554: ext_io
number: 2
mode:
output: true
mosi_pin:
pca9554: ext_io
number: 1
mode:
output: true
output:
- platform: ledc
id: backlight_pwm
inverted: true
pin: GPIO4
light:
- platform: monochromatic
id: backlight
name: "Backlight"
output: backlight_pwm
restore_mode: ALWAYS_ON
default_transition_length: 0s
on_turn_on:
- script.execute: activate_stream_a
on_turn_off:
- script.execute: deactivate_stream
# Simple on/off for Home Assistant automations (light still exposes brightness).
switch:
- platform: template
name: "Screen"
id: screen_power
icon: mdi:monitor
lambda: |-
return id(backlight).current_values.is_on();
turn_on_action:
- light.turn_on:
id: backlight
brightness: 100%
turn_off_action:
- light.turn_off: backlight
touchscreen:
- platform: gt911
id: touch
display: lcd
update_interval: 50ms
reset_pin:
pca9554: ext_io
number: 5
mode:
output: true
# INT is on the IO expander; used for address selection, polled for touches.
interrupt_pin:
pca9554: ext_io
number: 6
mode:
input: true
on_touch:
- script.execute: cycle_stream
display:
- platform: mipi_rgb
id: lcd
model: WAVESHARE-4-480x480
dimensions: 480x480
color_order: RGB
auto_clear_enabled: false
update_interval: never
spi_id: disp_spi
cs_pin:
pca9554: ext_io
number: 0
mode:
output: true
reset_pin:
pca9554: ext_io
number: 7
mode:
output: true
de_pin: GPIO17
hsync_pin:
number: GPIO46
ignore_strapping_warning: true
vsync_pin:
number: GPIO3
ignore_strapping_warning: true
pclk_pin: GPIO9
pclk_inverted: false
data_pins:
red: [GPIO10, GPIO11, GPIO12, GPIO13, GPIO14]
green: [GPIO21, GPIO8, GPIO18, GPIO45, GPIO38, GPIO39]
blue: [GPIO40, GPIO41, GPIO42, GPIO2, GPIO1]
init_sequence:
- [0xFF, 0x77, 0x01, 0x00, 0x00, 0x10]
- [0xC0, 0x3B, 0x00]
- [0xC1, 0x0D, 0x02]
- [0xC2, 0x21, 0x08]
- [0xCD, 0x08]
- [0xB0, 0x00, 0x11, 0x18, 0x0E, 0x11, 0x06, 0x07, 0x08, 0x07, 0x22, 0x04, 0x12, 0x0F, 0xAA, 0x31, 0x18]
- [0xB1, 0x00, 0x11, 0x19, 0x0E, 0x12, 0x07, 0x08, 0x08, 0x08, 0x22, 0x04, 0x11, 0x11, 0xA9, 0x32, 0x18]
- [0xFF, 0x77, 0x01, 0x00, 0x00, 0x11]
- [0xB0, 0x60]
- [0xB1, 0x30]
- [0xB2, 0x87]
- [0xB3, 0x80]
- [0xB5, 0x49]
- [0xB7, 0x85]
- [0xB8, 0x21]
- [0xC1, 0x78]
- [0xC2, 0x78]
- delay 20ms
- [0xE0, 0x00, 0x1B, 0x02]
- [0xE1, 0x08, 0xA0, 0x00, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x44, 0x44]
- [0xE2, 0x11, 0x11, 0x44, 0x44, 0xED, 0xA0, 0x00, 0x00, 0xEC, 0xA0, 0x00, 0x00]
- [0xE3, 0x00, 0x00, 0x11, 0x11]
- [0xE4, 0x44, 0x44]
- [0xE5, 0x0A, 0xE9, 0xD8, 0xA0, 0x0C, 0xEB, 0xD8, 0xA0, 0x0E, 0xED, 0xD8, 0xA0, 0x10, 0xEF, 0xD8, 0xA0]
- [0xE6, 0x00, 0x00, 0x11, 0x11]
- [0xE7, 0x44, 0x44]
- [0xE8, 0x09, 0xE8, 0xD8, 0xA0, 0x0B, 0xEA, 0xD8, 0xA0, 0x0D, 0xEC, 0xD8, 0xA0, 0x0F, 0xEE, 0xD8, 0xA0]
- [0xEB, 0x02, 0x00, 0xE4, 0xE4, 0x88, 0x00, 0x40]
- [0xEC, 0x3C, 0x00]
- [0xED, 0xAB, 0x89, 0x76, 0x54, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x45, 0x67, 0x98, 0xBA]
- [0xFF, 0x77, 0x01, 0x00, 0x00, 0x00]
- [0x36, 0x00]
- [0x3A, 0x66]
fast_jpeg:
id: doorbell_jpg
url: ${stream_a_url}
display_id: lcd
update_interval: 200ms
# If colours look swapped, set big_endian: false
big_endian: true