################################################################################ # chore-tracker-esphome.yaml (AUTO-GENERATED — edit chores_config.yaml) # Kids: Jordyn, Declan, Chloe # # HOME SCREEN BEHAVIOUR: # Red outline = chores incomplete # Solid green = all chores done # Resets to red automatically at midnight # # Hardware: Waveshare ESP32-S3-Touch-LCD-7 (800x480) ################################################################################ esphome: name: chore-tracker friendly_name: "Chore Tracker" on_boot: priority: -10 then: - light.turn_on: backlight - lvgl.page.show: page_home esp32: board: esp32-s3-devkitc-1 framework: type: esp-idf psram: mode: octal speed: 80MHz wifi: ssid: !secret wifi_ssid password: !secret wifi_password ap: ssid: "Chore Tracker Hotspot" password: "choretracker" captive_portal: logger: level: INFO api: encryption: key: !secret api_encryption_key ota: - platform: esphome password: !secret ota_password # ── I2C ─────────────────────────────────────────────────────────────────────── i2c: sda: 8 scl: 9 # ── CH422G IO Expander (controls LCD reset, touch reset, backlight) ─────────── ch422g: - id: ch422g_hub # ── Display ─────────────────────────────────────────────────────────────────── display: - platform: mipi_rgb model: ESP32-S3-TOUCH-LCD-7-800X480 id: main_display update_interval: never auto_clear_enabled: false reset_pin: ch422g: ch422g_hub number: 3 mode: output: true # ── Touchscreen ─────────────────────────────────────────────────────────────── touchscreen: platform: gt911 id: touch update_interval: 120ms reset_pin: ch422g: ch422g_hub number: 1 mode: output: true # ── Backlight ───────────────────────────────────────────────────────────────── output: - platform: template id: lcd_backlight_out type: binary write_action: - if: condition: lambda: return state; then: - switch.turn_on: lcd_backlight_raw else: - switch.turn_off: lcd_backlight_raw light: - platform: binary name: "Display Backlight" output: lcd_backlight_out id: backlight # ── Midnight reset ──────────────────────────────────────────────────────────── time: - platform: homeassistant id: ha_time on_time: - hours: 0 minutes: 0 seconds: 0 then: - lambda: |- id(reset_jordyn_chores).execute(); id(reset_declan_chores).execute(); id(reset_chloe_chores).execute(); - lvgl.page.show: page_home # ── Fonts (place files in /config/esphome/fonts/) ──────────────────────────── font: - file: "fonts/Nunito-Black.ttf" id: font_title size: 40 - file: "fonts/Nunito-ExtraBold.ttf" id: font_name size: 30 - file: "fonts/Nunito-Bold.ttf" id: font_med size: 22 - file: "fonts/Nunito-SemiBold.ttf" id: font_small size: 17 - file: "fonts/Nunito-SemiBold.ttf" id: font_tiny size: 13 # MDI icon font — used for chore icons and kid avatars - file: "fonts/materialdesignicons-webfont.ttf" id: font_mdi_large size: 48 bpp: 4 glyphs: 󰂨󰄛󰈙󰉥󰋣󰏧󰖸󰦩󰾞󱑷󱚠󱬥 - file: "fonts/materialdesignicons-webfont.ttf" id: font_mdi_small size: 32 bpp: 4 glyphs: 󰂨󰄛󰈙󰉥󰋣󰏧󰖸󰦩󰾞󱑷󱚠󱬥 # ── Switches — backlight raw + one per chore per kid ───────────────────────── switch: - platform: gpio id: lcd_backlight_raw name: "LCD Backlight Raw" restore_mode: ALWAYS_ON pin: ch422g: ch422g_hub number: 2 mode: output: true # ── Jordyn's chores ────────────────────────── - platform: template name: "Jordyn - Make Bed" id: jordyn_make_bed icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_jordyn_make_bed on_turn_off: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_jordyn_make_bed - platform: template name: "Jordyn - Brush Teeth" id: jordyn_brush_teeth icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_jordyn_brush_teeth on_turn_off: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_jordyn_brush_teeth - platform: template name: "Jordyn - Tidy Room" id: jordyn_tidy_room icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_jordyn_tidy_room on_turn_off: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_jordyn_tidy_room - platform: template name: "Jordyn - Homework" id: jordyn_homework icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_jordyn_homework on_turn_off: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_jordyn_homework - platform: template name: "Jordyn - Feed Dog" id: jordyn_feed_dog icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_jordyn_feed_dog on_turn_off: then: - script.execute: update_jordyn_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_jordyn_feed_dog # ── Declan's chores ────────────────────────── - platform: template name: "Declan - Make Bed" id: declan_make_bed icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_declan_make_bed on_turn_off: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_declan_make_bed - platform: template name: "Declan - Brush Teeth" id: declan_brush_teeth icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_declan_brush_teeth on_turn_off: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_declan_brush_teeth - platform: template name: "Declan - Set Table" id: declan_set_table icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_declan_set_table on_turn_off: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_declan_set_table - platform: template name: "Declan - Take Out Trash" id: declan_take_out_trash icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_declan_take_out_trash on_turn_off: then: - script.execute: update_declan_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_declan_take_out_trash # ── Chloe's chores ────────────────────────── - platform: template name: "Chloe - Make Bed" id: chloe_make_bed icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_chloe_make_bed on_turn_off: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_chloe_make_bed - platform: template name: "Chloe - Brush Teeth" id: chloe_brush_teeth icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_chloe_brush_teeth on_turn_off: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_chloe_brush_teeth - platform: template name: "Chloe - Water Plants" id: chloe_water_plants icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_chloe_water_plants on_turn_off: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_chloe_water_plants - platform: template name: "Chloe - Homework" id: chloe_homework icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_chloe_homework on_turn_off: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_chloe_homework - platform: template name: "Chloe - Tidy Room" id: chloe_tidy_room icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_chloe_tidy_room on_turn_off: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_chloe_tidy_room - platform: template name: "Chloe - Practice Piano" id: chloe_practice_piano icon: mdi:checkbox-marked-circle optimistic: true restore_mode: RESTORE_DEFAULT_OFF on_turn_on: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_on data: entity_id: switch.chore_tracker_chloe_practice_piano on_turn_off: then: - script.execute: update_chloe_ui - homeassistant.service: service: switch.turn_off data: entity_id: switch.chore_tracker_chloe_practice_piano # ── Sensors — reported to HA ───────────────────────────────────────────────── sensor: - platform: template name: "Jordyn Chores Done" id: jordyn_chores_done accuracy_decimals: 0 update_interval: 2s lambda: |- int done = 0; if (id(jordyn_make_bed).state) done++; if (id(jordyn_brush_teeth).state) done++; if (id(jordyn_tidy_room).state) done++; if (id(jordyn_homework).state) done++; if (id(jordyn_feed_dog).state) done++; return done; - platform: template name: "Declan Chores Done" id: declan_chores_done accuracy_decimals: 0 update_interval: 2s lambda: |- int done = 0; if (id(declan_make_bed).state) done++; if (id(declan_brush_teeth).state) done++; if (id(declan_set_table).state) done++; if (id(declan_take_out_trash).state) done++; return done; - platform: template name: "Chloe Chores Done" id: chloe_chores_done accuracy_decimals: 0 update_interval: 2s lambda: |- int done = 0; if (id(chloe_make_bed).state) done++; if (id(chloe_brush_teeth).state) done++; if (id(chloe_water_plants).state) done++; if (id(chloe_homework).state) done++; if (id(chloe_tidy_room).state) done++; if (id(chloe_practice_piano).state) done++; return done; # ── Scripts — reset + UI update ─────────────────────────────────────────────── script: - id: reset_jordyn_chores mode: single then: - lambda: |- id(jordyn_make_bed).turn_off(); id(jordyn_brush_teeth).turn_off(); id(jordyn_tidy_room).turn_off(); id(jordyn_homework).turn_off(); id(jordyn_feed_dog).turn_off(); - script.execute: update_jordyn_ui - id: update_jordyn_ui mode: single then: - lambda: |- int done = (id(jordyn_make_bed).state ? 1 : 0) + (id(jordyn_brush_teeth).state ? 1 : 0) + (id(jordyn_tidy_room).state ? 1 : 0) + (id(jordyn_homework).state ? 1 : 0) + (id(jordyn_feed_dog).state ? 1 : 0); int total = 5; char buf[24]; // Progress bar + label lv_bar_set_value(id(progress_bar_jordyn), done, LV_ANIM_ON); snprintf(buf, sizeof(buf), "%d / 5", done); lv_label_set_text(id(progress_label_jordyn), buf); // All-done message in sidebar lv_label_set_text(id(all_done_label_jordyn), done == total ? "All done!" : ""); // Home button: RED outline = incomplete, SOLID GREEN = all done if (done == total) { lv_obj_set_style_bg_opa(id(home_btn_jordyn), LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(id(home_btn_jordyn), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(home_btn_jordyn), 0, LV_PART_MAIN); lv_label_set_text(id(home_status_jordyn), "\u2713 all done!"); lv_obj_set_style_text_color(id(home_status_jordyn), lv_color_hex(0xFFFFFF), LV_PART_MAIN); } else { lv_obj_set_style_bg_opa(id(home_btn_jordyn), LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(id(home_btn_jordyn), lv_color_hex(0xFF4757), LV_PART_MAIN); lv_obj_set_style_border_width(id(home_btn_jordyn), 0, LV_PART_MAIN); snprintf(buf, sizeof(buf), "%d left", total - done); lv_label_set_text(id(home_status_jordyn), buf); lv_obj_set_style_text_color(id(home_status_jordyn), lv_color_hex(0xFF4757), LV_PART_MAIN); } // Card colours if (id(jordyn_make_bed).state) { lv_obj_set_style_bg_color(id(card_jordyn_make_bed), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_make_bed), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_make_bed), 3, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_make_bed), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_jordyn_make_bed), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_make_bed), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_make_bed), 2, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_make_bed), ""); } if (id(jordyn_brush_teeth).state) { lv_obj_set_style_bg_color(id(card_jordyn_brush_teeth), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_brush_teeth), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_brush_teeth), 3, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_brush_teeth), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_jordyn_brush_teeth), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_brush_teeth), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_brush_teeth), 2, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_brush_teeth), ""); } if (id(jordyn_tidy_room).state) { lv_obj_set_style_bg_color(id(card_jordyn_tidy_room), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_tidy_room), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_tidy_room), 3, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_tidy_room), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_jordyn_tidy_room), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_tidy_room), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_tidy_room), 2, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_tidy_room), ""); } if (id(jordyn_homework).state) { lv_obj_set_style_bg_color(id(card_jordyn_homework), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_homework), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_homework), 3, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_homework), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_jordyn_homework), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_homework), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_homework), 2, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_homework), ""); } if (id(jordyn_feed_dog).state) { lv_obj_set_style_bg_color(id(card_jordyn_feed_dog), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_feed_dog), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_feed_dog), 3, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_feed_dog), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_jordyn_feed_dog), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_jordyn_feed_dog), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_jordyn_feed_dog), 2, LV_PART_MAIN); lv_label_set_text(id(check_jordyn_feed_dog), ""); } - id: reset_declan_chores mode: single then: - lambda: |- id(declan_make_bed).turn_off(); id(declan_brush_teeth).turn_off(); id(declan_set_table).turn_off(); id(declan_take_out_trash).turn_off(); - script.execute: update_declan_ui - id: update_declan_ui mode: single then: - lambda: |- int done = (id(declan_make_bed).state ? 1 : 0) + (id(declan_brush_teeth).state ? 1 : 0) + (id(declan_set_table).state ? 1 : 0) + (id(declan_take_out_trash).state ? 1 : 0); int total = 4; char buf[24]; // Progress bar + label lv_bar_set_value(id(progress_bar_declan), done, LV_ANIM_ON); snprintf(buf, sizeof(buf), "%d / 4", done); lv_label_set_text(id(progress_label_declan), buf); // All-done message in sidebar lv_label_set_text(id(all_done_label_declan), done == total ? "All done!" : ""); // Home button: RED outline = incomplete, SOLID GREEN = all done if (done == total) { lv_obj_set_style_bg_opa(id(home_btn_declan), LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(id(home_btn_declan), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(home_btn_declan), 0, LV_PART_MAIN); lv_label_set_text(id(home_status_declan), "\u2713 all done!"); lv_obj_set_style_text_color(id(home_status_declan), lv_color_hex(0xFFFFFF), LV_PART_MAIN); } else { lv_obj_set_style_bg_opa(id(home_btn_declan), LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(id(home_btn_declan), lv_color_hex(0xFF4757), LV_PART_MAIN); lv_obj_set_style_border_width(id(home_btn_declan), 0, LV_PART_MAIN); snprintf(buf, sizeof(buf), "%d left", total - done); lv_label_set_text(id(home_status_declan), buf); lv_obj_set_style_text_color(id(home_status_declan), lv_color_hex(0xFF4757), LV_PART_MAIN); } // Card colours if (id(declan_make_bed).state) { lv_obj_set_style_bg_color(id(card_declan_make_bed), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_make_bed), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_make_bed), 3, LV_PART_MAIN); lv_label_set_text(id(check_declan_make_bed), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_declan_make_bed), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_make_bed), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_make_bed), 2, LV_PART_MAIN); lv_label_set_text(id(check_declan_make_bed), ""); } if (id(declan_brush_teeth).state) { lv_obj_set_style_bg_color(id(card_declan_brush_teeth), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_brush_teeth), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_brush_teeth), 3, LV_PART_MAIN); lv_label_set_text(id(check_declan_brush_teeth), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_declan_brush_teeth), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_brush_teeth), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_brush_teeth), 2, LV_PART_MAIN); lv_label_set_text(id(check_declan_brush_teeth), ""); } if (id(declan_set_table).state) { lv_obj_set_style_bg_color(id(card_declan_set_table), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_set_table), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_set_table), 3, LV_PART_MAIN); lv_label_set_text(id(check_declan_set_table), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_declan_set_table), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_set_table), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_set_table), 2, LV_PART_MAIN); lv_label_set_text(id(check_declan_set_table), ""); } if (id(declan_take_out_trash).state) { lv_obj_set_style_bg_color(id(card_declan_take_out_trash), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_take_out_trash), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_take_out_trash), 3, LV_PART_MAIN); lv_label_set_text(id(check_declan_take_out_trash), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_declan_take_out_trash), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_declan_take_out_trash), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_declan_take_out_trash), 2, LV_PART_MAIN); lv_label_set_text(id(check_declan_take_out_trash), ""); } - id: reset_chloe_chores mode: single then: - lambda: |- id(chloe_make_bed).turn_off(); id(chloe_brush_teeth).turn_off(); id(chloe_water_plants).turn_off(); id(chloe_homework).turn_off(); id(chloe_tidy_room).turn_off(); id(chloe_practice_piano).turn_off(); - script.execute: update_chloe_ui - id: update_chloe_ui mode: single then: - lambda: |- int done = (id(chloe_make_bed).state ? 1 : 0) + (id(chloe_brush_teeth).state ? 1 : 0) + (id(chloe_water_plants).state ? 1 : 0) + (id(chloe_homework).state ? 1 : 0) + (id(chloe_tidy_room).state ? 1 : 0) + (id(chloe_practice_piano).state ? 1 : 0); int total = 6; char buf[24]; // Progress bar + label lv_bar_set_value(id(progress_bar_chloe), done, LV_ANIM_ON); snprintf(buf, sizeof(buf), "%d / 6", done); lv_label_set_text(id(progress_label_chloe), buf); // All-done message in sidebar lv_label_set_text(id(all_done_label_chloe), done == total ? "All done!" : ""); // Home button: RED outline = incomplete, SOLID GREEN = all done if (done == total) { lv_obj_set_style_bg_opa(id(home_btn_chloe), LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(id(home_btn_chloe), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(home_btn_chloe), 0, LV_PART_MAIN); lv_label_set_text(id(home_status_chloe), "\u2713 all done!"); lv_obj_set_style_text_color(id(home_status_chloe), lv_color_hex(0xFFFFFF), LV_PART_MAIN); } else { lv_obj_set_style_bg_opa(id(home_btn_chloe), LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_color(id(home_btn_chloe), lv_color_hex(0xFF4757), LV_PART_MAIN); lv_obj_set_style_border_width(id(home_btn_chloe), 0, LV_PART_MAIN); snprintf(buf, sizeof(buf), "%d left", total - done); lv_label_set_text(id(home_status_chloe), buf); lv_obj_set_style_text_color(id(home_status_chloe), lv_color_hex(0xFF4757), LV_PART_MAIN); } // Card colours if (id(chloe_make_bed).state) { lv_obj_set_style_bg_color(id(card_chloe_make_bed), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_make_bed), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_make_bed), 3, LV_PART_MAIN); lv_label_set_text(id(check_chloe_make_bed), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_chloe_make_bed), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_make_bed), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_make_bed), 2, LV_PART_MAIN); lv_label_set_text(id(check_chloe_make_bed), ""); } if (id(chloe_brush_teeth).state) { lv_obj_set_style_bg_color(id(card_chloe_brush_teeth), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_brush_teeth), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_brush_teeth), 3, LV_PART_MAIN); lv_label_set_text(id(check_chloe_brush_teeth), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_chloe_brush_teeth), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_brush_teeth), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_brush_teeth), 2, LV_PART_MAIN); lv_label_set_text(id(check_chloe_brush_teeth), ""); } if (id(chloe_water_plants).state) { lv_obj_set_style_bg_color(id(card_chloe_water_plants), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_water_plants), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_water_plants), 3, LV_PART_MAIN); lv_label_set_text(id(check_chloe_water_plants), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_chloe_water_plants), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_water_plants), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_water_plants), 2, LV_PART_MAIN); lv_label_set_text(id(check_chloe_water_plants), ""); } if (id(chloe_homework).state) { lv_obj_set_style_bg_color(id(card_chloe_homework), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_homework), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_homework), 3, LV_PART_MAIN); lv_label_set_text(id(check_chloe_homework), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_chloe_homework), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_homework), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_homework), 2, LV_PART_MAIN); lv_label_set_text(id(check_chloe_homework), ""); } if (id(chloe_tidy_room).state) { lv_obj_set_style_bg_color(id(card_chloe_tidy_room), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_tidy_room), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_tidy_room), 3, LV_PART_MAIN); lv_label_set_text(id(check_chloe_tidy_room), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_chloe_tidy_room), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_tidy_room), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_tidy_room), 2, LV_PART_MAIN); lv_label_set_text(id(check_chloe_tidy_room), ""); } if (id(chloe_practice_piano).state) { lv_obj_set_style_bg_color(id(card_chloe_practice_piano), lv_color_hex(0xF0FFF4), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_practice_piano), lv_color_hex(0x6BCB77), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_practice_piano), 3, LV_PART_MAIN); lv_label_set_text(id(check_chloe_practice_piano), "\u2705"); } else { lv_obj_set_style_bg_color(id(card_chloe_practice_piano), lv_color_hex(0xFFFFFF), LV_PART_MAIN); lv_obj_set_style_border_color(id(card_chloe_practice_piano), lv_color_hex(0xEEEEEE), LV_PART_MAIN); lv_obj_set_style_border_width(id(card_chloe_practice_piano), 2, LV_PART_MAIN); lv_label_set_text(id(check_chloe_practice_piano), ""); } # ── LVGL UI ─────────────────────────────────────────────────────────────────── lvgl: displays: - main_display touchscreens: - touch theme: button: radius: 20 border_width: 0 pages: - id: page_home bg_color: 0xFFF9F0 widgets: - label: x: 0 y: 36 width: 800 align: TOP_MID text: "Chore Tracker" text_font: font_title text_color: 0x2D3436 - label: x: 0 y: 90 width: 800 align: TOP_MID text: "Tap a name to check off chores" text_font: font_small text_color: 0xB2BEC3 - button: x: 640 y: 424 width: 148 height: 40 bg_color: 0xFF4757 radius: 12 on_click: then: - script.execute: reset_jordyn_chores - script.execute: reset_declan_chores - script.execute: reset_chloe_chores widgets: - label: align: CENTER text: "Reset All" text_color: 0xFFFFFF text_font: font_tiny - button: id: home_btn_jordyn x: 80 y: 130 width: 200 height: 210 bg_color: 0xFF4757 bg_opa: COVER border_width: 0 radius: 24 on_click: then: - lvgl.page.show: page_jordyn widgets: - label: align: CENTER y: -45 text: "󰄛" text_font: font_mdi_large - label: align: CENTER y: 22 text: "Jordyn" text_font: font_name text_color: 0xFFFFFF - label: id: home_status_jordyn align: CENTER y: 66 text: "not done" text_font: font_tiny text_color: 0xFFFFFF - button: id: home_btn_declan x: 300 y: 130 width: 200 height: 210 bg_color: 0xFF4757 bg_opa: COVER border_width: 0 radius: 24 on_click: then: - lvgl.page.show: page_declan widgets: - label: align: CENTER y: -45 text: "󱑷" text_font: font_mdi_large - label: align: CENTER y: 22 text: "Declan" text_font: font_name text_color: 0xFFFFFF - label: id: home_status_declan align: CENTER y: 66 text: "not done" text_font: font_tiny text_color: 0xFFFFFF - button: id: home_btn_chloe x: 520 y: 130 width: 200 height: 210 bg_color: 0xFF4757 bg_opa: COVER border_width: 0 radius: 24 on_click: then: - lvgl.page.show: page_chloe widgets: - label: align: CENTER y: -45 text: "󱚠" text_font: font_mdi_large - label: align: CENTER y: 22 text: "Chloe" text_font: font_name text_color: 0xFFFFFF - label: id: home_status_chloe align: CENTER y: 66 text: "not done" text_font: font_tiny text_color: 0xFFFFFF - id: page_jordyn bg_color: 0xFFF9F0 widgets: # ── Sidebar ────────────────────────────────────────────────────────── - obj: x: 0 y: 0 width: 172 height: 480 bg_color: 0x4D96FF border_width: 0 radius: 0 pad_all: 0 widgets: - label: x: 0 y: 22 width: 172 align: TOP_MID text: "󰄛" text_font: font_mdi_large - label: x: 0 y: 76 width: 172 align: TOP_MID text: "Jordyn" text_font: font_name text_color: 0xFFFFFF - bar: id: progress_bar_jordyn x: 14 y: 132 width: 144 height: 16 bg_color: 0x2A6FCC indicator: bg_color: 0xFFFFFF value: 0 min_value: 0 max_value: 5 - label: id: progress_label_jordyn x: 0 y: 156 width: 172 align: TOP_MID text: "0 / 5" text_font: font_small text_color: 0xDDEEFF - label: id: all_done_label_jordyn x: 0 y: 192 width: 172 align: TOP_MID text: "" text_font: font_small text_color: 0xFFFFFF - button: x: 14 y: 364 width: 144 height: 44 bg_color: 0xFF4757 radius: 14 on_click: then: - script.execute: reset_jordyn_chores widgets: - label: align: CENTER text: "Reset" text_color: 0xFFFFFF text_font: font_small - button: x: 14 y: 420 width: 144 height: 44 bg_color: 0x2A6FCC radius: 14 on_click: then: - lvgl.page.show: page_home widgets: - label: align: CENTER text: "Home" text_color: 0xFFFFFF text_font: font_small # ── Chore cards ─────────────────────────────────────────────────────── - button: id: card_jordyn_make_bed x: 182 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: jordyn_make_bed widgets: - label: id: check_jordyn_make_bed align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰋣" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Make Bed" text_font: font_small text_color: 0x2D3436 - button: id: card_jordyn_brush_teeth x: 388 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: jordyn_brush_teeth widgets: - label: id: check_jordyn_brush_teeth align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰦩" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Brush Teeth" text_font: font_small text_color: 0x2D3436 - button: id: card_jordyn_tidy_room x: 594 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: jordyn_tidy_room widgets: - label: id: check_jordyn_tidy_room align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰂨" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Tidy Room" text_font: font_small text_color: 0x2D3436 - button: id: card_jordyn_homework x: 182 y: 158 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: jordyn_homework widgets: - label: id: check_jordyn_homework align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰈙" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Homework" text_font: font_small text_color: 0x2D3436 - button: id: card_jordyn_feed_dog x: 388 y: 158 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: jordyn_feed_dog widgets: - label: id: check_jordyn_feed_dog align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰉥" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Feed Dog" text_font: font_small text_color: 0x2D3436 - id: page_declan bg_color: 0xFFF9F0 widgets: # ── Sidebar ────────────────────────────────────────────────────────── - obj: x: 0 y: 0 width: 172 height: 480 bg_color: 0xC77DFF border_width: 0 radius: 0 pad_all: 0 widgets: - label: x: 0 y: 22 width: 172 align: TOP_MID text: "󱑷" text_font: font_mdi_large - label: x: 0 y: 76 width: 172 align: TOP_MID text: "Declan" text_font: font_name text_color: 0xFFFFFF - bar: id: progress_bar_declan x: 14 y: 132 width: 144 height: 16 bg_color: 0x8B42CC indicator: bg_color: 0xFFFFFF value: 0 min_value: 0 max_value: 4 - label: id: progress_label_declan x: 0 y: 156 width: 172 align: TOP_MID text: "0 / 4" text_font: font_small text_color: 0xDDEEFF - label: id: all_done_label_declan x: 0 y: 192 width: 172 align: TOP_MID text: "" text_font: font_small text_color: 0xFFFFFF - button: x: 14 y: 364 width: 144 height: 44 bg_color: 0xFF4757 radius: 14 on_click: then: - script.execute: reset_declan_chores widgets: - label: align: CENTER text: "Reset" text_color: 0xFFFFFF text_font: font_small - button: x: 14 y: 420 width: 144 height: 44 bg_color: 0x8B42CC radius: 14 on_click: then: - lvgl.page.show: page_home widgets: - label: align: CENTER text: "Home" text_color: 0xFFFFFF text_font: font_small # ── Chore cards ─────────────────────────────────────────────────────── - button: id: card_declan_make_bed x: 182 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: declan_make_bed widgets: - label: id: check_declan_make_bed align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰋣" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Make Bed" text_font: font_small text_color: 0x2D3436 - button: id: card_declan_brush_teeth x: 388 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: declan_brush_teeth widgets: - label: id: check_declan_brush_teeth align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰦩" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Brush Teeth" text_font: font_small text_color: 0x2D3436 - button: id: card_declan_set_table x: 594 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: declan_set_table widgets: - label: id: check_declan_set_table align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰏧" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Set Table" text_font: font_small text_color: 0x2D3436 - button: id: card_declan_take_out_trash x: 182 y: 158 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: declan_take_out_trash widgets: - label: id: check_declan_take_out_trash align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰖸" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Take Out Trash" text_font: font_small text_color: 0x2D3436 - id: page_chloe bg_color: 0xFFF9F0 widgets: # ── Sidebar ────────────────────────────────────────────────────────── - obj: x: 0 y: 0 width: 172 height: 480 bg_color: 0xFF6B9D border_width: 0 radius: 0 pad_all: 0 widgets: - label: x: 0 y: 22 width: 172 align: TOP_MID text: "󱚠" text_font: font_mdi_large - label: x: 0 y: 76 width: 172 align: TOP_MID text: "Chloe" text_font: font_name text_color: 0xFFFFFF - bar: id: progress_bar_chloe x: 14 y: 132 width: 144 height: 16 bg_color: 0xCC3A6F indicator: bg_color: 0xFFFFFF value: 0 min_value: 0 max_value: 6 - label: id: progress_label_chloe x: 0 y: 156 width: 172 align: TOP_MID text: "0 / 6" text_font: font_small text_color: 0xDDEEFF - label: id: all_done_label_chloe x: 0 y: 192 width: 172 align: TOP_MID text: "" text_font: font_small text_color: 0xFFFFFF - button: x: 14 y: 364 width: 144 height: 44 bg_color: 0xFF4757 radius: 14 on_click: then: - script.execute: reset_chloe_chores widgets: - label: align: CENTER text: "Reset" text_color: 0xFFFFFF text_font: font_small - button: x: 14 y: 420 width: 144 height: 44 bg_color: 0xCC3A6F radius: 14 on_click: then: - lvgl.page.show: page_home widgets: - label: align: CENTER text: "Home" text_color: 0xFFFFFF text_font: font_small # ── Chore cards ─────────────────────────────────────────────────────── - button: id: card_chloe_make_bed x: 182 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: chloe_make_bed widgets: - label: id: check_chloe_make_bed align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰋣" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Make Bed" text_font: font_small text_color: 0x2D3436 - button: id: card_chloe_brush_teeth x: 388 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: chloe_brush_teeth widgets: - label: id: check_chloe_brush_teeth align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰦩" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Brush Teeth" text_font: font_small text_color: 0x2D3436 - button: id: card_chloe_water_plants x: 594 y: 10 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: chloe_water_plants widgets: - label: id: check_chloe_water_plants align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󱬥" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Water Plants" text_font: font_small text_color: 0x2D3436 - button: id: card_chloe_homework x: 182 y: 158 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: chloe_homework widgets: - label: id: check_chloe_homework align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰈙" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Homework" text_font: font_small text_color: 0x2D3436 - button: id: card_chloe_tidy_room x: 388 y: 158 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: chloe_tidy_room widgets: - label: id: check_chloe_tidy_room align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰂨" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Tidy Room" text_font: font_small text_color: 0x2D3436 - button: id: card_chloe_practice_piano x: 594 y: 158 width: 196 height: 138 bg_color: 0xFFFFFF border_color: 0xEEEEEE border_width: 2 radius: 20 shadow_color: 0xCCCCCC shadow_width: 4 shadow_ofs_y: 3 on_click: then: - switch.toggle: chloe_practice_piano widgets: - label: id: check_chloe_practice_piano align: TOP_RIGHT x: -10 y: 8 text: "" text_font: font_med - label: align: CENTER y: -34 text: "󰾞" text_font: font_mdi_small - label: align: CENTER y: 17 text: "Practice Piano" text_font: font_small text_color: 0x2D3436