Files
Home-Assistant/esphome/chore-tracker-esphome.yaml
Joshua King 0a66aa438c Add chore tracker configuration and generator scripts
- Created `chores_config.yaml` for defining kids, chores, and settings.
- Implemented `generate.py` to generate ESPHome, Home Assistant, and Lovelace dashboard configurations based on the YAML file.
- Added `chore-tracker-ha.yaml` for Home Assistant integration, including sensors and automation for tracking chores and notifications.
2026-02-27 21:53:45 -05:00

2948 lines
107 KiB
YAML

################################################################################
# chore-tracker-esphome.yaml (AUTO-GENERATED — edit chores_config.yaml)
# Kids: Emma, Liam, Zoe
#
# HOME SCREEN BEHAVIOUR:
# Red outline = chores incomplete
# Solid green = all chores done ✓
# Resets to red automatically at midnight
################################################################################
esphome:
name: chore-tracker
friendly_name: "Chore Tracker"
esp32:
board: esp32s3box
framework:
type: esp-idf
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
# ── Display — Waveshare ESP32-S3 7" (adjust pins for your board revision) ─────
display:
- platform: rpi_dpi_rgb
id: main_display
auto_clear_enabled: false
color_order: RGB
dimensions:
width: 800
height: 480
de_pin:
number: GPIO40
ignore_strapping_warning: true
hsync_pin:
number: GPIO39
ignore_strapping_warning: true
vsync_pin:
number: GPIO41
pclk_pin: GPIO42
data_pins:
red: [GPIO45, GPIO48, GPIO47, GPIO21, GPIO14]
green: [GPIO5, GPIO6, GPIO7, GPIO15, GPIO16, GPIO4]
blue: [GPIO8, GPIO3, GPIO46, GPIO9, GPIO1]
touchscreen:
- platform: gt911
id: touch
display: main_display
i2c_id: i2c_touch
interrupt_pin: GPIO2
reset_pin: GPIO38
i2c:
- id: i2c_touch
sda: GPIO19
scl: GPIO20
frequency: 400kHz
output:
- platform: ledc
pin: GPIO17
id: backlight_output
light:
- platform: monochromatic
output: backlight_output
name: "Display Backlight"
id: backlight
restore_mode: ALWAYS_ON
# ── Time: drives the daily reset ─────────────────────────────────────────────
time:
- platform: homeassistant
id: ha_time
on_time:
- hours: 0
minutes: 0
seconds: 0
then:
- lambda: |-
// Reset all kids via named scripts (resets switches + refreshes UI)
id(reset_emma_chores).execute();
id(reset_liam_chores).execute();
id(reset_zoe_chores).execute();
- lvgl.page.show: page_home
fonts:
- file: "gfonts://Nunito:wght@900"
id: font_title
size: 40
- file: "gfonts://Nunito:wght@800"
id: font_name
size: 30
- file: "gfonts://Nunito:wght@700"
id: font_med
size: 22
- file: "gfonts://Nunito:wght@600"
id: font_small
size: 17
- file: "gfonts://Nunito:wght@600"
id: font_tiny
size: 13
# ── Switches — one per chore per kid, synced to HA ───────────────────────────
switch:
# ── Emma's chores ────────────────────────── - platform: template
name: "Emma - Make Bed"
id: emma_make_bed
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_make_bed
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_make_bed
- platform: template
name: "Emma - Brush Teeth"
id: emma_brush_teeth
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_brush_teeth
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_brush_teeth
- platform: template
name: "Emma - Tidy Room"
id: emma_tidy_room
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_tidy_room
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_tidy_room
- platform: template
name: "Emma - Homework"
id: emma_homework
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_homework
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_homework
- platform: template
name: "Emma - Set Table"
id: emma_set_table
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_set_table
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_set_table
- platform: template
name: "Emma - Take Out Trash"
id: emma_take_out_trash
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_take_out_trash
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_take_out_trash
- platform: template
name: "Emma - Feed Pet"
id: emma_feed_pet
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_feed_pet
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_feed_pet
- platform: template
name: "Emma - Water Plants"
id: emma_water_plants
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_emma_water_plants
on_turn_off:
then:
- script.execute: update_emma_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_emma_water_plants
# ── Liam's chores ────────────────────────── - platform: template
name: "Liam - Make Bed"
id: liam_make_bed
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_make_bed
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_make_bed
- platform: template
name: "Liam - Brush Teeth"
id: liam_brush_teeth
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_brush_teeth
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_brush_teeth
- platform: template
name: "Liam - Tidy Room"
id: liam_tidy_room
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_tidy_room
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_tidy_room
- platform: template
name: "Liam - Homework"
id: liam_homework
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_homework
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_homework
- platform: template
name: "Liam - Set Table"
id: liam_set_table
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_set_table
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_set_table
- platform: template
name: "Liam - Take Out Trash"
id: liam_take_out_trash
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_take_out_trash
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_take_out_trash
- platform: template
name: "Liam - Feed Pet"
id: liam_feed_pet
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_feed_pet
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_feed_pet
- platform: template
name: "Liam - Water Plants"
id: liam_water_plants
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_liam_water_plants
on_turn_off:
then:
- script.execute: update_liam_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_liam_water_plants
# ── Zoe's chores ────────────────────────── - platform: template
name: "Zoe - Make Bed"
id: zoe_make_bed
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_make_bed
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_make_bed
- platform: template
name: "Zoe - Brush Teeth"
id: zoe_brush_teeth
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_brush_teeth
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_brush_teeth
- platform: template
name: "Zoe - Tidy Room"
id: zoe_tidy_room
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_tidy_room
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_tidy_room
- platform: template
name: "Zoe - Homework"
id: zoe_homework
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_homework
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_homework
- platform: template
name: "Zoe - Set Table"
id: zoe_set_table
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_set_table
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_set_table
- platform: template
name: "Zoe - Take Out Trash"
id: zoe_take_out_trash
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_take_out_trash
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_take_out_trash
- platform: template
name: "Zoe - Feed Pet"
id: zoe_feed_pet
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_feed_pet
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_feed_pet
- platform: template
name: "Zoe - Water Plants"
id: zoe_water_plants
icon: mdi:star
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_on
data:
entity_id: switch.chore_tracker_zoe_water_plants
on_turn_off:
then:
- script.execute: update_zoe_ui
# Push to HA so it stays in sync when toggled on the screen
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_zoe_water_plants
# ── Sensors — reported to HA ─────────────────────────────────────────────────
sensor:
- platform: template
name: "Emma Chores Done"
id: emma_chores_done
accuracy_decimals: 0
update_interval: 2s
lambda: |-
int done = 0;
if (id(emma_make_bed).state) done++;
if (id(emma_brush_teeth).state) done++;
if (id(emma_tidy_room).state) done++;
if (id(emma_homework).state) done++;
if (id(emma_set_table).state) done++;
if (id(emma_take_out_trash).state) done++;
if (id(emma_feed_pet).state) done++;
if (id(emma_water_plants).state) done++;
return done;
- platform: template
name: "Emma Stars Today"
id: emma_stars
unit_of_measurement: "stars"
accuracy_decimals: 0
update_interval: 2s
lambda: |-
int stars = 0;
if (id(emma_make_bed).state) stars += 1;
if (id(emma_brush_teeth).state) stars += 1;
if (id(emma_tidy_room).state) stars += 2;
if (id(emma_homework).state) stars += 3;
if (id(emma_set_table).state) stars += 1;
if (id(emma_take_out_trash).state) stars += 2;
if (id(emma_feed_pet).state) stars += 1;
if (id(emma_water_plants).state) stars += 1;
return stars;
- platform: template
name: "Liam Chores Done"
id: liam_chores_done
accuracy_decimals: 0
update_interval: 2s
lambda: |-
int done = 0;
if (id(liam_make_bed).state) done++;
if (id(liam_brush_teeth).state) done++;
if (id(liam_tidy_room).state) done++;
if (id(liam_homework).state) done++;
if (id(liam_set_table).state) done++;
if (id(liam_take_out_trash).state) done++;
if (id(liam_feed_pet).state) done++;
if (id(liam_water_plants).state) done++;
return done;
- platform: template
name: "Liam Stars Today"
id: liam_stars
unit_of_measurement: "stars"
accuracy_decimals: 0
update_interval: 2s
lambda: |-
int stars = 0;
if (id(liam_make_bed).state) stars += 1;
if (id(liam_brush_teeth).state) stars += 1;
if (id(liam_tidy_room).state) stars += 2;
if (id(liam_homework).state) stars += 3;
if (id(liam_set_table).state) stars += 1;
if (id(liam_take_out_trash).state) stars += 2;
if (id(liam_feed_pet).state) stars += 1;
if (id(liam_water_plants).state) stars += 1;
return stars;
- platform: template
name: "Zoe Chores Done"
id: zoe_chores_done
accuracy_decimals: 0
update_interval: 2s
lambda: |-
int done = 0;
if (id(zoe_make_bed).state) done++;
if (id(zoe_brush_teeth).state) done++;
if (id(zoe_tidy_room).state) done++;
if (id(zoe_homework).state) done++;
if (id(zoe_set_table).state) done++;
if (id(zoe_take_out_trash).state) done++;
if (id(zoe_feed_pet).state) done++;
if (id(zoe_water_plants).state) done++;
return done;
- platform: template
name: "Zoe Stars Today"
id: zoe_stars
unit_of_measurement: "stars"
accuracy_decimals: 0
update_interval: 2s
lambda: |-
int stars = 0;
if (id(zoe_make_bed).state) stars += 1;
if (id(zoe_brush_teeth).state) stars += 1;
if (id(zoe_tidy_room).state) stars += 2;
if (id(zoe_homework).state) stars += 3;
if (id(zoe_set_table).state) stars += 1;
if (id(zoe_take_out_trash).state) stars += 2;
if (id(zoe_feed_pet).state) stars += 1;
if (id(zoe_water_plants).state) stars += 1;
return stars;
# ── Scripts — update LVGL visuals when chore state changes ───────────────────
script:
# Reset all of Emma's chores (used by manual reset button + midnight)
- id: reset_emma_chores
mode: single
then:
- lambda: |-
id(emma_make_bed).turn_off();
id(emma_brush_teeth).turn_off();
id(emma_tidy_room).turn_off();
id(emma_homework).turn_off();
id(emma_set_table).turn_off();
id(emma_take_out_trash).turn_off();
id(emma_feed_pet).turn_off();
id(emma_water_plants).turn_off();
- script.execute: update_emma_ui
- id: update_emma_ui
mode: single
then:
- lambda: |-
int done = (id(emma_make_bed).state ? 1 : 0) + (id(emma_brush_teeth).state ? 1 : 0) + (id(emma_tidy_room).state ? 1 : 0) + (id(emma_homework).state ? 1 : 0) + (id(emma_set_table).state ? 1 : 0) + (id(emma_take_out_trash).state ? 1 : 0) + (id(emma_feed_pet).state ? 1 : 0) + (id(emma_water_plants).state ? 1 : 0);
int stars = (id(emma_make_bed).state ? 1 : 0) + (id(emma_brush_teeth).state ? 1 : 0) + (id(emma_tidy_room).state ? 2 : 0) + (id(emma_homework).state ? 3 : 0) + (id(emma_set_table).state ? 1 : 0) + (id(emma_take_out_trash).state ? 2 : 0) + (id(emma_feed_pet).state ? 1 : 0) + (id(emma_water_plants).state ? 1 : 0);
int total = 8;
// ── Sidebar progress & stars ──────────────────────────────────────
lv_bar_set_value(id(progress_bar_emma), done, LV_ANIM_ON);
char buf[32];
snprintf(buf, sizeof(buf), "%d / 8", done);
lv_label_set_text(id(progress_label_emma), buf);
snprintf(buf, sizeof(buf), "⭐ %d star%s", stars, stars == 1 ? "" : "s");
lv_label_set_text(id(sidebar_stars_emma), buf);
// ── All-done celebration text ─────────────────────────────────────
if (done == total) {
lv_label_set_text(id(all_done_label_emma), "🎉 All done!");
} else {
lv_label_set_text(id(all_done_label_emma), "");
}
// ── Home screen button: RED outline = incomplete, GREEN = complete ─
if (done == total) {
// Solid green — all chores done
lv_obj_set_style_bg_opa(id(home_btn_emma), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_color(id(home_btn_emma), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(home_btn_emma), 0, LV_PART_MAIN);
lv_label_set_text(id(home_status_emma), "✓ all done!");
lv_obj_set_style_text_color(id(home_status_emma), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
} else {
// Transparent fill with red border — incomplete
lv_obj_set_style_bg_opa(id(home_btn_emma), LV_OPA_TRANSP, LV_PART_MAIN);
lv_obj_set_style_border_color(id(home_btn_emma), lv_color_hex(0xFF4757), LV_PART_MAIN);
lv_obj_set_style_border_width(id(home_btn_emma), 5, LV_PART_MAIN);
snprintf(buf, sizeof(buf), "%d left", total - done);
lv_label_set_text(id(home_status_emma), buf);
lv_obj_set_style_text_color(id(home_status_emma), lv_color_hex(0xFF4757), LV_PART_MAIN);
}
// ── Individual chore card colours ─────────────────────────────────
// Make Bed
if (id(emma_make_bed).state) {
lv_obj_set_style_bg_color(id(card_emma_make_bed), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_make_bed), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_make_bed), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_make_bed), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_make_bed), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_make_bed), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_make_bed), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_make_bed), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_make_bed), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_make_bed), "");
}
// Brush Teeth
if (id(emma_brush_teeth).state) {
lv_obj_set_style_bg_color(id(card_emma_brush_teeth), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_brush_teeth), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_brush_teeth), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_brush_teeth), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_brush_teeth), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_brush_teeth), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_brush_teeth), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_brush_teeth), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_brush_teeth), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_brush_teeth), "");
}
// Tidy Room
if (id(emma_tidy_room).state) {
lv_obj_set_style_bg_color(id(card_emma_tidy_room), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_tidy_room), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_tidy_room), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_tidy_room), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_tidy_room), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_tidy_room), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_tidy_room), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_tidy_room), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_tidy_room), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_tidy_room), "");
}
// Homework
if (id(emma_homework).state) {
lv_obj_set_style_bg_color(id(card_emma_homework), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_homework), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_homework), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_homework), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_homework), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_homework), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_homework), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_homework), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_homework), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_homework), "");
}
// Set Table
if (id(emma_set_table).state) {
lv_obj_set_style_bg_color(id(card_emma_set_table), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_set_table), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_set_table), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_set_table), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_set_table), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_set_table), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_set_table), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_set_table), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_set_table), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_set_table), "");
}
// Take Out Trash
if (id(emma_take_out_trash).state) {
lv_obj_set_style_bg_color(id(card_emma_take_out_trash), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_take_out_trash), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_take_out_trash), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_take_out_trash), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_take_out_trash), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_take_out_trash), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_take_out_trash), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_take_out_trash), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_take_out_trash), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_take_out_trash), "");
}
// Feed Pet
if (id(emma_feed_pet).state) {
lv_obj_set_style_bg_color(id(card_emma_feed_pet), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_feed_pet), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_feed_pet), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_feed_pet), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_feed_pet), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_feed_pet), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_feed_pet), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_feed_pet), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_feed_pet), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_feed_pet), "");
}
// Water Plants
if (id(emma_water_plants).state) {
lv_obj_set_style_bg_color(id(card_emma_water_plants), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_water_plants), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_water_plants), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_water_plants), 3, LV_PART_MAIN);
lv_label_set_text(id(check_emma_water_plants), "✅");
} else {
lv_obj_set_style_bg_color(id(card_emma_water_plants), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_emma_water_plants), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_emma_water_plants), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_emma_water_plants), 2, LV_PART_MAIN);
lv_label_set_text(id(check_emma_water_plants), "");
}
# Reset all of Liam's chores (used by manual reset button + midnight)
- id: reset_liam_chores
mode: single
then:
- lambda: |-
id(liam_make_bed).turn_off();
id(liam_brush_teeth).turn_off();
id(liam_tidy_room).turn_off();
id(liam_homework).turn_off();
id(liam_set_table).turn_off();
id(liam_take_out_trash).turn_off();
id(liam_feed_pet).turn_off();
id(liam_water_plants).turn_off();
- script.execute: update_liam_ui
- id: update_liam_ui
mode: single
then:
- lambda: |-
int done = (id(liam_make_bed).state ? 1 : 0) + (id(liam_brush_teeth).state ? 1 : 0) + (id(liam_tidy_room).state ? 1 : 0) + (id(liam_homework).state ? 1 : 0) + (id(liam_set_table).state ? 1 : 0) + (id(liam_take_out_trash).state ? 1 : 0) + (id(liam_feed_pet).state ? 1 : 0) + (id(liam_water_plants).state ? 1 : 0);
int stars = (id(liam_make_bed).state ? 1 : 0) + (id(liam_brush_teeth).state ? 1 : 0) + (id(liam_tidy_room).state ? 2 : 0) + (id(liam_homework).state ? 3 : 0) + (id(liam_set_table).state ? 1 : 0) + (id(liam_take_out_trash).state ? 2 : 0) + (id(liam_feed_pet).state ? 1 : 0) + (id(liam_water_plants).state ? 1 : 0);
int total = 8;
// ── Sidebar progress & stars ──────────────────────────────────────
lv_bar_set_value(id(progress_bar_liam), done, LV_ANIM_ON);
char buf[32];
snprintf(buf, sizeof(buf), "%d / 8", done);
lv_label_set_text(id(progress_label_liam), buf);
snprintf(buf, sizeof(buf), "⭐ %d star%s", stars, stars == 1 ? "" : "s");
lv_label_set_text(id(sidebar_stars_liam), buf);
// ── All-done celebration text ─────────────────────────────────────
if (done == total) {
lv_label_set_text(id(all_done_label_liam), "🎉 All done!");
} else {
lv_label_set_text(id(all_done_label_liam), "");
}
// ── Home screen button: RED outline = incomplete, GREEN = complete ─
if (done == total) {
// Solid green — all chores done
lv_obj_set_style_bg_opa(id(home_btn_liam), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_color(id(home_btn_liam), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(home_btn_liam), 0, LV_PART_MAIN);
lv_label_set_text(id(home_status_liam), "✓ all done!");
lv_obj_set_style_text_color(id(home_status_liam), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
} else {
// Transparent fill with red border — incomplete
lv_obj_set_style_bg_opa(id(home_btn_liam), LV_OPA_TRANSP, LV_PART_MAIN);
lv_obj_set_style_border_color(id(home_btn_liam), lv_color_hex(0xFF4757), LV_PART_MAIN);
lv_obj_set_style_border_width(id(home_btn_liam), 5, LV_PART_MAIN);
snprintf(buf, sizeof(buf), "%d left", total - done);
lv_label_set_text(id(home_status_liam), buf);
lv_obj_set_style_text_color(id(home_status_liam), lv_color_hex(0xFF4757), LV_PART_MAIN);
}
// ── Individual chore card colours ─────────────────────────────────
// Make Bed
if (id(liam_make_bed).state) {
lv_obj_set_style_bg_color(id(card_liam_make_bed), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_make_bed), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_make_bed), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_make_bed), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_make_bed), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_make_bed), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_make_bed), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_make_bed), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_make_bed), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_make_bed), "");
}
// Brush Teeth
if (id(liam_brush_teeth).state) {
lv_obj_set_style_bg_color(id(card_liam_brush_teeth), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_brush_teeth), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_brush_teeth), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_brush_teeth), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_brush_teeth), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_brush_teeth), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_brush_teeth), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_brush_teeth), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_brush_teeth), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_brush_teeth), "");
}
// Tidy Room
if (id(liam_tidy_room).state) {
lv_obj_set_style_bg_color(id(card_liam_tidy_room), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_tidy_room), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_tidy_room), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_tidy_room), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_tidy_room), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_tidy_room), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_tidy_room), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_tidy_room), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_tidy_room), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_tidy_room), "");
}
// Homework
if (id(liam_homework).state) {
lv_obj_set_style_bg_color(id(card_liam_homework), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_homework), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_homework), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_homework), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_homework), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_homework), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_homework), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_homework), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_homework), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_homework), "");
}
// Set Table
if (id(liam_set_table).state) {
lv_obj_set_style_bg_color(id(card_liam_set_table), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_set_table), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_set_table), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_set_table), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_set_table), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_set_table), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_set_table), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_set_table), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_set_table), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_set_table), "");
}
// Take Out Trash
if (id(liam_take_out_trash).state) {
lv_obj_set_style_bg_color(id(card_liam_take_out_trash), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_take_out_trash), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_take_out_trash), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_take_out_trash), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_take_out_trash), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_take_out_trash), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_take_out_trash), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_take_out_trash), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_take_out_trash), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_take_out_trash), "");
}
// Feed Pet
if (id(liam_feed_pet).state) {
lv_obj_set_style_bg_color(id(card_liam_feed_pet), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_feed_pet), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_feed_pet), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_feed_pet), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_feed_pet), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_feed_pet), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_feed_pet), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_feed_pet), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_feed_pet), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_feed_pet), "");
}
// Water Plants
if (id(liam_water_plants).state) {
lv_obj_set_style_bg_color(id(card_liam_water_plants), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_water_plants), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_water_plants), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_water_plants), 3, LV_PART_MAIN);
lv_label_set_text(id(check_liam_water_plants), "✅");
} else {
lv_obj_set_style_bg_color(id(card_liam_water_plants), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_liam_water_plants), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_liam_water_plants), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_liam_water_plants), 2, LV_PART_MAIN);
lv_label_set_text(id(check_liam_water_plants), "");
}
# Reset all of Zoe's chores (used by manual reset button + midnight)
- id: reset_zoe_chores
mode: single
then:
- lambda: |-
id(zoe_make_bed).turn_off();
id(zoe_brush_teeth).turn_off();
id(zoe_tidy_room).turn_off();
id(zoe_homework).turn_off();
id(zoe_set_table).turn_off();
id(zoe_take_out_trash).turn_off();
id(zoe_feed_pet).turn_off();
id(zoe_water_plants).turn_off();
- script.execute: update_zoe_ui
- id: update_zoe_ui
mode: single
then:
- lambda: |-
int done = (id(zoe_make_bed).state ? 1 : 0) + (id(zoe_brush_teeth).state ? 1 : 0) + (id(zoe_tidy_room).state ? 1 : 0) + (id(zoe_homework).state ? 1 : 0) + (id(zoe_set_table).state ? 1 : 0) + (id(zoe_take_out_trash).state ? 1 : 0) + (id(zoe_feed_pet).state ? 1 : 0) + (id(zoe_water_plants).state ? 1 : 0);
int stars = (id(zoe_make_bed).state ? 1 : 0) + (id(zoe_brush_teeth).state ? 1 : 0) + (id(zoe_tidy_room).state ? 2 : 0) + (id(zoe_homework).state ? 3 : 0) + (id(zoe_set_table).state ? 1 : 0) + (id(zoe_take_out_trash).state ? 2 : 0) + (id(zoe_feed_pet).state ? 1 : 0) + (id(zoe_water_plants).state ? 1 : 0);
int total = 8;
// ── Sidebar progress & stars ──────────────────────────────────────
lv_bar_set_value(id(progress_bar_zoe), done, LV_ANIM_ON);
char buf[32];
snprintf(buf, sizeof(buf), "%d / 8", done);
lv_label_set_text(id(progress_label_zoe), buf);
snprintf(buf, sizeof(buf), "⭐ %d star%s", stars, stars == 1 ? "" : "s");
lv_label_set_text(id(sidebar_stars_zoe), buf);
// ── All-done celebration text ─────────────────────────────────────
if (done == total) {
lv_label_set_text(id(all_done_label_zoe), "🎉 All done!");
} else {
lv_label_set_text(id(all_done_label_zoe), "");
}
// ── Home screen button: RED outline = incomplete, GREEN = complete ─
if (done == total) {
// Solid green — all chores done
lv_obj_set_style_bg_opa(id(home_btn_zoe), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_color(id(home_btn_zoe), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(home_btn_zoe), 0, LV_PART_MAIN);
lv_label_set_text(id(home_status_zoe), "✓ all done!");
lv_obj_set_style_text_color(id(home_status_zoe), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
} else {
// Transparent fill with red border — incomplete
lv_obj_set_style_bg_opa(id(home_btn_zoe), LV_OPA_TRANSP, LV_PART_MAIN);
lv_obj_set_style_border_color(id(home_btn_zoe), lv_color_hex(0xFF4757), LV_PART_MAIN);
lv_obj_set_style_border_width(id(home_btn_zoe), 5, LV_PART_MAIN);
snprintf(buf, sizeof(buf), "%d left", total - done);
lv_label_set_text(id(home_status_zoe), buf);
lv_obj_set_style_text_color(id(home_status_zoe), lv_color_hex(0xFF4757), LV_PART_MAIN);
}
// ── Individual chore card colours ─────────────────────────────────
// Make Bed
if (id(zoe_make_bed).state) {
lv_obj_set_style_bg_color(id(card_zoe_make_bed), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_make_bed), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_make_bed), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_make_bed), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_make_bed), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_make_bed), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_make_bed), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_make_bed), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_make_bed), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_make_bed), "");
}
// Brush Teeth
if (id(zoe_brush_teeth).state) {
lv_obj_set_style_bg_color(id(card_zoe_brush_teeth), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_brush_teeth), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_brush_teeth), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_brush_teeth), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_brush_teeth), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_brush_teeth), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_brush_teeth), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_brush_teeth), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_brush_teeth), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_brush_teeth), "");
}
// Tidy Room
if (id(zoe_tidy_room).state) {
lv_obj_set_style_bg_color(id(card_zoe_tidy_room), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_tidy_room), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_tidy_room), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_tidy_room), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_tidy_room), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_tidy_room), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_tidy_room), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_tidy_room), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_tidy_room), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_tidy_room), "");
}
// Homework
if (id(zoe_homework).state) {
lv_obj_set_style_bg_color(id(card_zoe_homework), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_homework), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_homework), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_homework), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_homework), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_homework), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_homework), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_homework), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_homework), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_homework), "");
}
// Set Table
if (id(zoe_set_table).state) {
lv_obj_set_style_bg_color(id(card_zoe_set_table), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_set_table), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_set_table), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_set_table), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_set_table), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_set_table), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_set_table), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_set_table), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_set_table), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_set_table), "");
}
// Take Out Trash
if (id(zoe_take_out_trash).state) {
lv_obj_set_style_bg_color(id(card_zoe_take_out_trash), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_take_out_trash), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_take_out_trash), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_take_out_trash), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_take_out_trash), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_take_out_trash), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_take_out_trash), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_take_out_trash), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_take_out_trash), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_take_out_trash), "");
}
// Feed Pet
if (id(zoe_feed_pet).state) {
lv_obj_set_style_bg_color(id(card_zoe_feed_pet), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_feed_pet), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_feed_pet), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_feed_pet), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_feed_pet), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_feed_pet), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_feed_pet), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_feed_pet), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_feed_pet), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_feed_pet), "");
}
// Water Plants
if (id(zoe_water_plants).state) {
lv_obj_set_style_bg_color(id(card_zoe_water_plants), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_water_plants), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_water_plants), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_water_plants), 3, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_water_plants), "✅");
} else {
lv_obj_set_style_bg_color(id(card_zoe_water_plants), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_bg_opa(id(card_zoe_water_plants), LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_zoe_water_plants), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_zoe_water_plants), 2, LV_PART_MAIN);
lv_label_set_text(id(check_zoe_water_plants), "");
}
# ── LVGL UI ───────────────────────────────────────────────────────────────────
lvgl:
displays:
- main_display
touchscreens:
- touch
theme:
btn:
radius: 20
border_width: 0
pages:
- id: page_home
bg_color: 0xFFF9F0
widgets:
- label:
x: 0
y: 38
width: 800
align: TOP_MID
text: "⭐ Chore Tracker"
text_font: font_title
text_color: 0x2D3436
- label:
x: 0
y: 96
width: 800
align: TOP_MID
text: "Tap a name to check off chores"
text_font: font_small
text_color: 0xB2BEC3
# Reset All button — bottom right, subtle red
- btn:
x: 660
y: 428
width: 130
height: 40
bg_color: 0xFF4757
radius: 12
on_click:
then:
- script.execute: reset_emma_chores
- script.execute: reset_liam_chores
- script.execute: reset_zoe_chores
widgets:
- label:
align: CENTER
text: "↺ Reset All"
text_color: 0xFFFFFF
text_font: font_tiny
# Emma — starts red (incomplete), turns green when all done
- btn:
id: home_btn_emma
x: 80
y: 140
width: 200
height: 200
bg_color: 0xFFFFFF
bg_opa: TRANSP
border_color: 0xFF4757
border_width: 5
radius: 24
on_click:
then:
- lvgl.page.show: page_emma
widgets:
- label:
align: CENTER
y: -38
text: "🐶"
text_font: font_title
- label:
align: CENTER
y: 28
text: "Emma"
text_font: font_name
text_color: 0x2D3436
- label:
id: home_status_emma
align: CENTER
y: 68
text: "not done"
text_font: font_tiny
text_color: 0xFF4757
# Liam — starts red (incomplete), turns green when all done
- btn:
id: home_btn_liam
x: 300
y: 140
width: 200
height: 200
bg_color: 0xFFFFFF
bg_opa: TRANSP
border_color: 0xFF4757
border_width: 5
radius: 24
on_click:
then:
- lvgl.page.show: page_liam
widgets:
- label:
align: CENTER
y: -38
text: "🐱"
text_font: font_title
- label:
align: CENTER
y: 28
text: "Liam"
text_font: font_name
text_color: 0x2D3436
- label:
id: home_status_liam
align: CENTER
y: 68
text: "not done"
text_font: font_tiny
text_color: 0xFF4757
# Zoe — starts red (incomplete), turns green when all done
- btn:
id: home_btn_zoe
x: 520
y: 140
width: 200
height: 200
bg_color: 0xFFFFFF
bg_opa: TRANSP
border_color: 0xFF4757
border_width: 5
radius: 24
on_click:
then:
- lvgl.page.show: page_zoe
widgets:
- label:
align: CENTER
y: -38
text: "🐻"
text_font: font_title
- label:
align: CENTER
y: 28
text: "Zoe"
text_font: font_name
text_color: 0x2D3436
- label:
id: home_status_zoe
align: CENTER
y: 68
text: "not done"
text_font: font_tiny
text_color: 0xFF4757
- id: page_emma
bg_color: 0xFFF9F0
widgets:
# ── Sidebar ──────────────────────────────────────────────────────────
- obj:
x: 0
y: 0
width: 180
height: 480
bg_color: 0x4D96FF
border_width: 0
radius: 0
pad_all: 0
widgets:
- label:
x: 0
y: 20
width: 180
align: TOP_MID
text: "🐶"
text_font: font_title
- label:
x: 0
y: 74
width: 180
align: TOP_MID
text: "Emma"
text_font: font_name
text_color: 0xFFFFFF
- label:
id: sidebar_stars_emma
x: 0
y: 120
width: 180
align: TOP_MID
text: "⭐ 0 stars"
text_font: font_med
text_color: 0xFFD93D
# Progress bar
- bar:
id: progress_bar_emma
x: 16
y: 164
width: 148
height: 16
bg_color: 0x2A6FCC
indicator:
bg_color: 0xFFFFFF
value: 0
min_value: 0
max_value: 8
- label:
id: progress_label_emma
x: 0
y: 188
width: 180
align: TOP_MID
text: "0 / 8"
text_font: font_tiny
text_color: 0xDDEEFF
# All-done celebration label (hidden until complete)
- label:
id: all_done_label_emma
x: 0
y: 214
width: 180
align: TOP_MID
text: ""
text_font: font_small
text_color: 0xFFFFFF
# Manual reset button (parent use — above back button)
- btn:
x: 16
y: 362
width: 148
height: 44
bg_color: 0xFF4757
radius: 14
on_click:
then:
- script.execute: reset_emma_chores
widgets:
- label:
align: CENTER
text: "↺ Reset"
text_color: 0xFFFFFF
text_font: font_small
# Back button
- btn:
x: 16
y: 418
width: 148
height: 46
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 ───────────────────────────────────────────────────────
# Make Bed
- btn:
id: card_emma_make_bed
x: 190
y: 10
width: 193
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: emma_make_bed
widgets:
- label:
id: check_emma_make_bed
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🛏️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Make Bed"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Brush Teeth
- btn:
id: card_emma_brush_teeth
x: 393
y: 10
width: 193
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: emma_brush_teeth
widgets:
- label:
id: check_emma_brush_teeth
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🦷"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Brush Teeth"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Tidy Room
- btn:
id: card_emma_tidy_room
x: 596
y: 10
width: 193
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: emma_tidy_room
widgets:
- label:
id: check_emma_tidy_room
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🧹"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Tidy Room"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 2"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Homework
- btn:
id: card_emma_homework
x: 190
y: 158
width: 193
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: emma_homework
widgets:
- label:
id: check_emma_homework
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "📚"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Homework"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 3"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Set Table
- btn:
id: card_emma_set_table
x: 393
y: 158
width: 193
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: emma_set_table
widgets:
- label:
id: check_emma_set_table
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🍽️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Set Table"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Take Out Trash
- btn:
id: card_emma_take_out_trash
x: 596
y: 158
width: 193
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: emma_take_out_trash
widgets:
- label:
id: check_emma_take_out_trash
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🗑️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Take Out Trash"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 2"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Feed Pet
- btn:
id: card_emma_feed_pet
x: 190
y: 306
width: 193
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: emma_feed_pet
widgets:
- label:
id: check_emma_feed_pet
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🐾"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Feed Pet"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Water Plants
- btn:
id: card_emma_water_plants
x: 393
y: 306
width: 193
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: emma_water_plants
widgets:
- label:
id: check_emma_water_plants
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🌱"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Water Plants"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
- id: page_liam
bg_color: 0xFFF9F0
widgets:
# ── Sidebar ──────────────────────────────────────────────────────────
- obj:
x: 0
y: 0
width: 180
height: 480
bg_color: 0xC77DFF
border_width: 0
radius: 0
pad_all: 0
widgets:
- label:
x: 0
y: 20
width: 180
align: TOP_MID
text: "🐱"
text_font: font_title
- label:
x: 0
y: 74
width: 180
align: TOP_MID
text: "Liam"
text_font: font_name
text_color: 0xFFFFFF
- label:
id: sidebar_stars_liam
x: 0
y: 120
width: 180
align: TOP_MID
text: "⭐ 0 stars"
text_font: font_med
text_color: 0xFFD93D
# Progress bar
- bar:
id: progress_bar_liam
x: 16
y: 164
width: 148
height: 16
bg_color: 0x8B42CC
indicator:
bg_color: 0xFFFFFF
value: 0
min_value: 0
max_value: 8
- label:
id: progress_label_liam
x: 0
y: 188
width: 180
align: TOP_MID
text: "0 / 8"
text_font: font_tiny
text_color: 0xDDEEFF
# All-done celebration label (hidden until complete)
- label:
id: all_done_label_liam
x: 0
y: 214
width: 180
align: TOP_MID
text: ""
text_font: font_small
text_color: 0xFFFFFF
# Manual reset button (parent use — above back button)
- btn:
x: 16
y: 362
width: 148
height: 44
bg_color: 0xFF4757
radius: 14
on_click:
then:
- script.execute: reset_liam_chores
widgets:
- label:
align: CENTER
text: "↺ Reset"
text_color: 0xFFFFFF
text_font: font_small
# Back button
- btn:
x: 16
y: 418
width: 148
height: 46
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 ───────────────────────────────────────────────────────
# Make Bed
- btn:
id: card_liam_make_bed
x: 190
y: 10
width: 193
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: liam_make_bed
widgets:
- label:
id: check_liam_make_bed
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🛏️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Make Bed"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Brush Teeth
- btn:
id: card_liam_brush_teeth
x: 393
y: 10
width: 193
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: liam_brush_teeth
widgets:
- label:
id: check_liam_brush_teeth
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🦷"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Brush Teeth"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Tidy Room
- btn:
id: card_liam_tidy_room
x: 596
y: 10
width: 193
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: liam_tidy_room
widgets:
- label:
id: check_liam_tidy_room
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🧹"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Tidy Room"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 2"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Homework
- btn:
id: card_liam_homework
x: 190
y: 158
width: 193
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: liam_homework
widgets:
- label:
id: check_liam_homework
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "📚"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Homework"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 3"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Set Table
- btn:
id: card_liam_set_table
x: 393
y: 158
width: 193
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: liam_set_table
widgets:
- label:
id: check_liam_set_table
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🍽️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Set Table"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Take Out Trash
- btn:
id: card_liam_take_out_trash
x: 596
y: 158
width: 193
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: liam_take_out_trash
widgets:
- label:
id: check_liam_take_out_trash
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🗑️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Take Out Trash"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 2"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Feed Pet
- btn:
id: card_liam_feed_pet
x: 190
y: 306
width: 193
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: liam_feed_pet
widgets:
- label:
id: check_liam_feed_pet
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🐾"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Feed Pet"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Water Plants
- btn:
id: card_liam_water_plants
x: 393
y: 306
width: 193
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: liam_water_plants
widgets:
- label:
id: check_liam_water_plants
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🌱"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Water Plants"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
- id: page_zoe
bg_color: 0xFFF9F0
widgets:
# ── Sidebar ──────────────────────────────────────────────────────────
- obj:
x: 0
y: 0
width: 180
height: 480
bg_color: 0xFF6B9D
border_width: 0
radius: 0
pad_all: 0
widgets:
- label:
x: 0
y: 20
width: 180
align: TOP_MID
text: "🐻"
text_font: font_title
- label:
x: 0
y: 74
width: 180
align: TOP_MID
text: "Zoe"
text_font: font_name
text_color: 0xFFFFFF
- label:
id: sidebar_stars_zoe
x: 0
y: 120
width: 180
align: TOP_MID
text: "⭐ 0 stars"
text_font: font_med
text_color: 0xFFD93D
# Progress bar
- bar:
id: progress_bar_zoe
x: 16
y: 164
width: 148
height: 16
bg_color: 0xCC3A6F
indicator:
bg_color: 0xFFFFFF
value: 0
min_value: 0
max_value: 8
- label:
id: progress_label_zoe
x: 0
y: 188
width: 180
align: TOP_MID
text: "0 / 8"
text_font: font_tiny
text_color: 0xDDEEFF
# All-done celebration label (hidden until complete)
- label:
id: all_done_label_zoe
x: 0
y: 214
width: 180
align: TOP_MID
text: ""
text_font: font_small
text_color: 0xFFFFFF
# Manual reset button (parent use — above back button)
- btn:
x: 16
y: 362
width: 148
height: 44
bg_color: 0xFF4757
radius: 14
on_click:
then:
- script.execute: reset_zoe_chores
widgets:
- label:
align: CENTER
text: "↺ Reset"
text_color: 0xFFFFFF
text_font: font_small
# Back button
- btn:
x: 16
y: 418
width: 148
height: 46
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 ───────────────────────────────────────────────────────
# Make Bed
- btn:
id: card_zoe_make_bed
x: 190
y: 10
width: 193
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: zoe_make_bed
widgets:
- label:
id: check_zoe_make_bed
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🛏️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Make Bed"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Brush Teeth
- btn:
id: card_zoe_brush_teeth
x: 393
y: 10
width: 193
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: zoe_brush_teeth
widgets:
- label:
id: check_zoe_brush_teeth
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🦷"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Brush Teeth"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Tidy Room
- btn:
id: card_zoe_tidy_room
x: 596
y: 10
width: 193
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: zoe_tidy_room
widgets:
- label:
id: check_zoe_tidy_room
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🧹"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Tidy Room"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 2"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Homework
- btn:
id: card_zoe_homework
x: 190
y: 158
width: 193
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: zoe_homework
widgets:
- label:
id: check_zoe_homework
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "📚"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Homework"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 3"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Set Table
- btn:
id: card_zoe_set_table
x: 393
y: 158
width: 193
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: zoe_set_table
widgets:
- label:
id: check_zoe_set_table
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🍽️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Set Table"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Take Out Trash
- btn:
id: card_zoe_take_out_trash
x: 596
y: 158
width: 193
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: zoe_take_out_trash
widgets:
- label:
id: check_zoe_take_out_trash
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🗑️"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Take Out Trash"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 2"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Feed Pet
- btn:
id: card_zoe_feed_pet
x: 190
y: 306
width: 193
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: zoe_feed_pet
widgets:
- label:
id: check_zoe_feed_pet
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🐾"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Feed Pet"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2
# Water Plants
- btn:
id: card_zoe_water_plants
x: 393
y: 306
width: 193
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: zoe_water_plants
widgets:
- label:
id: check_zoe_water_plants
align: TOP_RIGHT
x: -10
y: 8
text: ""
text_font: font_med
- label:
align: CENTER
y: -34
text: "🌱"
text_font: font_med
- label:
align: CENTER
y: 23
text: "Water Plants"
text_font: font_small
text_color: 0x2D3436
- label:
align: CENTER
y: 45
text: "⭐ 1"
text_font: font_tiny
text_color: 0x7A5900
bg_color: 0xFFD93D
radius: 8
pad_left: 8
pad_right: 8
pad_top: 2
pad_bottom: 2