From 07c62112b802b7048fb5421093ed8fee12231cac Mon Sep 17 00:00:00 2001 From: Ian Chua Date: Tue, 4 Aug 2026 18:12:51 +0800 Subject: [PATCH] Reconcile implementation split with PR tip --- src/slic3r/GUI/DeviceCore/DevManager.cpp | 42 +++++++++++++++++------- src/slic3r/GUI/DeviceCore/DevManager.h | 5 ++- tests/slic3rutils/test_printer_agent.cpp | 19 +++++++++++ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/DeviceCore/DevManager.cpp b/src/slic3r/GUI/DeviceCore/DevManager.cpp index 159bdc873e..6c2fa78b96 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.cpp +++ b/src/slic3r/GUI/DeviceCore/DevManager.cpp @@ -588,6 +588,7 @@ namespace Slic3r } else { + Slic3r::GUI::wxGetApp().reset_unsigned_plugin_warning(); if (m_agent) { if (it->second->connection_type() != "lan" || it->second->connection_type().empty()) @@ -621,6 +622,7 @@ namespace Slic3r } selected_machine = dev_id; + record_user_last_machine(selected_machine); return true; } @@ -885,20 +887,38 @@ namespace Slic3r } } + void DeviceManager::record_user_last_machine(const std::string& dev_id) + { + if (Slic3r::GUI::wxGetApp().app_config) { + Slic3r::GUI::wxGetApp().app_config->set("user_last_selected_machine", dev_id); + } + } + + std::string DeviceManager::get_user_last_machine() const + { + if (Slic3r::GUI::wxGetApp().app_config) { + const auto& user_last_machine = Slic3r::GUI::wxGetApp().app_config->get("user_last_selected_machine"); + if (!user_last_machine.empty()) { + return user_last_machine; + } else if (m_agent) { + return m_agent->get_user_selected_machine(); + } + } + + return ""; + } + void DeviceManager::load_last_machine() { - // Get all available machines, include cloud machines and lan machines that have access right - auto all_machines = get_my_machine_list(); - if (all_machines.empty()) + // Only reconnect the remembered cloud machine. Do not select an arbitrary + // first machine: agent swaps intentionally leave the selection empty until + // the new agent explicitly selects its configured printer. + if (userMachineList.empty()) return; - - // Reconnect the machine the user last selected, if it's still available. - // why: no first-available fallback - auto-connecting an arbitrary machine - // fights the agent-swap reset, which intentionally leaves nothing selected. - const std::string last_monitor_machine = m_agent ? m_agent->get_user_selected_machine() : ""; - const auto last_machine = all_machines.find(last_monitor_machine); - if (last_machine != all_machines.end()) - this->set_selected_machine(last_machine->second->get_dev_id()); + + const auto& last_monitor_machine = get_user_last_machine(); + if (userMachineList.find(last_monitor_machine) != userMachineList.end()) + set_selected_machine(last_monitor_machine); } void DeviceManager::OnMachineBindStateChanged(MachineObject* obj, const std::string& new_state) diff --git a/src/slic3r/GUI/DeviceCore/DevManager.h b/src/slic3r/GUI/DeviceCore/DevManager.h index 70bee613a8..51a428b092 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.h +++ b/src/slic3r/GUI/DeviceCore/DevManager.h @@ -52,6 +52,9 @@ public: // swap path can reuse it instead of duplicating the two sidebar calls. void OnSelectedMachineLost(); + void record_user_last_machine(const std::string& dev_id); + std::string get_user_last_machine() const; + // local machine void set_local_selected_machine(std::string dev_id) { local_selected_machine = dev_id; }; MachineObject* get_local_selected_machine() const { return get_local_machine(local_selected_machine); } @@ -143,4 +146,4 @@ public: protected: virtual void on_timer(wxTimerEvent& event); }; -}; \ No newline at end of file +}; diff --git a/tests/slic3rutils/test_printer_agent.cpp b/tests/slic3rutils/test_printer_agent.cpp index 0254db2266..e77ff14a29 100644 --- a/tests/slic3rutils/test_printer_agent.cpp +++ b/tests/slic3rutils/test_printer_agent.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -13,6 +14,24 @@ using namespace Slic3r; namespace py = pybind11; +// why: these builders preserve the Bambu firmware dialect byte-for-byte, including its trailing space. +TEST_CASE("unit: BBL AMS gcode builders preserve command bytes", "[unit][bbl]") +{ + CHECK(BBLPrinterAgent::ams_refresh_rfid_gcode("123") == "M620 R123 \n"); + CHECK(BBLPrinterAgent::ams_calibrate_gcode(123) == "M620 C123 \n"); + CHECK(BBLPrinterAgent::ams_select_tray_gcode("123") == "M620 P123 \n"); +} + +// why: an agent without a Bambu-dialect translation must refuse these commands before any network or wx path. +TEST_CASE("unit: default AMS commands report not supported", "[unit][moonraker]") +{ + MoonrakerPrinterAgent agent(""); + + CHECK(agent.command_ams_refresh_rfid("dev", "123", 1, false) == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED); + CHECK(agent.command_ams_calibrate("dev", 1, 2, false) == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED); + CHECK(agent.command_ams_select_tray("dev", "123", 3, false) == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED); +} + TEST_CASE("unit: Moonraker light name matching", "[unit][moonraker]") { CHECK(moonraker_is_light_name("caselight"));