diff --git a/esphome/esp-bedside-panel.yaml b/esphome/esp-bedside-panel.yaml index 7c628cb..0db7131 100644 --- a/esphome/esp-bedside-panel.yaml +++ b/esphome/esp-bedside-panel.yaml @@ -6,6 +6,7 @@ # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml #:########################################################################################:# # VERSIONS: +# V1.37 2026-07-19 Added four persistent Alarm Clock configuration rows # V1.36 2026-07-19 Added Alarm Clock navigation button and initial empty page # V1.35 2026-07-19 Added an adjustable Blackout range below 2 lx # V1.34 2026-07-19 Added three ambient-light ranges and periodic backlight rechecking @@ -128,7 +129,9 @@ # - Clock/idle brightness is rechecked periodically as ambient light changes. # - Calibration, thresholds, brightness and delay values persist across reboot. # - The Bedroom header has separate Bedtime and Alarm Clock controls. -# - The initial Alarm Clock page contains only Back and live-time navigation. +# - The Alarm Clock page contains four persistent configuration rows. +# - Enable, days, vibration profile, sound profile and lamp choices are active. +# - Alarm times are displayed in 24-hour format; the time editor comes next. #:########################################################################################:# # OFFLINE NOTES: # - LVGL, the clock, touch and backlight operate locally. @@ -147,12 +150,12 @@ substitutions: # Device Naming device_name: "esp-bedside-panel" friendly_name: "ESP Bedside Panel" - description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Added split Bedtime/Alarm controls and the initial Alarm Clock page. (Layout V1.1)" + description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Four-row Alarm Clock configuration interface with persistent enable, day, output and lamp selections. (Layout V1.1)" device_area: "Bedroom" # Project Naming project_name: "Guition.JC1060P470C_I_W_Y" - project_version: "v1.36" + project_version: "v1.37" # Passwords & Secrets api_key: !secret esp-api_key @@ -371,6 +374,7 @@ esphome: - script.execute: refresh_sleep_timer - script.execute: refresh_navigation_time - script.execute: refresh_jobs_page + - script.execute: refresh_alarm_clock_page #:########################################################################################:# # ESP PLATFORM AND FRAMEWORK: @@ -669,6 +673,8 @@ font: - "\U000F06D9" # mdi-garage - "\U000F1054" # mdi-outdoor-lamp - "\U000F014E" # mdi-clipboard-check + - "\U000F0131" # mdi-checkbox-blank-outline + - "\U000F0132" # mdi-checkbox-marked # Large bottom-navigation icons. - file: "https://raw.githubusercontent.com/Templarian/MaterialDesign-Webfont/master/fonts/materialdesignicons-webfont.ttf" @@ -1566,11 +1572,580 @@ globals: restore_value: false initial_value: "1" + #:######################################################################################:# + # ALARM CLOCK SETTINGS + #:######################################################################################:# + # + # Four alarm rows are stored locally. Alarm execution and the time editor are + # added later; this revision provides the persistent row controls. + # + # Day mask bits: + # 0 Monday, 1 Tuesday, 2 Wednesday, 3 Thursday, + # 4 Friday, 5 Saturday, 6 Sunday, 7 Public Holiday. + - id: alarm_enabled + type: bool[4] + restore_value: true + initial_value: '{false, false, false, false}' + + - id: alarm_hour + type: uint8_t[4] + restore_value: true + initial_value: '{7, 7, 7, 7}' + + - id: alarm_minute + type: uint8_t[4] + restore_value: true + initial_value: '{0, 0, 0, 0}' + + - id: alarm_day_mask + type: uint8_t[4] + restore_value: true + initial_value: '{31, 31, 31, 31}' + + - id: alarm_vibrate_option + type: uint8_t[4] + restore_value: true + initial_value: '{1, 1, 1, 1}' + + - id: alarm_sound_option + type: uint8_t[4] + restore_value: true + initial_value: '{1, 1, 1, 1}' + + - id: alarm_lamp_enabled + type: bool[4] + restore_value: true + initial_value: '{false, false, false, false}' + #:########################################################################################:# # SCRIPTS: # Refresh all state-dependent LVGL button colours #:########################################################################################:# script: + #:######################################################################################:# + # ALARM CLOCK PAGE STATE REFRESH + #:######################################################################################:# + - id: refresh_alarm_clock_page + mode: restart + then: + - if: + condition: + lambda: |- + return id(lvgl_ready); + + then: + - lvgl.widget.update: + id: alarm_1_enable_button + state: + checked: !lambda |- + return id(alarm_enabled)[0]; + + - lvgl.label.update: + id: alarm_1_enable_label + text: !lambda |- + return id(alarm_enabled)[0] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + - lvgl.label.update: + id: alarm_1_time_label + text: !lambda |- + char buffer[8]; + snprintf( + buffer, + sizeof(buffer), + "%02u:%02u", + id(alarm_hour)[0], + id(alarm_minute)[0] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_1_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[0] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_1_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[0] + ); + return std::string(buffer); + + - lvgl.widget.update: + id: alarm_1_lamp_button + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[0]; + + - lvgl.widget.update: + id: alarm_1_day_m + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 0) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_tu + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 1) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_w + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 2) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_th + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 3) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_f + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 4) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_sa + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 5) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_su + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 6) + ) != 0; + + - lvgl.widget.update: + id: alarm_1_day_h + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 7) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_enable_button + state: + checked: !lambda |- + return id(alarm_enabled)[1]; + + - lvgl.label.update: + id: alarm_2_enable_label + text: !lambda |- + return id(alarm_enabled)[1] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + - lvgl.label.update: + id: alarm_2_time_label + text: !lambda |- + char buffer[8]; + snprintf( + buffer, + sizeof(buffer), + "%02u:%02u", + id(alarm_hour)[1], + id(alarm_minute)[1] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_2_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[1] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_2_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[1] + ); + return std::string(buffer); + + - lvgl.widget.update: + id: alarm_2_lamp_button + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[1]; + + - lvgl.widget.update: + id: alarm_2_day_m + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 0) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_tu + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 1) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_w + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 2) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_th + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 3) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_f + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 4) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_sa + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 5) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_su + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 6) + ) != 0; + + - lvgl.widget.update: + id: alarm_2_day_h + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 7) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_enable_button + state: + checked: !lambda |- + return id(alarm_enabled)[2]; + + - lvgl.label.update: + id: alarm_3_enable_label + text: !lambda |- + return id(alarm_enabled)[2] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + - lvgl.label.update: + id: alarm_3_time_label + text: !lambda |- + char buffer[8]; + snprintf( + buffer, + sizeof(buffer), + "%02u:%02u", + id(alarm_hour)[2], + id(alarm_minute)[2] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_3_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[2] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_3_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[2] + ); + return std::string(buffer); + + - lvgl.widget.update: + id: alarm_3_lamp_button + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[2]; + + - lvgl.widget.update: + id: alarm_3_day_m + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 0) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_tu + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 1) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_w + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 2) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_th + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 3) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_f + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 4) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_sa + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 5) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_su + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 6) + ) != 0; + + - lvgl.widget.update: + id: alarm_3_day_h + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 7) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_enable_button + state: + checked: !lambda |- + return id(alarm_enabled)[3]; + + - lvgl.label.update: + id: alarm_4_enable_label + text: !lambda |- + return id(alarm_enabled)[3] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + - lvgl.label.update: + id: alarm_4_time_label + text: !lambda |- + char buffer[8]; + snprintf( + buffer, + sizeof(buffer), + "%02u:%02u", + id(alarm_hour)[3], + id(alarm_minute)[3] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_4_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[3] + ); + return std::string(buffer); + + - lvgl.label.update: + id: alarm_4_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[3] + ); + return std::string(buffer); + + - lvgl.widget.update: + id: alarm_4_lamp_button + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[3]; + + - lvgl.widget.update: + id: alarm_4_day_m + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 0) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_tu + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 1) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_w + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 2) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_th + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 3) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_f + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 4) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_sa + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 5) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_su + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 6) + ) != 0; + + - lvgl.widget.update: + id: alarm_4_day_h + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 7) + ) != 0; + #:######################################################################################:# # ADAPTIVE DISPLAY BACKLIGHT #:######################################################################################:# @@ -4604,6 +5179,8 @@ lvgl: text_color: 0xFFE8E8 on_click: + - script.execute: refresh_alarm_clock_page + - lvgl.page.show: id: alarm_clock_page animation: MOVE_LEFT @@ -7591,14 +8168,2093 @@ lvgl: # ALARM CLOCK PAGE #:####################################################################################:# # - # Initial shell page. Alarm configuration and display features will be - # added in later revisions. + # Four local alarm configuration rows. Alarm execution and time editing are + # deliberately deferred until their interaction design is finalised. - id: alarm_clock_page skip: true bg_color: 0x10151D bg_opa: COVER widgets: + #:################################################################################:# + # ALARM CONFIGURATION ROWS + #:################################################################################:# + - obj: + id: alarm_1_row + x: 10 + y: 10 + width: 1004 + height: 96 + bg_color: 0x171F29 + bg_opa: COVER + border_width: 1 + border_color: 0x364250 + outline_width: 0 + shadow_width: 0 + radius: 14 + pad_all: 0 + clickable: false + widgets: + - button: + id: alarm_1_enable_button + x: 8 + y: 13 + width: 54 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_enabled)[0]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x548C6C + radius: 11 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x416F55 + widgets: + - label: + id: alarm_1_enable_label + align: CENTER + text: !lambda |- + return id(alarm_enabled)[0] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + text_font: font_mdi_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_enabled)[0] = x; + + - lvgl.label.update: + id: alarm_1_enable_label + text: !lambda |- + return id(alarm_enabled)[0] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + # Time display. A dedicated 24-hour editor is added next. + - button: + id: alarm_1_time_button + x: 68 + y: 13 + width: 122 + height: 70 + bg_color: 0x214F72 + bg_opa: COVER + border_width: 2 + border_color: 0x3E7FA7 + radius: 11 + pressed: + bg_color: 0x2E6A96 + widgets: + - label: + id: alarm_1_time_label + align: CENTER + text: "07:00" + text_font: font_vehicle_bold + text_color: 0xFFFFFF + + - button: + id: alarm_1_day_m + x: 196 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 0) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "M" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 0); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 0)); + } + + - button: + id: alarm_1_day_tu + x: 240 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 1) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 1); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 1)); + } + + - button: + id: alarm_1_day_w + x: 284 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 2) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "W" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 2); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 2)); + } + + - button: + id: alarm_1_day_th + x: 328 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 3) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 3); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 3)); + } + + - button: + id: alarm_1_day_f + x: 372 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 4) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "F" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 4); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 4)); + } + + - button: + id: alarm_1_day_sa + x: 416 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 5) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 5); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 5)); + } + + - button: + id: alarm_1_day_su + x: 460 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 6) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 6); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 6)); + } + + - button: + id: alarm_1_day_h + x: 504 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[0] & + (1U << 7) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "H" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[0] |= + static_cast(1U << 7); + } else { + id(alarm_day_mask)[0] &= + static_cast(~(1U << 7)); + } + + - button: + id: alarm_1_vibrate_button + x: 556 + y: 13 + width: 132 + height: 70 + bg_color: 0x4B3A63 + bg_opa: COVER + border_width: 2 + border_color: 0x735E88 + radius: 11 + pressed: + bg_color: 0x624B7D + widgets: + - label: + id: alarm_1_vibrate_label + align: CENTER + text: "Vibrate\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_vibrate_option)[0] = + (id(alarm_vibrate_option)[0] % 3) + 1; + + - lvgl.label.update: + id: alarm_1_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[0] + ); + return std::string(buffer); + + - button: + id: alarm_1_sound_button + x: 696 + y: 13 + width: 126 + height: 70 + bg_color: 0x384E66 + bg_opa: COVER + border_width: 2 + border_color: 0x557895 + radius: 11 + pressed: + bg_color: 0x496681 + widgets: + - label: + id: alarm_1_sound_label + align: CENTER + text: "Sound\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_sound_option)[0] = + (id(alarm_sound_option)[0] % 3) + 1; + + - lvgl.label.update: + id: alarm_1_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[0] + ); + return std::string(buffer); + + - button: + id: alarm_1_lamp_button + x: 830 + y: 13 + width: 164 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[0]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x806E42 + radius: 11 + checked: + bg_color: 0x8C6815 + border_color: 0xC99A2B + pressed: + bg_color: 0xA67E20 + widgets: + - label: + align: CENTER + text: "Lamp" + text_font: font_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_lamp_enabled)[0] = x; + + - obj: + id: alarm_2_row + x: 10 + y: 116 + width: 1004 + height: 96 + bg_color: 0x171F29 + bg_opa: COVER + border_width: 1 + border_color: 0x364250 + outline_width: 0 + shadow_width: 0 + radius: 14 + pad_all: 0 + clickable: false + widgets: + - button: + id: alarm_2_enable_button + x: 8 + y: 13 + width: 54 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_enabled)[1]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x548C6C + radius: 11 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x416F55 + widgets: + - label: + id: alarm_2_enable_label + align: CENTER + text: !lambda |- + return id(alarm_enabled)[1] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + text_font: font_mdi_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_enabled)[1] = x; + + - lvgl.label.update: + id: alarm_2_enable_label + text: !lambda |- + return id(alarm_enabled)[1] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + # Time display. A dedicated 24-hour editor is added next. + - button: + id: alarm_2_time_button + x: 68 + y: 13 + width: 122 + height: 70 + bg_color: 0x214F72 + bg_opa: COVER + border_width: 2 + border_color: 0x3E7FA7 + radius: 11 + pressed: + bg_color: 0x2E6A96 + widgets: + - label: + id: alarm_2_time_label + align: CENTER + text: "07:00" + text_font: font_vehicle_bold + text_color: 0xFFFFFF + + - button: + id: alarm_2_day_m + x: 196 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 0) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "M" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 0); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 0)); + } + + - button: + id: alarm_2_day_tu + x: 240 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 1) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 1); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 1)); + } + + - button: + id: alarm_2_day_w + x: 284 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 2) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "W" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 2); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 2)); + } + + - button: + id: alarm_2_day_th + x: 328 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 3) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 3); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 3)); + } + + - button: + id: alarm_2_day_f + x: 372 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 4) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "F" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 4); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 4)); + } + + - button: + id: alarm_2_day_sa + x: 416 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 5) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 5); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 5)); + } + + - button: + id: alarm_2_day_su + x: 460 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 6) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 6); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 6)); + } + + - button: + id: alarm_2_day_h + x: 504 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[1] & + (1U << 7) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "H" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[1] |= + static_cast(1U << 7); + } else { + id(alarm_day_mask)[1] &= + static_cast(~(1U << 7)); + } + + - button: + id: alarm_2_vibrate_button + x: 556 + y: 13 + width: 132 + height: 70 + bg_color: 0x4B3A63 + bg_opa: COVER + border_width: 2 + border_color: 0x735E88 + radius: 11 + pressed: + bg_color: 0x624B7D + widgets: + - label: + id: alarm_2_vibrate_label + align: CENTER + text: "Vibrate\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_vibrate_option)[1] = + (id(alarm_vibrate_option)[1] % 3) + 1; + + - lvgl.label.update: + id: alarm_2_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[1] + ); + return std::string(buffer); + + - button: + id: alarm_2_sound_button + x: 696 + y: 13 + width: 126 + height: 70 + bg_color: 0x384E66 + bg_opa: COVER + border_width: 2 + border_color: 0x557895 + radius: 11 + pressed: + bg_color: 0x496681 + widgets: + - label: + id: alarm_2_sound_label + align: CENTER + text: "Sound\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_sound_option)[1] = + (id(alarm_sound_option)[1] % 3) + 1; + + - lvgl.label.update: + id: alarm_2_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[1] + ); + return std::string(buffer); + + - button: + id: alarm_2_lamp_button + x: 830 + y: 13 + width: 164 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[1]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x806E42 + radius: 11 + checked: + bg_color: 0x8C6815 + border_color: 0xC99A2B + pressed: + bg_color: 0xA67E20 + widgets: + - label: + align: CENTER + text: "Lamp" + text_font: font_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_lamp_enabled)[1] = x; + + - obj: + id: alarm_3_row + x: 10 + y: 222 + width: 1004 + height: 96 + bg_color: 0x171F29 + bg_opa: COVER + border_width: 1 + border_color: 0x364250 + outline_width: 0 + shadow_width: 0 + radius: 14 + pad_all: 0 + clickable: false + widgets: + - button: + id: alarm_3_enable_button + x: 8 + y: 13 + width: 54 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_enabled)[2]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x548C6C + radius: 11 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x416F55 + widgets: + - label: + id: alarm_3_enable_label + align: CENTER + text: !lambda |- + return id(alarm_enabled)[2] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + text_font: font_mdi_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_enabled)[2] = x; + + - lvgl.label.update: + id: alarm_3_enable_label + text: !lambda |- + return id(alarm_enabled)[2] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + # Time display. A dedicated 24-hour editor is added next. + - button: + id: alarm_3_time_button + x: 68 + y: 13 + width: 122 + height: 70 + bg_color: 0x214F72 + bg_opa: COVER + border_width: 2 + border_color: 0x3E7FA7 + radius: 11 + pressed: + bg_color: 0x2E6A96 + widgets: + - label: + id: alarm_3_time_label + align: CENTER + text: "07:00" + text_font: font_vehicle_bold + text_color: 0xFFFFFF + + - button: + id: alarm_3_day_m + x: 196 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 0) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "M" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 0); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 0)); + } + + - button: + id: alarm_3_day_tu + x: 240 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 1) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 1); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 1)); + } + + - button: + id: alarm_3_day_w + x: 284 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 2) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "W" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 2); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 2)); + } + + - button: + id: alarm_3_day_th + x: 328 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 3) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 3); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 3)); + } + + - button: + id: alarm_3_day_f + x: 372 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 4) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "F" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 4); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 4)); + } + + - button: + id: alarm_3_day_sa + x: 416 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 5) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 5); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 5)); + } + + - button: + id: alarm_3_day_su + x: 460 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 6) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 6); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 6)); + } + + - button: + id: alarm_3_day_h + x: 504 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[2] & + (1U << 7) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "H" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[2] |= + static_cast(1U << 7); + } else { + id(alarm_day_mask)[2] &= + static_cast(~(1U << 7)); + } + + - button: + id: alarm_3_vibrate_button + x: 556 + y: 13 + width: 132 + height: 70 + bg_color: 0x4B3A63 + bg_opa: COVER + border_width: 2 + border_color: 0x735E88 + radius: 11 + pressed: + bg_color: 0x624B7D + widgets: + - label: + id: alarm_3_vibrate_label + align: CENTER + text: "Vibrate\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_vibrate_option)[2] = + (id(alarm_vibrate_option)[2] % 3) + 1; + + - lvgl.label.update: + id: alarm_3_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[2] + ); + return std::string(buffer); + + - button: + id: alarm_3_sound_button + x: 696 + y: 13 + width: 126 + height: 70 + bg_color: 0x384E66 + bg_opa: COVER + border_width: 2 + border_color: 0x557895 + radius: 11 + pressed: + bg_color: 0x496681 + widgets: + - label: + id: alarm_3_sound_label + align: CENTER + text: "Sound\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_sound_option)[2] = + (id(alarm_sound_option)[2] % 3) + 1; + + - lvgl.label.update: + id: alarm_3_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[2] + ); + return std::string(buffer); + + - button: + id: alarm_3_lamp_button + x: 830 + y: 13 + width: 164 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[2]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x806E42 + radius: 11 + checked: + bg_color: 0x8C6815 + border_color: 0xC99A2B + pressed: + bg_color: 0xA67E20 + widgets: + - label: + align: CENTER + text: "Lamp" + text_font: font_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_lamp_enabled)[2] = x; + + - obj: + id: alarm_4_row + x: 10 + y: 328 + width: 1004 + height: 96 + bg_color: 0x171F29 + bg_opa: COVER + border_width: 1 + border_color: 0x364250 + outline_width: 0 + shadow_width: 0 + radius: 14 + pad_all: 0 + clickable: false + widgets: + - button: + id: alarm_4_enable_button + x: 8 + y: 13 + width: 54 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_enabled)[3]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x548C6C + radius: 11 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x416F55 + widgets: + - label: + id: alarm_4_enable_label + align: CENTER + text: !lambda |- + return id(alarm_enabled)[3] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + text_font: font_mdi_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_enabled)[3] = x; + + - lvgl.label.update: + id: alarm_4_enable_label + text: !lambda |- + return id(alarm_enabled)[3] + ? std::string("\U000F0132") + : std::string("\U000F0131"); + + # Time display. A dedicated 24-hour editor is added next. + - button: + id: alarm_4_time_button + x: 68 + y: 13 + width: 122 + height: 70 + bg_color: 0x214F72 + bg_opa: COVER + border_width: 2 + border_color: 0x3E7FA7 + radius: 11 + pressed: + bg_color: 0x2E6A96 + widgets: + - label: + id: alarm_4_time_label + align: CENTER + text: "07:00" + text_font: font_vehicle_bold + text_color: 0xFFFFFF + + - button: + id: alarm_4_day_m + x: 196 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 0) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "M" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 0); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 0)); + } + + - button: + id: alarm_4_day_tu + x: 240 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 1) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 1); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 1)); + } + + - button: + id: alarm_4_day_w + x: 284 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 2) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "W" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 2); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 2)); + } + + - button: + id: alarm_4_day_th + x: 328 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 3) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "T" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 3); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 3)); + } + + - button: + id: alarm_4_day_f + x: 372 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 4) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "F" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 4); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 4)); + } + + - button: + id: alarm_4_day_sa + x: 416 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 5) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 5); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 5)); + } + + - button: + id: alarm_4_day_su + x: 460 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 6) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "S" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 6); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 6)); + } + + - button: + id: alarm_4_day_h + x: 504 + y: 13 + width: 40 + height: 70 + checkable: true + state: + checked: !lambda |- + return ( + id(alarm_day_mask)[3] & + (1U << 7) + ) != 0; + bg_color: 0x28313D + bg_opa: COVER + border_width: 1 + border_color: 0x445365 + radius: 10 + checked: + bg_color: 0x315843 + border_color: 0x72AE88 + pressed: + bg_color: 0x3A4859 + widgets: + - label: + align: CENTER + text: "H" + text_font: font_small + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + if (x) { + id(alarm_day_mask)[3] |= + static_cast(1U << 7); + } else { + id(alarm_day_mask)[3] &= + static_cast(~(1U << 7)); + } + + - button: + id: alarm_4_vibrate_button + x: 556 + y: 13 + width: 132 + height: 70 + bg_color: 0x4B3A63 + bg_opa: COVER + border_width: 2 + border_color: 0x735E88 + radius: 11 + pressed: + bg_color: 0x624B7D + widgets: + - label: + id: alarm_4_vibrate_label + align: CENTER + text: "Vibrate\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_vibrate_option)[3] = + (id(alarm_vibrate_option)[3] % 3) + 1; + + - lvgl.label.update: + id: alarm_4_vibrate_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Vibrate\n%u", + id(alarm_vibrate_option)[3] + ); + return std::string(buffer); + + - button: + id: alarm_4_sound_button + x: 696 + y: 13 + width: 126 + height: 70 + bg_color: 0x384E66 + bg_opa: COVER + border_width: 2 + border_color: 0x557895 + radius: 11 + pressed: + bg_color: 0x496681 + widgets: + - label: + id: alarm_4_sound_label + align: CENTER + text: "Sound\n1" + text_font: font_small + text_align: CENTER + text_color: 0xFFFFFF + + on_click: + - lambda: |- + id(alarm_sound_option)[3] = + (id(alarm_sound_option)[3] % 3) + 1; + + - lvgl.label.update: + id: alarm_4_sound_label + text: !lambda |- + char buffer[16]; + snprintf( + buffer, + sizeof(buffer), + "Sound\n%u", + id(alarm_sound_option)[3] + ); + return std::string(buffer); + + - button: + id: alarm_4_lamp_button + x: 830 + y: 13 + width: 164 + height: 70 + checkable: true + state: + checked: !lambda |- + return id(alarm_lamp_enabled)[3]; + bg_color: 0x28313D + bg_opa: COVER + border_width: 2 + border_color: 0x806E42 + radius: 11 + checked: + bg_color: 0x8C6815 + border_color: 0xC99A2B + pressed: + bg_color: 0xA67E20 + widgets: + - label: + align: CENTER + text: "Lamp" + text_font: font_button + text_color: 0xFFFFFF + + on_value: + then: + - lambda: |- + id(alarm_lamp_enabled)[3] = x; + #:################################################################################:# # BOTTOM NAVIGATION #:################################################################################:#