Add a fleet overview page that shows every printer's status at once.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace bambu_display {
|
||||
@@ -212,6 +213,19 @@ struct Snapshot {
|
||||
for (char &c : text) c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
|
||||
return text;
|
||||
}
|
||||
std::string overview_task() const {
|
||||
if (!live()) return connected ? "Waiting for printer data" : "Waiting for Home Assistant";
|
||||
return valid_text(task) ? task : "No active print";
|
||||
}
|
||||
std::string overview_meta() const {
|
||||
if (!live()) return "--";
|
||||
const std::string progress_text = std::isfinite(progress)
|
||||
? number(std::clamp(progress, 0.0f, 100.0f)) + "%" : "--";
|
||||
const std::string time_line = remaining(time_left, remaining_unit);
|
||||
if (!finish_time.empty() && time_line != "--")
|
||||
return progress_text + " " + finish_time + " " + time_line;
|
||||
return progress_text + " " + time_line;
|
||||
}
|
||||
uint32_t status_color() const {
|
||||
if (!live()) return MUTED;
|
||||
const auto state = lower(status);
|
||||
@@ -223,6 +237,42 @@ struct Snapshot {
|
||||
}
|
||||
};
|
||||
|
||||
struct FleetCounts {
|
||||
int attention = 0, printing = 0, paused = 0, idle = 0, offline = 0, syncing = 0;
|
||||
};
|
||||
|
||||
inline void tally(FleetCounts &counts, const Snapshot &data) {
|
||||
if (!data.connected || lower(data.online) == "off" || lower(data.online) == "false") {
|
||||
++counts.offline;
|
||||
return;
|
||||
}
|
||||
if (!data.live()) {
|
||||
++counts.syncing;
|
||||
return;
|
||||
}
|
||||
if (data.has_print_error() || is_on(data.hms_error) || lower(data.status) == "failed") {
|
||||
++counts.attention;
|
||||
return;
|
||||
}
|
||||
const auto state = lower(data.status);
|
||||
if (state == "running" || state == "printing") ++counts.printing;
|
||||
else if (state == "pause" || state == "paused" || state == "pausing") ++counts.paused;
|
||||
else ++counts.idle;
|
||||
}
|
||||
|
||||
inline std::string fleet_summary(const FleetCounts &counts) {
|
||||
const std::pair<int, const char *> items[] = {
|
||||
{counts.attention, "attention"}, {counts.printing, "printing"}, {counts.paused, "paused"},
|
||||
{counts.idle, "idle"}, {counts.offline, "offline"}, {counts.syncing, "syncing"}};
|
||||
std::string text;
|
||||
for (const auto &item : items) {
|
||||
if (!item.first) continue;
|
||||
if (!text.empty()) text += ", ";
|
||||
text += std::to_string(item.first) + " " + item.second;
|
||||
}
|
||||
return text.empty() ? "Syncing" : text;
|
||||
}
|
||||
|
||||
} // namespace bambu_display
|
||||
|
||||
#ifdef USE_LVGL
|
||||
@@ -239,6 +289,9 @@ struct Widgets {
|
||||
GaugeWidgets uv{}, layer{};
|
||||
lv_obj_t *elapsed = nullptr;
|
||||
};
|
||||
struct OverviewWidgets {
|
||||
lv_obj_t *status, *task, *meta, *progress, *accent;
|
||||
};
|
||||
|
||||
inline void set_text(lv_obj_t *label, const std::string &text) {
|
||||
if (text != lv_label_get_text(label)) lv_label_set_text(label, text.c_str());
|
||||
@@ -306,5 +359,23 @@ inline void render(const Snapshot &data, const Widgets &widgets) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void render_overview(const Snapshot &data, const OverviewWidgets &widgets) {
|
||||
const bool live = data.live();
|
||||
const uint32_t color = data.status_color();
|
||||
set_text(widgets.status, data.status_text());
|
||||
lv_obj_set_style_text_color(widgets.status, lv_color_hex(color), 0);
|
||||
if (widgets.task) set_text(widgets.task, data.overview_task());
|
||||
set_text(widgets.meta, data.overview_meta());
|
||||
lv_bar_set_value(widgets.progress, live ? gauge_value(data.progress, 100) : 0, LV_ANIM_OFF);
|
||||
lv_obj_set_style_bg_color(widgets.progress, lv_color_hex(color), LV_PART_INDICATOR);
|
||||
lv_obj_set_style_bg_color(widgets.accent, lv_color_hex(color), 0);
|
||||
}
|
||||
|
||||
inline void render_fleet_summary(lv_obj_t *label, const FleetCounts &counts) {
|
||||
set_text(label, fleet_summary(counts));
|
||||
const uint32_t color = counts.attention ? RED : counts.printing ? GREEN : MUTED;
|
||||
lv_obj_set_style_text_color(label, lv_color_hex(color), 0);
|
||||
}
|
||||
|
||||
} // namespace bambu_display
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user