2026-10-17 17:09:47 -04:00
|
|
|
#include "dashboard.h"
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
using namespace bambu_display;
|
|
|
|
|
assert(remaining(1.75f, "h") == "1h 45m");
|
|
|
|
|
assert(remaining(105.0f, "min") == "1h 45m");
|
|
|
|
|
assert(remaining(6300.0f, "s") == "1h 45m");
|
2026-10-19 11:24:02 -04:00
|
|
|
assert(remaining(6300000.0f, "ms") == "1h 45m");
|
2026-10-17 17:09:47 -04:00
|
|
|
assert(remaining(0.15f, "h") == "0h 09m");
|
|
|
|
|
assert(remaining(NAN, "h") == "--");
|
|
|
|
|
assert(remaining(-1, "min") == "--");
|
|
|
|
|
assert(remaining(10, "") == "--");
|
|
|
|
|
assert(remaining(INFINITY, "h") == "--");
|
|
|
|
|
assert(number(NAN) == "--");
|
|
|
|
|
assert(temperature(219, 220, "°C") == "219 / 220 °C");
|
2026-10-17 17:26:25 -04:00
|
|
|
assert(filament_color("#00FF00FF") == GREEN);
|
|
|
|
|
assert(filament_color("60de9a") == 0x60DE9A);
|
2026-10-17 17:09:47 -04:00
|
|
|
assert(filament_color("#60DE9AZZ") == TRACK);
|
|
|
|
|
assert(filament_color("unknown") == TRACK);
|
|
|
|
|
assert(gauge_value(NAN, 100) == 0);
|
|
|
|
|
assert(gauge_value(110, 100) == 100);
|
|
|
|
|
assert(gauge_value(-10, 100) == 0);
|
2026-10-17 17:26:25 -04:00
|
|
|
assert(duration_seconds(1.75f, "h") == 6300);
|
|
|
|
|
assert(duration_seconds(105, "min") == 6300);
|
2026-10-19 11:24:02 -04:00
|
|
|
assert(duration_seconds(6300000, "ms") == 6300);
|
2026-10-17 17:26:25 -04:00
|
|
|
assert(duration_seconds(NAN, "h") == -1);
|
|
|
|
|
assert(duration_seconds(1, "") == -1);
|
|
|
|
|
assert(std::abs(celsius(392, "°F") - 200) < 0.01f);
|
2026-10-17 17:09:47 -04:00
|
|
|
|
|
|
|
|
Snapshot data;
|
|
|
|
|
data.online = "on";
|
|
|
|
|
data.status = "running";
|
|
|
|
|
assert(!data.live());
|
|
|
|
|
assert(data.status_text() == "HA OFFLINE");
|
|
|
|
|
data.connected = true;
|
|
|
|
|
assert(data.live());
|
|
|
|
|
assert(data.status_text() == "PRINTING");
|
|
|
|
|
data.online = "off";
|
|
|
|
|
assert(!data.live());
|
|
|
|
|
assert(data.status_text() == "PRINTER OFFLINE");
|
|
|
|
|
data.online = "unavailable";
|
|
|
|
|
assert(data.status_text() == "SYNCING");
|
|
|
|
|
data.online = "on";
|
|
|
|
|
data.status = "unknown";
|
|
|
|
|
assert(!data.live());
|
|
|
|
|
data.status = "pause";
|
|
|
|
|
assert(data.status_text() == "PAUSED");
|
|
|
|
|
assert(data.status_color() == AMBER);
|
|
|
|
|
data.print_error = "on";
|
|
|
|
|
assert(data.status_text() == "PRINT ERROR");
|
|
|
|
|
assert(data.status_color() == RED);
|
|
|
|
|
data.print_error = "off";
|
|
|
|
|
data.hms_error = "True";
|
2026-10-18 09:29:07 -04:00
|
|
|
assert(data.status_text() == "HEALTH NOTICE");
|
|
|
|
|
assert(data.status_color() == AMBER);
|
|
|
|
|
assert(data.health_details().find("have not arrived") != std::string::npos);
|
|
|
|
|
data.hms_count = "1";
|
|
|
|
|
data.health_notices = {{"DEMO_CODE", "A synthetic information message", "info"}};
|
|
|
|
|
assert(data.status_text() == "HEALTH INFO");
|
|
|
|
|
assert(data.health_details().find("DEMO_CODE") != std::string::npos);
|
|
|
|
|
assert(data.alert_summary() == "A synthetic information message");
|
|
|
|
|
data.health_notices.push_back({"DEMO_2", "A synthetic serious message", "serious"});
|
|
|
|
|
data.hms_count = "2";
|
|
|
|
|
assert(data.status_text() == "HEALTH ERROR");
|
2026-10-17 17:09:47 -04:00
|
|
|
assert(data.status_color() == RED);
|
2026-10-18 09:29:07 -04:00
|
|
|
assert(data.health_details().find("A synthetic serious message") != std::string::npos);
|
|
|
|
|
data.health_notices.pop_back();
|
|
|
|
|
data.hms_count = "5";
|
|
|
|
|
assert(data.status_text() == "HEALTH NOTICE");
|
|
|
|
|
assert(data.health_details().find("4 more") != std::string::npos);
|
2026-10-17 17:09:47 -04:00
|
|
|
data.hms_error = "off";
|
2026-10-18 09:29:07 -04:00
|
|
|
assert(data.health_details() == "No current printer health notifications.");
|
2026-10-17 17:09:47 -04:00
|
|
|
data.status = "finish";
|
|
|
|
|
assert(data.status_text() == "COMPLETE");
|
|
|
|
|
assert(data.status_color() == GREEN);
|
2026-10-19 11:24:02 -04:00
|
|
|
|
|
|
|
|
// Elegoo exposes error enums rather than Bambu binary errors/HMS notices.
|
|
|
|
|
data.elegoo = true;
|
|
|
|
|
data.print_error = "none";
|
|
|
|
|
data.print_error_reason = "ok";
|
|
|
|
|
data.status = "printing";
|
|
|
|
|
assert(data.live());
|
|
|
|
|
assert(!data.has_print_error());
|
|
|
|
|
assert(data.status_text() == "PRINTING");
|
|
|
|
|
data.print_error_reason = "filament_runout";
|
|
|
|
|
assert(data.status_text() == "PRINT ERROR");
|
|
|
|
|
assert(data.status_color() == RED);
|
|
|
|
|
assert(data.health_details().find("Filament runout") != std::string::npos);
|
|
|
|
|
data.print_error = "invalid_resolution";
|
|
|
|
|
assert(data.alert_summary() == "Invalid resolution / Filament runout");
|
|
|
|
|
data.print_error_reason = "unavailable";
|
|
|
|
|
assert(data.alert_summary() == "Invalid resolution");
|
|
|
|
|
data.print_error = "unknown";
|
|
|
|
|
assert(!data.has_print_error());
|
|
|
|
|
data.status = "error";
|
|
|
|
|
assert(data.has_print_error());
|
|
|
|
|
data.status = "pausing";
|
|
|
|
|
assert(data.status_color() == AMBER);
|
|
|
|
|
data.status = "complete";
|
|
|
|
|
assert(data.status_text() == "COMPLETE");
|
2026-10-21 14:02:50 -04:00
|
|
|
data.status = "preheating_completed";
|
|
|
|
|
data.stage = "printing";
|
|
|
|
|
data.progress = 0;
|
|
|
|
|
data.layer = 0;
|
|
|
|
|
data.total_layers = 400;
|
|
|
|
|
data.elapsed = 30;
|
|
|
|
|
data.elapsed_unit = "min";
|
|
|
|
|
data.total_time = 60;
|
|
|
|
|
data.total_time_unit = "min";
|
|
|
|
|
assert(std::fabs(data.completion() - 50.0f) < 0.01f);
|
|
|
|
|
data.layer = 100;
|
|
|
|
|
assert(std::fabs(data.completion() - 25.0f) < 0.01f);
|
|
|
|
|
data.progress = 67;
|
|
|
|
|
assert(std::fabs(data.completion() - 67.0f) < 0.01f);
|
|
|
|
|
data.progress = 0;
|
|
|
|
|
data.layer = 0;
|
|
|
|
|
data.status = "idle";
|
|
|
|
|
data.stage = "idle";
|
|
|
|
|
assert(data.completion() == 0.0f);
|
2026-10-19 11:24:02 -04:00
|
|
|
data.online = "off";
|
|
|
|
|
assert(!data.live());
|
|
|
|
|
assert(data.status_text() == "PRINTER OFFLINE");
|
|
|
|
|
assert(data.health_details().find("unavailable") != std::string::npos);
|
2026-10-20 13:05:32 -04:00
|
|
|
|
|
|
|
|
data.connected = true;
|
|
|
|
|
data.online = "on";
|
|
|
|
|
data.elegoo = false;
|
|
|
|
|
data.print_error = "off";
|
|
|
|
|
data.print_error_reason = "ok";
|
|
|
|
|
data.hms_error = "off";
|
|
|
|
|
data.status = "running";
|
|
|
|
|
data.task = "Workshop organizer";
|
|
|
|
|
data.progress = 67;
|
|
|
|
|
data.time_left = 1.75f;
|
|
|
|
|
data.remaining_unit = "h";
|
|
|
|
|
data.finish_time = "16:05";
|
|
|
|
|
assert(data.overview_task() == "Workshop organizer");
|
|
|
|
|
assert(data.overview_meta() == "67% 16:05 1h 45m");
|
|
|
|
|
data.task = "";
|
|
|
|
|
assert(data.overview_task() == "No active print");
|
|
|
|
|
data.connected = false;
|
|
|
|
|
assert(data.overview_task() == "Waiting for Home Assistant");
|
|
|
|
|
assert(data.overview_meta() == "--");
|
2026-10-20 19:22:04 -04:00
|
|
|
data.trays = {{"A1", "PLA", "#FF8800FF", "off"}, {"A2", "PETG", "00FF00", "on"}};
|
|
|
|
|
assert(data.active_filament_color() == GREEN);
|
|
|
|
|
data.trays[1].active = "off";
|
|
|
|
|
data.trays[0].active = "on";
|
|
|
|
|
assert(data.active_filament_color() == 0xFF8800);
|
|
|
|
|
data.trays.clear();
|
|
|
|
|
assert(data.active_filament_color() == GREEN);
|
2026-10-20 20:46:41 -04:00
|
|
|
assert(filament_is_black(0x000000));
|
|
|
|
|
assert(filament_is_black(filament_color("#000000FF")));
|
|
|
|
|
assert(filament_is_black(0x202020));
|
|
|
|
|
assert(!filament_is_black(0xFFFFFF));
|
|
|
|
|
assert(!filament_is_black(GREEN));
|
|
|
|
|
assert(!filament_is_black(0xFF8800));
|
2026-10-20 13:05:32 -04:00
|
|
|
|
|
|
|
|
FleetCounts counts;
|
|
|
|
|
data.connected = true;
|
|
|
|
|
data.online = "on";
|
|
|
|
|
data.status = "printing";
|
|
|
|
|
tally(counts, data);
|
|
|
|
|
data.status = "pause";
|
|
|
|
|
tally(counts, data);
|
|
|
|
|
data.print_error = "on";
|
|
|
|
|
tally(counts, data);
|
|
|
|
|
data.print_error = "off";
|
|
|
|
|
data.online = "off";
|
|
|
|
|
tally(counts, data);
|
|
|
|
|
data.online = "unavailable";
|
|
|
|
|
data.connected = true;
|
|
|
|
|
tally(counts, data);
|
|
|
|
|
assert(fleet_summary(counts) == "1 attention, 1 printing, 1 paused, 1 offline, 1 syncing");
|
2026-10-17 17:09:47 -04:00
|
|
|
}
|