From d6e5b35dcf27d88eef07532ce81b713435ce1980 Mon Sep 17 00:00:00 2001
From: Max Gramser
Date: Wed, 16 Sep 2026 16:41:10 +0200
Subject: [PATCH] Add a card for blinds and curtains, and fix what Studio 1
showed after 0.2.57 (0.2.58)
A tap on a cover now opens a card like Home Assistant's own, in the style
of the climate and vacuum cards: a tall position slider on which the blind
hangs from the top, a tilt slider over slats for venetian blinds, and open,
stop and close keys. The key of the direction the cover moves is filled; a
key that cannot move it further is disabled and stays out of the keys the
card's tick enables. Sliders show their value while dragged and send it on
release. The card offers only what supported_features allows. A
battery-powered blind shows its battery at the top right: the app sends
the device's battery sensor as the extra the vacuum card uses, and adds
current_tilt_position to the attributes.
Checking Studio 1 after its update to firmware 0.2.49 found that a setting
number equal to its initial state 0 (night brightness 0 %) was never
published, so Home Assistant kept it unknown and ESP Screens could not
change it; apply_screen_settings now publishes a number without a state.
The app also took "unavailable" for the device name during the restart
and wrote sensor.esp_screens_unavailable; diagnostics ignore unknown and
unavailable. The editor redraws its tiles, top bar and entity list when
the live stream opened a screen before the first full inventory (a busy
add-on), and loads app.js and style.css by content stamp after Safari kept
an old script.
Checked with 254 Python and 14 C++ tests, generate_packages --check, ESP32
builds of both profiles, and 20 API checks of the card on host builds of
both boards. Firmware 0.2.50.
Co-Authored-By: Claude Opus 5
---
README.md | 14 +-
components/smart_display/runtime_model.h | 4 +-
components/smart_display/runtime_tiles.h | 169 ++++++++++++++++++++++-
components/smart_display/tile_controls.h | 59 +++++++-
docs/RELEASING.md | 31 +++++
docs/TEST_RESULTS_0258.md | 66 +++++++++
docs/images/cyd-blind.png | Bin 0 -> 55858 bytes
docs/images/guition-blind.png | Bin 0 -> 91500 bytes
docs/images/guition-curtains.png | Bin 0 -> 66811 bytes
docs/images/guition-garage.png | Bin 0 -> 57181 bytes
guition-4848s040.yaml | 21 +--
home-like-2432s028.yaml | 21 +--
packages/cyd.yaml | 21 +--
packages/guition.yaml | 21 +--
screen_manager/CHANGELOG.md | 11 ++
screen_manager/app/core.py | 39 ++++--
screen_manager/app/server.py | 24 ++--
screen_manager/app/static/app.js | 4 +
screen_manager/config.yaml | 2 +-
tests/test_cover_card.py | 138 ++++++++++++++++++
tests/test_editor_startup.py | 38 +++++
tests/test_page_assets.py | 43 ++++++
tests/test_screen_owned_settings.py | 7 +-
tests/test_tile_controls.cpp | 32 +++++
24 files changed, 696 insertions(+), 69 deletions(-)
create mode 100644 docs/TEST_RESULTS_0258.md
create mode 100644 docs/images/cyd-blind.png
create mode 100644 docs/images/guition-blind.png
create mode 100644 docs/images/guition-curtains.png
create mode 100644 docs/images/guition-garage.png
create mode 100644 tests/test_cover_card.py
create mode 100644 tests/test_editor_startup.py
create mode 100644 tests/test_page_assets.py
diff --git a/README.md b/README.md
index e838649..e08ade0 100644
--- a/README.md
+++ b/README.md
@@ -85,6 +85,10 @@ The firmware and built-in CLI are tested with **ESPHome 2026.6.2**.
uses are shown (app 0.2.46 / firmware 0.2.39).
Scenes, scripts, and buttons show when they last ran. A tile that's waiting on
Home Assistant shows a small spinner on a light overlay.
+- **Cover card** for blinds, curtains, shutters, and garage doors, like Home Assistant's own:
+ a tall position slider on which the blind hangs from the top, a tilt slider over slats for
+ venetian blinds, open, stop, and close, and the battery of a battery-powered blind
+ (such as Motionblinds). A cover shows only what it supports (app 0.2.58 / firmware 0.2.50).
- **Top bar per screen** (firmware 0.2.32+): the name on the left, up to six
items of your choice on the right: the time, an analog clock, the date, or an
entity from Home Assistant with an icon, such as temperature, humidity, power usage, a door
@@ -120,8 +124,14 @@ The firmware and built-in CLI are tested with **ESPHome 2026.6.2**.
-
-
+
+
+
+
+
+
+
+
Features depend on the capabilities Home Assistant reports for an entity.
diff --git a/components/smart_display/runtime_model.h b/components/smart_display/runtime_model.h
index 1f2fc2e..2966248 100644
--- a/components/smart_display/runtime_model.h
+++ b/components/smart_display/runtime_model.h
@@ -77,13 +77,15 @@ struct Extra {
std::vector choices;
std::string room;
bool charging = false;
+ // Cover (firmware 0.2.50+): the tilt of its slats, 0 closed to 100 open.
+ float tilt = NAN;
Choice *choice(char kind) { for (auto &c : choices) if (c.kind == kind) return &c; return nullptr; }
bool empty() const {
return hvac_modes.empty() && fan_modes.empty() && swing_modes.empty() && fan_mode.empty() && swing_mode.empty() &&
hvac_action.empty() && options.empty() && forecast.empty() && hours.empty() && std::isnan(wind) &&
std::isnan(feels) && wind_unit.empty() && sunrise.empty() && sunset.empty() && duration.empty() &&
remaining.empty() && !timer_end && media_title.empty() && fan_speeds.empty() && fan_speed.empty() &&
- choices.empty() && room.empty() && !charging;
+ choices.empty() && room.empty() && !charging && std::isnan(tilt);
}
};
// The Extra of a tile on the heap, copied along with the tile like an ordinary member.
diff --git a/components/smart_display/runtime_tiles.h b/components/smart_display/runtime_tiles.h
index e1f940c..a84eb7e 100644
--- a/components/smart_display/runtime_tiles.h
+++ b/components/smart_display/runtime_tiles.h
@@ -65,6 +65,8 @@ inline const char *weather_icon(const std::string &condition);
inline const char *weather_text(const std::string &condition);
inline std::string timer_text(const Tile &t);
inline std::string last_run_text(uint32_t epoch);
+inline const char *icon_for(const Tile &tile);
+inline void label(lv_obj_t *obj, const std::string &text);
inline int active_index = -1;
inline uint32_t last_received = 0;
// Seconds between the manager's full repeats; every layout message declares it (app
@@ -380,6 +382,7 @@ inline std::string receive(const std::string &payload) {
tile.brightness = number(a["brightness"]);
tile.percentage = number(a["percentage"]);
tile.position = number(a["current_position"]);
+ next.tilt = number(a["current_tilt_position"]);
tile.current = number(a["current_temperature"]);
tile.target = number(a["temperature"]);
tile.humidity = number(a["current_humidity"]);
@@ -581,6 +584,8 @@ inline lv_obj_t *detail_button(const char *text,int x,int y,int width,int height
if(cmd==21)action("media_player.media_previous_track",t.entity);
if(cmd==22)action("media_player.media_next_track",t.entity);
if(cmd>=30 && cmd<38 && cmd-30<(int)t.extra().options.size())action(t.domain()+".select_option",t.entity,"option",t.extra().options[cmd-30]);
+ // Cover keys: 70 + tile_controls::Command (open, stop, close and the tilt keys).
+ if(cmd>=70 && cmd<130){auto a=tile_controls::key_action(t,cmd-70);if(a.valid()&&t.domain()=="cover")action(a.service,t.entity,a.key,a.value);}
if(cmd==40)action(t.state=="active"?"timer.pause":"timer.start",t.entity);
if(cmd==41)action("timer.cancel",t.entity);
},LV_EVENT_SHORT_CLICKED,(void*)(intptr_t)command);
@@ -880,6 +885,159 @@ inline void render_vacuum_detail(Tile &t,bool large,int width,int height,int pad
detail_text(detail_root,smart?"The robot chooses suction and water":"Suction and water as set per room",x,y,w,text,LV_TEXT_ALIGN_CENTER,0x6B6B6B);
}
}
+// ---- Cover card (firmware 0.2.50+): Home Assistant's cover dialog in the style of the vacuum and climate cards ----
+// A tall slider per movement: the position as a blind hanging from the top (a fully open cover shows none of it)
+// and the tilt as a handle over slats, each with its value below, like Home Assistant's own sliders. Open, stop
+// and close as a row of pill keys under them; the key of the direction the cover moves is filled. A slider
+// sends its value when the finger lifts, and shows it while it moves.
+inline constexpr uint32_t COVER_ACCENT = 0x926BC7, COVER_TRACK = 0xEFE8F7, COVER_SLATS = 0xDDD0EF;
+inline lv_obj_t *cover_values[2]{};
+inline std::string cover_status_line(const Tile &t){return t.available()?tile_controls::cover_card_status(t):"Unavailable";}
+inline void cover_slider_event(lv_event_t *e){
+ auto *slider=lv_event_get_target_obj(e);auto code=lv_event_get_code(e);
+ const bool tilt=(uintptr_t)lv_event_get_user_data(e)==1;
+ if(code==LV_EVENT_VALUE_CHANGED){
+ // The range reaches past 0 and 1000 only to keep the handle inside the track.
+ int raw=lv_slider_get_value(slider);
+ if(raw<0||raw>1000){raw=std::clamp(raw,0,1000);lv_slider_set_value(slider,raw,LV_ANIM_OFF);}
+ int percent=(int)std::lround(raw/10.0f);
+ if(auto *value=cover_values[tilt?1:0])label(value,std::to_string(tilt?percent:100-percent)+"%");
+ return;
+ }
+ if(code!=LV_EVENT_RELEASED||detail_index>=model.count)return;
+ auto &t=model.tiles[detail_index];
+ if(!fresh()||!t.available()||!cyd::touch_guard.accept_slider(esphome::millis(),390+(tilt?1:0)))return;
+ int percent=(int)std::lround(std::clamp(lv_slider_get_value(slider),0,1000)/10.0f);
+ if(tilt)action("cover.set_cover_tilt_position",t.entity,"tilt_position",std::to_string(percent));
+ else action("cover.set_cover_position",t.entity,"position",std::to_string(100-percent));
+}
+// One slider. The position fills from the top by how far the cover is closed; the tilt has no fill and its
+// handle moves over slats drawn behind it, thicker towards the closed end as in Home Assistant.
+inline lv_obj_t *cover_slider(lv_obj_t *parent,int x,int y,int w,int h,float value,bool tilt){
+ int radius=std::max(8,w/7),handle_h=std::max(4,w/18),handle_w=tilt?w*3/5:w*2/5,inset=std::max(6,w/9);
+ if(tilt){
+ auto *slats=detail_shape(parent,x,y,w,h,COVER_TRACK,radius);
+ const int count=10,pitch=(h-2*radius/2)/count;
+ for(int i=0;i &keys,unsigned count,int x,int y,int w,int h,int gap,const lv_font_t *icons){
+ int key_w=count?(w-gap*((int)count-1))/(int)count:0;
+ for(unsigned i=0;i keys,tilt_keys;
+ unsigned key_count=card.keys?tile_controls::cover_keys(t,keys):0,tilt_count=card.tilt_keys?tile_controls::cover_tilt_keys(t,tilt_keys):0;
+ int rows=(key_count?1:0)+(tilt_count?1:0);
+ int keys_y=bottom-rows*key_h-(rows>1?gap:0),top=large?108:72;
+ int box_h=keys_y-gap-top;
+ if(card.position||card.tilt){
+ detail_card(pad,top,inner,box_h);
+ struct Part{bool tilt;float value;const char *caption;};
+ Part parts[2];int n=0;
+ if(card.position)parts[n++]={false,t.position,"Position"};
+ if(card.tilt)parts[n++]={true,t.extra().tilt,"Tilt"};
+ int value_h=lv_font_get_line_height(big),caption_h=lv_font_get_line_height(text);
+ auto percent=[](float value){return std::isfinite(value)?std::to_string((int)std::lround(std::clamp(value,0.0f,100.0f)))+"%":std::string("--");};
+ if(large){
+ // Columns: the slider with its value and name below.
+ int edge=16,slider_h=box_h-2*edge-value_h-caption_h+4,slider_w=n==2?120:140,column_gap=48;
+ int x=pad+(inner-(n*slider_w+(n-1)*column_gap))/2;
+ for(int i=0;i=model.count)return;detail_index=index;auto &t=model.tiles[index];
if(!detail_font)detail_font=lv_obj_get_style_text_font(widgets[0].title,LV_PART_MAIN);
@@ -895,8 +1053,8 @@ inline void show_detail(unsigned index){
const lv_font_t *title_font=watch_font?watch_font:detail_font;
auto *heading=detail_label(detail_root,t.name,bar_x+bar+8,bar_y+(bar-lv_font_get_line_height(title_font))/2,width-2*(bar_x+bar+8));
lv_obj_set_style_text_font(heading,title_font,0);lv_obj_set_height(heading,lv_font_get_line_height(title_font));lv_obj_set_style_text_align(heading,LV_TEXT_ALIGN_CENTER,0);
- std::string state=detail_state(t);
auto d=t.domain();
+ std::string state=d=="cover"?cover_status_line(t):detail_state(t);
// The vacuum card draws its own state (hero or status row) with the battery beside it.
if(d!="vacuum"){detail_status=detail_label(detail_root,state+(t.unit.empty()?"":" "+t.unit),pad,large?80:50,width-2*pad);lv_obj_set_style_text_align(detail_status,LV_TEXT_ALIGN_CENTER,0);lv_obj_set_style_text_color(detail_status,lv_color_hex(0x616161),0);}
if(t.is_switch()){
@@ -922,6 +1080,9 @@ inline void show_detail(unsigned index){
detail_actions[detail_action_count++]=detail_switch;
}else if(d=="vacuum"){
render_vacuum_detail(t,large,width,height,pad);
+ }else if(d=="cover"){
+ if(detail_status && control_font){lv_obj_set_style_text_font(detail_status,control_font,0);lv_obj_set_height(detail_status,lv_font_get_line_height(control_font));}
+ render_cover_detail(t,large,width,height,pad);
}else if(d=="sensor"){
float minimum=INFINITY,maximum=-INFINITY;for(float value:t.history)if(t.has_history&&std::isfinite(value)){minimum=std::min(minimum,value);maximum=std::max(maximum,value);}
if(!std::isfinite(minimum)){detail_label(detail_root,"No numeric HA history",pad,top,width-2*pad);return;}
@@ -1084,9 +1245,9 @@ inline void event(lv_event_t *event) {
if(d=="climate" && tile.tap=="toggle" && code==LV_EVENT_SHORT_CLICKED){action("climate.toggle",tile.entity);return;}
// A short tap runs or pauses the timer; holding opens the card with a cancel button.
if(d=="timer" && !open){action(tile.state=="active"?"timer.pause":"timer.start",tile.entity);return;}
- if(d=="sensor" || d=="binary_sensor" || d=="weather" || d=="number" || d=="input_number" || d=="select" || d=="input_select" || d=="media_player" || d=="vacuum" || d=="sun" || d=="person" || d=="timer") { tile.begin(esphome::millis(),true); active_index=w.index; show_detail(w.index); return; }
+ if(d=="sensor" || d=="binary_sensor" || d=="weather" || d=="number" || d=="input_number" || d=="select" || d=="input_select" || d=="media_player" || d=="vacuum" || d=="cover" || d=="sun" || d=="person" || d=="timer") { tile.begin(esphome::millis(),true); active_index=w.index; show_detail(w.index); return; }
if (open) {
- if (d == "light" || d == "climate" || d == "vacuum" || d == "fan" || d == "cover") {
+ if (d == "light" || d == "climate" || d == "vacuum" || d == "fan") {
active_index = w.index;
tile.begin(esphome::millis(),true);
if (detail) detail(tile);
@@ -2318,7 +2479,7 @@ inline void tick() {
if(detail_root && !lv_obj_has_flag(detail_root,LV_OBJ_FLAG_HIDDEN) && detail_index &out) {
+ unsigned n = 0;
+ const uint32_t f = t.supported ? t.supported : feature::COVER_OPEN | feature::COVER_STOP | feature::COVER_CLOSE;
+ bool sideways = sideways_cover(t.device_class);
+ bool fully_open = std::isfinite(t.position) ? t.position >= 99.5f : t.state == "open";
+ bool fully_closed = std::isfinite(t.position) ? t.position <= 0.5f : t.state == "closed";
+ if (f & feature::COVER_OPEN) out[n++] = Key{sideways ? glyph::EXPAND : glyph::UP, COVER_OPEN, "", t.state == "opening", fully_open && t.state != "closing"};
+ if (f & feature::COVER_STOP) out[n++] = Key{glyph::STOP, COVER_STOP, "", false, false};
+ if (f & feature::COVER_CLOSE) out[n++] = Key{sideways ? glyph::COLLAPSE : glyph::DOWN, COVER_CLOSE, "", t.state == "closing", fully_closed && t.state != "opening"};
+ return n;
+}
+inline unsigned cover_tilt_keys(const Tile &t, std::array &out) {
+ unsigned n = 0;
+ const float tilt = t.extra().tilt;
+ if (t.supported & feature::COVER_OPEN_TILT) out[n++] = Key{glyph::BLINDS_OPEN, COVER_OPEN_TILT, "", false, std::isfinite(tilt) && tilt >= 99.5f};
+ if (t.supported & feature::COVER_STOP_TILT) out[n++] = Key{glyph::STOP, COVER_STOP_TILT, "", false, false};
+ if (t.supported & feature::COVER_CLOSE_TILT) out[n++] = Key{glyph::BLINDS, COVER_CLOSE_TILT, "", false, std::isfinite(tilt) && tilt <= 0.5f};
+ return n;
+}
// The row of up to three pill keys for a key-row panel; returns how many.
inline unsigned keys_for(const Tile &t, std::array &out) {
auto d = t.domain(); auto c = panel_kind(t); unsigned n = 0;
@@ -161,12 +207,8 @@ inline unsigned keys_for(const Tile &t, std::array &out) {
if (n < out.size()) out[n++] = Key{icon, command, arg, checked, disabled};
};
if (c == "buttons" && d == "cover") {
- bool sideways = sideways_cover(t.device_class);
- bool fully_open = std::isfinite(t.position) ? t.position >= 99.5f : t.state == "open";
- bool fully_closed = std::isfinite(t.position) ? t.position <= 0.5f : t.state == "closed";
- if (t.supported & feature::COVER_OPEN) add(sideways ? glyph::EXPAND : glyph::UP, COVER_OPEN, fully_open && t.state != "closing");
- if (t.supported & feature::COVER_STOP) add(glyph::STOP, COVER_STOP);
- if (t.supported & feature::COVER_CLOSE) add(sideways ? glyph::COLLAPSE : glyph::DOWN, COVER_CLOSE, fully_closed && t.state != "opening");
+ // The tile keys are the card's keys, without the direction a moving cover shows there.
+ if (t.supported) for (unsigned i = 0, count = cover_keys(t, out); i < count; ++i) { out[i].checked = false; ++n; }
} else if (c == "buttons" && d == "vacuum") {
bool cleaning = t.state == "cleaning";
if (cleaning && (t.supported & feature::VACUUM_PAUSE)) add(glyph::PAUSE, VACUUM_PAUSE);
@@ -211,6 +253,9 @@ inline Action key_action(const Tile &t, int command, const std::string &arg = ""
case COVER_OPEN: return {"cover.open_cover", "", ""};
case COVER_STOP: return {"cover.stop_cover", "", ""};
case COVER_CLOSE: return {"cover.close_cover", "", ""};
+ case COVER_OPEN_TILT: return {"cover.open_cover_tilt", "", ""};
+ case COVER_STOP_TILT: return {"cover.stop_cover_tilt", "", ""};
+ case COVER_CLOSE_TILT: return {"cover.close_cover_tilt", "", ""};
case VACUUM_START: return {(t.supported & feature::VACUUM_START) ? "vacuum.start" : "vacuum.turn_on", "", ""};
case VACUUM_PAUSE: return {"vacuum.pause", "", ""};
case VACUUM_STOP: return {(t.supported & feature::VACUUM_STOP) ? "vacuum.stop" : "vacuum.turn_off", "", ""};
diff --git a/docs/RELEASING.md b/docs/RELEASING.md
index 657e9a3..ba07219 100644
--- a/docs/RELEASING.md
+++ b/docs/RELEASING.md
@@ -176,6 +176,37 @@ 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.58 / firmware 0.2.50
+
+App, both board profiles and `components/smart_display`. Storage, tile protocol, preferences and keys are
+unchanged; the state message gains one attribute and one extra key that older firmware ignores.
+
+- Cover card: `runtime_tiles::event` sends a tap on a cover to `show_detail`, like the other runtime cards, instead
+ of `detail()` (the board's value overlay in `cover_position` mode, which stays in the profiles for now). The
+ `preview_runtime_card` action of both profiles does the same. `render_cover_detail` draws what
+ `tile_controls::cover_card` offers from `supported_features` (position 4, tilt position 128, open/close/stop
+ 1/2/8, tilt open/close/stop 16/32/64; unknown features get the three keys): a vertical `lv_slider` per movement
+ in a white card, its value and name below it (beside it on the CYD), and a row of pill keys. The position
+ slider's range is reversed (1000 down to a stub below 0) so the fill hangs from the top by how far the cover is
+ closed; the tilt slider has a transparent fill, a margin past both ends for its handle, and slats drawn behind
+ it. Track and fill share one radius, so neither draws into a layer. A slider sends `cover.set_cover_position` or
+ `cover.set_cover_tilt_position` on RELEASED after `touch_guard.accept_slider`. Keys use detail commands
+ 70 + `tile_controls::Command` through `key_action`; a disabled key is left out of `detail_actions`, so the
+ card's second tick does not enable it again. The tick keeps `cover_status_line` ("Open · 60% · Tilt 40%").
+- `Extra::tilt` holds `current_tilt_position`; the app adds it to `ATTRS`. A cover's device battery travels as
+ the extra `bat` (and `chg`) the vacuum card introduced: `core.device_power` and `cover_related` pick the
+ device's `battery` and `battery_charging` sensors, `Manager.related_entities` watches them, and `tile_message`
+ passes the device entries for covers too. The card draws the battery at the top right with `vacuum_battery`.
+- `apply_screen_settings` publishes a setting number that has no state yet: `number::Number::state` starts at
+ 0, so a standby or night brightness of 0 never differed from it and Home Assistant kept "unknown". Seen on
+ Studio 1 (night brightness) after updating to 0.2.49.
+- `discover_screens` ignores `unknown` and `unavailable` in the diagnostic sensors: the device name pattern
+ accepted "unavailable" while a screen restarted, and `publish_layouts` wrote `sensor.esp_screens_unavailable`.
+- Editor: the first full inventory redraws the top bar, tiles and entity list when the live stream opened a
+ screen before the catalogue arrived. `index.html` is served with `?v=` on `static/app.js` and
+ `static/style.css`. The responses already carried `Cache-Control: no-store`, yet Safari showed an old script
+ with the new page after the update to 0.2.57.
+
### Compatibility 0.2.57 / firmware 0.2.49
App, both board profiles and `components/smart_display`. Storage version 1, tile protocol `v: 1`, preference
diff --git a/docs/TEST_RESULTS_0258.md b/docs/TEST_RESULTS_0258.md
new file mode 100644
index 0000000..8e200f1
--- /dev/null
+++ b/docs/TEST_RESULTS_0258.md
@@ -0,0 +1,66 @@
+# Test results app 0.2.58 / firmware 0.2.50 (2026-09-16)
+
+Max asked for a detail card for blinds (his three Motionblinds venetian blinds report every cover feature and a
+battery sensor on their device) in the style of the climate and vacuum cards. Checking Studio 1 twenty minutes
+after its update to 0.2.49 found two bugs, and opening ESP Screens during that update a third. See CHANGELOG
+0.2.58 and the compatibility note in docs/RELEASING.md.
+
+## Automated
+
+- Python (`.venv-portal`): 254 tests OK. New: `tests/test_cover_card.py` (the tilt and the device battery in
+ the state message, the battery sensor watched, no layout sensor or node name "unavailable" while a screen
+ restarts, the tap and preview routing to the cover card, commits on release, the tick's status line,
+ disabled keys kept out of the tick, one radius for track and fill, every setting number published when it
+ has no state), `tests/test_editor_startup.py` (the first full inventory redraws the tiles, top bar and
+ entity list) and `tests/test_page_assets.py` (script and styles by content stamp).
+- C++ (`clang++ -std=c++17 -Wall -Wextra -Werror -I. -I components/smart_display`): 14/14 PASS.
+ `test_tile_controls` adds the cover card: what a venetian blind (255), curtains (15), a garage door (11),
+ slats that tilt without a position (51) and a cover without features get, the status line with the tilt, keys filled while
+ moving and disabled at the ends, and the tilt actions.
+- `generate_packages.py --check` green.
+
+## Builds (ESPHome 2026.6.2)
+
+Check profiles with the generated packages and local components, the same as for 0.2.57.
+
+| Profile | RAM | Flash | vs 0.2.57 |
+|---|---|---|---|
+| CYD | 23.4% (76,548 B) | 76.9% (1,411,823 B) | +8 B RAM, +5,596 B flash |
+| Guition | 24.4% (79,924 B) | 18.6% (1,515,263 B) | +8 B RAM, +4,708 B flash |
+
+The first ESP32 build failed on `std::clamp(lv_slider_get_value(...), 0, 1000)`: `int32_t` is a `long` on the
+ESP32 toolchain, so the host builds cannot catch this. Fixed with `std::clamp` before any release.
+
+## Firmware on the Mac (host builds, driven over the ESPHome API)
+
+- Cover card, Guition 20/20 and CYD 20/20 (the CYD run three times): a venetian blind with the demo home's
+ state opens its card with "Open · 60% · Tilt 40%", both sliders and three keys; the position slider shows
+ 75% while it moves and sends `cover.set_cover_position` 75 on release, the tilt slider
+ `cover.set_cover_tilt_position` 80; open, stop and close send their actions; a closing state at 30 % redraws
+ the card with the close key filled, and the tick keeps the status line; fully open disables the open key
+ after the tick and a tap on it sends nothing; unavailable disables sliders and keys; curtains get one slider,
+ a garage door only keys with close disabled while closed, and its open key works; a tap on the blind's tile
+ opens the card; no errors in the log.
+- A timing flake in the first CYD run (a key pressed 1.2 s after Home Assistant's answer, while the card's
+ once-a-second tick still showed the keys disabled) was the test waiting too briefly; the card behaves as the
+ vacuum card does.
+- Renders of the blind, curtains and garage door cards on both boards; the README shows them.
+
+## Studio 1 after updating to 0.2.57 / firmware 0.2.49 (16:20, read-only through Home Assistant)
+
+- The update succeeded ("Updated to firmware 0.2.49"): one restart at 16:10, back online within seconds on the
+ same IP address, "Synced" within a second of reconnecting, no repairs, no add-on warnings; Home Assistant
+ lists `esphome.studio_1_screen_message` as answering.
+- Every setting entity had its value except `number.studio_1_night_brightness` ("unknown", so the panel showed
+ it as unknown and refused changes): the number fix above.
+- `sensor.esp_screens_unavailable` next to `sensor.esp_screens_studio_1`, written at the restart: the node fix
+ above. Home Assistant drops the stale sensor at its next restart.
+- An empty Screen settings panel in Safari was an old cached script (the served files matched the release);
+ the page now loads its files by content stamp.
+
+## Not tested / for the owner
+
+- Real hardware and real blinds: the Motionblinds were unavailable during this work. On Studio 1 after the
+ update: open a blind's card, drag both sliders and use the keys, check the battery, and that
+ `number.studio_1_night_brightness` has a value in Home Assistant.
+- Free heap on a CYD with the cover card open.
diff --git a/docs/images/cyd-blind.png b/docs/images/cyd-blind.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f2f29551f1e7adce73a514439281170140d0581
GIT binary patch
literal 55858
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