Derive Centauri progress from layers or print time when percent stays at zero.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -122,9 +122,9 @@ struct Snapshot {
|
||||
std::string hms_count, print_error_message, print_error_code;
|
||||
std::string print_error_reason, uv_unit, elapsed_unit;
|
||||
bool elegoo = false, resin = false;
|
||||
float uv = NAN, elapsed = NAN;
|
||||
float uv = NAN, elapsed = NAN, total_time = NAN;
|
||||
std::vector<HealthNotice> health_notices;
|
||||
std::string remaining_unit, nozzle_unit, bed_unit;
|
||||
std::string remaining_unit, nozzle_unit, bed_unit, total_time_unit;
|
||||
std::string finish_time;
|
||||
float progress = NAN, nozzle = NAN, nozzle_target = NAN, bed = NAN, bed_target = NAN;
|
||||
float time_left = NAN, layer = NAN, total_layers = NAN, fan = NAN;
|
||||
@@ -134,6 +134,36 @@ struct Snapshot {
|
||||
std::vector<Tray> trays;
|
||||
|
||||
bool live() const { return connected && is_on(online) && valid_text(status); }
|
||||
// Centauri firmware parks on milestone names such as preheating_completed for
|
||||
// most of a job, so any status that is not a known idle or finished state is active.
|
||||
bool job_active() const {
|
||||
auto idle = [](const std::string &value) {
|
||||
return value.empty() || value == "unknown" || value == "unavailable" || value == "none" ||
|
||||
value == "idle" || value == "standby" || value == "ready" || value == "complete" ||
|
||||
value == "completed" || value == "finish" || value == "finished" || value == "cancelled" ||
|
||||
value == "canceled" || value == "stopped" || value == "stop" || value == "failed";
|
||||
};
|
||||
const auto state = lower(status);
|
||||
const auto machine = lower(stage);
|
||||
if (machine == "printing" || machine == "paused" || machine == "busy" || machine == "heating" ||
|
||||
machine == "preheating" || machine == "running")
|
||||
return true;
|
||||
return !idle(state);
|
||||
}
|
||||
// The Centauri reports percent_complete as 0 while CurrentLayer stays 0.
|
||||
// Layers, then elapsed time against the total, still describe the job.
|
||||
float completion() const {
|
||||
if (!elegoo) return progress;
|
||||
if (std::isfinite(progress) && progress > 0.0f) return std::clamp(progress, 0.0f, 100.0f);
|
||||
if (!job_active()) return std::isfinite(progress) ? 0.0f : NAN;
|
||||
if (std::isfinite(layer) && std::isfinite(total_layers) && layer > 0.0f && total_layers > 0.0f)
|
||||
return std::clamp(100.0f * layer / total_layers, 0.0f, 100.0f);
|
||||
const int elapsed_s = duration_seconds(elapsed, elapsed_unit);
|
||||
const int total_s = duration_seconds(total_time, total_time_unit);
|
||||
if (elapsed_s > 0 && total_s > 0)
|
||||
return std::clamp(100.0f * static_cast<float>(elapsed_s) / static_cast<float>(total_s), 0.0f, 100.0f);
|
||||
return std::isfinite(progress) ? 0.0f : NAN;
|
||||
}
|
||||
bool has_print_error() const {
|
||||
if (!elegoo) return is_on(print_error);
|
||||
return elegoo_fault(print_error) || elegoo_fault(print_error_reason) || lower(status) == "error";
|
||||
@@ -225,8 +255,9 @@ struct Snapshot {
|
||||
}
|
||||
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 float percent = completion();
|
||||
const std::string progress_text = std::isfinite(percent)
|
||||
? number(std::clamp(percent, 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;
|
||||
@@ -325,9 +356,10 @@ inline void render(const Snapshot &data, const Widgets &widgets) {
|
||||
set_text(widgets.status, data.status_text());
|
||||
lv_obj_set_style_text_color(widgets.status, lv_color_hex(color), 0);
|
||||
lv_obj_set_style_arc_color(widgets.progress.arc, lv_color_hex(color), LV_PART_INDICATOR);
|
||||
lv_bar_set_value(widgets.top_progress, live ? gauge_value(data.progress, 100) : 0, LV_ANIM_OFF);
|
||||
render_gauge(widgets.progress, live && std::isfinite(data.progress)
|
||||
? std::clamp(data.progress, 0.0f, 100.0f) : NAN, live ? data.progress : NAN, 100,
|
||||
const float percent = data.completion();
|
||||
lv_bar_set_value(widgets.top_progress, live ? gauge_value(percent, 100) : 0, LV_ANIM_OFF);
|
||||
render_gauge(widgets.progress, live && std::isfinite(percent)
|
||||
? std::clamp(percent, 0.0f, 100.0f) : NAN, live ? percent : NAN, 100,
|
||||
live ? remaining(data.time_left, data.remaining_unit) : "--");
|
||||
set_text(widgets.task, live ? (valid_text(data.task) ? data.task : "No active print")
|
||||
: data.connected ? "Waiting for printer data" : "Waiting for Home Assistant");
|
||||
@@ -377,12 +409,13 @@ 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 filament = data.active_filament_color();
|
||||
const float shown = live && std::isfinite(data.progress)
|
||||
? std::clamp(data.progress, 0.0f, 100.0f) : NAN;
|
||||
const float percent = data.completion();
|
||||
const float shown = live && std::isfinite(percent)
|
||||
? std::clamp(percent, 0.0f, 100.0f) : NAN;
|
||||
const bool black = filament_is_black(filament);
|
||||
lv_obj_set_style_arc_color(widgets.arc, lv_color_hex(black ? RING_BACKING : TRACK), LV_PART_MAIN);
|
||||
lv_obj_set_style_arc_color(widgets.arc, lv_color_hex(filament), LV_PART_INDICATOR);
|
||||
lv_arc_set_value(widgets.arc, live ? gauge_value(data.progress, 100) : 0);
|
||||
lv_arc_set_value(widgets.arc, live ? gauge_value(percent, 100) : 0);
|
||||
if (black) {
|
||||
lv_obj_set_style_arc_color(widgets.backing, lv_color_hex(RING_BACKING), LV_PART_MAIN);
|
||||
lv_obj_set_style_arc_color(widgets.backing, lv_color_hex(RING_BACKING), LV_PART_INDICATOR);
|
||||
|
||||
Reference in New Issue
Block a user