diff --git a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp index 5e81878b29e..f33886b3c5e 100644 --- a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp +++ b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp @@ -710,27 +710,46 @@ void MoonrakerPrinterAgent::build_ams_payload(int ams_count, int max_lane_index, bool MoonrakerPrinterAgent::fetch_filament_info(std::string dev_id) { - std::vector trays; - int max_lane_index = 0; - int active_lane_index = -1; + auto count_loaded = [](const std::vector& trays) { + int loaded = 0; + for (const auto& tray : trays) { + if (tray.has_filament) { + ++loaded; + } + } + return loaded; + }; - // Try Moonraker filament data (more generic, supports any filament changer - // software that reports lane data to Moonraker like AFC and recent Happy - // Hare as of Feb 15, 2026) - if (fetch_moonraker_filament_data(trays, max_lane_index)) { - BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: Detected Moonraker filament system with " - << (max_lane_index + 1) << " lanes"; - int ams_count = (max_lane_index + 4) / 4; - build_ams_payload(ams_count, max_lane_index, trays, active_lane_index); + // Query both sources. The Moonraker lane_data namespace (AFC and recent Happy + // Hare as of Feb 15, 2026) is more generic, but it can be stale or only + // partially populated, while the Happy Hare mmu object carries the full gate + // inventory (or vice versa). Pick whichever source reports more loaded slots + // so a sparse database can't shadow a fully-populated changer. + std::vector moonraker_trays; + int moonraker_max_lane = 0; + const bool moonraker_ok = fetch_moonraker_filament_data(moonraker_trays, moonraker_max_lane); + const int moonraker_loaded = moonraker_ok ? count_loaded(moonraker_trays) : 0; + + std::vector hh_trays; + int hh_max_lane = 0; + int hh_active_lane = -1; // KX/stable: 3-arg signature from PR #13719 + const bool hh_ok = fetch_hh_filament_info(hh_trays, hh_max_lane, hh_active_lane); + const int hh_loaded = hh_ok ? count_loaded(hh_trays) : 0; + + // Prefer Moonraker lane_data on ties to keep the original priority. + if (moonraker_ok && moonraker_loaded >= hh_loaded) { + BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: Using Moonraker filament data with " + << moonraker_loaded << " loaded of " << (moonraker_max_lane + 1) << " lanes"; + int ams_count = (moonraker_max_lane + 4) / 4; + build_ams_payload(ams_count, moonraker_max_lane, moonraker_trays); return true; } - // Attempt Happy Hare first (more widely adopted, supports more filament changers) - if (fetch_hh_filament_info(trays, max_lane_index, active_lane_index)) { - BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: Detected Happy Hare MMU with " - << (max_lane_index + 1) << " gates"; - int ams_count = (max_lane_index + 4) / 4; - build_ams_payload(ams_count, max_lane_index, trays, active_lane_index); + if (hh_ok) { + BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: Using Happy Hare MMU data with " + << hh_loaded << " loaded of " << (hh_max_lane + 1) << " gates"; + int ams_count = (hh_max_lane + 4) / 4; + build_ams_payload(ams_count, hh_max_lane, hh_trays); return true; } @@ -992,7 +1011,13 @@ bool MoonrakerPrinterAgent::fetch_moonraker_filament_data(std::vector