Show actual vacuum state when opening its detail card

This commit is contained in:
Max Gramser
2026-09-12 17:12:44 +02:00
parent f6efefc229
commit 732a220df5
10 changed files with 41 additions and 11 deletions
+1
View File
@@ -41,6 +41,7 @@ struct Tile {
uint32_t pending_since = 0;
bool pending = false, confirmed = false, local_feedback = false;
bool loading(uint32_t now) const { return pending && (now-pending_since < 1000 || (!confirmed && !local_feedback && now-pending_since < 6000)); }
bool awaiting_action(uint32_t now) const { return loading(now) && !local_feedback; }
void begin(uint32_t now, bool local=false) { pending=true; pending_since=now; confirmed=false; local_feedback=local; pending_revision=revision; }
void observe(const std::string &next) { revision=next; if (pending && revision!=pending_revision) confirmed=true; }
std::string domain() const { return entity.substr(0, entity.find('.')); }
+8 -5
View File
@@ -200,6 +200,7 @@ inline const lv_font_t *detail_font=nullptr;
inline lv_obj_t *detail_actions[16]{};
inline unsigned detail_action_count=0;
inline lv_obj_t *detail_status=nullptr;
inline lv_obj_t *detail_badge_status=nullptr;
inline lv_obj_t *detail_label(lv_obj_t *parent,const std::string &text,int x,int y,int width) {
auto *label=lv_label_create(parent);lv_label_set_text(label,text.c_str());lv_obj_set_pos(label,x,y);lv_obj_set_width(label,width);
lv_obj_set_style_text_font(label,detail_font,0);lv_obj_set_style_text_color(label,lv_color_hex(light_theme?0x202020:0xFFFFFF),0);
@@ -275,7 +276,7 @@ inline void show_detail(unsigned index){
if(index>=model.count)return;detail_index=index;auto &t=model.tiles[index];
if(!detail_font)detail_font=lv_obj_get_style_text_font(widgets[index].title,LV_PART_MAIN);
if(!detail_root){detail_root=lv_obj_create(lv_screen_active());lv_obj_remove_style_all(detail_root);lv_obj_set_size(detail_root,lv_pct(100),lv_pct(100));lv_obj_remove_flag(detail_root,LV_OBJ_FLAG_SCROLLABLE);}
detail_action_count=0;detail_status=nullptr;lv_obj_clean(detail_root);lv_obj_remove_flag(detail_root,LV_OBJ_FLAG_HIDDEN);lv_obj_move_foreground(detail_root);
detail_action_count=0;detail_status=nullptr;detail_badge_status=nullptr;lv_obj_clean(detail_root);lv_obj_remove_flag(detail_root,LV_OBJ_FLAG_HIDDEN);lv_obj_move_foreground(detail_root);
lv_obj_set_style_bg_color(detail_root,lv_color_hex(light_theme?0xE7E7E7:0x202A38),0);lv_obj_set_style_bg_opa(detail_root,LV_OPA_COVER,0);
int width=lv_display_get_horizontal_resolution(lv_display_get_default()), height=lv_display_get_vertical_resolution(lv_display_get_default());
bool large=width>=480;int pad=large?20:10, top=large?100:62, gap=large?12:6,bh=large?58:34,cw=(width-pad*2-gap)/2;
@@ -301,7 +302,8 @@ inline void show_detail(unsigned index){
shape(robot,29,59,26,5,0x00A6ED,3);
detail_label(hero,t.state=="cleaning"?"Aan het werk":t.state=="returning"?"Even opladen":t.state=="paused"?"Even pauze":"Klaar voor je huis",154,24,260);
auto *badge=shape(hero,154,59,240,32,muted,16);
auto *status=detail_label(badge,t.loading(esphome::millis())?"Opdracht verstuurd...":state,12,5,218);
auto *status=detail_label(badge,t.awaiting_action(esphome::millis())?"Opdracht verstuurd...":state,12,5,218);
detail_badge_status=status;
lv_obj_set_style_text_color(status,lv_color_hex(light_theme?0x087BA8:0xFFFFFF),0);
detail_label(hero,std::isfinite(t.battery)?"Batterij "+std::to_string((int)t.battery)+"%":"Verbonden via Home Assistant",154,107,260);
detail_button(t.state=="cleaning"?"Pauzeer schoonmaken":"Start schoonmaken",pad,260,width-2*pad,58,t.state=="cleaning"?1:0);
@@ -508,10 +510,11 @@ inline void render(lv_obj_t *room) {
}
inline void tick() {
if(detail_root && !lv_obj_has_flag(detail_root,LV_OBJ_FLAG_HIDDEN) && detail_index<model.count){
auto &t=model.tiles[detail_index];bool waiting=t.loading(esphome::millis())&&!t.local_feedback;
auto &t=model.tiles[detail_index];bool waiting=t.awaiting_action(esphome::millis());
for(unsigned i=0;i<detail_action_count;++i){if(waiting||!fresh()||!t.available())lv_obj_add_state(detail_actions[i],LV_STATE_DISABLED);else lv_obj_remove_state(detail_actions[i],LV_STATE_DISABLED);}
if(waiting && detail_status)lv_label_set_text(detail_status,t.confirmed?"Bevestigd door Home Assistant":"Opdracht verstuurd...");
else if(detail_status){std::string state=detail_state(t);lv_label_set_text(detail_status,(state+(t.unit.empty()?"":" "+t.unit)).c_str());}
std::string status=waiting?(t.confirmed?"Bevestigd door Home Assistant":"Opdracht verstuurd..."):detail_state(t);
if(detail_status)label(detail_status,status+(!waiting && !t.unit.empty()?" "+t.unit:""));
if(detail_badge_status)label(detail_badge_status,status);
}
if(!enabled)return;
bool redraw=false;
+22
View File
@@ -0,0 +1,22 @@
# Vacuumstatus 0.2.5
Een tegel openen gebruikt korte lokale feedback. Het statuslabel in de grote
vacuumkaart zag deze feedback ten onrechte als een echte opdracht en werd daarna
niet meer bijgewerkt. De kaart onderscheidt nu lokale feedback van een verstuurde
HA-actie. De kop en de statusbadge worden beide bijgewerkt: bij openen de actuele
status (bijvoorbeeld In dock), alleen na een opdracht de actiefeedback.
Gedeelde firmwarecorrectie voor Guition en CYD. Geen wijzigingen aan indelingen,
instellingen, opslagversie, voorkeurensleutels of paneelaansturing.
- 42 Python-tests en alle acht C++-regressieprogramma's geslaagd.
- Regressie voor lokale feedback versus echte acties en het verlopen van de
wachttijd toegevoegd aan de bestaande action-feedback-test.
- Gegenereerde pakketten met `--check` en Git-diff gecontroleerd.
- Alle vier ESPHome-builds geslaagd: Easy Setup en handmatige profielen van
Guition en CYD.
- Guition via OTA bijgewerkt; HA bevestigt firmware 0.2.5 en online-status.
- Vacuumkaart op de echte Guition via previewservice geopend, zonder HA-actie.
Interne LVGL-opname toont **In dock** in zowel de kop als de robotbadge.
Fysiek aantikken door de eigenaar is niet door deze preview vervangen.
- CYD niet aangesloten; alleen softwaretests en builds uitgevoerd.
+1 -1
View File
@@ -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.3"
SCREEN_FIRMWARE_VERSION: "0.2.5"
DYNAMIC_TILES: "false"
DASHBOARD_INBOX_INTERNAL: "true"
DEVICE_NAME: "guition-wallbox"
+1 -1
View File
@@ -58,7 +58,7 @@
############################################################
substitutions:
SCREEN_FIRMWARE_VERSION: "0.2.3"
SCREEN_FIRMWARE_VERSION: "0.2.5"
DYNAMIC_TILES: "false"
DASHBOARD_INBOX_INTERNAL: "true"
DEVICE_NAME: "cyd-new"
+1 -1
View File
@@ -59,7 +59,7 @@
############################################################
substitutions:
SCREEN_FIRMWARE_VERSION: "0.2.3"
SCREEN_FIRMWARE_VERSION: "0.2.5"
DYNAMIC_TILES: "true"
DASHBOARD_INBOX_INTERNAL: "false"
DEVICE_NAME: "cyd-new"
+1 -1
View File
@@ -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.3"
SCREEN_FIRMWARE_VERSION: "0.2.5"
DYNAMIC_TILES: "true"
DASHBOARD_INBOX_INTERNAL: "false"
DEVICE_NAME: "guition-new"
+4
View File
@@ -1,3 +1,7 @@
## 0.2.5
- Firmware: een vacuumkaart openen toont de echte status, geen opdrachtmelding. Het statuslabel in de robotkaart blijft ook na een actie actueel.
## 0.2.4
- Visuele tegelkiezer met domeiniconen, zachte kleuren en een klikbaar schermvoorbeeld van zes tegels per pagina. Selecteer een tegel om de instellingen te openen; sleep tegels in het voorbeeld om te ordenen. Geen firmware-update nodig.
+1 -1
View File
@@ -1,5 +1,5 @@
name: ESP Screen Manager
version: "0.2.4"
version: "0.2.5"
slug: esp_screen_manager
description: Kies tegels voor je CYD en Guition touchscreen, zonder opnieuw flashen.
url: https://github.com/MaxGramser/homeassistant_espscreen
+1 -1
View File
@@ -1,3 +1,3 @@
#include "components/smart_display/runtime_model.h"
#include <cassert>
int main(){runtime_tiles::Tile t;t.revision="off";t.begin(100);assert(t.loading(200));t.observe("off");assert(!t.confirmed);t.observe("on");assert(t.confirmed);assert(t.loading(999));assert(!t.loading(1100));t.begin(2000);t.observe("on");assert(t.loading(7999));assert(!t.loading(8000));t.begin(0xFFFFFFF0);assert(t.loading(20));t.begin(100,true);assert(t.loading(1099));assert(!t.loading(1100));}
int main(){runtime_tiles::Tile t;t.revision="off";t.begin(100);assert(t.loading(200));assert(t.awaiting_action(200));t.observe("off");assert(!t.confirmed);t.observe("on");assert(t.confirmed);assert(t.loading(999));assert(!t.loading(1100));t.begin(2000);t.observe("on");assert(t.loading(7999));assert(!t.loading(8000));assert(!t.awaiting_action(8000));t.begin(0xFFFFFFF0);assert(t.loading(20));t.begin(100,true);assert(t.loading(1099));assert(!t.awaiting_action(1099));assert(!t.loading(1100));}