diff --git a/esphome/esp-reterminal-e1001.yaml b/esphome/esp-reterminal-e1001.yaml index ef3f66e..30d5d0e 100644 --- a/esphome/esp-reterminal-e1001.yaml +++ b/esphome/esp-reterminal-e1001.yaml @@ -829,269 +829,6 @@ display: id(job_water_table_pot_plant_completed_time).state ); - #:####################################################################################:# - # PAGE 2 - VIEW ROAD APPLIANCES # - #:####################################################################################:# - - id: page_appliances - lambda: |- - const int screen_width = 800; - const int header_y = 58; - const int radius = 8; - const int normal_border = 2; - const int emphasis_border = 4; - const int finished_seconds = ${finished_highlight_seconds}; - - const auto now = id(homeassistant_time).now(); - const int64_t now_ts = now.is_valid() ? now.timestamp : 0; - - auto fill_rounded = [&](int x, int y, int w, int h, int r, Color colour) { - it.filled_rectangle(x + r, y, w - (2 * r), h, colour); - it.filled_rectangle(x, y + r, w, h - (2 * r), colour); - it.filled_circle(x + r, y + r, r, colour); - it.filled_circle(x + w - r - 1, y + r, r, colour); - it.filled_circle(x + r, y + h - r - 1, r, colour); - it.filled_circle(x + w - r - 1, y + h - r - 1, r, colour); - }; - - auto rounded_tile = [&](int x, int y, int w, int h, bool inverse, int border) { - fill_rounded(x, y, w, h, radius, COLOR_ON); - if (!inverse) { - int inner_radius = radius - border; - if (inner_radius < 2) inner_radius = 2; - fill_rounded( - x + border, - y + border, - w - (2 * border), - h - (2 * border), - inner_radius, - COLOR_OFF - ); - } - }; - - auto draw_panel_state_icon = [&](int centre_x, int centre_y) { - if (id(panel_awake_indicator)) { - // Two open eyes with pupils. - it.circle(centre_x - 9, centre_y, 6, COLOR_ON); - it.circle(centre_x + 9, centre_y, 6, COLOR_ON); - it.filled_circle(centre_x - 9, centre_y, 2, COLOR_ON); - it.filled_circle(centre_x + 9, centre_y, 2, COLOR_ON); - } else { - // Two closed eyelids, each drawn as a shallow downward curve. - it.line(centre_x - 16, centre_y - 2, centre_x - 10, centre_y + 2, COLOR_ON); - it.line(centre_x - 10, centre_y + 2, centre_x - 4, centre_y - 2, COLOR_ON); - it.line(centre_x + 2, centre_y - 2, centre_x + 8, centre_y + 2, COLOR_ON); - it.line(centre_x + 8, centre_y + 2, centre_x + 14, centre_y - 2, COLOR_ON); - } - }; - - auto make_date = [&]() -> std::string { - if (!now.is_valid()) return "Waiting for Home Assistant time"; - - const char *weekdays[] = { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }; - const char *months[] = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }; - - const int day = now.day_of_month; - const int last_two = day % 100; - const char *suffix = "th"; - if (last_two < 11 || last_two > 13) { - if ((day % 10) == 1) suffix = "st"; - else if ((day % 10) == 2) suffix = "nd"; - else if ((day % 10) == 3) suffix = "rd"; - } - - char buffer[72]; - snprintf( - buffer, - sizeof(buffer), - "%s, %d%s %s %d", - weekdays[now.day_of_week - 1], - day, - suffix, - months[now.month - 1], - now.year - ); - return std::string(buffer); - }; - - auto completed_clock = [&](const std::string &stop_local) -> std::string { - if (stop_local.length() >= 16) return stop_local.substr(11, 5); - return "unknown"; - }; - - auto draw_appliance = [&](int x, int y, - const char *title_line_1, - const char *title_line_2, - const std::string &state, - float stop_ts, - float duration_seconds, - const std::string &stop_local) { - const int w = 190; - const int h = 128; - - const bool valid_cycle = - !isnan(stop_ts) && stop_ts > 0 && - !isnan(duration_seconds) && duration_seconds > 0; - - bool recent_finish = false; - if (valid_cycle && now_ts > 0) { - const int64_t age = now_ts - static_cast(stop_ts); - recent_finish = age >= 0 && age < finished_seconds; - } - - std::string status = "Unavailable"; - bool inverse = false; - int border = normal_border; - - if (state == "Operating") { - status = "OPERATING"; - border = emphasis_border; - } else if (valid_cycle && recent_finish) { - status = "FINISHED"; - inverse = true; - } else if (valid_cycle) { - status = "Completed at " + completed_clock(stop_local); - } else if (state == "Standby") { - status = "STANDBY"; - } else if (state == "Off") { - status = "OFF"; - } else if (state == "Finished") { - status = "FINISHED"; - inverse = true; - } else if (!state.empty()) { - status = state; - } - - rounded_tile(x, y, w, h, inverse, border); - const Color text_colour = inverse ? COLOR_OFF : COLOR_ON; - - if (title_line_2[0] == '\0') { - it.printf( - x + (w / 2), y + 39, - id(font_appliance_title), text_colour, TextAlign::CENTER, - "%s", title_line_1 - ); - } else { - it.printf( - x + (w / 2), y + 25, - id(font_appliance_title), text_colour, TextAlign::CENTER, - "%s", title_line_1 - ); - it.printf( - x + (w / 2), y + 49, - id(font_appliance_title), text_colour, TextAlign::CENTER, - "%s", title_line_2 - ); - } - - it.printf( - x + (w / 2), y + 91, - id(font_appliance_status), text_colour, TextAlign::CENTER, - "%s", status.c_str() - ); - }; - - // Header. - it.print(14, 28, id(font_header), TextAlign::CENTER_LEFT, "View Road Appliances"); - draw_panel_state_icon(448, 28); - const std::string date_text = make_date(); - it.printf( - screen_width - 14, - 29, - id(font_date), - TextAlign::CENTER_RIGHT, - "%s", - date_text.c_str() - ); - it.line(8, header_y, screen_width - 9, header_y); - - // Four tiles on rows one and two; two centred tiles on row three. - draw_appliance( - 8, 70, "Washing", "Machine", - id(appliance_washing_state).state, - id(appliance_washing_stop_ts).state, - id(appliance_washing_duration).state, - id(appliance_washing_stop_local).state - ); - - draw_appliance( - 206, 70, "Dryer", "", - id(appliance_dryer_state).state, - id(appliance_dryer_stop_ts).state, - id(appliance_dryer_duration).state, - id(appliance_dryer_stop_local).state - ); - - draw_appliance( - 404, 70, "Main", "Dishwasher", - id(appliance_main_dishwasher_state).state, - id(appliance_main_dishwasher_stop_ts).state, - id(appliance_main_dishwasher_duration).state, - id(appliance_main_dishwasher_stop_local).state - ); - - draw_appliance( - 602, 70, "Downstairs", "Dishwasher", - id(appliance_downstairs_dishwasher_state).state, - id(appliance_downstairs_dishwasher_stop_ts).state, - id(appliance_downstairs_dishwasher_duration).state, - id(appliance_downstairs_dishwasher_stop_local).state - ); - - draw_appliance( - 8, 206, "EV Charger", "32A", - id(appliance_evcharger_32a_state).state, - id(appliance_evcharger_32a_stop_ts).state, - id(appliance_evcharger_32a_duration).state, - id(appliance_evcharger_32a_stop_local).state - ); - - draw_appliance( - 206, 206, "EV Charger", "16A", - id(appliance_evcharger_16a_state).state, - id(appliance_evcharger_16a_stop_ts).state, - id(appliance_evcharger_16a_duration).state, - id(appliance_evcharger_16a_stop_local).state - ); - - draw_appliance( - 404, 206, "Ryobi Charger", "Left", - id(appliance_ryobi_left_state).state, - id(appliance_ryobi_left_stop_ts).state, - id(appliance_ryobi_left_duration).state, - id(appliance_ryobi_left_stop_local).state - ); - - draw_appliance( - 602, 206, "Ryobi Charger", "Right", - id(appliance_ryobi_right_state).state, - id(appliance_ryobi_right_stop_ts).state, - id(appliance_ryobi_right_duration).state, - id(appliance_ryobi_right_stop_local).state - ); - - draw_appliance( - 206, 342, "Pool Pump", "", - id(appliance_pool_pump_state).state, - id(appliance_pool_pump_stop_ts).state, - id(appliance_pool_pump_duration).state, - id(appliance_pool_pump_stop_local).state - ); - - draw_appliance( - 404, 342, "3D Printer", "", - id(appliance_3d_printer_state).state, - id(appliance_3d_printer_stop_ts).state, - id(appliance_3d_printer_duration).state, - id(appliance_3d_printer_stop_local).state - ); - #:########################################################################################:# # DISPLAY CHANGE DETECTION: # Builds a signature from only the content that is currently visible. The display is not