FIX: update HMS to support multi-type machines

jira: [STUDIO-9582]
Change-Id: I5ad4083d666db4237d355ac8bd8160afb8e8a35f
This commit is contained in:
xin.zhang 2025-01-08 11:06:37 +08:00 committed by lane.wei
parent 663fb0d613
commit 954a270169
8 changed files with 186 additions and 122 deletions

View File

@ -756,7 +756,7 @@ PingCodeBindDialog::~PingCodeBindDialog() {
json j = json::parse(str.utf8_string());
if (j.contains("err_code")) {
int error_code = j["err_code"].get<int>();
wxGetApp().get_hms_query()->query_print_error_msg(error_code, extra);
extra = wxGetApp().get_hms_query()->query_print_error_msg(m_machine_info, error_code);
}
}
catch (...) {

View File

@ -1341,13 +1341,6 @@ void GUI_App::post_init()
mainframe->refresh_plugin_tips();
});
// update hms info
CallAfter([this] {
if (hms_query)
hms_query->check_hms_info();
});
DeviceManager::load_filaments_blacklist_config();
// remove old log files over LOG_FILES_MAX_NUM
@ -3713,9 +3706,8 @@ void GUI_App::recreate_GUI(const wxString &msg_name)
obj_list()->set_min_height();
update_mode();
//check hms info for different language
if (hms_query)
hms_query->check_hms_info();
// clear previous hms query, so that the hms info can use different language
if (hms_query) hms_query->clear_hms_info();
//BBS: trigger restore project logic here, and skip confirm
plater_->trigger_restore_project(1);

View File

@ -1,4 +1,5 @@
#include "HMS.hpp"
#include "DeviceManager.hpp"
#include <boost/log/trivial.hpp>
@ -43,10 +44,10 @@ int get_hms_info_version(std::string& version)
}
// Note: Download the hms into receive_json
int HMSQuery::download_hms_related(const std::string& hms_type, const std::string& dev_type, json* receive_json)
int HMSQuery::download_hms_related(const std::string& hms_type, const std::string& dev_id_type, json* receive_json)
{
std::string local_version = "0";
load_from_local(hms_type, dev_type, receive_json, local_version);
load_from_local(hms_type, dev_id_type, receive_json, local_version);
AppConfig* config = wxGetApp().app_config;
if (!config) return -1;
@ -64,7 +65,7 @@ int HMSQuery::download_hms_related(const std::string& hms_type, const std::strin
if (!local_version.empty()) { url += (url.find('?') != std::string::npos ? "&" : "?") + (boost::format("v=%1%") % local_version).str(); }
if (!dev_type.empty()) { url += (url.find('?') != std::string::npos ? "&" : "?") + (boost::format("d=%1%") % dev_type).str(); }
if (!dev_id_type.empty()) { url += (url.find('?') != std::string::npos ? "&" : "?") + (boost::format("d=%1%") % dev_id_type).str(); }
bool to_save_local = false;
@ -114,36 +115,11 @@ int HMSQuery::download_hms_related(const std::string& hms_type, const std::strin
}).perform_sync();
if (to_save_local && !receive_json->empty()) {
save_to_local(lang, hms_type, dev_type, *receive_json);
save_to_local(lang, hms_type, dev_id_type, *receive_json);
}
return 0;
}
bool HMSQuery::check_local_file(std::string dev_type)
{
if (data_dir().empty()) {
BOOST_LOG_TRIVIAL(error) << "HMS: load_from_local, data_dir() is empty";
return false;
}
std::string filename = get_hms_file(QUERY_HMS_INFO, HMSQuery::hms_language_code(), dev_type);
auto hms_folder = (boost::filesystem::path(data_dir()) / "hms");
if (!fs::exists(hms_folder)) fs::create_directory(hms_folder);
std::string dir_str = (hms_folder / filename).make_preferred().string();
std::ifstream json_file(encode_path(dir_str.c_str()));
try {
if (json_file.is_open()) {
json_file.close();
return true;
}
} catch (...) {
BOOST_LOG_TRIVIAL(error) << "HMS: load_from_local failed";
return false;
}
return false;
}
void HMSQuery::copy_from_data_dir_to_local()
{
const fs::path& from_dir = fs::path(Slic3r::resources_dir()) / HMS_PATH;
@ -165,14 +141,14 @@ void HMSQuery::copy_from_data_dir_to_local()
}
}
int HMSQuery::load_from_local(const std::string& hms_type, const std::string& dev_type, json* load_json, std::string& load_version)
int HMSQuery::load_from_local(const std::string& hms_type, const std::string& dev_id_type, json* load_json, std::string& load_version)
{
if (data_dir().empty()) {
load_version = "0";
BOOST_LOG_TRIVIAL(error) << "HMS: load_from_local, data_dir() is empty";
return -1;
}
std::string filename = get_hms_file(hms_type, HMSQuery::hms_language_code(), dev_type);
std::string filename = get_hms_file(hms_type, HMSQuery::hms_language_code(), dev_id_type);
auto hms_folder = (boost::filesystem::path(data_dir()) / "hms");
if (!fs::exists(hms_folder))
fs::create_directory(hms_folder);
@ -199,13 +175,13 @@ int HMSQuery::load_from_local(const std::string& hms_type, const std::string& de
return 0;
}
int HMSQuery::save_to_local(std::string lang, std::string hms_type, std::string dev_type, json save_json)
int HMSQuery::save_to_local(std::string lang, std::string hms_type, std::string dev_id_type, json save_json)
{
if (data_dir().empty()) {
BOOST_LOG_TRIVIAL(error) << "HMS: save_to_local, data_dir() is empty";
return -1;
}
std::string filename = get_hms_file(hms_type,lang, dev_type);
std::string filename = get_hms_file(hms_type,lang, dev_id_type);
auto hms_folder = (boost::filesystem::path(data_dir()) / "hms");
if (!fs::exists(hms_folder))
fs::create_directory(hms_folder);
@ -253,32 +229,63 @@ std::string HMSQuery::build_query_params(std::string& lang)
return query_params;
}
std::string HMSQuery::get_hms_file(std::string hms_type, std::string lang, std::string dev_type)
std::string HMSQuery::get_hms_file(std::string hms_type, std::string lang, std::string dev_id_type)
{
//return hms action filename
if (hms_type.compare(QUERY_HMS_ACTION) == 0) {
return (boost::format("hms_action_%1%.json") % dev_type).str();
return (boost::format("hms_action_%1%.json") % dev_id_type).str();
}
//return hms filename
return (boost::format("hms_%1%_%2%.json") % lang % dev_type).str();
return (boost::format("hms_%1%_%2%.json") % lang % dev_id_type).str();
}
wxString HMSQuery::query_hms_msg(std::string long_error_code) const
wxString HMSQuery::query_hms_msg(const MachineObject* obj, const std::string& long_error_code)
{
if (!obj)
{
return wxEmptyString;
}
AppConfig* config = wxGetApp().app_config;
if (!config) return wxEmptyString;
const std::string& lang_code = HMSQuery::hms_language_code();
return _query_hms_msg(get_dev_id_type(obj),long_error_code, lang_code);
}
wxString HMSQuery::query_hms_msg(const std::string& dev_id, const std::string& long_error_code)
{
AppConfig* config = wxGetApp().app_config;
if (!config) return wxEmptyString;
const std::string& lang_code = HMSQuery::hms_language_code();
return _query_hms_msg(long_error_code, lang_code);
return _query_hms_msg(dev_id.substr(0, 3), long_error_code, lang_code);
}
wxString HMSQuery::_query_hms_msg(std::string long_error_code, std::string lang_code) const
string HMSQuery::get_dev_id_type(const MachineObject* obj) const
{
if (obj)
{
return obj->dev_id.substr(0, 3);
}
return string();
}
wxString HMSQuery::_query_hms_msg(const string& dev_id_type, const string& long_error_code, const string& lang_code)
{
if (long_error_code.empty())
{
return wxEmptyString;
}
std::unique_lock unique_lock(m_hms_mutex);
init_hms_info(dev_id_type);
auto iter = m_hms_info_jsons.find(dev_id_type);
if (iter == m_hms_info_jsons.end())
{
BOOST_LOG_TRIVIAL(error) << "there are no hms info for the device";
return wxEmptyString;
}
const json& m_hms_info_json = iter->second;
if (!m_hms_info_json.is_object())
{
BOOST_LOG_TRIVIAL(error) << "the hms info is not a valid json object";
@ -308,7 +315,7 @@ wxString HMSQuery::_query_hms_msg(std::string long_error_code, std::string lang_
if (boost::to_upper_copy(error_code) == long_error_code && msg_item.contains("intro"))
{
BOOST_LOG_TRIVIAL(info) << "retry without lang_code successed.";
return msg_item["intro"].get<std::string>();
return wxString::FromUTF8(msg_item["intro"].get<std::string>());
}
}
}
@ -325,7 +332,7 @@ wxString HMSQuery::_query_hms_msg(std::string long_error_code, std::string lang_
const std::string& error_code = item.value("ecode", json()).get<std::string>();
if (boost::to_upper_copy(error_code) == long_error_code && item.contains("intro"))
{
return item["intro"].get<std::string>();
return wxString::FromUTF8(item["intro"].get<std::string>());
}
}
}
@ -334,17 +341,24 @@ wxString HMSQuery::_query_hms_msg(std::string long_error_code, std::string lang_
return wxEmptyString;
}
bool HMSQuery::_query_error_msg(wxString &error_msg, std::string error_code, std::string lang_code)
wxString HMSQuery::_query_error_msg(const std::string& dev_id_type,
const std::string& error_code,
const std::string& lang_code)
{
std::unique_lock unique_lock(m_hms_mutex);
init_hms_info(dev_id_type);
auto iter = m_hms_info_jsons.find(dev_id_type);
if (iter == m_hms_info_jsons.end())
{
return wxEmptyString;
}
const json& m_hms_info_json = iter->second;
if (m_hms_info_json.contains("device_error")) {
if (m_hms_info_json["device_error"].contains(lang_code)) {
for (auto item = m_hms_info_json["device_error"][lang_code].begin(); item != m_hms_info_json["device_error"][lang_code].end(); item++) {
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
if (item->contains("intro")) {
error_msg = wxString::FromUTF8((*item)["intro"].get<std::string>());
return true;
return wxString::FromUTF8((*item)["intro"].get<std::string>());
}
}
}
@ -357,8 +371,7 @@ bool HMSQuery::_query_error_msg(wxString &error_msg, std::string error_code, std
for (auto item = lang.begin(); item != lang.end(); item++) {
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
if (item->contains("intro")) {
error_msg = wxString::FromUTF8((*item)["intro"].get<std::string>());
return true;
return wxString::FromUTF8((*item)["intro"].get<std::string>());
}
}
}
@ -368,21 +381,27 @@ bool HMSQuery::_query_error_msg(wxString &error_msg, std::string error_code, std
}
else {
BOOST_LOG_TRIVIAL(info) << "device_error is not exists";
error_msg = wxEmptyString;
return false;
return wxEmptyString;
}
error_msg = wxEmptyString;
return false;
return wxEmptyString;
}
wxString HMSQuery::_query_error_url_action(std::string long_error_code, std::string dev_id, std::vector<int>& button_action)
wxString HMSQuery::_query_error_url_action(const std::string& dev_id_type, const std::string& long_error_code, std::vector<int>& button_action)
{
std::unique_lock unique_lock(m_hms_mutex);
init_hms_info(dev_id_type);
auto iter = m_hms_action_jsons.find(dev_id_type);
if (iter == m_hms_action_jsons.end())
{
return wxEmptyString;
}
const json& m_hms_action_json = iter->second;
if (m_hms_action_json.contains("data")) {
for (auto item = m_hms_action_json["data"].begin(); item != m_hms_action_json["data"].end(); item++) {
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == long_error_code) {
if (item->contains("device") && (boost::to_upper_copy((*item)["device"].get<std::string>()) == dev_id ||
if (item->contains("device") && (boost::to_upper_copy((*item)["device"].get<std::string>()) == dev_id_type ||
(*item)["device"].get<std::string>() == "default")) {
if (item->contains("actions")) {
for (auto item_actions = (*item)["actions"].begin(); item_actions != (*item)["actions"].end(); item_actions++) {
@ -404,48 +423,85 @@ wxString HMSQuery::_query_error_url_action(std::string long_error_code, std::str
}
bool HMSQuery::query_print_error_msg(int print_error, wxString &error_msg)
wxString HMSQuery::query_print_error_msg(const MachineObject* obj, int print_error)
{
if (!obj)
{
return wxEmptyString;
}
char buf[32];
::sprintf(buf, "%08X", print_error);
std::string lang_code = HMSQuery::hms_language_code();
return _query_error_msg(get_dev_id_type(obj), std::string(buf), lang_code);
}
wxString HMSQuery::query_print_error_msg(const std::string& dev_id, int print_error)
{
char buf[32];
::sprintf(buf, "%08X", print_error);
std::string lang_code = HMSQuery::hms_language_code();
return _query_error_msg(error_msg, std::string(buf), lang_code);
return _query_error_msg(dev_id.substr(0, 3), std::string(buf), lang_code);
}
wxString HMSQuery::query_print_error_url_action(int print_error, std::string dev_id, std::vector<int>& button_action)
wxString HMSQuery::query_print_error_url_action(const MachineObject* obj, int print_error, std::vector<int>& button_action)
{
if (!obj)
{
return wxEmptyString;
}
char buf[32];
::sprintf(buf, "%08X", print_error);
//The first three digits of SN number
dev_id = dev_id.substr(0, 3);
return _query_error_url_action(std::string(buf), dev_id, button_action);
return _query_error_url_action(get_dev_id_type(obj),std::string(buf), button_action);
}
int HMSQuery::check_hms_info(std::string dev_type)
void HMSQuery::clear_hms_info()
{
copy_from_data_dir_to_local();// STUDIO-9512
std::unique_lock unique_lock(m_hms_mutex);
m_hms_info_jsons.clear();
m_hms_action_jsons.clear();
}
std::vector<std::string> dev_sn;
dev_sn.push_back("00M");
dev_sn.push_back("00W");
dev_sn.push_back("03W");
dev_sn.push_back("01P");
dev_sn.push_back("01S");
dev_sn.push_back("030");
dev_sn.push_back("039");
// dev_sn.push_back("094"); // there are 094 files in local
void HMSQuery::init_hms_info(const std::string& dev_type_id)
{
std::unique_lock unique_lock(m_hms_mutex);
if (m_hms_info_jsons.count(dev_type_id) != 0)
{
return;
}
boost::thread check_thread = boost::thread([this, dev_type, dev_sn] {
static unordered_set<string> package_dev_id_types { "094" };
if (package_dev_id_types.count(dev_type_id) != 0)
{
copy_from_data_dir_to_local();// STUDIO-9512
std::unique_lock unique_lock(m_hms_mutex);
for (auto sn : dev_sn) {
download_hms_related(QUERY_HMS_INFO, sn, &m_hms_info_json);
download_hms_related(QUERY_HMS_ACTION, sn, &m_hms_action_json);
string dev_type = "094";
m_hms_info_jsons.emplace(dev_type, json());
m_hms_action_jsons.emplace(dev_type, json());
std::string load_version;
load_from_local(QUERY_HMS_INFO, dev_type, &m_hms_info_jsons[dev_type], load_version);
load_from_local(QUERY_HMS_ACTION, dev_type, &m_hms_action_jsons[dev_type], load_version);
}
static unordered_set<string> cloud_dev_id_types{ "00M", "00W", "03W", "01P", "01S", "030", "039" };
if (cloud_dev_id_types.count(dev_type_id) != 0)
{
if (m_hms_info_jsons.count(dev_type_id) == 0)
{
m_hms_info_jsons.emplace(dev_type_id, json());
}
return 0;
});
return 0;
if (m_hms_action_jsons.count(dev_type_id) == 0)
{
m_hms_action_jsons.emplace(dev_type_id, json());
}
download_hms_related(QUERY_HMS_INFO, dev_type_id, &m_hms_info_jsons[dev_type_id]);
download_hms_related(QUERY_HMS_ACTION, dev_type_id, &m_hms_action_jsons[dev_type_id]);
}
}
std::string get_hms_wiki_url(std::string error_code)

View File

@ -14,6 +14,9 @@
#include <mutex>
namespace Slic3r {
class MachineObject;
namespace GUI {
#define HMS_INFO_FILE "hms.json"
@ -23,30 +26,43 @@ namespace GUI {
class HMSQuery {
protected:
json m_hms_info_json;
json m_hms_action_json;
std::unordered_map<string, json> m_hms_info_jsons; // key-> device id type, the first three digits of SN number
std::unordered_map<string, json> m_hms_action_jsons;// key-> device id type
mutable std::mutex m_hms_mutex;
int download_hms_related(const std::string& hms_type, const std::string& dev_type, json *receive_json);
int load_from_local(const std::string& hms_type, const std::string& dev_type, json * receive_json, std::string& version_info);
int save_to_local(std::string lang, std::string hms_type, std::string dev_type, json save_json);
std::string get_hms_file(std::string hms_type, std::string lang = std::string("en"), std::string dev_type = "");
wxString _query_hms_msg(std::string long_error_code, std::string lang_code = std::string("en")) const;
bool _query_error_msg(wxString &error_msg, std::string long_error_code, std::string lang_code = std::string("en"));
wxString _query_error_url_action(std::string long_error_code, std::string dev_id, std::vector<int>& button_action);
public:
HMSQuery() { }
~HMSQuery() { clear_hms_info(); };
public:
HMSQuery() {}
int check_hms_info(std::string dev_type = "00M");
wxString query_hms_msg(std::string long_error_code) const;
bool query_print_error_msg(int print_error, wxString &error_msg);
wxString query_print_error_url_action(int print_error, std::string dev_id, std::vector<int>& button_action);
static std::string hms_language_code();
static std::string build_query_params(std::string& lang);
bool check_local_file(std::string dev_type);
// clear hms
void clear_hms_info();
// query
wxString query_hms_msg(const MachineObject* obj, const std::string& long_error_code);
wxString query_hms_msg(const std::string& dev_id, const std::string& long_error_code);
wxString query_print_error_msg(const MachineObject* obj, int print_error);
wxString query_print_error_msg(const std::string& dev_id, int print_error);
wxString query_print_error_url_action(const MachineObject* obj, int print_error, std::vector<int>& button_action);
public:
static std::string hms_language_code();
static std::string build_query_params(std::string& lang);
private:
// load hms
void init_hms_info(const std::string& dev_type_id);
void copy_from_data_dir_to_local();
int download_hms_related(const std::string& hms_type, const std::string& dev_id_type, json* receive_json);
int load_from_local(const std::string& hms_type, const std::string& dev_id_type, json* receive_json, std::string& version_info);
int save_to_local(std::string lang, std::string hms_type, std::string dev_id_type, json save_json);
std::string get_hms_file(std::string hms_type, std::string lang = std::string("en"), std::string dev_id_type = "");
// internal query
string get_dev_id_type(const MachineObject* obj) const;
wxString _query_hms_msg(const string& dev_id_type, const string& long_error_code, const string& lang_code = std::string("en"));
wxString _query_error_msg(const string& dev_id_type, const std::string& long_error_code, const std::string& lang_code = std::string("en"));
wxString _query_error_url_action(const string& dev_id_type, const std::string& long_error_code, std::vector<int>& button_action);
};
int get_hms_info_version(std::string &version);

View File

@ -16,9 +16,10 @@ namespace GUI {
wxDEFINE_EVENT(EVT_ALREADY_READ_HMS, wxCommandEvent);
HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item)
HMSNotifyItem::HMSNotifyItem(const std::string& dev_id, wxWindow *parent, HMSItem& item)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
, m_hms_item(item)
, dev_id(dev_id)
, long_error_code(item.get_long_error_code())
, m_url(get_hms_wiki_url(item.get_long_error_code()))
{
@ -40,7 +41,7 @@ HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item)
m_hms_content->SetForegroundColour(*wxBLACK);
m_hms_content->SetSize(HMS_NOTIFY_ITEM_TEXT_SIZE);
m_hms_content->SetMinSize(HMS_NOTIFY_ITEM_TEXT_SIZE);
m_hms_content->SetLabelText(_L(wxGetApp().get_hms_query()->query_hms_msg(m_hms_item.get_long_error_code())));
m_hms_content->SetLabelText(wxGetApp().get_hms_query()->query_hms_msg(dev_id, m_hms_item.get_long_error_code()));
m_hms_content->Wrap(HMS_NOTIFY_ITEM_TEXT_SIZE.GetX());
m_bitmap_arrow = new wxStaticBitmap(m_panel_hms, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
@ -185,9 +186,9 @@ HMSPanel::~HMSPanel() {
;
}
void HMSPanel::append_hms_panel(HMSItem& item) {
m_notify_item = new HMSNotifyItem(m_scrolledWindow, item);
wxString msg = wxGetApp().get_hms_query()->query_hms_msg(item.get_long_error_code());
void HMSPanel::append_hms_panel(const std::string& dev_id, HMSItem& item) {
m_notify_item = new HMSNotifyItem(dev_id, m_scrolledWindow, item);
wxString msg = wxGetApp().get_hms_query()->query_hms_msg(dev_id, item.get_long_error_code());
if (!msg.empty())
m_top_sizer->Add(m_notify_item, 0, wxALIGN_CENTER_HORIZONTAL);
else {
@ -221,7 +222,7 @@ void HMSPanel::update(MachineObject *obj)
temp_hms_list[key] = item;
}
append_hms_panel(item);
append_hms_panel(obj->dev_id, item);
}
}

View File

@ -16,6 +16,7 @@ class HMSNotifyItem : public wxPanel
{
HMSItem & m_hms_item;
std::string m_url;
std::string dev_id;
std::string long_error_code;
wxPanel * m_panel_hms;
@ -34,7 +35,7 @@ class HMSNotifyItem : public wxPanel
wxBitmap & get_notify_bitmap();
public:
HMSNotifyItem(wxWindow *parent, HMSItem& item);
HMSNotifyItem(const std::string& dev_id, wxWindow *parent, HMSItem& item);
~HMSNotifyItem();
void msw_rescale() {}
@ -49,7 +50,7 @@ protected:
HMSNotifyItem * m_notify_item;
int last_status;
void append_hms_panel(HMSItem &item);
void append_hms_panel(const std::string& dev_id, HMSItem &item);
void delete_hms_panels();

View File

@ -116,8 +116,7 @@ void BindJob::process()
try
{
error_code = stoi(result_info);
wxString error_msg;
wxGetApp().get_hms_query()->query_print_error_msg(error_code, error_msg);
wxString error_msg = wxGetApp().get_hms_query()->query_print_error_msg(m_dev_id, error_code);
result_info = error_msg.ToStdString();
}
catch (...) {

View File

@ -2748,15 +2748,14 @@ void StatusPanel::update_error_message()
std::string print_error_str = std::string(buf);
if (print_error_str.size() > 4) { print_error_str.insert(4, "-"); }
wxString error_msg;
bool is_errocode_exist = wxGetApp().get_hms_query()->query_print_error_msg(obj->print_error, error_msg);
wxString error_msg = wxGetApp().get_hms_query()->query_print_error_msg(obj, obj->print_error);
std::vector<int> used_button;
wxString error_image_url = wxGetApp().get_hms_query()->query_print_error_url_action(obj->print_error, obj->dev_id, used_button);
wxString error_image_url = wxGetApp().get_hms_query()->query_print_error_url_action(obj, obj->print_error, used_button);
// special case
if (print_error_str == "0300-8003" || print_error_str == "0300-8002" || print_error_str == "0300-800A") {
used_button.emplace_back(PrintErrorDialog::PrintErrorButton::JUMP_TO_LIVEVIEW);
}
show_error_message(obj, is_errocode_exist, error_msg, print_error_str, error_image_url, used_button);
show_error_message(obj, !error_msg.empty(), error_msg, print_error_str, error_image_url, used_button);
}
}
}