diff --git a/firmware/esp32-s3-dashboard/dashboard_config.h b/firmware/esp32-s3-dashboard/dashboard_config.h index d88273d..f03d790 100644 --- a/firmware/esp32-s3-dashboard/dashboard_config.h +++ b/firmware/esp32-s3-dashboard/dashboard_config.h @@ -1,12 +1,20 @@ #pragma once -static const char *DASHBOARD_VERSION = "0.1.88-clean-swipe-nav"; +static const char *DASHBOARD_VERSION = "0.1.89-async-swipe-page-switch"; // Update these if your Cargo ESP AP credentials are different. -static const char *CARGO_WIFI_SSID = "OverlandController"; -static const char *CARGO_WIFI_PASSWORD = "overland1234"; +//static const char *CARGO_WIFI_SSID = "OverlandController"; +//static const char *CARGO_WIFI_PASSWORD = "overland1234"; -static const char *CARGO_API_STATUS_URL = "http://192.168.4.1/api/v1/status"; -static const char *CARGO_API_FAST_STATUS_URL = "http://192.168.4.1/api/v1/status?fields=battery,temps,relays"; -static const char *CARGO_API_SLOW_STATUS_URL = "http://192.168.4.1/api/v1/status?fields=network,system,config"; -static const char *CARGO_API_RELAY_SET_URL = "http://192.168.4.1/api/v1/relay/set"; +static const char *CARGO_WIFI_SSID = "WardAP"; +static const char *CARGO_WIFI_PASSWORD = "Ward5213"; + +//static const char *CARGO_API_STATUS_URL = "http://192.168.4.1/api/v1/status"; +//static const char *CARGO_API_FAST_STATUS_URL = "http://192.168.4.1/api/v1/status?fields=battery,temps,relays"; +//static const char *CARGO_API_SLOW_STATUS_URL = "http://192.168.4.1/api/v1/status?fields=network,system,config"; +//static const char *CARGO_API_RELAY_SET_URL = "http://192.168.4.1/api/v1/relay/set"; + +static const char *CARGO_API_STATUS_URL = "http://192.168.88.108/api/v1/status"; +static const char *CARGO_API_FAST_STATUS_URL = "http://192.168.88.108/api/v1/status?fields=battery,temps,relays"; +static const char *CARGO_API_SLOW_STATUS_URL = "http://192.168.88.108/api/v1/status?fields=network,system,config"; +static const char *CARGO_API_RELAY_SET_URL = "http://192.168.88.108/api/v1/relay/set"; diff --git a/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino b/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino index 2be7606..c2a478b 100644 --- a/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino +++ b/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino @@ -558,157 +558,37 @@ static String signed_float_text(float value, int decimals, const char *suffix) +static bool dashboard_page_switch_queued = false; + +static void dashboard_page_switch_async_cb(void *user_data) +{ + DashboardScreen target = (DashboardScreen)(intptr_t)user_data; + dashboard_page_switch_queued = false; + show_dashboard_screen(target); +} + +static void queue_dashboard_page_switch(DashboardScreen target) +{ + if (dashboard_page_switch_queued) return; + if (target == current_dashboard_screen) return; + + dashboard_page_switch_queued = true; + lv_async_call(dashboard_page_switch_async_cb, (void *)(intptr_t)target); +} + static void dashboard_root_event_cb(lv_event_t *event) { if (lv_event_get_code(event) != LV_EVENT_GESTURE) return; + lv_indev_t *indev = lv_indev_get_act(); if (indev == nullptr) return; lv_dir_t dir = lv_indev_get_gesture_dir(indev); + if (current_dashboard_screen == SCREEN_OVERVIEW && dir == LV_DIR_RIGHT) { - show_dashboard_screen(SCREEN_BATTERY_DETAIL); + queue_dashboard_page_switch(SCREEN_BATTERY_DETAIL); } else if (current_dashboard_screen == SCREEN_BATTERY_DETAIL && dir == LV_DIR_LEFT) { - show_dashboard_screen(SCREEN_OVERVIEW); - } -} - -static void enable_dashboard_swipe_nav(lv_obj_t *obj) -{ - if (obj == nullptr) return; - - lv_obj_add_event_cb(obj, dashboard_root_event_cb, LV_EVENT_GESTURE, nullptr); - - uint32_t child_count = lv_obj_get_child_cnt(obj); - for (uint32_t i = 0; i < child_count; i++) { - enable_dashboard_swipe_nav(lv_obj_get_child(obj, i)); - } -} - -static void make_detail_label(lv_obj_t *parent, lv_obj_t **label, const char *text, const lv_font_t *font, lv_color_t color, int width, lv_align_t align, int x, int y, lv_text_align_t text_align = LV_TEXT_ALIGN_LEFT) -{ - *label = lv_label_create(parent); - lv_label_set_text(*label, text); - lv_obj_set_style_text_color(*label, color, 0); - lv_obj_set_style_text_font(*label, font, 0); - lv_obj_set_width(*label, width); - lv_obj_set_style_text_align(*label, text_align, 0); - lv_label_set_long_mode(*label, LV_LABEL_LONG_WRAP); - lv_obj_align(*label, align, x, y); -} - -static void update_battery_detail_widgets() -{ - if (battery_detail_soc_label == nullptr) return; - - String soc_text = status_model.soc >= 0 ? String(status_model.soc) + "%" : "--%"; - String status_text = status_model.bms_connected ? "BMS CONNECTED" : "BMS OFFLINE"; - String voltage_text = String(status_model.voltage, 2) + " V"; - String current_text = signed_float_text(status_model.current, 2, " A"); - String power_text = signed_float_text(status_model.voltage * status_model.current, 0, " W"); - String remaining_text = String(status_model.remaining_ah, 1) + " Ah"; - String capacity_text = String(status_model.capacity_ah, 1) + " Ah"; - String temp_text = String(status_model.battery_temp_f, 1) + "°F"; - String delta_text = status_model.cell_delta_mv >= 0 ? String(status_model.cell_delta_mv) + " mV" : "-- mV"; - - String estimate_text = "Idle"; - if (status_model.current > 0.05 && status_model.capacity_ah > 0.0) { - estimate_text = "Full in " + format_hours((status_model.capacity_ah - status_model.remaining_ah) / status_model.current); - } else if (status_model.current < -0.05 && status_model.remaining_ah > 0.0) { - estimate_text = "ETR " + format_hours(status_model.remaining_ah / abs(status_model.current)); - } - - set_label_text_if_changed(battery_detail_soc_label, last_battery_detail_soc_text, soc_text); - set_label_text_if_changed(battery_detail_status_label, last_battery_detail_status_text, status_text); - set_label_text_if_changed(battery_detail_voltage_label, last_battery_detail_voltage_text, voltage_text); - set_label_text_if_changed(battery_detail_current_label, last_battery_detail_current_text, current_text); - set_label_text_if_changed(battery_detail_power_label, last_battery_detail_power_text, power_text); - set_label_text_if_changed(battery_detail_remaining_label, last_battery_detail_remaining_text, remaining_text); - set_label_text_if_changed(battery_detail_capacity_label, last_battery_detail_capacity_text, capacity_text); - set_label_text_if_changed(battery_detail_temp_label, last_battery_detail_temp_text, temp_text); - set_label_text_if_changed(battery_detail_delta_label, last_battery_detail_delta_text, delta_text); - set_label_text_if_changed(battery_detail_estimate_label, last_battery_detail_estimate_text, estimate_text); -} - -static lv_obj_t *create_battery_metric_tile(lv_obj_t *parent, const char *title, lv_obj_t **value_label, int x, int y) -{ - lv_obj_t *tile = lv_obj_create(parent); - lv_obj_set_size(tile, 292, 132); - lv_obj_align(tile, LV_ALIGN_TOP_LEFT, x, y); - lv_obj_set_style_radius(tile, 18, 0); - lv_obj_set_style_bg_color(tile, lv_color_hex(0x17202A), 0); - lv_obj_set_style_border_color(tile, lv_color_hex(0x2F3A46), 0); - lv_obj_set_style_border_width(tile, 2, 0); - lv_obj_set_style_pad_all(tile, 0, 0); - lv_obj_clear_flag(tile, LV_OBJ_FLAG_SCROLLABLE); - - lv_obj_t *title_label = lv_label_create(tile); - lv_label_set_text(title_label, title); - lv_obj_set_style_text_color(title_label, lv_color_hex(0xB8C0C8), 0); - lv_obj_set_style_text_font(title_label, &lv_font_montserrat_26, 0); - lv_obj_set_width(title_label, 260); - lv_obj_align(title_label, LV_ALIGN_TOP_LEFT, 16, 14); - - make_detail_label(tile, value_label, "--", &lv_font_montserrat_30, lv_color_hex(0xFFFFFF), 260, LV_ALIGN_TOP_LEFT, 16, 58); - return tile; -} - - - -static void create_battery_detail_screen() -{ - lv_obj_t *screen = lv_scr_act(); - lv_obj_clean(screen); - current_dashboard_screen = SCREEN_BATTERY_DETAIL; - - lv_obj_set_style_bg_color(screen, lv_color_hex(0x101418), 0); - lv_obj_add_event_cb(screen, dashboard_root_event_cb, LV_EVENT_GESTURE, nullptr); - - lv_obj_t *system_card = create_card(screen, "", 960, 48, LV_ALIGN_TOP_MID, 0, 12); - lv_obj_add_flag(system_card, LV_OBJ_FLAG_CLICKABLE); - lv_obj_add_event_cb(system_card, system_card_event_cb, LV_EVENT_CLICKED, nullptr); - - lv_obj_t *title_label = nullptr; - make_detail_label(system_card, &title_label, "BATTERY DETAIL", &lv_font_montserrat_26, lv_color_hex(0xDDE3EA), 360, LV_ALIGN_LEFT_MID, 22, 0); - - lv_obj_t *page_dots = lv_label_create(system_card); - lv_label_set_text(page_dots, "BATT >"); - lv_obj_set_style_text_color(page_dots, lv_color_hex(0xB8C0C8), 0); - lv_obj_set_width(page_dots, 120); - lv_obj_set_style_text_align(page_dots, LV_TEXT_ALIGN_RIGHT, 0); - lv_obj_align(page_dots, LV_ALIGN_RIGHT_MID, -10, 0); - - lv_obj_t *hero_card = create_card(screen, "", 300, 500, LV_ALIGN_TOP_LEFT, 32, 78); - make_detail_label(hero_card, &battery_detail_status_label, "BMS --", &lv_font_montserrat_26, lv_color_hex(0xB8C0C8), 260, LV_ALIGN_TOP_MID, 0, 30, LV_TEXT_ALIGN_CENTER); - make_detail_label(hero_card, &battery_detail_soc_label, "--%", &lv_font_montserrat_48, lv_color_hex(0xFFFFFF), 260, LV_ALIGN_TOP_MID, 0, 126, LV_TEXT_ALIGN_CENTER); - make_detail_label(hero_card, &battery_detail_estimate_label, "--", &lv_font_montserrat_30, lv_color_hex(0xDDE3EA), 260, LV_ALIGN_TOP_MID, 0, 236, LV_TEXT_ALIGN_CENTER); - - lv_obj_t *hint_label = nullptr; - make_detail_label(hero_card, &hint_label, "Double tap to return", &lv_font_montserrat_26, lv_color_hex(0x7D8996), 260, LV_ALIGN_BOTTOM_MID, 0, -28, LV_TEXT_ALIGN_CENTER); - - create_battery_metric_tile(screen, "Voltage", &battery_detail_voltage_label, 356, 78); - create_battery_metric_tile(screen, "Current", &battery_detail_current_label, 670, 78); - create_battery_metric_tile(screen, "Power", &battery_detail_power_label, 356, 230); - create_battery_metric_tile(screen, "Remaining", &battery_detail_remaining_label, 670, 230); - create_battery_metric_tile(screen, "Capacity", &battery_detail_capacity_label, 356, 382); - create_battery_metric_tile(screen, "Battery Temp", &battery_detail_temp_label, 670, 382); - - lv_obj_t *delta_card = create_card(screen, "", 606, 70, LV_ALIGN_BOTTOM_MID, 177, -22); - lv_obj_t *delta_title = nullptr; - make_detail_label(delta_card, &delta_title, "Cell delta", &lv_font_montserrat_26, lv_color_hex(0xB8C0C8), 180, LV_ALIGN_LEFT_MID, 20, 0); - make_detail_label(delta_card, &battery_detail_delta_label, "-- mV", &lv_font_montserrat_30, lv_color_hex(0xFFFFFF), 220, LV_ALIGN_RIGHT_MID, -20, 0, LV_TEXT_ALIGN_RIGHT); - - update_battery_detail_widgets(); - enable_dashboard_swipe_nav(screen); -} - -static void show_dashboard_screen(DashboardScreen screen) -{ - if (screen == current_dashboard_screen) return; - - if (screen == SCREEN_BATTERY_DETAIL) { - create_battery_detail_screen(); - } else { - create_overland_overview_screen(); + queue_dashboard_page_switch(SCREEN_OVERVIEW); } }