diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 0decfaac12..39520649a1 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -607,6 +607,19 @@ std::string AppConfig::load() for (auto& j_model : it.value()) { m_printer_settings[j_model["machine"].get()] = j_model; } + } else if (it.key() == "local_machines") { + for (auto m = it.value().begin(); m != it.value().end(); ++m) { + const auto& p = m.value(); + BBLocalMachine local_machine; + local_machine.dev_id = m.key(); + if (p.contains("dev_name")) + local_machine.dev_name = p["dev_name"].get(); + if (p.contains("dev_ip")) + local_machine.dev_ip = p["dev_ip"].get(); + if (p.contains("printer_type")) + local_machine.printer_type = p["printer_type"].get(); + m_local_machines[local_machine.dev_id] = local_machine; + } } else { if (it.value().is_object()) { for (auto iter = it.value().begin(); iter != it.value().end(); iter++) { @@ -783,6 +796,14 @@ void AppConfig::save() for (const auto& preset : m_printer_settings) { j["orca_presets"].push_back(preset.second); } + for (const auto& local_machine : m_local_machines) { + json m_json; + m_json["dev_name"] = local_machine.second.dev_name; + m_json["dev_ip"] = local_machine.second.dev_ip; + m_json["printer_type"] = local_machine.second.printer_type; + + j["local_machines"][local_machine.first] = m_json; + } boost::nowide::ofstream c; c.open(path_pid, std::ios::out | std::ios::trunc); c << std::setw(4) << j << std::endl; @@ -791,7 +812,7 @@ void AppConfig::save() // WIN32 specific: The final "rename_file()" call is not safe in case of an application crash, there is no atomic "rename file" API // provided by Windows (sic!). Therefore we save a MD5 checksum to be able to verify file corruption. In addition, // we save the config file into a backup first before moving it to the final destination. - c << appconfig_md5_hash_line({j.dump(4)}); + c << appconfig_md5_hash_line(j.dump(4)); #endif c.close(); diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp index cf95b8ec8d..d30161e072 100644 --- a/src/libslic3r/AppConfig.hpp +++ b/src/libslic3r/AppConfig.hpp @@ -24,6 +24,22 @@ using namespace nlohmann; namespace Slic3r { + +// Connected LAN mode BambuLab printer +struct BBLocalMachine +{ + std::string dev_name; + std::string dev_ip; + std::string dev_id; /* serial number */ + std::string printer_type; /* model_id */ + + bool operator==(const BBLocalMachine& other) const + { + return dev_name == other.dev_name && dev_ip == other.dev_ip && dev_id == other.dev_id && printer_type == other.printer_type; + } + bool operator!=(const BBLocalMachine& other) const { return !operator==(other); } +}; + class AppConfig { public: @@ -152,7 +168,8 @@ public: { auto it = m_storage.find(section); if (it != m_storage.end()) { - it->second.erase(key); + it->second.erase(key); + m_dirty = true; } } @@ -194,11 +211,34 @@ public: return ""; return m_printer_settings[printer][name]; } - std::string set_printer_setting(std::string printer, std::string name, std::string value) { - return m_printer_settings[printer][name] = value; - m_dirty = true; + void set_printer_setting(std::string printer, std::string name, std::string value) { + m_printer_settings[printer][name] = value; + m_dirty = true; } + const std::map& get_local_machines() const { return m_local_machines; } + void erase_local_machine(std::string dev_id) + { + auto it = m_local_machines.find(dev_id); + if (it != m_local_machines.end()) { + m_local_machines.erase(it); + m_dirty = true; + } + } + void update_local_machine(const BBLocalMachine& machine) + { + auto it = m_local_machines.find(machine.dev_id); + if (it != m_local_machines.end()) { + const auto& current = it->second; + if (machine != current) { + m_local_machines[machine.dev_id] = machine; + m_dirty = true; + } + } else { + m_local_machines[machine.dev_id] = machine; + m_dirty = true; + } + } const std::vector &get_filament_presets() const { return m_filament_presets; } void set_filament_presets(const std::vector &filament_presets){ @@ -335,6 +375,8 @@ private: std::vector m_filament_colors; std::vector m_printer_cali_infos; + + std::map m_local_machines; }; } // namespace Slic3r diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index d978442267..96cf02ab53 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -431,7 +431,7 @@ std::string MachineObject::get_ftp_folder() return DeviceManager::get_ftp_folder(printer_type); } -std::string MachineObject::get_access_code() +std::string MachineObject::get_access_code() const { if (get_user_access_code().empty()) return access_code; @@ -445,6 +445,7 @@ void MachineObject::set_access_code(std::string code, bool only_refresh) AppConfig* config = GUI::wxGetApp().app_config; if (config && !code.empty()) { GUI::wxGetApp().app_config->set_str("access_code", dev_id, code); + DeviceManager::update_local_machine(*this); } } } @@ -466,11 +467,12 @@ void MachineObject::set_user_access_code(std::string code, bool only_refresh) AppConfig* config = GUI::wxGetApp().app_config; if (config && !code.empty()) { GUI::wxGetApp().app_config->set_str("user_access_code", dev_id, code); + DeviceManager::update_local_machine(*this); } } } -std::string MachineObject::get_user_access_code() +std::string MachineObject::get_user_access_code() const { AppConfig* config = GUI::wxGetApp().app_config; if (config) { @@ -479,7 +481,7 @@ std::string MachineObject::get_user_access_code() return ""; } -bool MachineObject::is_lan_mode_printer() +bool MachineObject::is_lan_mode_printer() const { bool result = false; if (!dev_connection_type.empty() && dev_connection_type == "lan") @@ -4822,6 +4824,7 @@ int MachineObject::parse_json(std::string payload, bool key_field_only) if (diff.count() > 10.0f) { BOOST_LOG_TRIVIAL(trace) << "parse_json timeout = " << diff.count(); } + DeviceManager::update_local_machine(*this); return 0; } @@ -5263,6 +5266,49 @@ bool DeviceManager::key_field_only = false; DeviceManager::DeviceManager(NetworkAgent* agent) { m_agent = agent; + + // Load saved local machines + if (agent) { + AppConfig* config = GUI::wxGetApp().app_config; + const auto local_machines = config->get_local_machines(); + for (auto& it : local_machines) { + const auto& m = it.second; + MachineObject* obj = new MachineObject(m_agent, m.dev_name, m.dev_id, m.dev_ip); + obj->printer_type = m.printer_type; + obj->dev_connection_type = "lan"; + obj->bind_state = "free"; + obj->bind_sec_link = "secure"; + obj->m_is_online = true; + obj->last_alive = Slic3r::Utils::get_current_time_utc(); + obj->set_access_code(config->get("access_code", m.dev_id), false); + obj->set_user_access_code(config->get("user_access_code", m.dev_id), false); + if (obj->has_access_right()) { + localMachineList.insert(std::make_pair(m.dev_id, obj)); + } else { + config->erase_local_machine(m.dev_id); + delete obj; + } + } + } +} + +void DeviceManager::update_local_machine(const MachineObject& m) +{ + AppConfig* config = GUI::wxGetApp().app_config; + if (config) { + if (m.is_lan_mode_printer()) { + if (m.has_access_right()) { + BBLocalMachine local_machine; + local_machine.dev_id = m.dev_id; + local_machine.dev_name = m.dev_name; + local_machine.dev_ip = m.dev_ip; + local_machine.printer_type = m.printer_type; + config->update_local_machine(local_machine); + } + } else { + config->erase_local_machine(m.dev_id); + } + } } DeviceManager::~DeviceManager() @@ -5443,6 +5489,7 @@ void DeviceManager::on_machine_alive(std::string json_str) BOOST_LOG_TRIVIAL(info) << "SsdpDiscovery::New Machine, ip = " << Slic3r::GUI::wxGetApp().format_IP(dev_ip) << ", printer_name= " << dev_name << ", printer_type = " << printer_type_str << ", signal = " << printer_signal; } + update_local_machine(*obj); } catch (...) { ; diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 085d6356ca..e68002e13b 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -426,14 +426,14 @@ public: std::string dev_connection_name; /* lan | eth */ void set_dev_ip(std::string ip) {dev_ip = ip;} std::string get_ftp_folder(); - bool has_access_right() { return !get_access_code().empty(); } - std::string get_access_code(); + bool has_access_right() const { return !get_access_code().empty(); } + std::string get_access_code() const; void set_access_code(std::string code, bool only_refresh = true); void set_user_access_code(std::string code, bool only_refresh = true); void erase_user_access_code(); - std::string get_user_access_code(); - bool is_lan_mode_printer(); + std::string get_user_access_code() const; + bool is_lan_mode_printer() const; //PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN; std::string printer_type; /* model_id */ @@ -1085,6 +1085,8 @@ public: static std::vector get_compatible_machine(std::string type_str); static boost::bimaps::bimap get_all_model_id_with_name(); static std::string load_gcode(std::string type_str, std::string gcode_file); + + static void update_local_machine(const MachineObject& m); }; // change the opacity diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 431307d3f4..2da75a8893 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -740,6 +740,11 @@ void SelectMachinePopup::update_user_devices() op->Bind(EVT_UNBIND_MACHINE, [this, dev, mobj](wxCommandEvent& e) { dev->set_selected_machine(""); if (mobj) { + AppConfig* config = wxGetApp().app_config; + if (config) { + config->erase_local_machine(mobj->dev_id); + } + mobj->set_access_code(""); mobj->erase_user_access_code(); }