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

View File

@ -417,7 +417,8 @@ public:
void show_printer_webview_tab();
// 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_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 request_model_download(std::string import_json) {}
void download_project(std::string project_id) {}

View File

@ -165,6 +165,17 @@ namespace {
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)
{
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::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()) {
BOOST_LOG_TRIVIAL(error) << "Failed to find compatible_printer_type in printer detail.";
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
{

View File

@ -64,9 +64,9 @@ public:
// standalone utility methods
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_apikey_from_json(const std::string& message) 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_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; }