Let Home Assistant automations switch Auto standby per screen, and teach the skill (0.2.48)
App 0.2.48 / firmware 0.2.41: - Both boards expose the switch "Auto standby", the same standby_enabled setting as the checkbox in ESP Screens. Off wakes a dimmed screen and keeps it on; on counts the standby time from that moment. The change is saved on the screen and reported through esphome.screen_setting, so ESP Screens stores it too. No action runs at boot (restore_mode DISABLED). - The Claude skill gains "Standby and brightness": the switch, Standby after and the three brightness numbers, with an example automation that keeps screens awake while someone is home and a light is on or a window is open. - EASY_SETUP and the README describe the entities and the automation. Tested through Home Assistant's API on both bench boards (CYD: dimmed -> off wakes in 1.1 s, stays bright past the standby time, on dims again after 61 s); see docs/TEST_RESULTS_0248.md, which also records a CYD rollback after the first OTA that points to memory headroom, not to this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -92,7 +92,8 @@ The firmware and built-in CLI are tested with **ESPHome 2026.6.2**.
|
||||
changed ("5 min ago", "Yesterday"). See [Top bar](#top-bar).
|
||||
- **Screen settings:** standby time, normal and dimmed brightness,
|
||||
night hours, 24- or 12-hour clock, return to the home page, and optional swiping
|
||||
between pages.
|
||||
between pages. Home Assistant automations can turn **Auto standby** off and on per
|
||||
screen (firmware 0.2.41+), for example to keep a screen on while someone is home.
|
||||
- **Guition rotation:** 0°, 90°, 180°, or 270°, directly from the management page.
|
||||
Native LVGL rotation turns the display and touch together. The CYD keeps its fixed
|
||||
orientation and its own calibration.
|
||||
|
||||
@@ -238,6 +238,41 @@ After this, changes to these settings don't need a new firmware flash.
|
||||
| Swipe between pages | Native horizontal swipe, firmware 0.2.7+ | Off |
|
||||
| Guition rotation | 0°, 90°, 180°, 270°, firmware 0.2.9+ | 0° |
|
||||
|
||||
Home Assistant shows the same settings on each screen's ESPHome device: the switch
|
||||
**Auto standby** (firmware 0.2.41+) and the numbers **Standby after**, **Normal brightness**,
|
||||
**Standby brightness** and **Night brightness**. Changing them there, for example from an
|
||||
automation, also changes them in ESP Screens and keeps them after a restart. Turning Auto
|
||||
standby off wakes the screen and keeps it on; turning it on counts the standby time from
|
||||
that moment. To keep a screen on while someone is home and a light is on:
|
||||
|
||||
```yaml
|
||||
alias: Keep the kitchen screen awake
|
||||
mode: restart
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: [person.alex, light.living_room]
|
||||
actions:
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: person.alex
|
||||
state: home
|
||||
- condition: state
|
||||
entity_id: light.living_room
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.kitchen_screen_auto_standby
|
||||
else:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.kitchen_screen_auto_standby
|
||||
```
|
||||
|
||||
Every change is saved on the screen, so switch on changes that happen a few times a day,
|
||||
not on every motion. ESP Screens → Settings → Claude installs a skill that writes such
|
||||
automations for you.
|
||||
|
||||
Night hours use the ESPHome device's timezone and the time from HA.
|
||||
Without a valid time, the screen uses the regular standby brightness; matching
|
||||
start and end times turn the night window off. At 0%, only the
|
||||
|
||||
@@ -176,6 +176,20 @@ icons sit off-center in the browser); run `generate_packages.py` afterward.
|
||||
The `MDI_GLYPH_*` substitutions are retired: `TILEn_ICON` in manual
|
||||
profiles must come from the set. No changed preferences or keys.
|
||||
|
||||
### Compatibility 0.2.48 / firmware 0.2.41
|
||||
|
||||
Storage, protocol, preferences and keys are unchanged.
|
||||
|
||||
- Both profiles add a template switch `setting_auto_standby` ("Auto standby", entity category config,
|
||||
`restore_mode: DISABLED`, state from `screen_settings::current.standby_enabled` through its lambda).
|
||||
Its actions change `standby_enabled`, save the settings preference, send the existing
|
||||
`esphome.screen_setting` event (`standby_enabled`, 1/0; the app already stores bool settings from it)
|
||||
and run `apply_screen_settings`, which wakes a dimmed screen when standby is off. Turning it on sets
|
||||
`last_touch_ms`, so the standby time counts from then.
|
||||
- `claude_skill.text()` gains "Standby and brightness" (the switch, the four numbers, an example
|
||||
automation); `core.AUTO_STANDBY_MIN_FIRMWARE` is 0.2.41. The skill description stays under 200 bytes.
|
||||
An installed skill shows as outdated until it is installed again.
|
||||
|
||||
### Compatibility 0.2.47 / firmware 0.2.40
|
||||
|
||||
Firmware and board profiles; the app only raises `FIRMWARE_VERSION`. Storage, protocol, preferences and
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Test results app 0.2.48 / firmware 0.2.41 (2026-09-15)
|
||||
|
||||
The Auto standby switch for Home Assistant automations and the standby section of the Claude skill.
|
||||
See CHANGELOG 0.2.48 and RELEASING "Compatibility 0.2.48".
|
||||
|
||||
## Automated
|
||||
|
||||
- Python (`.venv-portal`): 170 tests OK; `tests/test_claude_skill.py` checks the new section (the
|
||||
switch, the four numbers, the minimum firmware, the intro link) and parses the new example
|
||||
automation (five YAML blocks), including that it triggers on every entity its condition reads.
|
||||
- C++ (`clang++ -std=c++17 -Wall -Wextra -Werror -I . -I components/smart_display`): 13/13 PASS.
|
||||
- `generate_packages.py --check` green, `generate_icons.py --check` verified.
|
||||
- ESPHome 2026.6.2 compile SUCCESS, one after another: `easy-cyd-device.yaml` (RAM 32.0%, flash
|
||||
78.6%), `easy-guition-device.yaml` (RAM 33.0%, flash 19.0%), `guition-device.yaml` (RAM 33.1%, flash 20.0%)
|
||||
and `device.yaml` (RAM 32.1%, flash 83.3%). Packages carry `SCREEN_FIRMWARE_VERSION` 0.2.41.
|
||||
|
||||
## Bench boards (OTA) and Home Assistant
|
||||
|
||||
Both boards run 0.2.41. The switch was driven only through Home Assistant's REST API, the way an
|
||||
automation does it, and watched through the backlight light entity and the app's inventory.
|
||||
|
||||
- CYD (standby after 60 s): the screen had dimmed to 55 %. `switch.turn_off` switched the entity off and
|
||||
brought the backlight to 100 % within 1.1 s; the app's stored settings showed `standby_enabled: false`.
|
||||
After 80 s without a touch the screen was still at 100 %. `switch.turn_on` switched it on and the screen
|
||||
dimmed again after 61 s. The stored setting returned to `true`.
|
||||
- Guition: `switch.turn_off` switched the entity off within 1.2 s and the screen stayed bright for 30 s;
|
||||
`switch.turn_on` switched it back on; the stored setting returned to `true`.
|
||||
|
||||
## Observed on the CYD, not caused by this release
|
||||
|
||||
- The first OTA of 0.2.41 crashed within its first minute and the bootloader rolled back to 0.2.40 by
|
||||
itself ("OTA rollback detected"). A second OTA of the same build booted, was marked successful and
|
||||
passed the test above without a restart.
|
||||
- Around the crash the CYD logged LVGL failing to allocate 13.8 KB layer buffers and a task watchdog
|
||||
reset with a backtrace in the API connection code. The CYD also restarted twice on 0.2.40 while a
|
||||
diagnostic script opened API connections every few seconds. Heap after the boot sync is about 70 KB.
|
||||
This points to the CYD's memory headroom under bursts (boot sync, several API clients, object
|
||||
opacity layers), not to the switch; a separate check of the CYD's LVGL layer use is due.
|
||||
|
||||
## Not tested / for the owner
|
||||
|
||||
- An automation of the owner's own that switches Auto standby over a day.
|
||||
- Installing the updated skill from Settings → Claude and letting Claude write the automation.
|
||||
+28
-1
@@ -1,7 +1,7 @@
|
||||
# Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911.
|
||||
# Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile.
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.40"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.41"
|
||||
# 0: no drift limit; LVGL decides, releasing inside the tile is a tap, leaving it is not
|
||||
# (like iOS). The CYD keeps a limit because its resistive panel jumps.
|
||||
TOUCH_MOVE_LIMIT_PX: "0"
|
||||
@@ -1933,6 +1933,33 @@ text_sensor:
|
||||
switch:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
# Auto standby, the same setting as the checkbox in ESP Screens (firmware 0.2.41+), so Home Assistant
|
||||
# automations can keep a screen on. Off wakes the screen and keeps it on; on counts the standby time
|
||||
# from that moment. Nothing runs at boot: the switch follows the saved setting.
|
||||
- platform: template
|
||||
id: setting_auto_standby
|
||||
name: "Auto standby"
|
||||
icon: "mdi:sleep"
|
||||
entity_category: config
|
||||
restore_mode: DISABLED
|
||||
lambda: return screen_settings::current.standby_enabled;
|
||||
turn_on_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
id(last_touch_ms) = millis();
|
||||
if (s.standby_enabled) return;
|
||||
s.standby_enabled = true;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 1);
|
||||
id(apply_screen_settings).execute();
|
||||
turn_off_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
if (!s.standby_enabled) return;
|
||||
s.standby_enabled = false;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 0);
|
||||
id(apply_screen_settings).execute();
|
||||
|
||||
# Two SPI buses used by the CYD:
|
||||
# - lcd: built-in display
|
||||
|
||||
+28
-1
@@ -57,7 +57,7 @@
|
||||
############################################################
|
||||
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.40"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.41"
|
||||
# A tap survives a finger that drifts up to this far (320 px over 58 mm: 1 cm); further is a swipe.
|
||||
TOUCH_MOVE_LIMIT_PX: "56"
|
||||
# Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not.
|
||||
@@ -2116,6 +2116,33 @@ text_sensor:
|
||||
switch:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
# Auto standby, the same setting as the checkbox in ESP Screens (firmware 0.2.41+), so Home Assistant
|
||||
# automations can keep a screen on. Off wakes the screen and keeps it on; on counts the standby time
|
||||
# from that moment. Nothing runs at boot: the switch follows the saved setting.
|
||||
- platform: template
|
||||
id: setting_auto_standby
|
||||
name: "Auto standby"
|
||||
icon: "mdi:sleep"
|
||||
entity_category: config
|
||||
restore_mode: DISABLED
|
||||
lambda: return screen_settings::current.standby_enabled;
|
||||
turn_on_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
id(last_touch_ms) = millis();
|
||||
if (s.standby_enabled) return;
|
||||
s.standby_enabled = true;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 1);
|
||||
id(apply_screen_settings).execute();
|
||||
turn_off_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
if (!s.standby_enabled) return;
|
||||
s.standby_enabled = false;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 0);
|
||||
id(apply_screen_settings).execute();
|
||||
|
||||
# Two SPI buses used by the CYD:
|
||||
# - lcd: built-in display
|
||||
|
||||
+28
-1
@@ -58,7 +58,7 @@
|
||||
############################################################
|
||||
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.40"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.41"
|
||||
# A tap survives a finger that drifts up to this far (320 px over 58 mm: 1 cm); further is a swipe.
|
||||
TOUCH_MOVE_LIMIT_PX: "56"
|
||||
# Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not.
|
||||
@@ -2047,6 +2047,33 @@ text_sensor:
|
||||
switch:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
# Auto standby, the same setting as the checkbox in ESP Screens (firmware 0.2.41+), so Home Assistant
|
||||
# automations can keep a screen on. Off wakes the screen and keeps it on; on counts the standby time
|
||||
# from that moment. Nothing runs at boot: the switch follows the saved setting.
|
||||
- platform: template
|
||||
id: setting_auto_standby
|
||||
name: "Auto standby"
|
||||
icon: "mdi:sleep"
|
||||
entity_category: config
|
||||
restore_mode: DISABLED
|
||||
lambda: return screen_settings::current.standby_enabled;
|
||||
turn_on_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
id(last_touch_ms) = millis();
|
||||
if (s.standby_enabled) return;
|
||||
s.standby_enabled = true;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 1);
|
||||
id(apply_screen_settings).execute();
|
||||
turn_off_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
if (!s.standby_enabled) return;
|
||||
s.standby_enabled = false;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 0);
|
||||
id(apply_screen_settings).execute();
|
||||
|
||||
# Two SPI buses used by the CYD:
|
||||
# - lcd: built-in display
|
||||
|
||||
+28
-1
@@ -2,7 +2,7 @@
|
||||
# Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911.
|
||||
# Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile.
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.40"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.41"
|
||||
# 0: no drift limit; LVGL decides, releasing inside the tile is a tap, leaving it is not
|
||||
# (like iOS). The CYD keeps a limit because its resistive panel jumps.
|
||||
TOUCH_MOVE_LIMIT_PX: "0"
|
||||
@@ -1864,6 +1864,33 @@ text_sensor:
|
||||
switch:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
# Auto standby, the same setting as the checkbox in ESP Screens (firmware 0.2.41+), so Home Assistant
|
||||
# automations can keep a screen on. Off wakes the screen and keeps it on; on counts the standby time
|
||||
# from that moment. Nothing runs at boot: the switch follows the saved setting.
|
||||
- platform: template
|
||||
id: setting_auto_standby
|
||||
name: "Auto standby"
|
||||
icon: "mdi:sleep"
|
||||
entity_category: config
|
||||
restore_mode: DISABLED
|
||||
lambda: return screen_settings::current.standby_enabled;
|
||||
turn_on_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
id(last_touch_ms) = millis();
|
||||
if (s.standby_enabled) return;
|
||||
s.standby_enabled = true;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 1);
|
||||
id(apply_screen_settings).execute();
|
||||
turn_off_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
if (!s.standby_enabled) return;
|
||||
s.standby_enabled = false;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_enabled", 0);
|
||||
id(apply_screen_settings).execute();
|
||||
|
||||
# Two SPI buses used by the CYD:
|
||||
# - lcd: built-in display
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.2.48 (firmware 0.2.41)
|
||||
|
||||
Keep a screen awake from a Home Assistant automation.
|
||||
|
||||
- **Auto standby in Home Assistant.** Every screen gets the switch **Auto standby**, the same setting as the checkbox in ESP Screens. Turn it off and a dimmed screen wakes at once and stays on; turn it on and the screen dims again after its standby time, counted from that moment. So an automation can keep the screens on while someone is home and the lights are on or a window is open. A change shows in ESP Screens too and is kept after a restart.
|
||||
- **The Claude skill knows it.** The skill under Settings → Claude now also covers standby and brightness: the Auto standby switch, Standby after and the three brightness numbers, with an example automation. Install it again from the Settings page to get the new version.
|
||||
- Firmware 0.2.41 for both boards; the app offers the update.
|
||||
|
||||
## 0.2.47 (firmware 0.2.40)
|
||||
|
||||
The new climate card comes to the Guition, with fan and swing right on the card.
|
||||
|
||||
@@ -13,12 +13,13 @@ import zipfile
|
||||
|
||||
import tile_icons
|
||||
from core import (ALERT_ENDINGS, ALERT_EVENT, ALERT_FALLBACK_ICON, ALERT_FIELDS, ALERT_LIMITS, ALERT_MAX_TIMEOUT,
|
||||
ALERT_MIN_FIRMWARE, ALERT_SUGGESTED_ICONS, BROADCAST_DISMISS, BROADCAST_SHOW, TILE_BACKGROUNDS)
|
||||
ALERT_MIN_FIRMWARE, ALERT_SUGGESTED_ICONS, AUTO_STANDBY_MIN_FIRMWARE, BROADCAST_DISMISS, BROADCAST_SHOW,
|
||||
TILE_BACKGROUNDS)
|
||||
|
||||
NAME = 'esp-screens'
|
||||
# claude.ai accepts at most 200 characters; Claude Code picks the skill by this sentence.
|
||||
DESCRIPTION = ('Show alerts or notifications on ESP Screens (CYD and Guition touchscreens run from Home Assistant): '
|
||||
'all screens or one, now or in an automation, with the icons and colors they support.')
|
||||
DESCRIPTION = ('Alerts and standby on ESP Screens (CYD and Guition touchscreens run from Home Assistant): alerts on '
|
||||
'all screens or one with the icons they support, and an automation that keeps screens awake.')
|
||||
TYPES = {'string': 'text', 'int': 'number', 'bool': 'on/off'}
|
||||
|
||||
def skill_dir(config=None):
|
||||
@@ -31,7 +32,8 @@ def _limit(name, kind):
|
||||
return f'0 to {ALERT_MAX_TIMEOUT} s' if kind == 'int' else ''
|
||||
|
||||
def text():
|
||||
"""SKILL.md: when to use it, the event for every screen, the per-screen action, fields, colors and icons."""
|
||||
"""SKILL.md: when to use it, the event for every screen, the per-screen action, fields, colors and icons,
|
||||
then the standby and brightness entities every screen has in Home Assistant."""
|
||||
fields = '\n'.join(f'| `{name}` | {TYPES[kind]} | {help_} | {_limit(name, kind)} |' for name, kind, _, help_, _ in ALERT_FIELDS)
|
||||
colors = ', '.join(f"`{name}` ({item['label']})" for name, item in TILE_BACKGROUNDS.items() if item['color'])
|
||||
suggested = ', '.join(f'`{name}`' for name in ALERT_SUGGESTED_ICONS)
|
||||
@@ -43,10 +45,12 @@ name: {NAME}
|
||||
description: {DESCRIPTION}
|
||||
---
|
||||
|
||||
# Alerts on ESP Screens
|
||||
# Alerts and standby on ESP Screens
|
||||
|
||||
Made by ESP Screen Manager (ESP Screens → Settings → Claude). Installing it again from there replaces this file, so changes made here get lost.
|
||||
|
||||
Two things Home Assistant can do with the screens: show an alert (below), and keep a screen awake or let it dim ([Standby and brightness](#standby-and-brightness)).
|
||||
|
||||
An alert is a card over the whole screen with an icon, a title, a subtitle and one button. It wakes the screen and stays until someone presses the button or the timeout runs out. A new alert replaces the one showing.
|
||||
|
||||
## All screens: fire an event
|
||||
@@ -160,6 +164,56 @@ actions:
|
||||
sequence:
|
||||
- event: {BROADCAST_DISMISS}
|
||||
```
|
||||
|
||||
## Standby and brightness
|
||||
|
||||
Every screen has these entities in Home Assistant, on its ESPHome device. `<screen>` stands for the start Home Assistant gave the screen's entity IDs, the same as in `text.<screen>_tile_settings`; look them up rather than guessing.
|
||||
|
||||
| Entity | What it does |
|
||||
|---|---|
|
||||
| `switch.<screen>_auto_standby` | On: the screen dims after the standby time without a touch. Off: the screen wakes up and stays on. Firmware {AUTO_STANDBY_MIN_FIRMWARE} or newer. |
|
||||
| `number.<screen>_standby_after` | Seconds without a touch before standby, 60 to 86400. |
|
||||
| `number.<screen>_normal_brightness` | Brightness while in use, 5 to 100 %. |
|
||||
| `number.<screen>_standby_brightness` | Brightness in standby, 0 to 100 %, at most the normal brightness. |
|
||||
| `number.<screen>_night_brightness` | Brightness in standby during the night hours set in ESP Screens, 0 to 100 %. |
|
||||
|
||||
These are the same settings as in ESP Screens: a change made from Home Assistant shows there too and stays after a restart. Turning Auto standby on again counts the standby time from that moment. Every change is saved on the screen, so switch on changes that happen a few times a day (someone comes home, a light goes on, a window opens), never on every motion.
|
||||
|
||||
To keep screens on while something is going on at home, turn Auto standby off when the situation starts and on when it ends, all from one automation. Example with placeholders for the user's own entities:
|
||||
|
||||
```yaml
|
||||
alias: Keep the screens awake
|
||||
mode: restart
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id:
|
||||
- person.alex
|
||||
- light.living_room
|
||||
- binary_sensor.bedroom_window
|
||||
actions:
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: person.alex
|
||||
state: home
|
||||
- condition: or
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: light.living_room
|
||||
state: "on"
|
||||
- condition: state
|
||||
entity_id: binary_sensor.bedroom_window
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.kitchen_screen_auto_standby
|
||||
else:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.kitchen_screen_auto_standby
|
||||
```
|
||||
|
||||
Replace the person, light, window and screen with the real entity IDs (ask which screens when there are several), and leave out conditions the user did not ask for.
|
||||
'''
|
||||
|
||||
def status(directory):
|
||||
|
||||
@@ -17,7 +17,9 @@ WEEKDAYS = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
|
||||
REPO = 'https://github.com/MaxGramser/homeassistant_espscreen'
|
||||
REFS = {'cyd': 'main', 'guition': 'main'}
|
||||
# Firmware shipped with this app release; screens below it get an update offer.
|
||||
FIRMWARE_VERSION = '0.2.40'
|
||||
FIRMWARE_VERSION = '0.2.41'
|
||||
# The Auto standby switch a screen offers Home Assistant automations.
|
||||
AUTO_STANDBY_MIN_FIRMWARE = '0.2.41'
|
||||
ATTRS = frozenset('brightness percentage current_position current_temperature temperature current_humidity min_temp max_temp target_temp_step supported_color_modes hvac_modes hvac_action hs_color color_temp_kelvin min_color_temp_kelvin max_color_temp_kelvin fan_speed_list unit_of_measurement battery_level fan_speed volume_level is_volume_muted media_title options min max step temperature_unit supported_features device_class next_rising next_setting finishes_at duration remaining humidity wind_speed wind_speed_unit apparent_temperature fan_modes swing_modes fan_mode swing_mode'.split())
|
||||
# Attributes whose boolean value the screen needs; every other bool stays behind.
|
||||
BOOL_ATTRS = frozenset(['is_volume_muted'])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: ESP Screen Manager
|
||||
version: "0.2.47"
|
||||
version: "0.2.48"
|
||||
slug: esp_screen_manager
|
||||
description: Choose tiles for your CYD and Guition touchscreen, without reflashing.
|
||||
url: https://github.com/MaxGramser/homeassistant_espscreen
|
||||
|
||||
@@ -11,7 +11,7 @@ ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / 'screen_manager/app'))
|
||||
import claude_skill # noqa: E402
|
||||
import tile_icons # noqa: E402
|
||||
from core import ALERT_EVENT, ALERT_FIELDS, ALERT_LIMITS, ALERT_MIN_FIRMWARE, BROADCAST_DISMISS, BROADCAST_SHOW, TILE_BACKGROUNDS # noqa: E402
|
||||
from core import ALERT_EVENT, ALERT_FIELDS, ALERT_LIMITS, ALERT_MIN_FIRMWARE, AUTO_STANDBY_MIN_FIRMWARE, BROADCAST_DISMISS, BROADCAST_SHOW, TILE_BACKGROUNDS # noqa: E402
|
||||
|
||||
HAS_YAML = importlib.util.find_spec('yaml') is not None
|
||||
HAS_AIOHTTP = importlib.util.find_spec('aiohttp') is not None
|
||||
@@ -27,7 +27,7 @@ class SkillText(unittest.TestCase):
|
||||
self.assertIsNotNone(front)
|
||||
self.assertEqual(front[1], 'esp-screens')
|
||||
self.assertLessEqual(len(front[2]), 200, 'claude.ai refuses longer descriptions')
|
||||
for words in ('ESP Screens', 'alerts', 'all screens', 'automation', 'icons'):
|
||||
for words in ('ESP Screens', 'alerts', 'all screens', 'automation', 'icons', 'awake'):
|
||||
self.assertIn(words, front[2])
|
||||
self.assertEqual(text, claude_skill.text(), 'same text every time, so status() can compare')
|
||||
self.assertNotRegex(text, r'\{[A-Z_]+\}', 'no placeholder left over')
|
||||
@@ -44,6 +44,13 @@ class SkillText(unittest.TestCase):
|
||||
for name, item in TILE_BACKGROUNDS.items():
|
||||
if item['color']:
|
||||
self.assertIn(f'`{name}`', text)
|
||||
# Standby from automations (0.2.48): the switch, the numbers and when the switch arrived.
|
||||
standby = text.split('## Standby and brightness', 1)[1]
|
||||
for entity in ('switch.<screen>_auto_standby', 'number.<screen>_standby_after', 'number.<screen>_normal_brightness',
|
||||
'number.<screen>_standby_brightness', 'number.<screen>_night_brightness'):
|
||||
self.assertIn(f'`{entity}`', standby)
|
||||
self.assertIn(AUTO_STANDBY_MIN_FIRMWARE, standby)
|
||||
self.assertIn('(#standby-and-brightness)', text, 'the intro links to the section')
|
||||
icons = text.split('## Icons', 1)[1].split('## When an alert ends', 1)[0]
|
||||
self.assertEqual(set(re.findall(r'`([a-z0-9-]+)`', icons)) - {'icon'}, set(tile_icons.GLYPHS), 'exactly the glyphs the firmware carries')
|
||||
|
||||
@@ -51,7 +58,7 @@ class SkillText(unittest.TestCase):
|
||||
def test_every_yaml_example_parses(self):
|
||||
import yaml
|
||||
blocks = re.findall(r'```yaml\n(.*?)```', claude_skill.text(), re.S)
|
||||
self.assertEqual(len(blocks), 4)
|
||||
self.assertEqual(len(blocks), 5)
|
||||
parsed = [yaml.safe_load(block) for block in blocks]
|
||||
self.assertEqual(parsed[0]['actions'][0]['event'], BROADCAST_SHOW)
|
||||
self.assertEqual(set(parsed[0]['actions'][0]['event_data']), {name for name, *_ in ALERT_FIELDS})
|
||||
@@ -59,6 +66,14 @@ class SkillText(unittest.TestCase):
|
||||
self.assertEqual(parsed[2][0]['wait_for_trigger'][0]['event_type'], ALERT_EVENT)
|
||||
choose = parsed[3]['actions'][0]['choose']
|
||||
self.assertEqual([option['sequence'][0]['event'] for option in choose], [BROADCAST_SHOW, BROADCAST_DISMISS])
|
||||
awake = parsed[4]
|
||||
self.assertEqual(awake['mode'], 'restart')
|
||||
branch = awake['actions'][0]
|
||||
self.assertEqual((branch['then'][0]['action'], branch['else'][0]['action']), ('switch.turn_off', 'switch.turn_on'))
|
||||
self.assertTrue(branch['then'][0]['target']['entity_id'].endswith('_auto_standby'))
|
||||
watched = set(awake['triggers'][0]['entity_id'])
|
||||
conditions = {branch['if'][0]['entity_id']} | {c['entity_id'] for c in branch['if'][1]['conditions']}
|
||||
self.assertEqual(watched, conditions, 'the automation reacts to every entity its condition reads')
|
||||
|
||||
|
||||
class Archive(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user