Merge branch '2.2.0' into dev_bury_point_alves

This commit is contained in:
alves
2025-12-18 14:10:47 +08:00
35 changed files with 53505 additions and 62693 deletions
+1 -1
View File
@@ -7160,7 +7160,7 @@ msgstr ""
msgid "Asia-Pacific"
msgstr ""
msgid "China"
msgid "Chinese Mainland"
msgstr ""
msgid "Europe"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -7261,7 +7261,7 @@ msgstr ""
msgid "Asia-Pacific"
msgstr ""
msgid "China"
msgid "Chinese Mainland"
msgstr ""
msgid "Europe"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -7613,7 +7613,7 @@ msgstr "Keičiama programos kalba"
msgid "Asia-Pacific"
msgstr "Azija-Ramusis vandenynas"
msgid "China"
msgid "Chinese Mainland"
msgstr "Kinija"
msgid "Europe"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -7493,7 +7493,7 @@ msgstr "Đang thay đổi ngôn ngữ ứng dụng"
msgid "Asia-Pacific"
msgstr "Châu Á-Thái Bình Dương"
msgid "China"
msgid "Chinese Mainland"
msgstr "Trung Quốc"
msgid "Europe"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -45,7 +45,7 @@ var LangText = {
t43: "2. Device network interruption. Check if the device has lost connectivity.",
t47: "Please select your login region",
t48: "Asia-Pacific",
t49: "China",
t49: "Chinese Mainland",
t50: "Log out",
t52: "Skip",
t53: "Join",
@@ -158,7 +158,7 @@ var LangText = {
t40: "Desconnexió de la xarxa, si us plau comprova i intenta-ho de nou més tard.",
t47: "Si us plau selecciona la teva regió d'inici de sessió",
t48: "Àsia-Pacífic",
t49: "Xina",
t49: "Xina continental",
t50: "Tancar sessió",
t52: "Saltar",
t53: "Unir-se",
@@ -267,7 +267,7 @@ var LangText = {
t40: "Desconectado, por favor compruebe la conexión de red e inténtelo de nuevo.",
t47: "Por favor, seleccione su región:",
t48: "Asia-Pacífico",
t49: "China",
t49: "Chinese Mainland",
t50: "Desconectarse",
t52: "Saltar",
t53: "Ingresar",
@@ -379,7 +379,7 @@ var LangText = {
t40: "Netzwerkunterbrechung, bitte überprüfen und später erneut versuchen.",
t47: "Bitte wählen Sie Ihre Login-Region aus",
t48: "Asien-Pazifik",
t49: "China",
t49: "Chinesisches Festland",
t50: "Abmelden",
t52: "Überspringen",
t53: "Beitreten",
@@ -481,7 +481,7 @@ var LangText = {
t40: "Síť je odpojena, prosím zkontrolujte a zkuste to znovu později.",
t47: "Vyberte prosím svou oblast přihlášení",
t48: "Asie-Pacifik",
t49: "Čína",
t49: "Pevninská Čína",
t50: "Odhlásit se",
t52: "Přeskočit",
t53: "Připojit se",
@@ -583,7 +583,7 @@ var LangText = {
t40: "Déconnexion du réseau, veuillez vérifier et réessayer plus tard.",
t47: "Veuillez sélectionner votre région de connexion",
t48: "Asie-Pacifique",
t49: "Chine",
t49: "Chine continentale",
t50: "Se déconnecter",
t52: "Passer",
t53: "Rejoindre",
@@ -707,7 +707,7 @@ var LangText = {
t43: "2. 设备网络终端,检测设备网络是否终端",
t47: "请选择登录区域",
t48: "亚太",
t49: "中国",
t49: "中国大陆",
t50: "退出登录",
t52: "忽略",
t53: "同意",
@@ -833,7 +833,7 @@ var LangText = {
t40: "網路不通,請檢查並稍後重試。",
t47: "請選擇登入區域",
t48: "亞太",
t49: "中國",
t49: "中國大陸",
t50: "登出",
t52: "忽略",
t53: "同意",
@@ -938,7 +938,7 @@ var LangText = {
t40: "Сеть отключена. Пожалуйста, проверьте подключение и попробуйте снова.",
t47: "Пожалуйста, выберите регион входа",
t48: "Азиатско-Тихоокеанский регион",
t49: "Китай",
t49: "Континентальный Китай",
t50: "Выйти",
t52: "Пропустить",
t53: "Войти",
@@ -1050,7 +1050,7 @@ var LangText = {
t40: "네트워크 연결이 끊겼습니다. 확인하고 나중에 다시 시도하세요.",
t47: "로그인 지역을 선택해주세요",
t48: "아시아 태평양",
t49: "중국",
t49: "중국 대륙",
t50: "로그 아웃",
t52: "건너뛰기",
t53: "가입",
@@ -1141,7 +1141,7 @@ var LangText = {
t40: "Ağ bağlantısı kesildi, lütfen kontrol edin ve daha sonra tekrar deneyin.",
t47: "Lütfen giriş bölgenizi seçin",
t48: "Asya-Pasifik",
t49: "Çin",
t49: "Çin ana karası",
t50: "Çıkış Yap",
t52: "Atla",
t53: "Katıl",
@@ -1250,7 +1250,7 @@ var LangText = {
t40: "Rozłączenie sieci, proszę sprawdzić i spróbować ponownie później.",
t47: "Proszę wybrać swój region logowania",
t48: "Azja-Pacyfik",
t49: "Chiny",
t49: "Chińska część kontynentalna",
t50: "Wyloguj",
t52: "Pomiń",
t53: "Dołącz",
@@ -1362,7 +1362,7 @@ var LangText = {
t40: "Conexão desconectada, por favor cheque e tente novamente.",
t47: "Por favor, selecione sua região de login",
t48: "Asia-Pacifico",
t49: "China",
t49: "China continental",
t50: "Desconectar",
t52: "Pular",
t53: "Juntar",
+1 -1
View File
@@ -22,7 +22,7 @@
<div id="EarthIcon"><img src="earth.png"/></div>
<div id="RegionList">
<div class="trans RegionItem RegionSelected TextS1" tid="t48" region="Asia-Pacific" onclick="ChooseRegion('Asia-Pacific')">Asia-Pacific</div>
<div class="trans RegionItem" tid="t49" region="China" onclick="ChooseRegion('China')">China</div>
<div class="trans RegionItem" tid="t49" region="Chinese Mainland" onclick="ChooseRegion('Chinese Mainland')">Chinese Mainland</div>
<div class="trans RegionItem" tid="t60" region="Europe" onclick="ChooseRegion('Europe')">Europe</div>
<div class="trans RegionItem" tid="t61" region="North America" onclick="ChooseRegion('North America')">North America</div>
<div class="trans RegionItem" tid="t62" region="Others" onclick="ChooseRegion('Others')">Others</div>
+11 -1
View File
@@ -686,6 +686,16 @@ std::string AppConfig::load()
return err.what();
}
// Convert "China" to "Chinese Mainland" for region parameter
auto it_app = m_storage.find("app");
if (it_app != m_storage.end()) {
auto it_region = it_app->second.find("region");
if (it_region != it_app->second.end() && it_region->second == "China") {
it_region->second = "Chinese Mainland";
m_dirty = true;
}
}
// Figure out if datadir has legacy presets
auto ini_ver = Semver::parse(get("version"));
m_legacy_datadir = false;
@@ -1324,7 +1334,7 @@ std::string AppConfig::get_country_code()
// #if !BBL_RELEASE_TO_PUBLIC
// if (is_engineering_region()) { return region; }
// #endif
if (region == "CHN" || region == "China")
if (region == "CHN" || region == "Chinese Mainland" || region == "China")
return "CN";
else if (region == "USA")
return "US";
+3 -1
View File
@@ -993,6 +993,8 @@ void GUI_App::post_init()
CallAfter([this] {
bool cw_showed = this->config_wizard_startup();
SSWCP_MqttAgent_Instance::m_dialog = new WebPresetDialog(this);
std::string http_url = get_http_url(app_config->get_country_code());
std::string language = GUI::into_u8(current_language_code());
std::string network_ver = Slic3r::NetworkAgent::get_version();
@@ -3219,7 +3221,7 @@ void GUI_App::update_publish_status()
bool GUI_App::has_model_mall()
{
if (auto cc = app_config->get_region(); cc == "CNH" || cc == "China" || cc == "")
if (auto cc = app_config->get_region(); cc == "CNH" || cc == "Chinese Mainland" || cc == "")
return false;
return true;
}
+5 -5
View File
@@ -392,13 +392,13 @@ void NetworkTestDialog::start_all_job_sequence()
update_status(-1, "");
auto app_config = wxGetApp().app_config;
std::string region = app_config->get("region");
wxString login_api_url = (region == "China") ? "https://id.snapmaker.cn" : "https://id.snapmaker.com";
wxString login_api_url = (region == "Chinese Mainland" || region == "China") ? "https://id.snapmaker.cn" : "https://id.snapmaker.com";
start_test_url(TEST_LOGIN_API_JOB, "Login API", login_api_url);
if (m_closing.load()) return;
// 测试上传API
update_status(-1, "");
wxString upload_api_url = (region == "China") ? "https://public.resource.snapmaker.cn" : "https://public.resource.snapmaker.com";
wxString upload_api_url = (region == "Chinese Mainland" || region == "China") ? "https://public.resource.snapmaker.cn" : "https://public.resource.snapmaker.com";
start_test_url(TEST_UPLOAD_API_JOB, "Upload API", upload_api_url);
if (m_closing.load()) return;
@@ -869,7 +869,7 @@ wxString NetworkTestDialog::get_cloud_server_address()
{
auto app_config = wxGetApp().app_config;
std::string region = app_config->get("region");
if (region == "China")
if (region == "Chinese Mainland")
return "a1su7rk2r6cmbq.ats.iot.cn-north-1.amazonaws.com.cn";
else
return "a1pr8yczi3n0se-ats.iot.us-west-1.amazonaws.com";
@@ -946,7 +946,7 @@ void NetworkTestDialog::start_test_login_api_thread()
test_job[TEST_LOGIN_API_JOB] = new boost::thread([this] {
auto app_config = wxGetApp().app_config;
std::string region = app_config->get("region");
wxString login_api_url = (region == "China") ? "https://id.snapmaker.cn" : "https://id.snapmaker.com";
wxString login_api_url = (region == "Chinese Mainland") ? "https://id.snapmaker.cn" : "https://id.snapmaker.com";
start_test_url(TEST_LOGIN_API_JOB, "Login API", login_api_url);
});
}
@@ -965,7 +965,7 @@ void NetworkTestDialog::start_test_upload_api_thread()
test_job[TEST_UPLOAD_API_JOB] = new boost::thread([this] {
auto app_config = wxGetApp().app_config;
std::string region = app_config->get("region");
wxString upload_api_url = (region == "China") ? "https://public.resource.snapmaker.cn" : "https://public.resource.snapmaker.com";
wxString upload_api_url = (region == "Chinese Mainland") ? "https://public.resource.snapmaker.cn" : "https://public.resource.snapmaker.com";
start_test_url(TEST_UPLOAD_API_JOB, "Upload API", upload_api_url);
});
}
+2 -2
View File
@@ -298,7 +298,7 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(
wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWindow *parent, wxString tooltip, std::vector<wxString> vlist)
{
std::vector<wxString> local_regions = {"Asia-Pacific", "China", "Europe", "North America", "Others"};
std::vector<wxString> local_regions = {"Asia-Pacific", "Chinese Mainland", "Europe", "North America", "Others"};
wxBoxSizer *m_sizer_combox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_combox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
@@ -1175,7 +1175,7 @@ wxWindow* PreferencesDialog::create_general_page()
std::sort(language_infos.begin(), language_infos.end(), [](const wxLanguageInfo *l, const wxLanguageInfo *r) { return l->Description < r->Description; });
auto item_language = create_item_language_combobox(_L("Language"), page, _L("Language"), 50, "language", language_infos);
std::vector<wxString> Regions = {_L("Asia-Pacific"), _L("China"), _L("Europe"), _L("North America"), _L("Others")};
std::vector<wxString> Regions = {_L("Asia-Pacific"), _L("Chinese Mainland"), _L("Europe"), _L("North America"), _L("Others")};
auto item_region= create_item_region_combobox(_L("Login Region"), page, _L("Login Region"), Regions);
// SM Beta: temporarily open the item_stealth_mode and close the network plugin
+90 -531
View File
@@ -23,6 +23,7 @@
#include <boost/asio/ip/host_name.hpp>
#include <slic3r/GUI/Widgets/WebView.hpp>
#include "NetworkTestDialog.hpp"
#include "MoonRaker.hpp"
@@ -460,6 +461,8 @@ void SSWCP_Instance::process() {
sw_OpenOrcaWebview();
} else if (m_cmd == "sw_OpenBrowser") {
sw_OpenBrowser();
} else if (m_cmd == "sw_OpenNetworkDialog"){
sw_OpenNetworkDialog();
}
else {
handle_general_fail();
@@ -504,6 +507,23 @@ void SSWCP_Instance::sw_UploadEvent() {
}
}
void SSWCP_Instance::sw_OpenNetworkDialog() {
try {
send_to_js();
finish_job();
wxGetApp().CallAfter([]() {
NetworkTestDialog dlg(wxGetApp().mainframe);
dlg.ShowModal();
});
}
catch (std::exception& e) {
handle_general_fail();
}
}
void SSWCP_Instance::sw_OpenBrowser() {
try {
std::string url = m_param_data.count("url") ? m_param_data["url"].get<std::string>() : "";
@@ -1978,8 +1998,12 @@ void SSWCP_MachineOption_Instance::process()
sw_UploadCameraTimelapse();
} else if (m_cmd == "sw_DeleteCameraTimelapse") {
sw_DeleteCameraTimelapse();
} else if (m_cmd == "sw_GetTimelapseInstance") {
sw_GetTimelapseInstance();
} else if (m_cmd == "sw_ServerClientManagerSetUserinfo") {
sw_ServerClientManagerSetUserinfo();
} else if (m_cmd == "sw_DefectDetactionConfig"){
sw_DefectDetactionConfig();
}
else {
@@ -3562,6 +3586,30 @@ void SSWCP_MachineOption_Instance::sw_UploadCameraTimelapse()
}
}
void SSWCP_MachineOption_Instance::sw_GetTimelapseInstance()
{
try {
std::shared_ptr<PrintHost> host = nullptr;
wxGetApp().get_connect_host(host);
if (!host) {
handle_general_fail(-1, "Connection lost!");
return;
}
auto weak_self = std::weak_ptr<SSWCP_Instance>(shared_from_this());
host->async_get_timelapse_instance(m_param_data, [weak_self](const json& response) {
auto self = weak_self.lock();
if (self) {
SSWCP_Instance::on_mqtt_msg_arrived(self, response);
}
});
}
catch (std::exception& e) {
handle_general_fail();
}
}
void SSWCP_MachineOption_Instance::sw_DeleteCameraTimelapse()
{
try {
@@ -3585,6 +3633,29 @@ void SSWCP_MachineOption_Instance::sw_DeleteCameraTimelapse()
}
}
void SSWCP_MachineOption_Instance::sw_DefectDetactionConfig()
{
try {
std::shared_ptr<PrintHost> host = nullptr;
wxGetApp().get_connect_host(host);
if (!host) {
handle_general_fail(-1, "Connection lost!");
return;
}
auto weak_self = std::weak_ptr<SSWCP_Instance>(shared_from_this());
host->async_defect_detaction_config(m_param_data, [weak_self](const json& response) {
auto self = weak_self.lock();
if (self) {
SSWCP_Instance::on_mqtt_msg_arrived(self, response);
}
});
} catch (std::exception& e) {
handle_general_fail();
}
}
void SSWCP_MachineOption_Instance::sw_GetFileListPage()
{
try {
@@ -3845,521 +3916,7 @@ void SSWCP_MachineConnect_Instance::sw_test_connect() {
}
void SSWCP_MachineConnect_Instance::sw_connect() {
try {
// 兼容第三方机器连接
if (m_param_data.count("from_homepage") && m_param_data["from_homepage"].get<bool>() && m_param_data.count("sn") &&
m_param_data["sn"].get<std::string>() == "-1") {
auto weak_self = std::weak_ptr<SSWCP_Instance>(shared_from_this());
wxGetApp().CallAfter([weak_self]() {
// 从首页触发的请求,没有sn的一律认为是第三方机器
auto self = weak_self.lock();
if (!self) {
return;
}
std::string dev_id = self->m_param_data.count("dev_id") ? self->m_param_data["dev_id"].get<std::string>() : "";
if (dev_id == "") {
// 失败
self->handle_general_fail();
return;
}
auto cfg = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
auto devices = wxGetApp().app_config->get_devices();
for (const auto& device : devices) {
if (device.dev_id == dev_id) {
cfg->option<ConfigOptionEnum<PrintHostType>>("host_type")->value = PrintHostType(device.protocol);
cfg->set("print_host", device.ip);
cfg->set("printhost_apikey", device.api_key);
break;
}
}
SMPhysicalPrinterDialog dialog = SMPhysicalPrinterDialog(wxGetApp().mainframe->plater()->GetParent());
dialog.ShowModal();
if (!dialog.m_connected) {
self->handle_general_fail();
}
});
}
else {
if (m_param_data.count("ip")) {
std::string ip = m_param_data["ip"].get<std::string>();
int port = -1;
if (m_param_data.count("port") && m_param_data["port"].is_number_integer()) {
port = m_param_data["port"].get<int>();
}
// test
if (port == -1 || port == 1883) {
port = 1884;
}
std::string protocol = "moonraker";
if (m_param_data.count("protocol") && m_param_data["protocol"].is_string()) {
protocol = m_param_data["protocol"].get<std::string>();
}
auto config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
PrintHostType type = PrintHostType::htMoonRaker_mqtt;
// todo : 增加输入与type的映射
config.option<ConfigOptionEnum<PrintHostType>>("host_type")->value = type;
config.set("print_host", ip + (port == -1 ? "" : ":" + std::to_string(port)));
std::shared_ptr<PrintHost> host(PrintHost::get_print_host(&config));
wxGetApp().set_connect_host(host);
wxGetApp().set_host_config(config);
json connect_params;
if (m_param_data.count("sn") && m_param_data["sn"].is_string()) {
connect_params["sn"] = m_param_data["sn"].get<std::string>();
}
// 序列化参数
if (m_param_data.count("code"))
connect_params["code"] = m_param_data["code"];
if (m_param_data.count("ca"))
connect_params["ca"] = m_param_data["ca"];
if (m_param_data.count("cert"))
connect_params["cert"] = m_param_data["cert"];
if (m_param_data.count("key"))
connect_params["key"] = m_param_data["key"];
if (m_param_data.count("user"))
connect_params["user"] = m_param_data["user"];
if (m_param_data.count("password"))
connect_params["password"] = m_param_data["password"];
if (m_param_data.count("port"))
connect_params["port"] = m_param_data["port"];
if (m_param_data.count("clientId"))
connect_params["clientId"] = m_param_data["clientId"];
std::string link_mode = m_param_data.count("link_mode") ? m_param_data["link_mode"] : "lan";
connect_params["link_mode"] = link_mode;
std::string id = m_param_data.count("id") ? m_param_data["id"].get<std::string>() : "";
std::string userid = m_param_data.count("userid") ? m_param_data["userid"].get<std::string>() : "";
if (!host) {
// 错误处理
finish_job();
} else {
auto weak_self = std::weak_ptr<SSWCP_Instance>(shared_from_this());
//设置断联回调
m_work_thread = std::thread([weak_self, host, connect_params, link_mode, id, userid] {
auto self = weak_self.lock();
wxString msg = "";
json params;
host->set_connection_lost([&host]() {
SSWCP_Instance::m_first_connected = true;
wxGetApp().CallAfter([&host]() {
wxGetApp().app_config->set("use_new_connect", "false");
auto p_config = &(wxGetApp().preset_bundle->printers.get_edited_preset().config);
p_config->set("print_host", "");
wxGetApp().set_connect_host(nullptr);
wxString msg = "";
json params;
host->disconnect(msg, params);
auto devices = wxGetApp().app_config->get_devices();
for (size_t i = 0; i < devices.size(); ++i) {
if (devices[i].connected) {
devices[i].connected = false;
wxGetApp().app_config->save_device_info(devices[i]);
break;
}
}
// 更新卡片
json param;
param["command"] = "local_devices_arrived";
param["sequece_id"] = "10001";
param["data"] = devices;
std::string logout_cmd = param.dump();
wxString strJS = wxString::Format("window.postMessage(%s)", logout_cmd);
GUI::wxGetApp().run_script(strJS);
// wcp订阅
json data = devices;
wxGetApp().device_card_notify(data);
/*MessageDialog msg_window(nullptr, " " + _L("Connection Lost !") + "\n", _L("Machine Disconnected"),
wxICON_QUESTION | wxOK);
msg_window.ShowModal();*/
wxGetApp().mainframe->plater()->sidebar().update_all_preset_comboboxes();
});
});
bool res = host->connect(msg, connect_params);
std::string ip_port = host->get_host();
if (res) {
int pos = ip_port.find(':');
std::string ip = ip_port;
if (pos != std::string::npos) {
ip = ip_port.substr(0, pos);
}
// 更新其他设备连接状态为断开
auto devices = wxGetApp().app_config->get_devices();
for (size_t i = 0; i < devices.size(); ++i) {
if (devices[i].connected) {
devices[i].connected = false;
wxGetApp().app_config->save_device_info(devices[i]);
break;
}
}
// 查询机器的机型和喷嘴信息
std::string machine_type = "";
std::vector<std::string> nozzle_diameters;
std::string device_name = "";
std::shared_ptr<PrintHost> host = nullptr;
wxGetApp().get_connect_host(host);
if (!host->check_sn_arrived()) {
wxGetApp().CallAfter([ip]() {
MessageDialog msg_window(nullptr, ip + " " + _L("connected unseccessfully !") + "\n", _L("Failed"),
wxICON_QUESTION | wxOK);
msg_window.ShowModal();
std::shared_ptr<PrintHost> host = nullptr;
wxGetApp().get_connect_host(host);
wxString msg = "";
host->disconnect(msg, {});
});
auto self = weak_self.lock();
if (!self) {
return;
}
self->m_status = 1;
self->m_msg = "sn is not exist";
self->send_to_js();
self->finish_job();
return;
}
if (SSWCP::query_machine_info(host, machine_type, nozzle_diameters, device_name) && machine_type != "") {
wxGetApp().CallAfter([ip, host, link_mode, machine_type, connect_params,nozzle_diameters, device_name, id, userid]() {
// 查询成功
DeviceInfo info;
info.ip = ip;
info.dev_id = host->get_sn() != "" ? host->get_sn() : ip;
info.dev_name = ip;
info.connected = true;
info.link_mode = link_mode;
info.id = id;
info.userid = userid;
;
info.model_name = machine_type;
info.protocol = int(PrintHostType::htMoonRaker_mqtt);
if (connect_params.count("sn") && connect_params["sn"].is_string()) {
std::string sn = host->get_sn();
info.sn = connect_params["sn"].get<std::string>();
if (sn != "" && sn != info.sn) {
info.sn = sn;
}
info.dev_name = info.sn != "" ? info.sn : info.dev_name;
info.dev_id = info.sn != "" ? info.sn : info.ip;
}
if (device_name != "") {
info.dev_name = device_name;
}
size_t vendor_pos = machine_type.find_first_of(" ");
if (vendor_pos != std::string::npos) {
std::string vendor = machine_type.substr(0, vendor_pos);
std::string machine_cover = LOCALHOST_URL +
std::to_string(wxGetApp().m_page_http_server.get_port()) +
"/profiles/" + vendor + "/" + machine_type + "_cover.png";
info.img = machine_cover;
}
auto auth_info = host->get_auth_info();
try {
info.ca = auth_info["ca"];
info.cert = auth_info["cert"];
info.key = auth_info["key"];
info.user = auth_info["user"];
info.password = auth_info["password"];
info.port = auth_info["port"];
info.clientId = auth_info["clientId"];
} catch (std::exception& e) {}
DeviceInfo query_info;
bool exist = wxGetApp().app_config->get_device_info(info.dev_id, query_info);
if (nozzle_diameters.empty()) {
if (exist) {
query_info.connected = true;
wxGetApp().app_config->save_device_info(query_info);
} else {
wxGetApp().app_config->save_device_info(info);
MessageDialog msg_window(nullptr,
ip + " " + _L("The target machine model has been detected as") + "" +
machine_type + "\n" + _L("Please bind the nozzle information") +
"\n",
_L("Nozzle Bind"), wxICON_QUESTION | wxOK);
msg_window.ShowModal();
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_bind_nozzle = true;
dialog.m_device_id = ip;
dialog.run();
}
} else {
info.nozzle_sizes = nozzle_diameters;
info.preset_name = machine_type + " (" + nozzle_diameters[0] + " nozzle)";
wxGetApp().app_config->save_device_info(info);
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_device_id = ip;
// 检查是否该预设已经选入系统
int nModel = m_ProfileJson["model"].size();
bool isFind = false;
for (int m = 0; m < nModel; m++) {
if (m_ProfileJson["model"][m]["model"].get<std::string>() == info.model_name) {
// 绑定的预设已被选入系统
isFind = true;
std::string nozzle_selected = m_ProfileJson["model"][m]["nozzle_selected"].get<std::string>();
std::string se_nozz_selected = nozzle_diameters[0];
if (nozzle_selected.find(se_nozz_selected) == std::string::npos) {
nozzle_selected += ";" + se_nozz_selected;
m_ProfileJson["model"][m]["nozzle_selected"] = nozzle_selected;
}
break;
}
}
if (!isFind) {
json new_item;
new_item["vendor"] = "Snapmaker";
new_item["model"] = info.model_name;
new_item["nozzle_selected"] = nozzle_diameters[0];
m_ProfileJson["model"].push_back(new_item);
}
wxGetApp().mainframe->plater()->sidebar().update_all_preset_comboboxes();
dialog.SaveProfile();
bool flag = false;
dialog.apply_config(wxGetApp().app_config, wxGetApp().preset_bundle, wxGetApp().preset_updater,
flag);
wxGetApp().update_mode();
}
});
} else {
wxGetApp().CallAfter([connect_params, ip, host, link_mode, id, userid]() {
// 是否为连接过的设备
DeviceInfo query_info;
std::string dev_id = connect_params.count("sn") ? connect_params["sn"].get<std::string>() : ip;
if (wxGetApp().app_config->get_device_info(dev_id, query_info)) {
query_info.connected = true;
wxGetApp().app_config->save_device_info(query_info);
} else {
auto machine_ip_type = MachineIPType::getInstance();
if (machine_ip_type) {
std::string machine_type = "";
if (machine_ip_type->get_machine_type(ip, machine_type)) {
// 已经发现过的机型信息
// test
if (machine_type == "lava" || machine_type == "Snapmaker test") {
machine_type = "Snapmaker U1";
}
DeviceInfo info;
host->get_auth_info();
auto auth_info = host->get_auth_info();
try {
info.ca = auth_info["ca"];
info.cert = auth_info["cert"];
info.key = auth_info["key"];
info.user = auth_info["user"];
info.password = auth_info["password"];
info.port = auth_info["port"];
info.clientId = auth_info["clientId"];
} catch (std::exception& e) {}
info.ip = ip;
info.dev_id = dev_id;
info.dev_name = ip;
info.connected = true;
info.model_name = machine_type;
info.protocol = int(PrintHostType::htMoonRaker_mqtt);
info.link_mode = link_mode;
info.id = id;
info.userid = userid;
if (connect_params.count("sn") && connect_params["sn"].is_string()) {
info.sn = connect_params["sn"].get<std::string>();
info.dev_name = info.sn != "" ? info.sn : info.dev_name;
info.dev_id = info.sn != "" ? info.sn : info.dev_name;
}
size_t vendor_pos = machine_type.find_first_of(" ");
if (vendor_pos != std::string::npos) {
std::string vendor = machine_type.substr(0, vendor_pos);
std::string machine_cover = LOCALHOST_URL +
std::to_string(wxGetApp().m_page_http_server.get_port()) +
"/profiles/" + vendor + "/" + machine_type + "_cover.png";
info.img = machine_cover;
}
wxGetApp().app_config->save_device_info(info);
// todo 绑定喷嘴
MessageDialog msg_window(nullptr,
ip + " " + _L("The target machine model has been detected as") +
" " + machine_type + "\n" +
_L("Please bind the nozzle information") + "\n",
_L("Nozzle Bind"), wxICON_QUESTION | wxOK);
msg_window.ShowModal();
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_bind_nozzle = true;
dialog.m_device_id = ip;
dialog.run();
if (info.nozzle_sizes.empty())
info.nozzle_sizes.push_back("0.4");
info.preset_name = machine_type + " (" + info.nozzle_sizes[0] + " nozzle)";
wxGetApp().app_config->save_device_info(info);
} else {
DeviceInfo info;
auto auth_info = host->get_auth_info();
try {
info.ca = auth_info["ca"];
info.cert = auth_info["cert"];
info.key = auth_info["key"];
info.user = auth_info["user"];
info.password = auth_info["password"];
info.port = auth_info["port"];
info.clientId = auth_info["clientId"];
} catch (std::exception& e) {}
info.ip = ip;
info.dev_id = dev_id;
info.dev_name = ip;
info.connected = true;
info.link_mode = link_mode;
info.id = id;
info.userid = id;
info.protocol = int(PrintHostType::htMoonRaker_mqtt);
if (connect_params.count("sn") && connect_params["sn"].is_string()) {
info.sn = connect_params["sn"].get<std::string>();
info.dev_name = info.sn != "" ? info.sn : info.dev_name;
info.dev_id = info.sn != "" ? info.sn : info.dev_name;
}
wxGetApp().app_config->save_device_info(info);
MessageDialog msg_window(
nullptr,
ip + " " + _L("The target machine model has not been detected. Please bind manually."),
_L("Machine Bind"), wxICON_QUESTION | wxOK);
msg_window.ShowModal();
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_device_id = info.dev_id;
dialog.run();
}
}
}
});
}
wxGetApp().CallAfter([weak_self]() {
// 更新首页设备卡片
auto devices = wxGetApp().app_config->get_devices();
json param;
param["command"] = "local_devices_arrived";
param["sequece_id"] = "10001";
param["data"] = devices;
std::string logout_cmd = param.dump();
wxString strJS = wxString::Format("window.postMessage(%s)", logout_cmd);
GUI::wxGetApp().run_script(strJS);
// wcp订阅
json data = devices;
wxGetApp().device_card_notify(data);
/*MessageDialog msg_window(nullptr, ip + " " + _L("connected sucessfully !") + "\n", _L("Machine
Connected"), wxICON_QUESTION | wxOK); msg_window.ShowModal();*/
auto dialog = wxGetApp().get_web_device_dialog();
if (dialog) {
dialog->EndModal(1);
}
wxGetApp().app_config->set("use_new_connect", "true");
wxGetApp().mainframe->plater()->sidebar().update_all_preset_comboboxes();
wxGetApp().mainframe->m_print_enable = true;
wxGetApp().mainframe->update_slice_print_status(MainFrame::eEventPlateUpdate);
// wxGetApp().mainframe->load_printer_url("http://" + ip); //到时全部加载本地交互页面
if (!wxGetApp().mainframe->m_printer_view->isSnapmakerPage()) {
wxString url = wxString::FromUTF8(LOCALHOST_URL + std::to_string(PAGE_HTTP_PORT) + "/web/flutter_web/index.html?path=2");
auto real_url = wxGetApp().get_international_url(url);
wxGetApp().mainframe->load_printer_url(real_url); // 到时全部加载本地交互页面
} else {
wxGetApp().mainframe->m_printer_view->reload();
}
auto self = weak_self.lock();
if (!self) {
return;
}
self->send_to_js();
self->finish_job();
});
} else {
wxGetApp().CallAfter([ip_port]() {
MessageDialog msg_window(nullptr, ip_port + " " + _L("connected unseccessfully !") + "\n", _L("Failed"),
wxICON_QUESTION | wxOK);
msg_window.ShowModal();
});
if (self) {
self->m_status = 1;
self->m_msg = msg.c_str();
}
}
if (self) {
self->send_to_js();
self->finish_job();
}
});
}
} else {
// 错误处理
finish_job();
}
}
} catch (std::exception& e) {
handle_general_fail();
}
}
void SSWCP_MachineConnect_Instance::sw_get_connect_machine() {
@@ -4853,6 +4410,7 @@ std::unordered_map<wxWebView*, std::pair<std::string, std::shared_ptr<MqttClient
std::mutex SSWCP_MqttAgent_Instance::m_engine_map_mtx;
std::map<std::pair<std::string, wxWebView*>, std::string> SSWCP_MqttAgent_Instance::m_subscribe_map;
std::map<std::pair<std::string, wxWebView*>, std::weak_ptr<SSWCP_Instance>> SSWCP_MqttAgent_Instance::m_subscribe_instance_map;
WebPresetDialog* SSWCP_MqttAgent_Instance::m_dialog = nullptr;
void SSWCP_MqttAgent_Instance::process()
{
@@ -5605,10 +5163,9 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
_L("Nozzle Bind"), wxICON_QUESTION | wxOK);
msg_window.ShowModal();
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_bind_nozzle = true;
dialog.m_device_id = ip;
dialog.run();
m_dialog->m_bind_nozzle = true;
m_dialog->m_device_id = ip;
m_dialog->run();
}
} else {
@@ -5616,8 +5173,7 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
info.preset_name = machine_type + " (" + nozzle_diameters[0] + " nozzle)";
wxGetApp().app_config->save_device_info(info);
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_device_id = ip;
m_dialog->m_device_id = ip;
// 检查是否该预设已经选入系统
int nModel = m_ProfileJson["model"].size();
@@ -5648,9 +5204,9 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
wxGetApp().mainframe->plater()->sidebar().update_all_preset_comboboxes(false);
dialog.SaveProfile();
m_dialog->SaveProfile();
bool flag = false;
dialog.apply_config(wxGetApp().app_config, wxGetApp().preset_bundle, wxGetApp().preset_updater,
m_dialog->apply_config(wxGetApp().app_config, wxGetApp().preset_bundle, wxGetApp().preset_updater,
flag);
wxGetApp().update_mode();
}
@@ -5722,10 +5278,10 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
_L("Please bind the nozzle information") + "\n",
_L("Nozzle Bind"), wxICON_QUESTION | wxOK);
msg_window.ShowModal();
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_bind_nozzle = true;
dialog.m_device_id = ip;
dialog.run();
m_dialog->m_bind_nozzle = true;
m_dialog->m_device_id = ip;
m_dialog->run();
if (info.nozzle_sizes.empty())
info.nozzle_sizes.push_back("0.4");
@@ -5765,9 +5321,9 @@ void SSWCP_MqttAgent_Instance::sw_mqtt_set_engine()
_L("The target machine model has not been detected. Please bind manually."),
_L("Machine Bind"), wxICON_QUESTION | wxOK);
msg_window.ShowModal();
auto dialog = WebPresetDialog(&wxGetApp());
dialog.m_device_id = info.dev_id;
dialog.run();
m_dialog->m_device_id = info.dev_id;
m_dialog->run();
}
}
}
@@ -6026,7 +5582,9 @@ std::unordered_set<std::string> SSWCP::m_machine_option_cmd_list = {
"sw_UpdateMachineFilamentInfo",
"sw_UploadCameraTimelapse",
"sw_DeleteCameraTimelapse",
"sw_ServerClientManagerSetUserinfo"
"sw_GetTimelapseInstance",
"sw_ServerClientManagerSetUserinfo",
"sw_DefectDetactionConfig"
};
std::unordered_set<std::string> SSWCP::m_machine_connect_cmd_list = {
@@ -6083,6 +5641,7 @@ std::shared_ptr<SSWCP_Instance> SSWCP::create_sswcp_instance(std::string cmd, co
// Handle incoming web messages
void SSWCP::handle_web_message(std::string message, wxWebView* webview) {
try {
if (!webview) {
return;
}
+9 -1
View File
@@ -176,6 +176,9 @@ private:
// Sentry
void sw_UploadEvent();
// open network dialog
void sw_OpenNetworkDialog();
public:
// 抽象工具类函数
@@ -238,6 +241,7 @@ private:
};
// mqtt-agent
class WebPresetDialog;
class SSWCP_MqttAgent_Instance : public SSWCP_Instance
{
public:
@@ -262,6 +266,8 @@ public:
static std::map<std::pair<std::string, wxWebView*>, std::string> m_subscribe_map; // ((event_id, webview), topic)
static std::map<std::pair<std::string, wxWebView*>, std::weak_ptr<SSWCP_Instance>> m_subscribe_instance_map; // ((event_id, webview), instance)
static WebPresetDialog* m_dialog;
public:
bool validate_id(const std::string& id);
std::shared_ptr<MqttClient> get_current_engine() {
@@ -304,7 +310,6 @@ private:
static void mqtt_msg_cb(const std::string& topic, const std::string& payload, void* client);
};
// Instance class for handling machine discovery
@@ -411,6 +416,9 @@ private:
void sw_GetFileListPage();
void sw_UploadCameraTimelapse();
void sw_DeleteCameraTimelapse();
void sw_GetTimelapseInstance();
void sw_DefectDetactionConfig();
// Download machine file
+4 -73
View File
@@ -181,8 +181,10 @@ WebPresetDialog::WebPresetDialog(GUI_App* pGUI, long style)
// Connect the idle events
// Bind(wxEVT_IDLE, &WebPresetDialog::OnIdle, this);
// Bind(wxEVT_CLOSE_WINDOW, &WebPresetDialog::OnClose, this);
LoadProfile();
std::thread* load_thread = new std::thread([this]() {
LoadProfile();
});
// LoadProfile();
// UI
SetStartPage(BBL_REGION);
@@ -752,77 +754,6 @@ int WebPresetDialog::SaveProfile()
m_MainPtr->app_config->save();
// Load BBS Conf
/*wxString strConfPath = wxGetApp().app_config->config_path();
json jCfg;
std::ifstream(w2s(strConfPath)) >> jCfg;
//model
jCfg["models"] = json::array();
int nM = m_ProfileJson["model"].size();
int nModelChoose = 0;
for (int m = 0; m < nM; m++)
{
json amodel = m_ProfileJson["model"][m];
amodel["nozzle_diameter"] = amodel["nozzle_selected"];
amodel.erase("nozzle_selected");
amodel.erase("preview");
amodel.erase("sub_path");
amodel.erase("cover");
amodel.erase("materials");
std::string ss = amodel["nozzle_diameter"];
if (ss.compare("") != 0) {
nModelChoose++;
jCfg["models"].push_back(amodel);
}
}
if (nModelChoose == 0)
jCfg.erase("models");
if (nModelChoose > 0) {
// filament
jCfg["filaments"] = json::array();
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
if (it.value()["selected"] == 1) { jCfg["filaments"].push_back(it.key()); }
}
// Preset
jCfg["presets"]["filaments"] = json::array();
jCfg["presets"]["filaments"].push_back(jCfg["filaments"][0]);
std::string PresetMachine = m_ProfileJson["machine"][0]["name"];
jCfg["presets"]["machine"] = PresetMachine;
int nTotal = m_ProfileJson["process"].size();
int nSet = nTotal / 2;
if (nSet > 0) nSet--;
std::string sMode = m_ProfileJson["process"][nSet]["name"];
jCfg["presets"]["process"] = sMode;
} else {
jCfg["presets"]["filaments"] = json::array();
jCfg["presets"]["filaments"].push_back("Default Filament");
jCfg["presets"]["machine"] = "Default Printer";
jCfg["presets"]["process"] = "Default Setting";
}
std::string sOut = jCfg.dump(4, ' ', false);
std::ofstream output_file(w2s(strConfPath));
output_file << sOut;
output_file.close();
//Copy Profiles
if (bbl_bundle_rsrc)
{
CopyDir(rsrc_vendor_dir,vendor_dir);
}*/
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "before save to app_config: " << std::endl << strAll;
+2 -2
View File
@@ -48,8 +48,8 @@ SMUserLogin::SMUserLogin(bool isLogout) : wxDialog((wxWindow *) (wxGetApp().main
TargetUrl = "https://id.snapmaker.com?from=orca";
LogoutUrl = "https://id.snapmaker.com/logout?from=orca";
m_hostUrl = "https://id.snapmaker.com";
m_accountUrl = "https://account.snapmaker.com";
m_userInfoUrl = "https://account.snapmaker.com/api/common/accounts/current";
m_accountUrl = "https://id.snapmaker.com";
m_userInfoUrl = "https://id.snapmaker.com/api/common/accounts/current";
m_home_url = "https://www.snapmaker.com/";
} else {
TargetUrl = "https://id.snapmaker.cn?from=orca";
+55 -1
View File
@@ -2371,6 +2371,33 @@ void Moonraker_Mqtt::async_upload_camera_timelapse(const nlohmann::json& targets
}
}
// 获取延时摄影列表
void Moonraker_Mqtt::async_get_timelapse_instance(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)> callback)
{
auto& wcp_loger = GUI::WCP_Logger::getInstance();
BOOST_LOG_TRIVIAL(warning) << "[Moonraker_Mqtt] 开始请求获取延时摄影文件列表";
wcp_loger.add_log("开始请求获取延时摄影文件列表", false, "", "Moonraker_Mqtt", "info");
std::string method = "camera.get_timelapse_instance";
json params = json::object();
params = targets;
if (!send_to_request(method, params, true, callback,
[callback, &wcp_loger]() {
BOOST_LOG_TRIVIAL(warning) << "[Moonraker_Mqtt] 请求获取延时摄影文件列表超时";
wcp_loger.add_log("请求获取延时摄影文件列表超时", false, "", "Moonraker_Mqtt", "warning");
json res;
res["error"] = "timeout";
callback(res);
}) &&
callback) {
BOOST_LOG_TRIVIAL(error) << "[Moonraker_Mqtt] 发送请求获取延时摄影文件列表失败";
wcp_loger.add_log("发送请求获取延时摄影文件列表失败", false, "", "Moonraker_Mqtt", "error");
callback(json::value_t::null);
}
}
// 请求删除延时摄影文件
void Moonraker_Mqtt::async_delete_camera_timelapse(const nlohmann::json& targets,
std::function<void(const nlohmann::json& response)> callback)
@@ -2393,12 +2420,39 @@ void Moonraker_Mqtt::async_delete_camera_timelapse(const nlohmann::json&
callback(res);
}) &&
callback) {
BOOST_LOG_TRIVIAL(error) << "[Moonraker_Mqtt] 发送请求上传删除摄影文件失败";
BOOST_LOG_TRIVIAL(error) << "[Moonraker_Mqtt] 发送请求删除延时摄影文件失败";
wcp_loger.add_log("发送请求删除延时摄影文件失败", false, "", "Moonraker_Mqtt", "error");
callback(json::value_t::null);
}
}
// 请求缺陷检测配置
void Moonraker_Mqtt::async_defect_detaction_config(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)> callback)
{
auto& wcp_loger = GUI::WCP_Logger::getInstance();
BOOST_LOG_TRIVIAL(warning) << "[Moonraker_Mqtt] 开始请求缺陷检测配置";
wcp_loger.add_log("开始请求缺陷检测配置", false, "", "Moonraker_Mqtt", "info");
std::string method = "printer.defect_detection.config";
json params = json::object();
params = targets;
if (!send_to_request(method, params, true, callback,
[callback, &wcp_loger]() {
BOOST_LOG_TRIVIAL(warning) << "[Moonraker_Mqtt] 请求缺陷检测配置超时";
wcp_loger.add_log("请求缺陷检测配置超时", false, "", "Moonraker_Mqtt", "warning");
json res;
res["error"] = "timeout";
callback(res);
}) &&
callback) {
BOOST_LOG_TRIVIAL(error) << "[Moonraker_Mqtt] 发送请求缺陷检测配置失败";
wcp_loger.add_log("发送请求缺陷检测配置失败", false, "", "Moonraker_Mqtt", "error");
callback(json::value_t::null);
}
}
// 请求设备下载云文件并打印
void Moonraker_Mqtt::async_start_cloud_print(const nlohmann::json& targets,
std::function<void(const nlohmann::json& response)> callback)
+9
View File
@@ -136,6 +136,11 @@ public:
virtual void async_delete_camera_timelapse(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) {}
virtual void async_get_timelapse_instance(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) {}
virtual void async_defect_detaction_config(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) {}
protected:
// Internal upload implementations
#ifdef WIN32
@@ -265,6 +270,10 @@ public:
virtual void async_delete_camera_timelapse(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) override;
virtual void async_get_timelapse_instance(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) override;
virtual void async_defect_detaction_config(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) override;
void set_connection_lost(std::function<void()> callback) override;
std::string get_sn() override;
+4
View File
@@ -169,6 +169,10 @@ public:
virtual void async_delete_camera_timelapse(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) {}
virtual void async_get_timelapse_instance(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) {}
virtual void async_defect_detaction_config(const nlohmann::json& targets, std::function<void(const nlohmann::json& response)>) {}
//Support for cloud webui login
virtual bool is_cloud() const { return false; }
virtual bool is_logged_in() const { return false; }