2026-10-18 20:20:13 +02:00
|
|
|
from esphome import pins
|
|
|
|
|
import esphome.codegen as cg
|
|
|
|
|
from esphome.components import display
|
|
|
|
|
import esphome.config_validation as cv
|
|
|
|
|
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_PAGES
|
|
|
|
|
|
|
|
|
|
from . import el512_ns
|
|
|
|
|
|
|
|
|
|
DEPENDENCIES = ["esp32"]
|
|
|
|
|
|
|
|
|
|
CONF_VCLK_PIN = "vclk_pin"
|
|
|
|
|
CONF_VID_PIN = "vid_pin"
|
|
|
|
|
CONF_TVID_PIN = "tvid_pin"
|
|
|
|
|
CONF_HS_PIN = "hs_pin"
|
|
|
|
|
CONF_VS_PIN = "vs_pin"
|
|
|
|
|
CONF_ENABLE_PIN = "enable_pin"
|
|
|
|
|
CONF_LOW_POWER_PIN = "low_power_pin"
|
|
|
|
|
CONF_STILL_ALIVE_PAGE = "still_alive_page"
|
2026-10-18 23:29:12 +02:00
|
|
|
CONF_ANIMATED_PAGES = "animated_pages"
|
|
|
|
|
CONF_ANIMATION_INTERVAL = "animation_interval"
|
2026-10-18 20:20:13 +02:00
|
|
|
|
|
|
|
|
EL512Display = el512_ns.class_("EL512Display", display.DisplayBuffer)
|
|
|
|
|
|
|
|
|
|
# The signals are routed through the GPIO matrix, so any output-capable GPIO
|
|
|
|
|
# works; the defaults are the wiring in include/pins.h.
|
|
|
|
|
CONFIG_SCHEMA = cv.All(
|
|
|
|
|
display.FULL_DISPLAY_SCHEMA.extend(
|
|
|
|
|
{
|
|
|
|
|
cv.GenerateID(): cv.declare_id(EL512Display),
|
|
|
|
|
cv.Optional(CONF_VCLK_PIN, default=18): pins.internal_gpio_output_pin_number,
|
|
|
|
|
cv.Optional(CONF_VID_PIN, default=19): pins.internal_gpio_output_pin_number,
|
|
|
|
|
cv.Optional(CONF_TVID_PIN, default=21): pins.internal_gpio_output_pin_number,
|
|
|
|
|
cv.Optional(CONF_HS_PIN, default=22): pins.internal_gpio_output_pin_number,
|
|
|
|
|
cv.Optional(CONF_VS_PIN, default=23): pins.internal_gpio_output_pin_number,
|
|
|
|
|
cv.Optional(CONF_ENABLE_PIN): pins.internal_gpio_output_pin_number,
|
|
|
|
|
cv.Optional(CONF_LOW_POWER_PIN): pins.internal_gpio_output_pin_number,
|
|
|
|
|
# Page (from `pages:`) that plays the Portal end-credits show; its
|
|
|
|
|
# lambda should call it.draw_still_alive() via id(...).
|
|
|
|
|
cv.Optional(CONF_STILL_ALIVE_PAGE): cv.use_id(display.DisplayPage),
|
2026-10-18 23:29:12 +02:00
|
|
|
# Pages that redraw every animation_interval while shown; their
|
|
|
|
|
# lambdas can use id(...).page_age_ms() as the animation clock.
|
|
|
|
|
cv.Optional(CONF_ANIMATED_PAGES): cv.ensure_list(cv.use_id(display.DisplayPage)),
|
|
|
|
|
cv.Optional(
|
|
|
|
|
CONF_ANIMATION_INTERVAL, default="66ms"
|
|
|
|
|
): cv.positive_time_period_milliseconds,
|
2026-10-18 20:20:13 +02:00
|
|
|
}
|
|
|
|
|
).extend(cv.polling_component_schema("1s")),
|
|
|
|
|
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def to_code(config):
|
|
|
|
|
var = cg.new_Pvariable(config[CONF_ID])
|
|
|
|
|
await display.register_display(var, config)
|
|
|
|
|
|
|
|
|
|
cg.add(
|
|
|
|
|
var.set_pins(
|
|
|
|
|
config[CONF_VCLK_PIN],
|
|
|
|
|
config[CONF_VID_PIN],
|
|
|
|
|
config[CONF_TVID_PIN],
|
|
|
|
|
config[CONF_HS_PIN],
|
|
|
|
|
config[CONF_VS_PIN],
|
|
|
|
|
config.get(CONF_ENABLE_PIN, -1),
|
|
|
|
|
config.get(CONF_LOW_POWER_PIN, -1),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
if CONF_STILL_ALIVE_PAGE in config:
|
|
|
|
|
page = await cg.get_variable(config[CONF_STILL_ALIVE_PAGE])
|
|
|
|
|
cg.add(var.set_still_alive_page(page))
|
2026-10-18 23:29:12 +02:00
|
|
|
for page_id in config.get(CONF_ANIMATED_PAGES, []):
|
|
|
|
|
page = await cg.get_variable(page_id)
|
|
|
|
|
cg.add(var.add_animated_page(page))
|
|
|
|
|
cg.add(var.set_animation_interval(config[CONF_ANIMATION_INTERVAL].total_milliseconds))
|
2026-10-18 20:20:13 +02:00
|
|
|
if CONF_LAMBDA in config:
|
|
|
|
|
lambda_ = await cg.process_lambda(
|
|
|
|
|
config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
|
|
|
|
|
)
|
|
|
|
|
cg.add(var.set_writer(lambda_))
|