Files
Home-Assistant/esphome/chore-tracker-esphome.yaml
Joshua King 689b173f30 Refactor chore tracker configuration and update chore counts
- Updated chore counts for Jordyn, Declan, and Chloe in the dashboard and configuration files.
- Modified chore names and icons for Jordyn, Declan, and Chloe to reflect new tasks.
- Adjusted automation scripts to align with the updated chore structure and counts.
- Ensured notifications reflect the correct number of completed chores for each child.
2026-02-28 11:52:51 -05:00

1380 lines
49 KiB
YAML

################################################################################
# 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 - Put on underwear"
id: jordyn_put_on_underwear
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_put_on_underwear
on_turn_off:
then:
- script.execute: update_jordyn_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_jordyn_put_on_underwear
- 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 - Check & fill water bowls"
id: jordyn_check_&_fill_water_bowls
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_check_&_fill_water_bowls
on_turn_off:
then:
- script.execute: update_jordyn_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_jordyn_check_&_fill_water_bowls
- platform: template
name: "Jordyn - Restock Cat Food Cans"
id: jordyn_restock_cat_food_cans
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_restock_cat_food_cans
on_turn_off:
then:
- script.execute: update_jordyn_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_jordyn_restock_cat_food_cans
# ── Declan's chores ──────────────────────────
- platform: template
name: "Declan - Take morning pill"
id: declan_take_morning_pill
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_morning_pill
on_turn_off:
then:
- script.execute: update_declan_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_declan_take_morning_pill
- platform: template
name: "Declan - Scoop Dog Poop"
id: declan_scoop_dog_poop
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_scoop_dog_poop
on_turn_off:
then:
- script.execute: update_declan_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_declan_scoop_dog_poop
# ── Chloe's chores ──────────────────────────
- platform: template
name: "Chloe - Check & fill kitty feeders"
id: chloe_check_&_fill_kitty_feeders
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_check_&_fill_kitty_feeders
on_turn_off:
then:
- script.execute: update_chloe_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_chloe_check_&_fill_kitty_feeders
- platform: template
name: "Chloe - Scoop Kitty Litter"
id: chloe_scoop_kitty_litter
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_scoop_kitty_litter
on_turn_off:
then:
- script.execute: update_chloe_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_chloe_scoop_kitty_litter
- platform: template
name: "Chloe - Replace Kitty Litter Bags"
id: chloe_replace_kitty_litter_bags
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_replace_kitty_litter_bags
on_turn_off:
then:
- script.execute: update_chloe_ui
- homeassistant.service:
service: switch.turn_off
data:
entity_id: switch.chore_tracker_chloe_replace_kitty_litter_bags
# ── 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_put_on_underwear).state) done++;
if (id(jordyn_brush_teeth).state) done++;
if (id(jordyn_check_&_fill_water_bowls).state) done++;
if (id(jordyn_restock_cat_food_cans).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_take_morning_pill).state) done++;
if (id(declan_scoop_dog_poop).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_check_&_fill_kitty_feeders).state) done++;
if (id(chloe_scoop_kitty_litter).state) done++;
if (id(chloe_replace_kitty_litter_bags).state) done++;
return done;
# ── Scripts — reset + UI update ───────────────────────────────────────────────
script:
- id: reset_jordyn_chores
mode: single
then:
- lambda: |-
id(jordyn_put_on_underwear).turn_off();
id(jordyn_brush_teeth).turn_off();
id(jordyn_check_&_fill_water_bowls).turn_off();
id(jordyn_restock_cat_food_cans).turn_off();
- script.execute: update_jordyn_ui
- id: update_jordyn_ui
mode: single
then:
- lambda: |-
int done = (id(jordyn_put_on_underwear).state ? 1 : 0) + (id(jordyn_brush_teeth).state ? 1 : 0) + (id(jordyn_check_&_fill_water_bowls).state ? 1 : 0) + (id(jordyn_restock_cat_food_cans).state ? 1 : 0);
int total = 4;
char buf[24];
// Progress bar + label
lv_bar_set_value(id(progress_bar_jordyn), done, LV_ANIM_ON);
snprintf(buf, sizeof(buf), "%d / 4", 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_put_on_underwear).state) {
lv_obj_set_style_bg_color(id(card_jordyn_put_on_underwear), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_jordyn_put_on_underwear), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_jordyn_put_on_underwear), 3, LV_PART_MAIN);
lv_label_set_text(id(check_jordyn_put_on_underwear), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_jordyn_put_on_underwear), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_jordyn_put_on_underwear), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_jordyn_put_on_underwear), 2, LV_PART_MAIN);
lv_label_set_text(id(check_jordyn_put_on_underwear), "");
}
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_check_&_fill_water_bowls).state) {
lv_obj_set_style_bg_color(id(card_jordyn_check_&_fill_water_bowls), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_jordyn_check_&_fill_water_bowls), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_jordyn_check_&_fill_water_bowls), 3, LV_PART_MAIN);
lv_label_set_text(id(check_jordyn_check_&_fill_water_bowls), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_jordyn_check_&_fill_water_bowls), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_jordyn_check_&_fill_water_bowls), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_jordyn_check_&_fill_water_bowls), 2, LV_PART_MAIN);
lv_label_set_text(id(check_jordyn_check_&_fill_water_bowls), "");
}
if (id(jordyn_restock_cat_food_cans).state) {
lv_obj_set_style_bg_color(id(card_jordyn_restock_cat_food_cans), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_jordyn_restock_cat_food_cans), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_jordyn_restock_cat_food_cans), 3, LV_PART_MAIN);
lv_label_set_text(id(check_jordyn_restock_cat_food_cans), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_jordyn_restock_cat_food_cans), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_jordyn_restock_cat_food_cans), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_jordyn_restock_cat_food_cans), 2, LV_PART_MAIN);
lv_label_set_text(id(check_jordyn_restock_cat_food_cans), "");
}
- id: reset_declan_chores
mode: single
then:
- lambda: |-
id(declan_take_morning_pill).turn_off();
id(declan_scoop_dog_poop).turn_off();
- script.execute: update_declan_ui
- id: update_declan_ui
mode: single
then:
- lambda: |-
int done = (id(declan_take_morning_pill).state ? 1 : 0) + (id(declan_scoop_dog_poop).state ? 1 : 0);
int total = 2;
char buf[24];
// Progress bar + label
lv_bar_set_value(id(progress_bar_declan), done, LV_ANIM_ON);
snprintf(buf, sizeof(buf), "%d / 2", 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_take_morning_pill).state) {
lv_obj_set_style_bg_color(id(card_declan_take_morning_pill), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_declan_take_morning_pill), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_declan_take_morning_pill), 3, LV_PART_MAIN);
lv_label_set_text(id(check_declan_take_morning_pill), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_declan_take_morning_pill), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_declan_take_morning_pill), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_declan_take_morning_pill), 2, LV_PART_MAIN);
lv_label_set_text(id(check_declan_take_morning_pill), "");
}
if (id(declan_scoop_dog_poop).state) {
lv_obj_set_style_bg_color(id(card_declan_scoop_dog_poop), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_declan_scoop_dog_poop), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_declan_scoop_dog_poop), 3, LV_PART_MAIN);
lv_label_set_text(id(check_declan_scoop_dog_poop), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_declan_scoop_dog_poop), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_declan_scoop_dog_poop), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_declan_scoop_dog_poop), 2, LV_PART_MAIN);
lv_label_set_text(id(check_declan_scoop_dog_poop), "");
}
- id: reset_chloe_chores
mode: single
then:
- lambda: |-
id(chloe_check_&_fill_kitty_feeders).turn_off();
id(chloe_scoop_kitty_litter).turn_off();
id(chloe_replace_kitty_litter_bags).turn_off();
- script.execute: update_chloe_ui
- id: update_chloe_ui
mode: single
then:
- lambda: |-
int done = (id(chloe_check_&_fill_kitty_feeders).state ? 1 : 0) + (id(chloe_scoop_kitty_litter).state ? 1 : 0) + (id(chloe_replace_kitty_litter_bags).state ? 1 : 0);
int total = 3;
char buf[24];
// Progress bar + label
lv_bar_set_value(id(progress_bar_chloe), done, LV_ANIM_ON);
snprintf(buf, sizeof(buf), "%d / 3", 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_check_&_fill_kitty_feeders).state) {
lv_obj_set_style_bg_color(id(card_chloe_check_&_fill_kitty_feeders), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_chloe_check_&_fill_kitty_feeders), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_chloe_check_&_fill_kitty_feeders), 3, LV_PART_MAIN);
lv_label_set_text(id(check_chloe_check_&_fill_kitty_feeders), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_chloe_check_&_fill_kitty_feeders), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_chloe_check_&_fill_kitty_feeders), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_chloe_check_&_fill_kitty_feeders), 2, LV_PART_MAIN);
lv_label_set_text(id(check_chloe_check_&_fill_kitty_feeders), "");
}
if (id(chloe_scoop_kitty_litter).state) {
lv_obj_set_style_bg_color(id(card_chloe_scoop_kitty_litter), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_chloe_scoop_kitty_litter), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_chloe_scoop_kitty_litter), 3, LV_PART_MAIN);
lv_label_set_text(id(check_chloe_scoop_kitty_litter), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_chloe_scoop_kitty_litter), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_chloe_scoop_kitty_litter), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_chloe_scoop_kitty_litter), 2, LV_PART_MAIN);
lv_label_set_text(id(check_chloe_scoop_kitty_litter), "");
}
if (id(chloe_replace_kitty_litter_bags).state) {
lv_obj_set_style_bg_color(id(card_chloe_replace_kitty_litter_bags), lv_color_hex(0xF0FFF4), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_chloe_replace_kitty_litter_bags), lv_color_hex(0x6BCB77), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_chloe_replace_kitty_litter_bags), 3, LV_PART_MAIN);
lv_label_set_text(id(check_chloe_replace_kitty_litter_bags), "\u2705");
} else {
lv_obj_set_style_bg_color(id(card_chloe_replace_kitty_litter_bags), lv_color_hex(0xFFFFFF), LV_PART_MAIN);
lv_obj_set_style_border_color(id(card_chloe_replace_kitty_litter_bags), lv_color_hex(0xEEEEEE), LV_PART_MAIN);
lv_obj_set_style_border_width(id(card_chloe_replace_kitty_litter_bags), 2, LV_PART_MAIN);
lv_label_set_text(id(check_chloe_replace_kitty_litter_bags), "");
}
# ── 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: 4
- label:
id: progress_label_jordyn
x: 0
y: 156
width: 172
align: TOP_MID
text: "0 / 4"
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_put_on_underwear
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_put_on_underwear
widgets:
- label:
id: check_jordyn_put_on_underwear
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: "Put on underwear"
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_check_&_fill_water_bowls
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_check_&_fill_water_bowls
widgets:
- label:
id: check_jordyn_check_&_fill_water_bowls
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: "Check & fill water bowls"
text_font: font_small
text_color: 0x2D3436
- button:
id: card_jordyn_restock_cat_food_cans
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_restock_cat_food_cans
widgets:
- label:
id: check_jordyn_restock_cat_food_cans
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: "Restock Cat Food Cans"
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: 2
- label:
id: progress_label_declan
x: 0
y: 156
width: 172
align: TOP_MID
text: "0 / 2"
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_take_morning_pill
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_take_morning_pill
widgets:
- label:
id: check_declan_take_morning_pill
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 morning pill"
text_font: font_small
text_color: 0x2D3436
- button:
id: card_declan_scoop_dog_poop
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_scoop_dog_poop
widgets:
- label:
id: check_declan_scoop_dog_poop
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: "Scoop Dog Poop"
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: 3
- label:
id: progress_label_chloe
x: 0
y: 156
width: 172
align: TOP_MID
text: "0 / 3"
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_check_&_fill_kitty_feeders
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_check_&_fill_kitty_feeders
widgets:
- label:
id: check_chloe_check_&_fill_kitty_feeders
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: "Check & fill kitty feeders"
text_font: font_small
text_color: 0x2D3436
- button:
id: card_chloe_scoop_kitty_litter
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_scoop_kitty_litter
widgets:
- label:
id: check_chloe_scoop_kitty_litter
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: "Scoop Kitty Litter"
text_font: font_small
text_color: 0x2D3436
- button:
id: card_chloe_replace_kitty_litter_bags
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_replace_kitty_litter_bags
widgets:
- label:
id: check_chloe_replace_kitty_litter_bags
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: "Replace Kitty Litter Bags"
text_font: font_small
text_color: 0x2D3436