dashboard: refine main overview layout
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
static const char *DASHBOARD_VERSION = "0.1.10-large-fonts-enabled";
|
||||
static const char *DASHBOARD_VERSION = "0.1.11-main-ui-pass";
|
||||
|
||||
// Update these if your Cargo ESP AP credentials are different.
|
||||
static const char *CARGO_WIFI_SSID = "OverlandController";
|
||||
|
||||
@@ -18,10 +18,13 @@ static lv_obj_t *battery_soc_arc = nullptr;
|
||||
static lv_obj_t *battery_charge_pulse_arc = nullptr;
|
||||
static lv_obj_t *battery_voltage_label = nullptr;
|
||||
static lv_obj_t *battery_current_label = nullptr;
|
||||
static lv_obj_t *battery_estimate_label = nullptr;
|
||||
static lv_obj_t *battery_soc_label = nullptr;
|
||||
static lv_obj_t *inside_temp_label = nullptr;
|
||||
static lv_obj_t *outside_temp_label = nullptr;
|
||||
static lv_obj_t *system_status_label = nullptr;
|
||||
static lv_obj_t *wifi_icon_label = nullptr;
|
||||
static lv_obj_t *cargo_status_dot = nullptr;
|
||||
static lv_obj_t *relay_buttons[6] = {nullptr};
|
||||
static lv_obj_t *relay_button_labels[6] = {nullptr};
|
||||
|
||||
@@ -54,6 +57,7 @@ static bool pending_relay_previous_state = false;
|
||||
|
||||
static String last_battery_voltage_text;
|
||||
static String last_battery_current_text;
|
||||
static String last_battery_estimate_text;
|
||||
static String last_battery_soc_text;
|
||||
static String last_inside_temp_text;
|
||||
static String last_outside_temp_text;
|
||||
@@ -64,6 +68,69 @@ static String on_off(bool value)
|
||||
return value ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
static String format_hours(float hours)
|
||||
{
|
||||
if (hours <= 0.0 || isnan(hours) || isinf(hours)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
int total_minutes = (int)(hours * 60.0 + 0.5);
|
||||
int h = total_minutes / 60;
|
||||
int m = total_minutes % 60;
|
||||
|
||||
String text;
|
||||
if (h > 0) {
|
||||
text += String(h);
|
||||
text += "h ";
|
||||
}
|
||||
|
||||
text += String(m);
|
||||
text += "m";
|
||||
return text;
|
||||
}
|
||||
|
||||
static String wifi_bars()
|
||||
{
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
return "□□□□";
|
||||
}
|
||||
|
||||
int rssi = WiFi.RSSI();
|
||||
|
||||
if (rssi > -60) {
|
||||
return "■■■■";
|
||||
}
|
||||
|
||||
if (rssi > -70) {
|
||||
return "■■■□";
|
||||
}
|
||||
|
||||
if (rssi > -80) {
|
||||
return "■■□□";
|
||||
}
|
||||
|
||||
return "■□□□";
|
||||
}
|
||||
|
||||
static void update_status_icons()
|
||||
{
|
||||
if (wifi_icon_label == nullptr || cargo_status_dot == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
lvgl_port_lock(-1);
|
||||
|
||||
lv_label_set_text(wifi_icon_label, wifi_bars().c_str());
|
||||
|
||||
lv_obj_set_style_bg_color(
|
||||
cargo_status_dot,
|
||||
status_model.api_ok ? lv_color_hex(0x32D583) : lv_color_hex(0xF97066),
|
||||
0
|
||||
);
|
||||
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
|
||||
static int clamp_int(int value, int min_value, int max_value)
|
||||
{
|
||||
if (value < min_value) {
|
||||
@@ -191,6 +258,13 @@ static void layout_relay_buttons()
|
||||
int total_width = (button_width * visible_count) + (RELAY_BUTTON_GAP * (visible_count - 1));
|
||||
int start_x = (available_width - total_width) / 2;
|
||||
|
||||
lv_obj_t *vehicle_label = lv_label_create(vehicle_card);
|
||||
lv_label_set_text(vehicle_label, "Vehicle\n\nOffline\n\nFuture:\nCoolant\nTrans Temp\n4WD\nTilt/Roll");
|
||||
lv_obj_set_style_text_color(vehicle_label, lv_color_hex(0xDDE3EA), 0);
|
||||
lv_obj_set_width(vehicle_label, 230);
|
||||
lv_label_set_long_mode(vehicle_label, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_align(vehicle_label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (relay_buttons[i] == nullptr) {
|
||||
continue;
|
||||
@@ -370,30 +444,12 @@ static void update_system_status_label()
|
||||
was_wifi_connected = false;
|
||||
}
|
||||
|
||||
if (millis() - last_wifi_label_update_ms < 5000) {
|
||||
if (millis() - last_wifi_label_update_ms < 1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_wifi_label_update_ms = millis();
|
||||
|
||||
String text;
|
||||
|
||||
if (wifi_connected) {
|
||||
text += "WiFi ";
|
||||
text += WiFi.localIP().toString();
|
||||
text += " | RSSI ";
|
||||
text += String(WiFi.RSSI());
|
||||
text += " dBm";
|
||||
} else {
|
||||
text += "WiFi connecting";
|
||||
}
|
||||
|
||||
text += " | Cargo ";
|
||||
text += status_model.api_ok ? "online" : "waiting";
|
||||
text += " | FW ";
|
||||
text += status_model.firmware_version;
|
||||
|
||||
set_label_text_if_changed(system_status_label, last_system_status_text, text);
|
||||
update_status_icons();
|
||||
}
|
||||
|
||||
|
||||
@@ -405,10 +461,19 @@ static void update_overview_widgets()
|
||||
voltage_text += " V";
|
||||
|
||||
String current_text = "";
|
||||
String estimate_text = "";
|
||||
|
||||
if (status_model.current > 0.05 || status_model.current < -0.05) {
|
||||
current_text += status_model.current > 0 ? "+" : "";
|
||||
current_text += String(status_model.current, 2);
|
||||
current_text += " A";
|
||||
|
||||
if (status_model.current > 0.05 && status_model.capacity_ah > 0.0) {
|
||||
float remaining_to_full_ah = status_model.capacity_ah - status_model.remaining_ah;
|
||||
estimate_text = "Full in " + format_hours(remaining_to_full_ah / status_model.current);
|
||||
} else if (status_model.current < -0.05 && status_model.remaining_ah > 0.0) {
|
||||
estimate_text = "Runtime " + format_hours(status_model.remaining_ah / abs(status_model.current));
|
||||
}
|
||||
}
|
||||
|
||||
String soc_text;
|
||||
@@ -418,6 +483,16 @@ static void update_overview_widgets()
|
||||
update_battery_soc_gauge();
|
||||
set_label_text_if_changed(battery_voltage_label, last_battery_voltage_text, voltage_text);
|
||||
update_battery_current_label(current_text, status_model.current);
|
||||
set_label_text_if_changed(battery_estimate_label, last_battery_estimate_text, estimate_text);
|
||||
if (battery_estimate_label != nullptr) {
|
||||
lvgl_port_lock(-1);
|
||||
if (estimate_text.length() == 0) {
|
||||
lv_obj_add_flag(battery_estimate_label, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_clear_flag(battery_estimate_label, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
set_label_text_if_changed(battery_soc_label, last_battery_soc_text, soc_text);
|
||||
set_label_text_if_changed(system_status_label, last_system_status_text, last_system_status_text);
|
||||
}
|
||||
@@ -636,13 +711,14 @@ static void create_overland_overview_screen()
|
||||
lv_obj_clean(screen);
|
||||
lv_obj_set_style_bg_color(screen, lv_color_hex(0x101418), 0);
|
||||
|
||||
lv_obj_t *system_card = create_card(screen, "", 960, 72, LV_ALIGN_TOP_MID, 0, 16);
|
||||
lv_obj_t *battery_card = create_card(screen, "", 300, 330, LV_ALIGN_TOP_LEFT, 32, 104);
|
||||
lv_obj_t *temp_card = create_card(screen, "", 300, 330, LV_ALIGN_TOP_MID, 0, 104);
|
||||
lv_obj_t *system_card = create_card(screen, "", 960, 54, LV_ALIGN_TOP_MID, 0, 14);
|
||||
lv_obj_t *battery_card = create_card(screen, "", 380, 340, LV_ALIGN_TOP_LEFT, 32, 84);
|
||||
lv_obj_t *temp_card = create_card(screen, "", 260, 340, LV_ALIGN_TOP_LEFT, 426, 84);
|
||||
lv_obj_t *vehicle_card = create_card(screen, "", 274, 340, LV_ALIGN_TOP_RIGHT, -32, 84);
|
||||
lv_obj_t *relay_card = create_card(screen, "", RELAY_STRIP_W, 138, LV_ALIGN_TOP_LEFT, RELAY_STRIP_X, RELAY_STRIP_Y);
|
||||
|
||||
battery_charge_pulse_arc = lv_arc_create(battery_card);
|
||||
lv_obj_set_size(battery_charge_pulse_arc, 236, 236);
|
||||
lv_obj_set_size(battery_charge_pulse_arc, 292, 292);
|
||||
lv_obj_align(battery_charge_pulse_arc, LV_ALIGN_TOP_MID, 0, 42);
|
||||
lv_arc_set_range(battery_charge_pulse_arc, 0, 100);
|
||||
lv_arc_set_value(battery_charge_pulse_arc, 0);
|
||||
@@ -658,7 +734,7 @@ static void create_overland_overview_screen()
|
||||
lv_obj_add_flag(battery_charge_pulse_arc, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
battery_soc_arc = lv_arc_create(battery_card);
|
||||
lv_obj_set_size(battery_soc_arc, 214, 214);
|
||||
lv_obj_set_size(battery_soc_arc, 266, 266);
|
||||
lv_obj_align(battery_soc_arc, LV_ALIGN_TOP_MID, 0, 49);
|
||||
lv_arc_set_range(battery_soc_arc, 0, 100);
|
||||
lv_arc_set_value(battery_soc_arc, 0);
|
||||
@@ -720,7 +796,7 @@ static void create_overland_overview_screen()
|
||||
lv_obj_set_style_text_color(inside_temp_label, lv_color_hex(0xFFFFFF), 0);
|
||||
lv_obj_set_style_text_font(inside_temp_label, &lv_font_montserrat_40, 0);
|
||||
lv_obj_set_width(inside_temp_label, 260);
|
||||
lv_obj_align(inside_temp_label, LV_ALIGN_TOP_LEFT, 0, 45);
|
||||
lv_obj_align(inside_temp_label, LV_ALIGN_TOP_LEFT, 0, 56);
|
||||
|
||||
outside_temp_label = lv_label_create(temp_card);
|
||||
lv_label_set_text(outside_temp_label, "Outside\n--");
|
||||
@@ -733,7 +809,7 @@ static void create_overland_overview_screen()
|
||||
lv_obj_set_style_text_color(outside_temp_label, lv_color_hex(0xFFFFFF), 0);
|
||||
lv_obj_set_style_text_font(outside_temp_label, &lv_font_montserrat_40, 0);
|
||||
lv_obj_set_width(outside_temp_label, 260);
|
||||
lv_obj_align(outside_temp_label, LV_ALIGN_TOP_LEFT, 0, 145);
|
||||
lv_obj_align(outside_temp_label, LV_ALIGN_TOP_LEFT, 0, 190);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
relay_buttons[i] = lv_btn_create(relay_card);
|
||||
@@ -753,19 +829,30 @@ static void create_overland_overview_screen()
|
||||
lv_obj_add_flag(relay_buttons[i], LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
wifi_icon_label = lv_label_create(system_card);
|
||||
lv_label_set_text(wifi_icon_label, "□□□□");
|
||||
lv_obj_set_style_text_color(wifi_icon_label, lv_color_hex(0xDDE3EA), 0);
|
||||
lv_obj_set_style_text_font(wifi_icon_label, &lv_font_montserrat_30, 0);
|
||||
lv_obj_align(wifi_icon_label, LV_ALIGN_LEFT_MID, 10, 0);
|
||||
|
||||
cargo_status_dot = lv_obj_create(system_card);
|
||||
lv_obj_set_size(cargo_status_dot, 22, 22);
|
||||
lv_obj_set_style_radius(cargo_status_dot, LV_RADIUS_CIRCLE, 0);
|
||||
lv_obj_set_style_bg_color(cargo_status_dot, lv_color_hex(0xF97066), 0);
|
||||
lv_obj_set_style_border_width(cargo_status_dot, 0, 0);
|
||||
lv_obj_align(cargo_status_dot, LV_ALIGN_LEFT_MID, 118, 0);
|
||||
|
||||
system_status_label = lv_label_create(system_card);
|
||||
lv_label_set_text(system_status_label, "Connecting to Cargo ESP...");
|
||||
lv_obj_set_style_text_color(system_status_label, lv_color_hex(0xDDE3EA), 0);
|
||||
lv_obj_set_width(system_status_label, 830);
|
||||
lv_label_set_long_mode(system_status_label, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_align(system_status_label, LV_ALIGN_TOP_LEFT, 0, 32);
|
||||
lv_label_set_text(system_status_label, "");
|
||||
lv_obj_set_width(system_status_label, 1);
|
||||
lv_obj_add_flag(system_status_label, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
lv_obj_t *page_dots = lv_label_create(system_card);
|
||||
lv_label_set_text(page_dots, "● ○ ○ ○");
|
||||
lv_obj_set_style_text_color(page_dots, lv_color_hex(0xB8C0C8), 0);
|
||||
lv_obj_set_width(page_dots, 110);
|
||||
lv_obj_set_width(page_dots, 140);
|
||||
lv_obj_set_style_text_align(page_dots, LV_TEXT_ALIGN_RIGHT, 0);
|
||||
lv_obj_align(page_dots, LV_ALIGN_TOP_RIGHT, 0, 32);
|
||||
lv_obj_align(page_dots, LV_ALIGN_RIGHT_MID, -10, 0);
|
||||
}
|
||||
|
||||
void setup()
|
||||
|
||||
Reference in New Issue
Block a user