diff --git a/src/slic3r/Utils/QidiPrinterAgent.cpp b/src/slic3r/Utils/QidiPrinterAgent.cpp index c2dc4411a6..063f7721f0 100644 --- a/src/slic3r/Utils/QidiPrinterAgent.cpp +++ b/src/slic3r/Utils/QidiPrinterAgent.cpp @@ -73,7 +73,14 @@ bool QidiPrinterAgent::fetch_filament_info(std::string dev_id, FilamentSyncMode // 3. Fetch slot info and build AmsTrayData directly std::vector trays; int box_count = 0; - if (!fetch_slot_info(device_info.base_url, device_info.api_key, dict, series_id, trays, box_count, error)) { + bool slots_ok = false; + try { + slots_ok = fetch_slot_info(device_info.base_url, device_info.api_key, dict, series_id, trays, box_count, error); + } catch (const nlohmann::json::exception& e) { + // A slot value of an unexpected type fails the sync instead of escaping to the UI + error = e.what(); + } + if (!slots_ok) { BOOST_LOG_TRIVIAL(warning) << "QidiPrinterAgent::fetch_filament_info: Failed to fetch slot info: " << error; return false; } @@ -91,7 +98,7 @@ bool QidiPrinterAgent::fetch_slot_info(const std::string& base_url, int& box_count, std::string& error) { - std::string url = join_url(base_url, "/printer/objects/query?save_variables=variables"); + std::string url = join_url(base_url, "/printer/objects/query?save_variables=variables&multi_color_controller=box"); for (int i = 0; i < 16; ++i) { url += "&box_stepper%20slot" + std::to_string(i) + "=runout_button"; } @@ -164,9 +171,12 @@ bool QidiPrinterAgent::fetch_slot_info(const std::string& base_url, AmsTrayData tray; tray.slot_index = i; - // Read slot variables - const int color_index = variables.value("color_slot" + std::to_string(i), 1); - const int filament_type = variables.value("filament_slot" + std::to_string(i), 1); + // Read slot variables. Newer firmware stores a hex color list and a material id instead of dictionary + // indexes, and only in the slots it has rewritten, so each slot is checked for both forms. + const auto color_value = variables.value("color_slot" + std::to_string(i), nlohmann::json(1)); + const auto filament_value = variables.value("filament_slot" + std::to_string(i), nlohmann::json(1)); + const int color_index = color_value.is_number() ? color_value.get() : 0; + const int filament_type = filament_value.is_number() ? filament_value.get() : 0; const int vendor_type = variables.value("vendor_slot" + std::to_string(i), 0); // Check filament presence via runout sensor @@ -187,6 +197,13 @@ bool QidiPrinterAgent::fetch_slot_info(const std::string& base_url, if (filament_it != dict.filaments.end()) { filament_name = filament_it->second; } + if (filament_value.is_string()) { + const nlohmann::json::json_pointer decoded_type("/multi_color_controller/box/box" + std::to_string(i / 4) + + "_filament_info_" + std::to_string(i % 4) + "_filament_type"); + if (status.contains(decoded_type) && status[decoded_type].is_string()) { + filament_name = status[decoded_type].get(); + } + } tray.tray_type = normalize_filament_type(filament_name); // Try Qidi-specific setting ID first; fall back to visible preset by type @@ -202,7 +219,9 @@ bool QidiPrinterAgent::fetch_slot_info(const std::string& base_url, // Look up color from dictionary auto color_it = dict.colors.find(color_index); - if (color_it != dict.colors.end()) { + if (color_value.is_array() && !color_value.empty() && color_value[0].is_string()) { + tray.tray_color = color_value[0].get(); + } else if (color_it != dict.colors.end()) { tray.tray_color = color_it->second; } else { tray.tray_color = "FFFFFFFF";