Fixes in selecting printer and filament

This commit is contained in:
David Kocik 2024-04-19 15:14:45 +02:00
parent 58cd6c5a09
commit 63e25828ae
4 changed files with 169 additions and 69 deletions

View File

@ -3680,21 +3680,24 @@ bool GUI_App::select_printer_preset(const Preset* preset)
bool GUI_App::select_printer_from_connect(const std::string& msg) bool GUI_App::select_printer_from_connect(const std::string& msg)
{ {
// parse message // parse message
std::vector<std::string> compatible_printers; std::string model_name = plater()->get_user_account()->get_keyword_from_json(msg, "printer_model");
plater()->get_user_account()->fill_compatible_printers_from_json(msg, compatible_printers); if (model_name.empty()) {
std::string model_name; std::vector<std::string> compatible_printers;
if (compatible_printers.empty()) { plater()->get_user_account()->fill_compatible_printers_from_json(msg, compatible_printers);
// TODO: This should go away when compatible printers gives right information. if (!compatible_printers.empty()) {
model_name = compatible_printers.front();
}
}
// TODO: This should go away when compatible printers gives right information.
if (model_name.empty()) {
model_name = plater()->get_user_account()->get_model_from_json(msg); model_name = plater()->get_user_account()->get_model_from_json(msg);
} }
else { if (model_name.empty()) {
model_name = compatible_printers.front(); BOOST_LOG_TRIVIAL(error) << "Failed to select printer from Connect. Printer_model is empty.";
return false;
} }
std::string nozzle = plater()->get_user_account()->get_nozzle_from_json(msg); std::string nozzle = plater()->get_user_account()->get_nozzle_from_json(msg);
assert(!model_name.empty()); BOOST_LOG_TRIVIAL(info) << "Select printer from Connect. Model: " << model_name << "nozzle: " << nozzle;
if (model_name.empty())
return false;
// select printer // select printer
const Preset* printer_preset = preset_bundle->printers.find_system_preset_by_model_and_variant(model_name, nozzle); const Preset* printer_preset = preset_bundle->printers.find_system_preset_by_model_and_variant(model_name, nozzle);
bool is_installed = printer_preset && select_printer_preset(printer_preset); bool is_installed = printer_preset && select_printer_preset(printer_preset);
@ -3704,82 +3707,92 @@ bool GUI_App::select_printer_from_connect(const std::string& msg)
GUI::format(_L("Selected Printer:\n%1%"), printer_preset->name)) : GUI::format(_L("Selected Printer:\n%1%"), printer_preset->name)) :
GUI::format(_L("Printer not found:\n%1%"), model_name); GUI::format(_L("Printer not found:\n%1%"), model_name);
this->plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectPrinterFromConnect); this->plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectPrinterFromConnect);
this->plater()->get_notification_manager()->push_notification(NotificationType::SelectPrinterFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, out); this->plater()->get_notification_manager()->push_notification(
NotificationType::SelectPrinterFromConnect
, printer_preset ? NotificationManager::NotificationLevel::ImportantNotificationLevel : NotificationManager::NotificationLevel::WarningNotificationLevel
, out);
return printer_preset; return printer_preset;
} }
bool GUI_App::select_filament_preset(const Preset* preset) bool GUI_App::select_filament_preset(const Preset* preset, size_t extruder_index)
{ {
assert(preset && preset->is_compatible); assert(preset && preset->is_compatible);
if (!preset->is_visible) { if (!preset->is_visible) {
size_t preset_id = preset_bundle->filaments.get_preset_idx_by_name(preset->name); //size_t preset_id = preset_bundle->filaments.get_preset_idx_by_name(preset->name);
assert(preset_id != size_t(-1)); //assert(preset_id != size_t(-1));
preset_bundle->filaments.select_preset(preset_id); //preset_bundle->filaments.select_preset(preset_id);
bool r = preset_bundle->extruders_filaments[extruder_index].select_filament(preset->name);
assert(r);
} }
return get_tab(Preset::Type::TYPE_FILAMENT)->select_preset(preset->name); return get_tab(Preset::Type::TYPE_FILAMENT)->select_preset(preset->name);
} }
void GUI_App::select_filament_from_connect(const std::string& msg) void GUI_App::search_and_select_filaments(const std::string& material, size_t extruder_index, std::string& out_message)
{ {
const DynamicPrintConfig& config = preset_bundle->extruders_filaments[extruder_index].get_selected_preset()->config;
// parse message // selected is ok
std::string desired_type; if (config.has("filament_type") && config.option("filament_type")->serialize() == material) {
desired_type = plater()->get_user_account()->get_keyword_from_json(msg, "material");
if (desired_type.empty()) {
return; return;
} }
// test if currently selected is same type // find first installed compatible filament with suitable type and select it
std::string selected_type = preset_bundle->filaments.get_selected_preset().config.option("filament_type")->serialize(); for (const auto& filament : preset_bundle->extruders_filaments[extruder_index]) {
if (selected_type == desired_type) { if (filament.is_compatible
return; && !filament.preset->is_default
} && filament.preset->is_visible
// find first filament with suitable type && !filament.preset->vendor->templates_profile
for (const auto& filament_preset : preset_bundle->filaments) { && filament.preset->config.has("filament_type")
if (filament_preset.is_visible && filament.preset->config.option("filament_type")->serialize() == material
&& !filament_preset.vendor->templates_profile && select_filament_preset(filament.preset, extruder_index)
&& filament_preset.is_compatible )
&& filament_preset.config.option("filament_type")->serialize() == desired_type
&& select_filament_preset(&filament_preset))
{ {
std::string out = GUI::format(_L("Selected Filament:\n%1%"), filament_preset.name); out_message += /*(extruder_count == 1)
plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectFilamentFromConnect); ? GUI::format(_L("Selected Filament:\n%1%"), filament_preset.preset->name)
plater()->get_notification_manager()->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, out); : */GUI::format(_L("Extruder %1%: Selected Filament %2%\n"), extruder_index + 1, filament.preset->name);
return; return;
} }
} }
// find profile to install // find profile to install
// first try finding Prusament // try finding Prusament
for (const auto& filament_preset : preset_bundle->filaments) { for (const auto& filament : preset_bundle->extruders_filaments[extruder_index]) {
if (!filament_preset.vendor->templates_profile if (filament.is_compatible
&& filament_preset.is_compatible && !filament.preset->is_default
&& filament_preset.config.option("filament_type")->serialize() == desired_type && !filament.preset->vendor->templates_profile
&& filament_preset.name.compare(0, 9, "Prusament") == 0 && filament.preset->config.has("filament_type")
&& select_filament_preset(&filament_preset)) && filament.preset->config.option("filament_type")->serialize() == material
&& filament.preset->name.compare(0, 9, "Prusament") == 0
&& select_filament_preset(filament.preset, 0))
{ {
std::string out = GUI::format(_L("Installed and Selected Filament:\n%1%"), filament_preset.name); out_message += GUI::format(_L("Extruder %1%: Selected and Installed Filament %2%\n"), extruder_index + 1, filament.preset->name);
plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectFilamentFromConnect);
plater()->get_notification_manager()->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, out);
return; return;
} }
} }
// then just any compatible out_message += GUI::format(_L("Extruder %2%: Failed to Find and Select Filament type: %1%\n"), material, extruder_index + 1);
for (const auto& filament_preset : preset_bundle->filaments) { }
if (!filament_preset.vendor->templates_profile
&& filament_preset.is_compatible void GUI_App::select_filament_from_connect(const std::string& msg)
&& filament_preset.config.option("filament_type")->serialize() == desired_type {
&& select_filament_preset(&filament_preset)) // parse message
{ std::vector<std::string> materials;
std::string out = GUI::format(_L("Installed and Selected Filament:\n%1%"), filament_preset.name); plater()->get_user_account()->fill_material_from_json(msg, materials);
plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectFilamentFromConnect); if (materials.empty()) {
plater()->get_notification_manager()->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, out); BOOST_LOG_TRIVIAL(error) << "Failed to select filament from Connect. No material data.";
return; return;
} }
// test if currently selected is same type
size_t extruder_count = preset_bundle->extruders_filaments.size();
if (extruder_count != materials.size()) {
BOOST_LOG_TRIVIAL(error) << format("Failed to select filament from Connect. Selected printer has %1% extruders while data from Connect contains %2% materials.", extruder_count, materials.size());
return;
}
std::string notification_text;
for (size_t i = 0; i < extruder_count; i++) {
search_and_select_filaments(materials[i], i, notification_text);
} }
// no filamet found
std::string out = GUI::format(_L("Failed to find and select filament type:\n%1%"), desired_type);
plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectFilamentFromConnect); plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectFilamentFromConnect);
plater()->get_notification_manager()->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, out); plater()->get_notification_manager()->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, notification_text);
return;
} }
void GUI_App::handle_connect_request_printer_pick(const std::string& msg) void GUI_App::handle_connect_request_printer_pick(const std::string& msg)
@ -3788,10 +3801,11 @@ void GUI_App::handle_connect_request_printer_pick(const std::string& msg)
// return to plater // return to plater
this->mainframe->select_tab(size_t(0)); this->mainframe->select_tab(size_t(0));
if (!select_printer_from_connect(msg)) { //if (!select_printer_from_connect(msg)) {
// If printer was not selected, do not select filament. // // If printer was not selected, do not select filament.
return; // return;
} //}
// TODO: Selecting SLA material
if (Preset::printer_technology(preset_bundle->printers.get_selected_preset().config) != ptFFF) { if (Preset::printer_technology(preset_bundle->printers.get_selected_preset().config) != ptFFF) {
return; return;
} }

View File

@ -417,7 +417,8 @@ public:
void show_printer_webview_tab(); void show_printer_webview_tab();
// return true if preset vas invisible and we have to installed it to make it selectable // return true if preset vas invisible and we have to installed it to make it selectable
bool select_printer_preset(const Preset* printer_preset); bool select_printer_preset(const Preset* printer_preset);
bool select_filament_preset(const Preset* filament_preset); bool select_filament_preset(const Preset* filament_preset, size_t extruder_index);
void search_and_select_filaments(const std::string& material, size_t extruder_index, std::string& out_message);
void handle_script_message(std::string msg) {} void handle_script_message(std::string msg) {}
void request_model_download(std::string import_json) {} void request_model_download(std::string import_json) {}
void download_project(std::string project_id) {} void download_project(std::string project_id) {}

View File

@ -165,6 +165,17 @@ namespace {
return {}; return {};
} }
void parse_tree_for_param_vector(const pt::ptree& tree, const std::string& param, std::vector<std::string>& results)
{
for (const auto& section : tree) {
if (section.first == param) {
results.emplace_back(section.second.data());
} else {
parse_tree_for_param_vector(section.second, param, results);
}
}
}
pt::ptree parse_tree_for_subtree(const pt::ptree& tree, const std::string& param) pt::ptree parse_tree_for_subtree(const pt::ptree& tree, const std::string& param)
{ {
for (const auto& section : tree) { for (const auto& section : tree) {
@ -333,7 +344,7 @@ void UserAccount::fill_compatible_printers_from_json(const std::string& json, st
pt::ptree ptree; pt::ptree ptree;
pt::read_json(ss, ptree); pt::read_json(ss, ptree);
pt::ptree out = parse_tree_for_subtree(ptree, "printer_type_compatible"); pt::ptree out = parse_tree_for_subtree(ptree, "supported_printer_models");
if (out.empty()) { if (out.empty()) {
BOOST_LOG_TRIVIAL(error) << "Failed to find compatible_printer_type in printer detail."; BOOST_LOG_TRIVIAL(error) << "Failed to find compatible_printer_type in printer detail.";
return; return;
@ -347,6 +358,80 @@ void UserAccount::fill_compatible_printers_from_json(const std::string& json, st
} }
} }
void UserAccount::fill_material_from_json(const std::string& json, std::vector<std::string>& result) const
{
/* option 1:
"slot": {
"active": 2,
"slots": {
"1": {
"material": "PLA",
"temp": 170,
"fan_hotend": 7689,
"fan_print": 0
},
"2": {
"material": "PLA",
"temp": 225,
"fan_hotend": 7798,
"fan_print": 6503
},
"3": {
"material": "PLA",
"temp": 36,
"fan_hotend": 6636,
"fan_print": 0
},
"4": {
"material": "PLA",
"temp": 35,
"fan_hotend": 0,
"fan_print": 0
},
"5": {
"material": "PETG",
"temp": 136,
"fan_hotend": 8132,
"fan_print": 0
}
}
}
*/
/* option 2
"filament": {
"material": "PLA",
"bed_temperature": 60,
"nozzle_temperature": 210
}
*/
// try finding "slot" subtree a use it to
// if not found, find "filament" subtree
try {
std::stringstream ss(json);
pt::ptree ptree;
pt::read_json(ss, ptree);
// find "slot" subtree
pt::ptree slot_subtree = parse_tree_for_subtree(ptree, "slot");
if (slot_subtree.empty()) {
// if not found, find "filament" subtree
pt::ptree filament_subtree = parse_tree_for_subtree(ptree, "filament");
if (!filament_subtree.empty()) {
std::string material = parse_tree_for_param(filament_subtree, "material");
if (!material.empty()) {
result.emplace_back(std::move(material));
}
}
return;
}
// search "slot" subtree for all "material"s
parse_tree_for_param_vector(slot_subtree, "material", result);
}
catch (const std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "Could not parse prusaconnect message. " << e.what();
}
}
std::string UserAccount::get_printer_type_from_name(const std::string& printer_name) const std::string UserAccount::get_printer_type_from_name(const std::string& printer_name) const
{ {

View File

@ -64,9 +64,9 @@ public:
// standalone utility methods // standalone utility methods
std::string get_model_from_json(const std::string& message) const; std::string get_model_from_json(const std::string& message) const;
std::string get_nozzle_from_json(const std::string& message) const; std::string get_nozzle_from_json(const std::string& message) const;
//std::string get_apikey_from_json(const std::string& message) const;
std::string get_keyword_from_json(const std::string& json, const std::string& keyword) const; std::string get_keyword_from_json(const std::string& json, const std::string& keyword) const;
void fill_compatible_printers_from_json(const std::string& json, std::vector<std::string>& result) const; void fill_compatible_printers_from_json(const std::string& json, std::vector<std::string>& result) const;
void fill_material_from_json(const std::string& json, std::vector<std::string>& result) const;
const std::map<std::string, ConnectPrinterState>& get_printer_state_table() const { return printer_state_table; } const std::map<std::string, ConnectPrinterState>& get_printer_state_table() const { return printer_state_table; }