mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-21 06:21:16 +00:00
Fix current gen Qidi printer AMS sync (#16679)
Newer Qidi firmware for the Q2, Q2C, Plus 5 and Max 4 stores a slot's color as a hex list and its filament as a material id, and filament sync crashed on it. Each slot is now read in either form, the filament type comes from the box object, and any other JSON type error fails the sync instead of closing Orca.
This commit is contained in:
1 parent
25fd549d17
commit
07da005fab
1 file changed
+25
-6
@@ -73,7 +73,14 @@ bool QidiPrinterAgent::fetch_filament_info(std::string dev_id, FilamentSyncMode
|
||||
// 3. Fetch slot info and build AmsTrayData directly
|
||||
std::vector<AmsTrayData> 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<int>() : 0;
|
||||
const int filament_type = filament_value.is_number() ? filament_value.get<int>() : 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<std::string>();
|
||||
}
|
||||
}
|
||||
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<std::string>();
|
||||
} else if (color_it != dict.colors.end()) {
|
||||
tray.tray_color = color_it->second;
|
||||
} else {
|
||||
tray.tray_color = "FFFFFFFF";
|
||||
|
||||
Reference in new issue
Block a user