Add setting to enable uploads to abnormal Storage; improve sd_card_state error reporting (#10981)

* Add option to allow upload to SD-Cards marked as abnormal, also add better error description

+ Adds the options under the Network Settings to allow upload to abnormal SD-Card.
+ If not enabled user will now see why the upload is stuck at 10% depending on the sd_card_state (Readonly/Abnormal)

* Merging with current branch, and updateing "sd-card" to "storage"

* Generate localization and also change remaining sd_card_abnormal states to _storage_abnormal

* Fix issues from merge, and other bugfixes.

* Regenerate localization files.

* Improve Missing Storage Message, Add skip for abnormal storage in printer select dialog
This commit is contained in:
Seref
2025-10-29 13:32:38 +01:00
committed by GitHub
parent dedfd9d4ed
commit 4b7b81a0a2
33 changed files with 7555 additions and 4844 deletions

View File

@@ -266,6 +266,9 @@ void AppConfig::set_defaults()
if (get("stealth_mode").empty()) {
set_bool("stealth_mode", false);
}
if (get("allow_abnormal_storage").empty()) {
set_bool("allow_abnormal_storage", false);
}
if (get("legacy_networking").empty()) {
set_bool("legacy_networking", false);
}

View File

@@ -560,15 +560,32 @@ void PrintJob::process(Ctl &ctl)
ctl.update_status(curr_percent, _u8L("Sending print job through cloud service"));
result = m_agent->start_print(params, update_fn, cancel_fn, wait_fn);
}
}
} else {
if (this->has_sdcard) {
ctl.update_status(curr_percent, _u8L("Sending print job over LAN"));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
} else {
ctl.update_status(curr_percent, _u8L("Storage needs to be inserted before printing via LAN."));
return;
}
}
} else {
switch(this->sdcard_state) {
case DevStorage::SdcardState::NO_SDCARD:
ctl.update_status(curr_percent, _u8L("A Storage needs to be inserted before printing via LAN."));
return;
case DevStorage::SdcardState::HAS_SDCARD_ABNORMAL:
if(this->has_sdcard) {
// means the storage is abnormal but can be used option is enabled
ctl.update_status(curr_percent, _u8L("Sending print job over LAN, but the Storage in the printer is abnormal and print-issues may be caused by this."));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
break;
}
ctl.update_status(curr_percent, _u8L("The Storage in the printer is abnormal. Please replace it with a normal Storage before sending print job to printer."));
return;
case DevStorage::SdcardState::HAS_SDCARD_READONLY:
ctl.update_status(curr_percent, _u8L("The Storage in the printer is read-only. Please replace it with a normal Storage before sending print job to printer."));
return;
case DevStorage::SdcardState::HAS_SDCARD_NORMAL:
ctl.update_status(curr_percent, _u8L("Sending print job over LAN"));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
break;
default:
ctl.update_status(curr_percent, _u8L("Encountered an unknown error with the Storage status. Please try again."));
return;
}
}
if (result < 0) {

View File

@@ -5,6 +5,7 @@
#include <boost/filesystem/operations.hpp>
#include "libslic3r/PrintConfig.hpp"
#include "Job.hpp"
#include "slic3r/GUI/DeviceCore/DevStorage.h"
namespace fs = boost::filesystem;
@@ -82,6 +83,8 @@ public:
bool cloud_print_only { false };
bool has_sdcard { false };
bool task_use_ams { true };
DevStorage::SdcardState sdcard_state = DevStorage::SdcardState::NO_SDCARD;
bool task_ext_change_assist { false };
int auto_bed_leveling{0};

View File

@@ -297,13 +297,30 @@ void SendJob::process(Ctl &ctl)
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN"));
}
} else {
if (this->has_sdcard) {
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN"));
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
} else {
ctl.update_status(curr_percent, _u8L("Storage needs to be inserted before sending to printer."));
return;
}
switch(this->sdcard_state) {
case DevStorage::SdcardState::NO_SDCARD:
ctl.update_status(curr_percent, _u8L("Storage needs to be inserted before sending to printer."));
return;
case DevStorage::SdcardState::HAS_SDCARD_ABNORMAL:
if(this->has_sdcard) {
// means the sdcard is abnormal but can be used option is enabled
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN, but the Storage in the printer is abnormal and print-issues may be caused by this."));
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
break;
}
ctl.update_status(curr_percent, _u8L("The Storage in the printer is abnormal. Please replace it with a normal Storage before sending to printer."));
return;
case DevStorage::SdcardState::HAS_SDCARD_READONLY:
ctl.update_status(curr_percent, _u8L("The Storage in the printer is read-only. Please replace it with a normal Storage before sending to printer."));
return;
case DevStorage::SdcardState::HAS_SDCARD_NORMAL:
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN"));
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
break;
default:
ctl.update_status(curr_percent, _u8L("Encountered an unknown error with the Storage status. Please try again."));
return;
}
}
if (ctl.was_canceled()) {

View File

@@ -3,6 +3,7 @@
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "slic3r/GUI/DeviceCore/DevStorage.h"
#include "Job.hpp"
#include "PrintJob.hpp"
@@ -45,6 +46,8 @@ public:
bool cloud_print_only { false };
bool has_sdcard { false };
bool task_use_ams { true };
DevStorage::SdcardState sdcard_state = DevStorage::SdcardState::NO_SDCARD;
wxWindow* m_parent{nullptr};

View File

@@ -72,7 +72,7 @@ wxString PrePrintChecker::get_pre_state_msg(PrintDialogStatus status)
case PrintStatusAmsMappingMixInvalid: return _L("Please do not mix-use the Ext with AMS");
case PrintStatusNozzleDataInvalid: return _L("Invalid nozzle information, please refresh or manually set nozzle information.");
case PrintStatusLanModeNoSdcard: return _L("Storage needs to be inserted before printing via LAN.");
case PrintStatusLanModeSDcardNotAvailable: return _L("Storage is not available or is in read-only mode.");
case PrintStatusLanModeSDcardNotAvailable: return _L("Storage is in abnormal state or is in read-only mode.");
case PrintStatusNoSdcard: return _L("Storage needs to be inserted before printing.");
case PrintStatusNeedForceUpgrading: return _L("Cannot send the print job to a printer whose firmware is required to get updated.");
case PrintStatusNeedConsistencyUpgrading: return _L("Cannot send the print job to a printer whose firmware is required to get updated.");

View File

@@ -1342,7 +1342,9 @@ void PreferencesDialog::create_items()
g_sizer->Add(item_enable_plugin);
auto item_legacy_network = create_item_checkbox(_L("Use legacy network plugin"), _L("Disable to use latest network plugin that supports new BambuLab firmwares."), "legacy_networking", _L("(Requires restart)"));
g_sizer->Add(item_legacy_network);
g_sizer->Add(item_legacy_network);
//// ONLINE > Storage
g_sizer->AddSpacer(FromDIP(10));
sizer_page->Add(g_sizer, 0, wxEXPAND);
@@ -1404,6 +1406,10 @@ void PreferencesDialog::create_items()
auto item_mix_print_high_low_temperature = create_item_checkbox(_L("Remove mixed temperature restriction"), _L("With this option enabled, you can print materials with a large temperature difference together."), "enable_high_low_temp_mixed_printing");
g_sizer->Add(item_mix_print_high_low_temperature);
g_sizer->Add(create_item_title(_L("Storage")), 1, wxEXPAND);
auto item_allow_abnormal_storage = create_item_checkbox(_L("Allow Abnormal Storage"), _L("This allows the use of Storage that is marked as abnormal by the Printer.\nUse at your own risk, can cause issues!"), "allow_abnormal_storage");
g_sizer->Add(item_allow_abnormal_storage);
g_sizer->Add(create_item_title(_L("Log Level")), 1, wxEXPAND);
auto log_level_list = std::vector<wxString>{_L("fatal"), _L("error"), _L("warning"), _L("info"), _L("debug"), _L("trace")};
auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), _L("Log Level"), log_level_list);

View File

@@ -2516,8 +2516,14 @@ void SelectMachineDialog::on_send_print()
if (build_nozzles_info(m_print_job->task_nozzles_info)) {
BOOST_LOG_TRIVIAL(error) << "build_nozzle_info errors";
}
m_print_job->has_sdcard = obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_NORMAL;
m_print_job->sdcard_state = obj_->GetStorage()->get_sdcard_state() ;
m_print_job->has_sdcard = wxGetApp().app_config->get("allow_abnormal_storage") == "true"
? (m_print_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_NORMAL
|| m_print_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_ABNORMAL)
: m_print_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_NORMAL;
bool timelapse_option = m_checkbox_list["timelapse"]->IsShown()?true:false;
@@ -3313,7 +3319,10 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_)
if (obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::NO_SDCARD) {
show_status(PrintDialogStatus::PrintStatusLanModeNoSdcard);
return;
} else if (obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_ABNORMAL || obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_READONLY) {
} else if (obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_READONLY) {
show_status(PrintDialogStatus::PrintStatusLanModeSDcardNotAvailable);
return;
} else if(obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_ABNORMAL && (wxGetApp().app_config->get("allow_abnormal_storage") == "false")){
show_status(PrintDialogStatus::PrintStatusLanModeSDcardNotAvailable);
return;
}

View File

@@ -960,7 +960,7 @@ void SendToPrinterDialog::on_ok(wxCommandEvent &event)
update_print_status_msg(_L("No available external storage was obtained. Please confirm and try again."), true, true);
}
}
} else {
} else {
auto m_send_job = std::make_unique<SendJob>(m_printer_last_select);
m_send_job->m_dev_ip = obj_->get_dev_ip();
@@ -982,8 +982,15 @@ void SendToPrinterDialog::on_ok(wxCommandEvent &event)
#endif
m_send_job->connection_type = obj_->connection_type();
m_send_job->cloud_print_only = true;
m_send_job->has_sdcard = obj_->GetStorage()->get_sdcard_state() == DevStorage::SdcardState::HAS_SDCARD_NORMAL;
m_send_job->set_project_name(m_current_project_name.utf8_string());
m_send_job->sdcard_state = obj_->GetStorage()->get_sdcard_state();
m_send_job->has_sdcard = wxGetApp().app_config->get("allow_abnormal_storage") == "true"
? (m_send_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_NORMAL
|| m_send_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_ABNORMAL)
: m_send_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_NORMAL;
m_send_job->set_project_name(m_current_project_name.utf8_string());
enable_prepare_mode = false;

View File

@@ -1,6 +1,7 @@
#include "CalibUtils.hpp"
#include "../GUI/I18N.hpp"
#include "../GUI/GUI_App.hpp"
#include "../GUI/DeviceCore/DevStorage.h"
#include "../GUI/DeviceManager.hpp"
#include "../GUI/Jobs/ProgressIndicator.hpp"
#include "../GUI/PartPlate.hpp"
@@ -1815,8 +1816,14 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, wxString &error_mess
CalibMode cali_mode = calib_info.params.mode;
print_job->m_project_name = get_calib_mode_name(cali_mode, flow_ratio_mode);
print_job->set_calibration_task(true);
print_job->has_sdcard = obj_->GetStorage()->get_sdcard_state() == DevStorage::HAS_SDCARD_NORMAL;
print_job->sdcard_state = obj_->GetStorage()->get_sdcard_state();
print_job->has_sdcard = wxGetApp().app_config->get("allow_abnormal_storage") == "true"
? (print_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_NORMAL
|| print_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_ABNORMAL)
: print_job->sdcard_state == DevStorage::SdcardState::HAS_SDCARD_NORMAL;
print_job->set_print_config(MachineBedTypeString[bed_type], true, false, false, false, true, false, 0, 0, 0);
print_job->set_print_job_finished_event(wxGetApp().plater()->get_send_calibration_finished_event(), print_job->m_project_name);