diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 57da37fb9..987d3b30c 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -1389,6 +1389,21 @@ bool MachineObject::is_recording() return camera_recording; } +std::string MachineObject::parse_version() +{ + auto ota_version = module_vers.find("ota"); + if (ota_version != module_vers.end()) return ota_version->second.sw_ver; + auto series = get_printer_series(); + if (series == PrinterSeries::SERIES_X1) { + auto rv1126_version = module_vers.find("rv1126"); + if (rv1126_version != module_vers.end()) return rv1126_version->second.sw_ver; + } else if (series == PrinterSeries::SERIES_P1P) { + auto esp32_version = module_vers.find("esp32"); + if (esp32_version != module_vers.end()) return esp32_version->second.sw_ver; + } + return ""; +} + void MachineObject::parse_version_func() { auto ota_version = module_vers.find("ota"); @@ -2744,6 +2759,10 @@ int MachineObject::parse_json(std::string payload) if (j_pre["print"]["msg"].get() == 0) { //all message BOOST_LOG_TRIVIAL(trace) << "static: get push_all msg, dev_id=" << dev_id; m_push_count++; + if (j_pre["print"].contains("printer_type")) { + printer_type = parse_printer_type(j_pre["print"]["printer_type"].get()); + } + print_json.load_compatible_settings(printer_type, ""); print_json.diff2all_base_reset(j_pre); } else if (j_pre["print"]["msg"].get() == 1) { //diff message if (print_json.diff2all(j_pre, j) == 0) { @@ -2774,6 +2793,55 @@ int MachineObject::parse_json(std::string payload) BOOST_LOG_TRIVIAL(trace) << "parse_json: dev_id=" << dev_id << ", playload=" << j.dump(4); + // Parse version info first, as if version arrive or change, 'print' need parse again with new compatible settings + try { + if (j.contains("info")) { + if (j["info"].contains("command") && j["info"]["command"].get() == "get_version") { + json j_module = j["info"]["module"]; + module_vers.clear(); + for (auto it = j_module.begin(); it != j_module.end(); it++) { + ModuleVersionInfo ver_info; + ver_info.name = (*it)["name"].get(); + if ((*it).contains("sw_ver")) + ver_info.sw_ver = (*it)["sw_ver"].get(); + if ((*it).contains("sn")) + ver_info.sn = (*it)["sn"].get(); + if ((*it).contains("hw_ver")) + ver_info.hw_ver = (*it)["hw_ver"].get(); + module_vers.emplace(ver_info.name, ver_info); + if (ver_info.name == "ota") { + NetworkAgent* agent = GUI::wxGetApp().getAgent(); + if (agent) agent->track_update_property("dev_ota_version", ver_info.sw_ver); + } + } + + parse_version_func(); + + bool get_version_result = true; + if (j["info"].contains("result")) + if (j["info"]["result"].get() == "fail") + get_version_result = false; + if ((!check_version_valid() && get_version_retry-- >= 0) + && get_version_result) { + BOOST_LOG_TRIVIAL(info) << "get_version_retry = " << get_version_retry; + boost::thread retry = boost::thread([this] { + boost::this_thread::sleep_for(boost::chrono::milliseconds(RETRY_INTERNAL)); + GUI::wxGetApp().CallAfter([this] { + this->command_get_version(false); + }); + }); + } + } + std::string version = parse_version(); + if (!version.empty() && print_json.load_compatible_settings("", version)) { + // reload because compatible settings changed + j.clear(); + print_json.diff2all(json{}, j); + } + + } + } catch (...) {} + if (j.contains("print")) { json jj = j["print"]; int sequence_id = 0; @@ -4196,46 +4264,6 @@ int MachineObject::parse_json(std::string payload) } } - try { - if (j.contains("info")) { - if (j["info"].contains("command") && j["info"]["command"].get() == "get_version") { - json j_module = j["info"]["module"]; - module_vers.clear(); - for (auto it = j_module.begin(); it != j_module.end(); it++) { - ModuleVersionInfo ver_info; - ver_info.name = (*it)["name"].get(); - if ((*it).contains("sw_ver")) - ver_info.sw_ver = (*it)["sw_ver"].get(); - if ((*it).contains("sn")) - ver_info.sn = (*it)["sn"].get(); - if ((*it).contains("hw_ver")) - ver_info.hw_ver = (*it)["hw_ver"].get(); - module_vers.emplace(ver_info.name, ver_info); - if (ver_info.name == "ota") { - NetworkAgent* agent = GUI::wxGetApp().getAgent(); - if (agent) agent->track_update_property("dev_ota_version", ver_info.sw_ver); - } - } - parse_version_func(); - - bool get_version_result = true; - if (j["info"].contains("result")) - if (j["info"]["result"].get() == "fail") - get_version_result = false; - if ((!check_version_valid() && get_version_retry-- >= 0) - && get_version_result) { - BOOST_LOG_TRIVIAL(info) << "get_version_retry = " << get_version_retry; - boost::thread retry = boost::thread([this] { - boost::this_thread::sleep_for(boost::chrono::milliseconds(RETRY_INTERNAL)); - GUI::wxGetApp().CallAfter([this] { - this->command_get_version(false); - }); - }); - } - } - } - } catch (...) {} - try { if (j.contains("camera")) { if (j["camera"].contains("command")) { diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 45382db9b..d6eec94c4 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -743,6 +743,7 @@ public: MachineObject(NetworkAgent* agent, std::string name, std::string id, std::string ip); ~MachineObject(); + std::string parse_version(); void parse_version_func(); bool is_studio_cmd(int seq); /* command commands */ diff --git a/src/slic3r/Utils/json_diff.cpp b/src/slic3r/Utils/json_diff.cpp index da3cc1a1f..a1e3609f1 100644 --- a/src/slic3r/Utils/json_diff.cpp +++ b/src/slic3r/Utils/json_diff.cpp @@ -9,10 +9,13 @@ #include #include "nlohmann/json.hpp" + +#include + using namespace std; using json = nlohmann::json; -int json_diff::diff_objects(json in, json &out, json &base) +int json_diff::diff_objects(json const &in, json &out, json const &base) { for (auto& el: in.items()) { if (el.value().empty()) { @@ -63,14 +66,46 @@ int json_diff::diff_objects(json in, json &out, json &base) return 0; } -int json_diff::all2diff_base_reset(json &base) +int json_diff::all2diff_base_reset(json const &base) { BOOST_LOG_TRIVIAL(trace) << "all2diff_base_reset"; all2diff_base = base; return 0; } -int json_diff::all2diff(json& in, json& out) +bool json_diff::load_compatible_settings(std::string const &type, std::string const &version) +{ + std::string type2 = type.empty() ? printer_type : type; + std::string version2 = version.empty() ? printer_version : version; + if (type2 == printer_type && version2 == printer_version) + return false; + printer_type = type2; + printer_version = version2; + settings_base.clear(); + std::string config_file = Slic3r::resources_dir() + "/printers/" + type2 + ".json"; + std::ifstream json_file(config_file.c_str()); + try { + json versions; + if (json_file.is_open()) { + json_file >> versions; + for (auto iter = versions.begin(); iter != versions.end(); ++iter) { + if (iter.key() > version2) + break; + merge_objects(*iter, settings_base); + } + if (!full_message.empty()) + diff2all_base_reset(full_message); + return true; + } else { + BOOST_LOG_TRIVIAL(error) << "load_compatible_settings failed, file = " << config_file; + } + } catch (...) { + BOOST_LOG_TRIVIAL(error) << "load_compatible_settings failed, file = " << config_file; + } + return false; +} + +int json_diff::all2diff(json const &in, json &out) { int ret = 0; if (all2diff_base.empty()) { @@ -88,7 +123,7 @@ int json_diff::all2diff(json& in, json& out) return 0; } -int json_diff::restore_objects(json in, json &out, json &base) +int json_diff::restore_objects(json const &in, json &out, json const &base) { json jout; @@ -145,7 +180,7 @@ int json_diff::restore_objects(json in, json &out, json &base) return 0; } -int json_diff::restore_append_objects(json in, json &out) +int json_diff::restore_append_objects(json const &in, json &out) { /*a new element comming, but be recoreded in base need be added to output*/ @@ -173,7 +208,22 @@ int json_diff::restore_append_objects(json in, json &out) return 0; } -int json_diff::diff2all(json &in, json &out) +void json_diff::merge_objects(json const &in, json &out) +{ + for (auto &el : in.items()) { + if (!out.contains(el.key())) { + out[el.key()] = el.value(); + continue; + } + if (el.value().is_object()) { + merge_objects(el.value(), out[el.key()]); + continue; + } + out[el.key()] = el.value(); + } +} + +int json_diff::diff2all(json const &in, json &out) { if (!diff2all_base.empty()) { int ret = restore_objects(in, out, diff2all_base); @@ -218,8 +268,13 @@ bool json_diff::is_need_request() return false; } -int json_diff::diff2all_base_reset(json &base){ +int json_diff::diff2all_base_reset(json &base) +{ BOOST_LOG_TRIVIAL(trace) << "diff2all_base_reset"; + full_message = base; + if (!settings_base.empty()) { + merge_objects(settings_base, base); + } diff2all_base = base; return 0; } diff --git a/src/slic3r/Utils/json_diff.hpp b/src/slic3r/Utils/json_diff.hpp index a72fa1de4..6ba5a1b8e 100644 --- a/src/slic3r/Utils/json_diff.hpp +++ b/src/slic3r/Utils/json_diff.hpp @@ -14,19 +14,26 @@ using namespace std; class json_diff { private: + std::string printer_type; + std::string printer_version = "00.00.00.00"; + json settings_base; + json full_message; + json diff2all_base; json all2diff_base; int decode_error_count = 0; - int diff_objects(json in, json &out, json &base); - int restore_objects(json in, json &out, json &base); - int restore_append_objects(json in, json &out); + int diff_objects(json const &in, json &out, json const &base); + int restore_objects(json const &in, json &out, json const &base); + int restore_append_objects(json const &in, json &out); + void merge_objects(json const &in, json &out); public: - int all2diff(json &in, json &out); - int diff2all(json &in, json &out); - int all2diff_base_reset(json &base); - int diff2all_base_reset(json &base); + bool load_compatible_settings(std::string const &type, std::string const &version); + int all2diff(json const &in, json &out); + int diff2all(json const &in, json &out); + int all2diff_base_reset(json const &base); + int diff2all_base_reset(json &base); void compare_print(json &a, json &b); bool is_need_request();