diff --git a/esphome/esp-bedside-panel.yaml b/esphome/esp-bedside-panel.yaml index cadfbb8..261ad60 100644 --- a/esphome/esp-bedside-panel.yaml +++ b/esphome/esp-bedside-panel.yaml @@ -4367,6 +4367,414 @@ script: return state; + - lvgl.widget.update: + id: job_6_button + bg_color: !lambda |- + const auto state = id(job_6_state).state; + + if (state == "Complete") return lv_color_hex(0x2E7D32); + if (state == "Not Due") return lv_color_hex(0x7E8995); + if (state == "Due") return lv_color_hex(0xB08A18); + if (state == "Overdue") return lv_color_hex(0xC66A1B); + if (state == "Missed") return lv_color_hex(0xB53636); + return lv_color_hex(0x28313D); + + - lvgl.label.update: + id: job_6_status_label + text: !lambda |- + const auto state = id(job_6_state).state; + + if (state == "Complete") { + const float raw_hours = + id(job_6_hours_since_completed).state; + + if (isnan(raw_hours) || raw_hours < 0.0f) { + return std::string("Complete"); + } + + const int hours = (int) lroundf(raw_hours); + if (hours <= 0) return std::string("Complete - Just now"); + + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + hours == 1 + ? "Complete - 1 hr ago" + : "Complete - %d hrs ago", + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + days == 1 + ? "Complete - 1 day ago" + : "Complete - %d days ago", + days + ); + } + return std::string(buffer); + } + + if (state == "Not Due") { + return std::string("Not Due"); + } + + if (state == "Due" || state == "Overdue") { + const float raw_hours = + id(job_6_hours_since_required).state; + const bool overdue = state == "Overdue"; + + if (isnan(raw_hours) || raw_hours <= 0.0f) { + return overdue + ? std::string("Overdue") + : std::string("Due - Just now"); + } + + const int hours = (int) lroundf(raw_hours); + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + overdue + ? (hours == 1 ? "Overdue - 1 hr" : "Overdue - %d hrs") + : (hours == 1 ? "Due - 1 hr ago" : "Due - %d hrs ago"), + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + overdue + ? (days == 1 ? "Overdue - 1 day" : "Overdue - %d days") + : (days == 1 ? "Due - 1 day ago" : "Due - %d days ago"), + days + ); + } + return std::string(buffer); + } + + if (state == "Missed") return std::string("Missed"); + if ( + state.empty() || + state == "unknown" || + state == "unavailable" + ) { + return std::string("Unknown"); + } + return state; + + - lvgl.widget.update: + id: job_7_button + bg_color: !lambda |- + const auto state = id(job_7_state).state; + + if (state == "Complete") return lv_color_hex(0x2E7D32); + if (state == "Not Due") return lv_color_hex(0x7E8995); + if (state == "Due") return lv_color_hex(0xB08A18); + if (state == "Overdue") return lv_color_hex(0xC66A1B); + if (state == "Missed") return lv_color_hex(0xB53636); + return lv_color_hex(0x28313D); + + - lvgl.label.update: + id: job_7_status_label + text: !lambda |- + const auto state = id(job_7_state).state; + + if (state == "Complete") { + const float raw_hours = + id(job_7_hours_since_completed).state; + + if (isnan(raw_hours) || raw_hours < 0.0f) { + return std::string("Complete"); + } + + const int hours = (int) lroundf(raw_hours); + if (hours <= 0) return std::string("Complete - Just now"); + + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + hours == 1 + ? "Complete - 1 hr ago" + : "Complete - %d hrs ago", + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + days == 1 + ? "Complete - 1 day ago" + : "Complete - %d days ago", + days + ); + } + return std::string(buffer); + } + + if (state == "Not Due") { + return std::string("Not Due"); + } + + if (state == "Due" || state == "Overdue") { + const float raw_hours = + id(job_7_hours_since_required).state; + const bool overdue = state == "Overdue"; + + if (isnan(raw_hours) || raw_hours <= 0.0f) { + return overdue + ? std::string("Overdue") + : std::string("Due - Just now"); + } + + const int hours = (int) lroundf(raw_hours); + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + overdue + ? (hours == 1 ? "Overdue - 1 hr" : "Overdue - %d hrs") + : (hours == 1 ? "Due - 1 hr ago" : "Due - %d hrs ago"), + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + overdue + ? (days == 1 ? "Overdue - 1 day" : "Overdue - %d days") + : (days == 1 ? "Due - 1 day ago" : "Due - %d days ago"), + days + ); + } + return std::string(buffer); + } + + if (state == "Missed") return std::string("Missed"); + if ( + state.empty() || + state == "unknown" || + state == "unavailable" + ) { + return std::string("Unknown"); + } + return state; + + - lvgl.widget.update: + id: job_8_button + bg_color: !lambda |- + const auto state = id(job_8_state).state; + + if (state == "Complete") return lv_color_hex(0x2E7D32); + if (state == "Not Due") return lv_color_hex(0x7E8995); + if (state == "Due") return lv_color_hex(0xB08A18); + if (state == "Overdue") return lv_color_hex(0xC66A1B); + if (state == "Missed") return lv_color_hex(0xB53636); + return lv_color_hex(0x28313D); + + - lvgl.label.update: + id: job_8_status_label + text: !lambda |- + const auto state = id(job_8_state).state; + + if (state == "Complete") { + const float raw_hours = + id(job_8_hours_since_completed).state; + + if (isnan(raw_hours) || raw_hours < 0.0f) { + return std::string("Complete"); + } + + const int hours = (int) lroundf(raw_hours); + if (hours <= 0) return std::string("Complete - Just now"); + + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + hours == 1 + ? "Complete - 1 hr ago" + : "Complete - %d hrs ago", + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + days == 1 + ? "Complete - 1 day ago" + : "Complete - %d days ago", + days + ); + } + return std::string(buffer); + } + + if (state == "Not Due") { + return std::string("Not Due"); + } + + if (state == "Due" || state == "Overdue") { + const float raw_hours = + id(job_8_hours_since_required).state; + const bool overdue = state == "Overdue"; + + if (isnan(raw_hours) || raw_hours <= 0.0f) { + return overdue + ? std::string("Overdue") + : std::string("Due - Just now"); + } + + const int hours = (int) lroundf(raw_hours); + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + overdue + ? (hours == 1 ? "Overdue - 1 hr" : "Overdue - %d hrs") + : (hours == 1 ? "Due - 1 hr ago" : "Due - %d hrs ago"), + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + overdue + ? (days == 1 ? "Overdue - 1 day" : "Overdue - %d days") + : (days == 1 ? "Due - 1 day ago" : "Due - %d days ago"), + days + ); + } + return std::string(buffer); + } + + if (state == "Missed") return std::string("Missed"); + if ( + state.empty() || + state == "unknown" || + state == "unavailable" + ) { + return std::string("Unknown"); + } + return state; + + - lvgl.widget.update: + id: job_9_button + bg_color: !lambda |- + const auto state = id(job_9_state).state; + + if (state == "Complete") return lv_color_hex(0x2E7D32); + if (state == "Not Due") return lv_color_hex(0x7E8995); + if (state == "Due") return lv_color_hex(0xB08A18); + if (state == "Overdue") return lv_color_hex(0xC66A1B); + if (state == "Missed") return lv_color_hex(0xB53636); + return lv_color_hex(0x28313D); + + - lvgl.label.update: + id: job_9_status_label + text: !lambda |- + const auto state = id(job_9_state).state; + + if (state == "Complete") { + const float raw_hours = + id(job_9_hours_since_completed).state; + + if (isnan(raw_hours) || raw_hours < 0.0f) { + return std::string("Complete"); + } + + const int hours = (int) lroundf(raw_hours); + if (hours <= 0) return std::string("Complete - Just now"); + + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + hours == 1 + ? "Complete - 1 hr ago" + : "Complete - %d hrs ago", + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + days == 1 + ? "Complete - 1 day ago" + : "Complete - %d days ago", + days + ); + } + return std::string(buffer); + } + + if (state == "Not Due") { + return std::string("Not Due"); + } + + if (state == "Due" || state == "Overdue") { + const float raw_hours = + id(job_9_hours_since_required).state; + const bool overdue = state == "Overdue"; + + if (isnan(raw_hours) || raw_hours <= 0.0f) { + return overdue + ? std::string("Overdue") + : std::string("Due - Just now"); + } + + const int hours = (int) lroundf(raw_hours); + char buffer[48]; + if (hours < 24) { + snprintf( + buffer, + sizeof(buffer), + overdue + ? (hours == 1 ? "Overdue - 1 hr" : "Overdue - %d hrs") + : (hours == 1 ? "Due - 1 hr ago" : "Due - %d hrs ago"), + hours + ); + } else { + const int days = (hours + 12) / 24; + snprintf( + buffer, + sizeof(buffer), + overdue + ? (days == 1 ? "Overdue - 1 day" : "Overdue - %d days") + : (days == 1 ? "Due - 1 day ago" : "Due - %d days ago"), + days + ); + } + return std::string(buffer); + } + + if (state == "Missed") return std::string("Missed"); + if ( + state.empty() || + state == "unknown" || + state == "unavailable" + ) { + return std::string("Unknown"); + } + return state; + # Update Bedroom and Clock status values after LVGL has finished constructing. - id: refresh_header_status mode: restart