Fix Orion AMS mapping and show printer health details
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -99,9 +100,13 @@ struct Tray {
|
||||
std::string label, type, color, active;
|
||||
};
|
||||
|
||||
struct HealthNotice { std::string code, message, severity; };
|
||||
|
||||
struct Snapshot {
|
||||
bool connected = false;
|
||||
std::string online, status, task, stage, print_error, hms_error;
|
||||
std::string hms_count, print_error_message, print_error_code;
|
||||
std::vector<HealthNotice> health_notices;
|
||||
std::string remaining_unit, nozzle_unit, bed_unit;
|
||||
std::string finish_time;
|
||||
float progress = NAN, nozzle = NAN, nozzle_target = NAN, bed = NAN, bed_target = NAN;
|
||||
@@ -112,12 +117,70 @@ struct Snapshot {
|
||||
std::vector<Tray> trays;
|
||||
|
||||
bool live() const { return connected && is_on(online) && valid_text(status); }
|
||||
int notice_count() const {
|
||||
int loaded = 0;
|
||||
for (const auto ¬ice : health_notices)
|
||||
if (valid_text(notice.code) || valid_text(notice.message)) ++loaded;
|
||||
char *end;
|
||||
const long count = std::strtol(hms_count.c_str(), &end, 10);
|
||||
return end != hms_count.c_str() && *end == '\0' && count >= 0 && count < 10000
|
||||
? std::max(loaded, static_cast<int>(count)) : loaded;
|
||||
}
|
||||
int health_severity_rank() const {
|
||||
int rank = 1, loaded = 0;
|
||||
for (const auto ¬ice : health_notices) {
|
||||
if (!valid_text(notice.code) && !valid_text(notice.message)) continue;
|
||||
++loaded;
|
||||
const auto severity = lower(notice.severity);
|
||||
rank = std::max(rank, severity == "fatal" || severity == "serious" ? 3 : severity == "info" ? 1 : 2);
|
||||
}
|
||||
// Missing/unloaded messages cannot establish an info-only notification.
|
||||
return loaded == 0 || notice_count() > loaded ? std::max(rank, 2) : rank;
|
||||
}
|
||||
std::string alert_summary() const {
|
||||
if (is_on(print_error))
|
||||
return valid_text(print_error_message) ? print_error_message : "Print error reported; tap status for details";
|
||||
if (is_on(hms_error)) {
|
||||
for (const auto ¬ice : health_notices)
|
||||
if (valid_text(notice.message)) return notice.message;
|
||||
return "Printer health notification; tap status for details";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
std::string health_details() const {
|
||||
if (!live()) return "Printer health data is unavailable. Waiting for a live connection.";
|
||||
std::string details;
|
||||
if (is_on(print_error)) {
|
||||
details = "PRINT ERROR\n";
|
||||
if (valid_text(print_error_code)) details += print_error_code + "\n";
|
||||
details += valid_text(print_error_message) ? print_error_message : "Message not supplied by Home Assistant.";
|
||||
details += "\n\n";
|
||||
}
|
||||
if (is_on(hms_error)) {
|
||||
details += "HMS = Health Management System\n";
|
||||
int loaded = 0;
|
||||
for (const auto ¬ice : health_notices) {
|
||||
if (!valid_text(notice.code) && !valid_text(notice.message)) continue;
|
||||
details += "\nNotice " + std::to_string(++loaded);
|
||||
if (valid_text(notice.severity)) details += " / " + notice.severity;
|
||||
details += "\n";
|
||||
if (valid_text(notice.code)) details += notice.code + "\n";
|
||||
details += valid_text(notice.message) ? notice.message : "Message not supplied by Home Assistant.";
|
||||
details += "\n";
|
||||
}
|
||||
if (loaded == 0) details += "\nNotification is active; details have not arrived from Home Assistant.\n";
|
||||
if (notice_count() > loaded)
|
||||
details += "\n" + std::to_string(notice_count() - loaded) + " more notification(s). View all in Home Assistant.\n";
|
||||
}
|
||||
return details.empty() ? "No current printer health notifications." : details;
|
||||
}
|
||||
std::string status_text() const {
|
||||
if (!connected) return "HA OFFLINE";
|
||||
if (lower(online) == "off" || lower(online) == "false") return "PRINTER OFFLINE";
|
||||
if (!live()) return "SYNCING";
|
||||
if (is_on(print_error)) return "PRINT ERROR";
|
||||
if (is_on(hms_error)) return "HMS ALERT";
|
||||
if (is_on(hms_error))
|
||||
return health_severity_rank() >= 3 ? "HEALTH ERROR" : health_severity_rank() == 1 ? "HEALTH INFO" : "HEALTH NOTICE";
|
||||
const auto state = lower(status);
|
||||
if (state == "running") return "PRINTING";
|
||||
if (state == "pause" || state == "paused") return "PAUSED";
|
||||
@@ -129,7 +192,9 @@ struct Snapshot {
|
||||
uint32_t status_color() const {
|
||||
if (!live()) return MUTED;
|
||||
const auto state = lower(status);
|
||||
if (is_on(print_error) || is_on(hms_error) || state == "failed") return RED;
|
||||
if (is_on(print_error) || state == "failed") return RED;
|
||||
if (is_on(hms_error))
|
||||
return health_severity_rank() >= 3 ? RED : health_severity_rank() == 1 ? 0x00E5E5 : AMBER;
|
||||
if (state == "pause" || state == "paused") return AMBER;
|
||||
return GREEN;
|
||||
}
|
||||
@@ -145,7 +210,7 @@ namespace bambu_display {
|
||||
struct TrayWidgets { lv_obj_t *card, *swatch, *label; };
|
||||
struct GaugeWidgets { lv_obj_t *arc, *value, *detail; };
|
||||
struct Widgets {
|
||||
lv_obj_t *status, *task, *top_progress, *remaining, *layers, *stage;
|
||||
lv_obj_t *status, *task, *top_progress, *remaining, *layers, *stage, *health_details;
|
||||
GaugeWidgets progress, nozzle, bed, fan, aux, exhaust;
|
||||
std::vector<TrayWidgets> trays;
|
||||
};
|
||||
@@ -192,7 +257,10 @@ inline void render(const Snapshot &data, const Widgets &widgets) {
|
||||
set_text(widgets.remaining, time_line);
|
||||
set_text(widgets.layers, live ? "Layer " + number(data.layer) + " / " + number(data.total_layers) : "--");
|
||||
std::string stage = live ? humanize(data.stage) : "Telemetry unavailable";
|
||||
if (live && (is_on(data.print_error) || is_on(data.hms_error))) stage = data.alert_summary();
|
||||
set_text(widgets.stage, stage);
|
||||
lv_obj_set_style_text_color(widgets.stage, lv_color_hex(live && !data.alert_summary().empty() ? color : MUTED), 0);
|
||||
set_text(widgets.health_details, data.health_details());
|
||||
for (size_t i = 0; i < std::min(data.trays.size(), widgets.trays.size()); ++i) {
|
||||
const auto &tray = data.trays[i];
|
||||
const auto &widget = widgets.trays[i];
|
||||
|
||||
Reference in New Issue
Block a user