8a587303d7
Override YAML on a screen edits <name>.local.yaml, a package loaded after the shared board package. New profiles get an empty one; an existing profile is attached on the first save without reformatting the file. The editor validates YAML, refuses the managed sections and substitutions, and Save & check runs ESPHome's full validation of the complete profile. The example uses !extend: ESPHome appends package lists instead of merging them by id, so a bare id added a second display without a platform and failed the build. An override is 12 KB at most and a too-large body answers as JSON instead of a bare 413. The sidecar is written before the profile includes it, and a symlinked sidecar is refused. Firmware stays 0.2.52. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
590 lines
26 KiB
HTML
590 lines
26 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<title>ESP Screens</title>
|
||
<link rel="stylesheet" href="static/style.css" />
|
||
<script src="static/app.js" defer></script>
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<div class="brand">
|
||
<span class="mark">▦</span>
|
||
<div>
|
||
<strong>ESP Screens</strong
|
||
><small>Tiles for your CYD and Guition, without reflashing</small>
|
||
</div>
|
||
</div>
|
||
<nav class="toolbar" aria-label="Actions">
|
||
<button id="open-settings" class="tool" type="button" aria-controls="settings-view">
|
||
<span class="tool-icon" id="open-settings-icon" aria-hidden="true">⚙</span>
|
||
<span class="tool-text"
|
||
><b id="open-settings-label">Settings</b
|
||
><small id="open-settings-hint">New screen, updates, alerts, Claude</small></span
|
||
>
|
||
</button>
|
||
</nav>
|
||
</header>
|
||
<main>
|
||
<div id="home-view">
|
||
<div class="intro">
|
||
<div>
|
||
<p class="eyebrow">HOME ASSISTANT</p>
|
||
<h1>Manage your remote screens here.</h1>
|
||
</div>
|
||
<span id="connection" role="status" class="badge">Connecting…</span>
|
||
</div>
|
||
<div class="workspace">
|
||
<aside>
|
||
<h2>My screens</h2>
|
||
<div id="screens"></div>
|
||
<div id="pending"></div>
|
||
<button class="quiet" id="refresh">↻ Refresh</button>
|
||
</aside>
|
||
<section id="empty" class="empty">
|
||
<span class="empty-icon">▦</span>
|
||
<h2>Start with a screen</h2>
|
||
<p>
|
||
Connect a CYD or Guition via USB to your Home Assistant machine.
|
||
Profile, firmware, and the first flash happen in one window.
|
||
</p>
|
||
<button id="start">Install new screen</button>
|
||
</section>
|
||
<section id="editor" hidden>
|
||
<div class="editor-head">
|
||
<div>
|
||
<p class="eyebrow" id="screen-name"></p>
|
||
<h2>Make it your screen</h2>
|
||
</div>
|
||
<div class="editor-head-actions">
|
||
<button id="open-override" class="quiet mini" type="button">Override YAML</button>
|
||
<span id="delivery" class="badge"></span>
|
||
</div>
|
||
</div>
|
||
<section class="topbar-editor" id="topbar" aria-labelledby="topbar-title">
|
||
<div class="section-title">
|
||
<h3 id="topbar-title">Top bar</h3>
|
||
<span id="topbar-count"></span>
|
||
</div>
|
||
<div class="topbar-fields">
|
||
<label class="topbar-name"
|
||
>Left: name<input
|
||
id="title"
|
||
maxlength="60"
|
||
placeholder="For example: Living room"
|
||
/></label>
|
||
<div class="topbar-right">
|
||
<span class="topbar-caption" id="topbar-caption">Right: time, sensors, or a clock</span>
|
||
<div
|
||
id="topbar-chips"
|
||
class="topbar-chips"
|
||
role="list"
|
||
aria-labelledby="topbar-caption"
|
||
></div>
|
||
</div>
|
||
</div>
|
||
<p class="hint" id="topbar-hint"></p>
|
||
</section>
|
||
<div class="columns" id="tile-section">
|
||
<div class="tile-editor">
|
||
<div class="section-title">
|
||
<h3>Your tiles</h3>
|
||
<span id="count">0 / 10</span>
|
||
</div>
|
||
<div id="layout-preview" aria-label="Screen layout"></div>
|
||
<button id="add-page" class="quiet add-page" type="button">
|
||
+ Add page
|
||
</button>
|
||
<p id="no-tiles" class="hint">
|
||
Add your first light, scene, or device via the picker.
|
||
</p>
|
||
<p id="positions-hint" class="hint" hidden></p>
|
||
</div>
|
||
<div class="picker">
|
||
<label for="search">Add an entity</label
|
||
><input
|
||
id="search"
|
||
type="search"
|
||
placeholder="Search by name, device, or room…"
|
||
autocomplete="off"
|
||
/>
|
||
<div class="filters" id="filters"></div>
|
||
<div id="results" aria-live="polite"></div>
|
||
</div>
|
||
</div>
|
||
<section class="screen-settings" id="general-settings" aria-labelledby="settings-heading">
|
||
<div class="section-title settings-title">
|
||
<h3 id="settings-heading">Screen settings</h3>
|
||
<span class="hint" id="settings-status" role="status"></span>
|
||
</div>
|
||
<div class="settings-cards" id="settings-groups"></div>
|
||
</section>
|
||
<details class="screen-settings" id="inspector-section">
|
||
<summary>
|
||
Inspector
|
||
<span class="hint"
|
||
>Connection, status, and supported properties</span
|
||
>
|
||
</summary>
|
||
<button id="inspect" class="quiet">Read current data</button>
|
||
<div id="inspection-summary"></div>
|
||
<pre id="inspection">Select a screen and read the data.</pre>
|
||
</details>
|
||
<footer class="savebar">
|
||
<div>
|
||
<strong id="dirty">All saved</strong
|
||
><small id="save-detail"
|
||
>Changes apply without reflashing.</small
|
||
>
|
||
</div>
|
||
<button id="save">Save & send to screen</button>
|
||
</footer>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
<section id="settings-view" class="settings-view" hidden aria-labelledby="settings-title">
|
||
<div class="intro">
|
||
<div>
|
||
<p class="eyebrow">SETTINGS</p>
|
||
<h1 id="settings-title">Everything around your screens.</h1>
|
||
</div>
|
||
<button type="button" class="quiet" id="close-settings">← My screens</button>
|
||
</div>
|
||
<div class="settings-groups">
|
||
<section class="settings-group" aria-labelledby="settings-screens-title">
|
||
<h2 id="settings-screens-title">Screens</h2>
|
||
<p class="hint">Add a screen, or build and reinstall the firmware of one you already have.</p>
|
||
<div class="settings-tools">
|
||
<button id="new-screen" class="tool tool-primary" type="button">
|
||
<span class="tool-icon" aria-hidden="true">+</span>
|
||
<span class="tool-text"
|
||
><b>New screen</b><small>Connect and install</small></span
|
||
>
|
||
</button>
|
||
<button id="open-firmware" class="tool" type="button">
|
||
<span class="tool-icon" aria-hidden="true">⇪</span>
|
||
<span class="tool-text"
|
||
><b>Firmware & USB</b
|
||
><small>Build and install via USB or Wi-Fi</small></span
|
||
>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
<section class="settings-group updates" id="updates" aria-labelledby="updates-title">
|
||
<h2 id="updates-title">Firmware updates</h2>
|
||
<p class="hint" id="updates-hint"></p>
|
||
<button id="update-all" hidden>Update all screens</button>
|
||
<label class="check">
|
||
<input type="checkbox" id="auto-update" />
|
||
<span
|
||
>Update automatically every night<small
|
||
>Between 03:00 and 06:00, one screen at a time. Stops on an
|
||
error and reports it in Home Assistant.</small
|
||
></span
|
||
>
|
||
</label>
|
||
</section>
|
||
<section class="settings-group" aria-labelledby="settings-alerts-title">
|
||
<h2 id="settings-alerts-title">Alerts</h2>
|
||
<p class="hint">
|
||
A card over the whole screen from an automation, on one screen or on all of them.
|
||
The cheatsheet has the action names, fields, icons, and colors.
|
||
</p>
|
||
<div class="settings-tools">
|
||
<button id="open-alerts" class="tool" type="button">
|
||
<span class="tool-icon" aria-hidden="true">!</span>
|
||
<span class="tool-text"
|
||
><b>Alerts</b
|
||
><small>Full-screen notifications, from an automation</small></span
|
||
>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
<section class="settings-group" id="claude" aria-labelledby="claude-title">
|
||
<h2 id="claude-title">Claude</h2>
|
||
<p class="hint">
|
||
Teach Claude about ESP Screens, then ask: "Show an alert on all my screens when the
|
||
mailbox is full." Claude knows the alert events, every field, color, and icon.
|
||
</p>
|
||
<div class="claude-skill">
|
||
<button type="button" id="claude-install">Install for Claude Code</button>
|
||
<span id="claude-status" class="hint" role="status"></span>
|
||
</div>
|
||
<small>
|
||
For Claude Code in Home Assistant. Writes one file to
|
||
<code id="claude-path">/homeassistant/.claude/skills/esp-screens</code>; installing
|
||
again replaces it.
|
||
</small>
|
||
<div class="claude-skill">
|
||
<a class="button again" id="claude-download" href="api/claude-skill.zip" download="esp-screens.zip">Download for claude.ai</a>
|
||
<small>Upload the zip in Claude under Customize → Skills.</small>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
<dialog id="installer">
|
||
<form id="install-form">
|
||
<div class="dialog-head">
|
||
<div>
|
||
<p class="eyebrow">NEW SCREEN</p>
|
||
<h2 id="install-title">Connect and install.</h2>
|
||
</div>
|
||
<button
|
||
type="button"
|
||
class="quiet"
|
||
id="close-install"
|
||
aria-label="Close"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
<div id="install-setup">
|
||
<p>
|
||
Connect the screen with a USB data cable to the machine running Home
|
||
Assistant. ESP Screens creates its own profile with unique
|
||
keys, builds the firmware, and puts it straight on the screen.
|
||
</p>
|
||
<fieldset>
|
||
<legend>Which screen do you have?</legend>
|
||
<label class="board"
|
||
><input type="radio" name="board" value="cyd" checked /><span
|
||
><b>CYD · 2.8 inch</b
|
||
><small>ESP32-2432S028 · 320 × 240</small></span
|
||
></label
|
||
><label class="board"
|
||
><input type="radio" name="board" value="guition" /><span
|
||
><b>Guition · 4 inch</b
|
||
><small>ESP32-S3-4848S040 · 480 × 480 · GT911</small></span
|
||
></label
|
||
>
|
||
</fieldset>
|
||
<label
|
||
>Name<input
|
||
name="friendly_name"
|
||
required
|
||
maxlength="60"
|
||
placeholder="Living room screen"
|
||
autocomplete="off" /><small class="node-line"
|
||
>Device name <code id="node-preview">screen</code
|
||
><button type="button" class="link" id="edit-node">
|
||
customize
|
||
</button></small
|
||
><small
|
||
>Every screen gets its own profile with its own keys. Four
|
||
screens? Go through this four times with a different name.</small
|
||
></label
|
||
>
|
||
<label id="node-label" hidden
|
||
>Device name<input
|
||
name="name"
|
||
pattern="[a-z][a-z0-9-]{0,29}"
|
||
maxlength="30"
|
||
autocomplete="off" /><small
|
||
>Lowercase letters, digits, and dashes. A different name for
|
||
each screen.</small
|
||
></label
|
||
>
|
||
<fieldset id="wifi-fields" class="wifi" hidden disabled>
|
||
<legend>Wi-Fi</legend>
|
||
<p class="hint" id="wifi-status"></p>
|
||
<label id="wifi-ssid-label"
|
||
>Wi-Fi name (2.4 GHz)<input name="wifi_ssid" autocomplete="off"
|
||
/></label>
|
||
<label id="wifi-password-label"
|
||
>Wi-Fi password<input
|
||
name="wifi_password"
|
||
type="password"
|
||
autocomplete="new-password"
|
||
/></label>
|
||
</fieldset>
|
||
<label
|
||
>Install via<select name="target" id="install-target"></select
|
||
><small id="target-hint"></small
|
||
></label>
|
||
<p class="hint" id="install-note"></p>
|
||
<div class="install-actions">
|
||
<button type="submit" id="install-go">Install</button>
|
||
<span id="install-status" role="status"></span>
|
||
</div>
|
||
</div>
|
||
<div id="install-progress" hidden>
|
||
<div class="progress-head">
|
||
<span class="spin" id="progress-spin"></span>
|
||
<span class="outcome" id="progress-mark" hidden></span>
|
||
<strong id="progress-title"></strong>
|
||
</div>
|
||
<p id="progress-detail"></p>
|
||
<div id="install-result" hidden>
|
||
<div class="key-box">
|
||
<span>API key</span><code id="api-key"></code>
|
||
<button type="button" class="mini" id="copy-key">Copy</button>
|
||
</div>
|
||
<ol class="steps" id="install-steps"></ol>
|
||
</div>
|
||
<details id="install-log-wrap">
|
||
<summary>ESPHome log</summary>
|
||
<pre id="install-log"></pre>
|
||
</details>
|
||
<div class="install-actions">
|
||
<button type="button" id="install-retry" hidden>
|
||
Retry
|
||
</button>
|
||
<button type="button" class="quiet" id="install-close">
|
||
Close
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
<dialog id="firmware-dialog">
|
||
<div class="dialog-head">
|
||
<div>
|
||
<p class="eyebrow">FIRMWARE & USB</p>
|
||
<h2>Build and install screen firmware</h2>
|
||
</div>
|
||
<button id="close-firmware" class="quiet" aria-label="Close">✕</button>
|
||
</div>
|
||
<p>
|
||
The built-in ESPHome CLI uses your own profile (YAML with keys)
|
||
and secrets. Choose the screen's profile, then a USB port (screen
|
||
connected to the Home Assistant machine) or <b>Wi-Fi / OTA</b> with the hostname.
|
||
<b>Check</b> only validates, <b>Build only</b> compiles,
|
||
<b>Build & install</b> puts the firmware on the screen. Your tiles
|
||
stay as they are in ESP Screens. The first build takes a few minutes.
|
||
</p>
|
||
<label>ESPHome profile<select id="firmware-file"></select></label>
|
||
<label
|
||
>Install to<select id="firmware-port">
|
||
<option value="ota">Wi-Fi / OTA</option>
|
||
</select></label
|
||
>
|
||
<label id="firmware-host-label"
|
||
>IP address or hostname<input
|
||
id="firmware-host"
|
||
placeholder="screen-livingroom.local"
|
||
/></label>
|
||
<div class="yaml-actions">
|
||
<button id="firmware-validate" class="quiet">Check</button
|
||
><button id="firmware-build" class="quiet">Build only</button
|
||
><button id="firmware-install">Build & install</button>
|
||
</div>
|
||
<p id="firmware-status" role="status"></p>
|
||
<pre id="firmware-log"></pre>
|
||
</dialog>
|
||
<dialog id="override-dialog" class="override-dialog" aria-labelledby="override-title">
|
||
<div class="dialog-head">
|
||
<div>
|
||
<p class="eyebrow">ADVANCED · LOCAL OVERRIDE</p>
|
||
<h2 id="override-title">Override YAML</h2>
|
||
</div>
|
||
<button id="close-override" class="quiet" type="button" aria-label="Close">✕</button>
|
||
</div>
|
||
<p class="override-intro">
|
||
This small file is yours. It is loaded after the shared screen package and stays in place when
|
||
ESP Screen Manager updates. Change hardware-specific details here, such as a display model.
|
||
</p>
|
||
<div class="override-notice">
|
||
<span class="override-icon" aria-hidden="true">⌘</span>
|
||
<div>
|
||
<strong>What is safe to change?</strong>
|
||
<span>Display, touchscreen, substitutions, pins and other device details. Name, Wi-Fi, API, OTA and package links remain managed.</span>
|
||
</div>
|
||
</div>
|
||
<div class="override-file-row">
|
||
<span id="override-file" class="override-file"></span>
|
||
<span id="override-state" class="badge"></span>
|
||
</div>
|
||
<div class="yaml-editor" id="yaml-editor-wrap">
|
||
<div id="override-gutter" class="yaml-gutter" aria-hidden="true">1</div>
|
||
<textarea id="override-editor" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off"
|
||
aria-label="Local override YAML" placeholder="# Example\ndisplay:\n - id: !extend my_display\n model: ST7789V"></textarea>
|
||
</div>
|
||
<div class="override-tools">
|
||
<button id="override-example" class="quiet mini" type="button">Use example</button>
|
||
<button id="override-empty" class="quiet mini" type="button">Clear</button>
|
||
<span id="override-count" class="hint"></span>
|
||
</div>
|
||
<p id="override-status" class="override-status" role="status"></p>
|
||
<div class="yaml-actions override-actions">
|
||
<button id="override-check" class="quiet" type="button">Save & check</button>
|
||
<button id="override-save" type="button">Save override</button>
|
||
</div>
|
||
</dialog>
|
||
<dialog id="tile-sheet" class="tile-sheet" aria-label="Configure tile"></dialog>
|
||
<dialog id="topbar-sheet" class="tile-sheet" aria-label="Top bar"></dialog>
|
||
<dialog id="alerts-dialog" class="alerts" aria-label="Alerts">
|
||
<div class="dialog-head">
|
||
<div>
|
||
<p class="eyebrow">ALERTS · CHEATSHEET</p>
|
||
<h2>A full-screen notification, from an automation.</h2>
|
||
</div>
|
||
<button id="close-alerts" class="quiet" aria-label="Close">✕</button>
|
||
</div>
|
||
<p>
|
||
Every screen has the <code>show_alert</code> action. It places a card over everything,
|
||
wakes the screen, and keeps the backlight at normal brightness until someone taps
|
||
the button or the timeout runs out. Home Assistant itself shows no explanation or
|
||
dropdowns for ESPHome actions; everything you can fill in is listed here.
|
||
</p>
|
||
<div class="alert-hero">
|
||
<div class="alert-mock" id="alert-mock" aria-hidden="true">
|
||
<div class="alert-mock-card">
|
||
<span class="mdi alert-mock-icon" id="alert-mock-icon"></span>
|
||
<strong id="alert-mock-title">Someone is at the door</strong>
|
||
<span id="alert-mock-subtitle">Door 3, back</span>
|
||
<button type="button" id="alert-mock-button" tabindex="-1">Coming</button>
|
||
</div>
|
||
</div>
|
||
<nav class="alerts-nav" aria-label="Sections">
|
||
<button type="button" data-jump="alerts-screens">Your screens</button>
|
||
<button type="button" data-jump="alerts-howto">In an automation</button>
|
||
<button type="button" data-jump="alerts-all">All screens</button>
|
||
<button type="button" data-jump="alerts-fields">The fields</button>
|
||
<button type="button" data-jump="alerts-icons">Icons</button>
|
||
<button type="button" data-jump="alerts-colors">Colors</button>
|
||
<button type="button" data-jump="alerts-behaviour">Behavior</button>
|
||
<button type="button" data-jump="alerts-events">Events</button>
|
||
<button type="button" data-jump="alerts-tips">Tips</button>
|
||
</nav>
|
||
</div>
|
||
<section id="alerts-screens">
|
||
<h3>Your screens</h3>
|
||
<p>
|
||
Every screen has its own action, with the device name in it. From firmware
|
||
<code id="alerts-min-firmware">0.2.31</code>; update an older screen with its
|
||
Update button under My screens.
|
||
</p>
|
||
<div id="alerts-screen-list"></div>
|
||
</section>
|
||
<section id="alerts-howto">
|
||
<h3>In an automation</h3>
|
||
<ol class="steps">
|
||
<li><b>Add action</b> and search for <b>ESPHome</b>. Choose your screen's action:
|
||
Home Assistant calls it "Performs the action show_alert of the node
|
||
<i>device name</i>".</li>
|
||
<li><b>Fill in the fields.</b> Home Assistant asks for all seven; leave what you don't
|
||
use empty (<code>""</code>, <code>0</code>, off).</li>
|
||
<li>Prefer YAML? Choose <b>Edit in YAML</b> on the action and paste the example
|
||
below.</li>
|
||
</ol>
|
||
<div class="alert-example">
|
||
<label
|
||
>Example for<select id="alerts-example-screen"></select
|
||
></label>
|
||
<div class="copy-line">
|
||
<pre id="alerts-example"></pre>
|
||
<button type="button" class="mini" id="alerts-example-copy">Copy YAML</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section id="alerts-all">
|
||
<h3>All screens at once</h3>
|
||
<p>
|
||
Fire the event <code id="alerts-all-event">esp_screens_show_alert</code> with the same
|
||
fields, and ESP Screens passes the alert on to every screen that is online, including
|
||
screens you add later. <code id="alerts-all-dismiss">esp_screens_dismiss_alert</code>
|
||
clears it everywhere. In an automation, add the <b>Event</b> action or paste the example
|
||
under <b>Edit in YAML</b>. Leave out the fields you don't use. ESP Screens has to be
|
||
running for this.
|
||
</p>
|
||
<div class="copy-line">
|
||
<pre id="alerts-all-example"></pre>
|
||
<button type="button" class="mini" id="alerts-all-copy">Copy YAML</button>
|
||
</div>
|
||
</section>
|
||
<section id="alerts-fields">
|
||
<h3>The fields</h3>
|
||
<p>
|
||
Text is free-form; the limit is in bytes, and an accented letter counts as two.
|
||
What doesn't fit gets an ellipsis (title) or is dropped (subtitle).
|
||
</p>
|
||
<div class="table-scroll"><table id="alerts-field-table"></table></div>
|
||
</section>
|
||
<section id="alerts-icons">
|
||
<h3>Icons</h3>
|
||
<p>
|
||
Fill in the name in <code>icon</code>, for example <code>doorbell</code>.
|
||
<code>mdi:doorbell</code> and the hex codepoint (<code>F12E6</code>) also work.
|
||
Only these icons are included in the firmware; any other name shows the
|
||
warning triangle. Tap an icon to copy its name.
|
||
</p>
|
||
<p class="alerts-subhead">Handy for notifications</p>
|
||
<div class="chips" id="alerts-suggested"></div>
|
||
<label class="alerts-search"
|
||
>Search for an icon<input
|
||
id="alerts-icon-search"
|
||
type="search"
|
||
placeholder="Search by name or description…"
|
||
autocomplete="off"
|
||
/></label>
|
||
<div id="alerts-icon-groups"></div>
|
||
</section>
|
||
<section id="alerts-colors">
|
||
<h3>Colors</h3>
|
||
<p>
|
||
Fill in the name in <code>color</code>. These are the pastel shades of the tiles,
|
||
with dark text. Empty or unknown gives the white card. Tap to copy.
|
||
</p>
|
||
<div class="swatches" id="alerts-swatches"></div>
|
||
</section>
|
||
<section id="alerts-behaviour">
|
||
<h3>Behavior</h3>
|
||
<ul class="alerts-list">
|
||
<li><b>Wakes the screen.</b> An alert immediately wakes a dimmed or dark screen and
|
||
appears above every page, every open light card, and the standby layer.</li>
|
||
<li><b>On until the button.</b> As long as the card is showing, the backlight stays at
|
||
normal brightness. Standby and night hours wait. After the button, the regular
|
||
standby time starts again.</li>
|
||
<li><b>Timeout.</b> <code>timeout: 0</code> waits for the button, however long that
|
||
takes. With <code>timeout: 60</code> the card disappears after a minute, but the
|
||
button closes it sooner.</li>
|
||
<li><b>Blinking.</b> <code>flash: true</code> blinks the backlight four times
|
||
when the alert arrives (about a second) and leaves the screen on afterward.</li>
|
||
<li><b>Replacing.</b> A new alert replaces the current one; there's no stack.
|
||
The replaced alert reports itself as <code>replaced</code>.</li>
|
||
<li><b>Closing remotely.</b> <code>dismiss_alert</code> clears the card,
|
||
for example if the door is already open. Without an alert, that action does nothing.</li>
|
||
<li><b>Tapping beside the card</b> does nothing; only the button closes it. That way a
|
||
wake-up tap never accidentally dismisses the alert.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="alerts-events">
|
||
<h3>Events</h3>
|
||
<p>
|
||
Every end fires the event <code id="alerts-event-name">esphome.screen_alert</code>
|
||
with <code>action</code>, <code>title</code>, <code>screen</code> (the device name)
|
||
and the <code>device_id</code> that Home Assistant adds. Visible under
|
||
Settings → Tools → Events.
|
||
</p>
|
||
<div class="table-scroll"><table id="alerts-ending-table"></table></div>
|
||
<p class="alerts-subhead">Waiting until someone presses the button</p>
|
||
<div class="copy-line">
|
||
<pre id="alerts-wait-example"></pre>
|
||
<button type="button" class="mini" id="alerts-wait-copy">Copy YAML</button>
|
||
</div>
|
||
</section>
|
||
<section id="alerts-tips">
|
||
<h3>Tips</h3>
|
||
<ul class="alerts-list">
|
||
<li>Use a <b>color per kind of notification</b>: orange for the door, red for
|
||
smoke or water, green for "done". The text always stays dark and readable.</li>
|
||
<li>Keep the title <b>short</b>; the CYD shows about forty characters on one line.
|
||
Put details in the subtitle.</li>
|
||
<li>A <b>custom button text</b> turns the notification into a question: "Coming", "Seen",
|
||
"Turn off". The event then tells you who responded.</li>
|
||
<li>For an alert that resolves itself (the door opens, the laundry gets taken out)
|
||
close it in the same automation with <code>dismiss_alert</code>.</li>
|
||
<li>Every screen? Fire <code>esp_screens_show_alert</code> once (see All screens at
|
||
once). The screens still work independently and each reports with its own
|
||
<code>screen</code>.</li>
|
||
<li>Rather <b>ask Claude</b> for the automation? Install the ESP Screens skill under
|
||
Settings → Claude.</li>
|
||
</ul>
|
||
</section>
|
||
</dialog>
|
||
<div id="toast" role="status" hidden></div>
|
||
</body>
|
||
</html>
|