diff --git a/localization/i18n/list.txt b/localization/i18n/list.txt index d519a11168..e23eb9ad67 100644 --- a/localization/i18n/list.txt +++ b/localization/i18n/list.txt @@ -138,6 +138,7 @@ src/slic3r/GUI/ObjectDataViewModel.cpp src/slic3r/GUI/OpenGLManager.cpp src/slic3r/GUI/OptionsGroup.cpp src/slic3r/GUI/PrintOptionsDialog.cpp +src/slic3r/GUI/SafetyOptionsDialog.cpp src/slic3r/GUI/ParamsPanel.cpp src/slic3r/GUI/PartPlate.cpp src/slic3r/GUI/Plater.cpp diff --git a/src/slic3r/GUI/DeviceCore/DevPrintOptions.cpp b/src/slic3r/GUI/DeviceCore/DevPrintOptions.cpp index 9083c758ca..dd8bd77070 100644 --- a/src/slic3r/GUI/DeviceCore/DevPrintOptions.cpp +++ b/src/slic3r/GUI/DeviceCore/DevPrintOptions.cpp @@ -107,7 +107,6 @@ void DevPrintOptionsParser::ParseDetectionV1_2(DevPrintOptions *opts, MachineObj } } - if (time(nullptr) - opts->xcam_auto_recovery_hold_start > HOLD_TIME_3SEC) { if (print_json.contains("auto_recovery")) { opts->xcam_auto_recovery_step_loss = print_json["auto_recovery"].get(); } } @@ -145,7 +144,11 @@ void DevPrintOptionsParser::ParseDetectionV2_0(DevPrintOptions *opts, std::strin if (time(nullptr) - opts->xcam_filament_tangle_detect_hold_start > HOLD_TIME_3SEC) { opts->xcam_filament_tangle_detect = DevUtil::get_flag_bits(print_json, 23); } +} +void DevPrintOptionsParser::ParseDetectionV2_1(DevPrintOptions *opts, std::string cfg) { + if (time(nullptr) - opts->idel_heating_protect_hold_strat > HOLD_TIME_3SEC) + opts->idel_heating_protect_enabled = DevUtil::get_flag_bits(cfg, 32, 2); } void DevPrintOptions::SetPrintingSpeedLevel(DevPrintingSpeedLevel speed_level) @@ -168,8 +171,15 @@ int DevPrintOptions::command_xcam_control_ai_monitoring(bool on_off, std::string xcam_ai_monitoring_hold_start = time(nullptr); xcam_ai_monitoring_sensitivity = lvl; return command_xcam_control("printing_monitor", on_off, m_obj, lvl); - } + +int DevPrintOptions::command_xcam_control_idelheatingprotect_detector(bool on_off) +{ + idel_heating_protect_enabled = on_off; + idel_heating_protect_hold_strat = time(nullptr); + return command_set_against_continued_heating_mode(on_off); +} + int DevPrintOptions::command_xcam_control_buildplate_marker_detector(bool on_off) { xcam_buildplate_marker_detector = on_off; @@ -239,6 +249,15 @@ int DevPrintOptions::command_xcam_control(std::string module_name, bool on_off , return obj->publish_json(j); } +int DevPrintOptions::command_set_against_continued_heating_mode(bool on_off) +{ + json j; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["command"] = "set_against_continued_heating_mode"; + j["print"]["enable"] = on_off; + return m_obj->publish_json(j); +} + int DevPrintOptions::command_set_printing_option(bool auto_recovery, MachineObject *obj) { json j; diff --git a/src/slic3r/GUI/DeviceCore/DevPrintOptions.h b/src/slic3r/GUI/DeviceCore/DevPrintOptions.h index 0de681b7b2..46461af561 100644 --- a/src/slic3r/GUI/DeviceCore/DevPrintOptions.h +++ b/src/slic3r/GUI/DeviceCore/DevPrintOptions.h @@ -27,6 +27,7 @@ public: int command_xcam_control_auto_recovery_step_loss(bool on_off); int command_xcam_control_allow_prompt_sound(bool on_off); int command_xcam_control_filament_tangle_detect(bool on_off); + int command_xcam_control_idelheatingprotect_detector(bool on_off); int command_xcam_control(std::string module_name, bool on_off, MachineObject *obj ,std::string lvl = ""); @@ -37,19 +38,20 @@ public: // set fliament tangle detect int command_set_filament_tangle_detect(bool fliament_tangle_detect, MachineObject *obj); + int command_set_against_continued_heating_mode(bool on_off); void parse_auto_recovery_step_loss_status(int flag); void parse_allow_prompt_sound_status(int flag); void parse_filament_tangle_detect_status(int flag); - bool GetAiMonitoring() const { return xcam_ai_monitoring; }; - bool GetFirstLayerInspector() const{ return xcam_first_layer_inspector; }; - bool GetBuildplateMarkerDetector() const { return xcam_buildplate_marker_detector; }; - bool GetAutoRecoveryStepLoss() const { return xcam_auto_recovery_step_loss; }; - bool GetAllowPromptSound() const { return xcam_allow_prompt_sound; }; - bool GetFilamentTangleDetect() const { return xcam_filament_tangle_detect; }; - - string GetAiMonitoringSensitivity() const { return xcam_ai_monitoring_sensitivity; }; + bool GetAiMonitoring() const { return xcam_ai_monitoring; } + bool GetFirstLayerInspector() const{ return xcam_first_layer_inspector; } + bool GetBuildplateMarkerDetector() const { return xcam_buildplate_marker_detector; } + bool GetAutoRecoveryStepLoss() const { return xcam_auto_recovery_step_loss; } + bool GetAllowPromptSound() const { return xcam_allow_prompt_sound; } + bool GetFilamentTangleDetect() const { return xcam_filament_tangle_detect; } + int GetIdelHeatingProtectEenabled() const { return idel_heating_protect_enabled; } + string GetAiMonitoringSensitivity() const { return xcam_ai_monitoring_sensitivity; } private: @@ -65,12 +67,14 @@ private: bool xcam_auto_recovery_step_loss{false}; bool xcam_allow_prompt_sound{false}; bool xcam_filament_tangle_detect{false}; + int idel_heating_protect_enabled = -1; time_t xcam_ai_monitoring_hold_start = 0; time_t xcam_buildplate_marker_hold_start = 0; time_t xcam_first_layer_hold_start = 0; time_t xcam_auto_recovery_hold_start = 0; time_t xcam_prompt_sound_hold_start = 0; time_t xcam_filament_tangle_detect_hold_start = 0; + time_t idel_heating_protect_hold_strat = 0; MachineObject* m_obj;/*owner*/ }; @@ -85,7 +89,8 @@ public: static void ParseDetectionV1_1(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json, bool enable); static void ParseDetectionV1_2(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json); - static void ParseDetectionV2_0(DevPrintOptions *opts, std::string print_json); + static void ParseDetectionV2_0(DevPrintOptions *opts, std::string cfg); + static void ParseDetectionV2_1(DevPrintOptions *opts, std::string cfg); }; } // namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 0f071be841..9ab8286e0c 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -4882,22 +4882,17 @@ void MachineObject::parse_new_info(json print) tutk_state = get_flag_bits(cfg, 6) == 1 ? "disable" : ""; m_lamp->SetChamberLight(get_flag_bits(cfg, 7) == 1 ? DevLamp::LIGHT_EFFECT_ON : DevLamp::LIGHT_EFFECT_OFF); //is_support_build_plate_marker_detect = get_flag_bits(cfg, 12); todo yangcong + if (time(nullptr) - xcam_first_layer_hold_start > HOLD_TIME_3SEC) { xcam_first_layer_inspector = get_flag_bits(cfg, 12); } - if (time(nullptr) - xcam_first_layer_hold_start > HOLD_TIME_3SEC) { - xcam_first_layer_inspector = get_flag_bits(cfg, 12); - } - - if (time(nullptr) - xcam_ai_monitoring_hold_start > HOLD_COUNT_MAX) - { + if (time(nullptr) - xcam_ai_monitoring_hold_start > HOLD_COUNT_MAX) { xcam_ai_monitoring = get_flag_bits(cfg, 15); - switch (get_flag_bits(cfg, 13, 2)) - { - case 0: xcam_ai_monitoring_sensitivity = "never_halt"; break; - case 1: xcam_ai_monitoring_sensitivity = "low"; break; - case 2: xcam_ai_monitoring_sensitivity = "medium"; break; - case 3: xcam_ai_monitoring_sensitivity = "high"; break; - default: break; + switch (get_flag_bits(cfg, 13, 2)) { + case 0: xcam_ai_monitoring_sensitivity = "never_halt"; break; + case 1: xcam_ai_monitoring_sensitivity = "low"; break; + case 2: xcam_ai_monitoring_sensitivity = "medium"; break; + case 3: xcam_ai_monitoring_sensitivity = "high"; break; + default: break; } } @@ -4934,6 +4929,8 @@ void MachineObject::parse_new_info(json print) } installed_upgrade_kit = get_flag_bits(cfg, 25); + + DevPrintOptionsParser::ParseDetectionV2_1(m_print_options, cfg); } /*fun*/ @@ -4970,6 +4967,7 @@ void MachineObject::parse_new_info(json print) m_fan->SetSupportCoolingFilter(get_flag_bits(fun, 46)); is_support_ext_change_assist = get_flag_bits(fun, 48); is_support_partskip = get_flag_bits(fun, 49); + is_support_idelheadingprotect_detection = get_flag_bits(fun, 62); } /*aux*/ diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index ea54d72cbb..478c07ecdf 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -609,6 +609,7 @@ public: bool is_support_purgechutepileup_detection{false}; bool is_support_nozzleclumping_detection{false}; bool is_support_airprinting_detection{false}; + bool is_support_idelheadingprotect_detection{false}; bool installed_upgrade_kit{false}; int bed_temperature_limit = -1; diff --git a/src/slic3r/GUI/SafetyOptionsDialog.cpp b/src/slic3r/GUI/SafetyOptionsDialog.cpp index 45b627e6aa..2ec5894908 100644 --- a/src/slic3r/GUI/SafetyOptionsDialog.cpp +++ b/src/slic3r/GUI/SafetyOptionsDialog.cpp @@ -8,6 +8,7 @@ #include "DeviceCore/DevConfig.h" #include "DeviceCore/DevExtruderSystem.h" #include "DeviceCore/DevNozzleSystem.h" +#include "DeviceCore/DevPrintOptions.h" static const wxColour STATIC_BOX_LINE_COL = wxColour(238, 238, 238); static const wxColour STATIC_TEXT_CAPTION_COL = wxColour(100, 100, 100); @@ -58,7 +59,7 @@ SafetyOptionsDialog::SafetyOptionsDialog(wxWindow* parent) evt.Skip(); }); - open_door_switch_board->Bind(wxCUSTOMEVT_SWITCH_POS, [this](wxCommandEvent &evt) + m_open_door_switch_board->Bind(wxCUSTOMEVT_SWITCH_POS, [this](wxCommandEvent &evt) { if (evt.GetInt() == 0) { @@ -71,6 +72,35 @@ SafetyOptionsDialog::SafetyOptionsDialog(wxWindow* parent) evt.Skip(); }); + m_cb_idel_heating_protection->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent &evt) { + if (obj) + { + obj->GetPrintOptions()->command_xcam_control_idelheatingprotect_detector(m_cb_idel_heating_protection->GetValue()); + } + else + { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "obj is empty"; + } + evt.Skip(); + }); + + auto toast_click = [this](wxMouseEvent &e) { + if (m_idel_protect_unavailable) { + show_idel_heating_toast(_L("Unavailable while heating maintenance function is on.")); + } + e.Skip(); + }; + m_text_idel_heating_protection->Bind(wxEVT_LEFT_DOWN, toast_click); + m_text_idel_heating_protection_caption->Bind(wxEVT_LEFT_DOWN, toast_click); + m_idel_heating_container->Bind(wxEVT_LEFT_DOWN, toast_click); + + m_idel_heating_toast_timer.SetOwner(this); + Bind( wxEVT_TIMER, [this](wxTimerEvent &e) { + if (m_idel_heating_toast) { + m_idel_heating_toast->Destroy(); + m_idel_heating_toast = nullptr; + }}, m_idel_heating_toast_timer.GetId()); + wxGetApp().UpdateDlgDarkUI(this); } @@ -87,41 +117,70 @@ void SafetyOptionsDialog::update_options(MachineObject* obj_) { if (!obj_) return; - UpdateOptionOpenDoorCheck(obj_); + updateOpenDoorCheck(obj_); + updateIdelHeatingProtect(obj_); this->Freeze(); this->Thaw(); Layout(); } -void SafetyOptionsDialog::UpdateOptionOpenDoorCheck(MachineObject *obj) { +void SafetyOptionsDialog::updateOpenDoorCheck(MachineObject *obj) { if (!obj || !obj->support_door_open_check()) { m_cb_open_door->Hide(); - text_open_door->Hide(); - open_door_switch_board->Hide(); + m_text_open_door->Hide(); + m_open_door_switch_board->Hide(); return; } if (obj->get_door_open_check_state() != MachineObject::DOOR_OPEN_CHECK_DISABLE) { m_cb_open_door->SetValue(true); - open_door_switch_board->Enable(); + m_open_door_switch_board->Enable(); if (obj->get_door_open_check_state() == MachineObject::DOOR_OPEN_CHECK_ENABLE_WARNING) { - open_door_switch_board->updateState("left"); - open_door_switch_board->Refresh(); + m_open_door_switch_board->updateState("left"); + m_open_door_switch_board->Refresh(); } else if (obj->get_door_open_check_state() == MachineObject::DOOR_OPEN_CHECK_ENABLE_PAUSE_PRINT) { - open_door_switch_board->updateState("right"); - open_door_switch_board->Refresh(); + m_open_door_switch_board->updateState("right"); + m_open_door_switch_board->Refresh(); } } else { m_cb_open_door->SetValue(false); - open_door_switch_board->Disable(); + m_open_door_switch_board->Disable(); } m_cb_open_door->Show(); - text_open_door->Show(); - open_door_switch_board->Show(); + m_text_open_door->Show(); + m_open_door_switch_board->Show(); +} + +void SafetyOptionsDialog::updateIdelHeatingProtect(MachineObject *obj) +{ + if (obj->is_support_idelheadingprotect_detection) { + m_idel_heating_container->Show(); + } else { + m_idel_heating_container->Hide(); + m_idel_protect_unavailable = false; + return; + } + + if (obj->GetPrintOptions()->GetIdelHeatingProtectEenabled() == 2) + { + m_cb_idel_heating_protection->SetValue(false); + m_cb_idel_heating_protection->Enable(false); + m_text_idel_heating_protection->SetForegroundColour(wxColour(170, 170, 170)); + m_text_idel_heating_protection_caption->SetForegroundColour(wxColour(170, 170, 170)); + m_cb_idel_heating_protection->SetBackgroundColour(wxColour(255, 255, 255)); + m_idel_protect_unavailable = true; + } else { + m_cb_idel_heating_protection->Enable(true); + m_cb_idel_heating_protection->SetValue(obj->GetPrintOptions()->GetIdelHeatingProtectEenabled()); + m_text_idel_heating_protection->SetForegroundColour(*wxBLACK); + m_text_idel_heating_protection_caption->SetForegroundColour(STATIC_TEXT_CAPTION_COL); + m_cb_idel_heating_protection->SetForegroundColour(*wxBLACK); + m_idel_protect_unavailable = false; + } } wxBoxSizer* SafetyOptionsDialog::create_settings_group(wxWindow* parent) @@ -131,19 +190,44 @@ wxBoxSizer* SafetyOptionsDialog::create_settings_group(wxWindow* parent) //Open Door Detection wxBoxSizer* line_sizer = new wxBoxSizer(wxHORIZONTAL); m_cb_open_door = new CheckBox(parent); - text_open_door = new Label(parent, _L("Open Door Detection")); - text_open_door->SetFont(Label::Body_14); - open_door_switch_board = new SwitchBoard(parent, _L("Notification"), _L("Pause printing"), wxSize(FromDIP(200), FromDIP(26))); - open_door_switch_board->Disable(); - line_sizer->Add(FromDIP(5), 0, 0, 0); + m_text_open_door = new Label(parent, _L("Open Door Detection")); + m_text_open_door->SetFont(Label::Body_14); + m_open_door_switch_board = new SwitchBoard(parent, _L("Notification"), _L("Pause printing"), wxSize(FromDIP(200), FromDIP(26))); + m_open_door_switch_board->Disable(); + line_sizer->AddSpacer(FromDIP(5)); line_sizer->Add(m_cb_open_door, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); - line_sizer->Add(text_open_door, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add(m_text_open_door, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); sizer->Add(line_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(18)); - sizer->Add(open_door_switch_board, 0, wxLEFT, FromDIP(58)); + sizer->Add(m_open_door_switch_board, 0, wxLEFT, FromDIP(65)); line_sizer->Add(FromDIP(10), 0, 0, 0); sizer->Add(0, 0, 0, wxTOP, FromDIP(15)); + //Idel Heating Protect + m_idel_heating_container = new wxPanel(parent, wxID_ANY); + m_idel_heating_container->SetBackgroundColour(*wxWHITE); + wxBoxSizer* idel_container_sizer = new wxBoxSizer(wxVERTICAL); + + line_sizer = new wxBoxSizer(wxHORIZONTAL); + m_cb_idel_heating_protection = new CheckBox(m_idel_heating_container); + m_text_idel_heating_protection = new Label(m_idel_heating_container, _L("Idel Heating Protection")); + m_text_idel_heating_protection->SetFont(Label::Body_14); + line_sizer->AddSpacer(FromDIP(5)); + line_sizer->Add(m_cb_idel_heating_protection, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add(m_text_idel_heating_protection, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + idel_container_sizer->Add(line_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(18)); + + line_sizer = new wxBoxSizer(wxHORIZONTAL); + m_text_idel_heating_protection_caption = new Label(m_idel_heating_container, _L("Stops heating automatically after 5 mins of idle to ensure safety.")); + m_text_idel_heating_protection_caption->SetFont(Label::Body_12); + m_text_idel_heating_protection_caption->SetForegroundColour(STATIC_TEXT_CAPTION_COL); + line_sizer->AddSpacer(FromDIP(20)); + line_sizer->Add(m_text_idel_heating_protection_caption, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + idel_container_sizer->Add(line_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30)); + + m_idel_heating_container->SetSizer(idel_container_sizer); + sizer->Add(m_idel_heating_container, 0, wxEXPAND); + return sizer; } @@ -161,4 +245,31 @@ bool SafetyOptionsDialog::Show(bool show) return DPIDialog::Show(show); } +void SafetyOptionsDialog::show_idel_heating_toast(const wxString &text) +{ + if (m_idel_heating_toast) + { + m_idel_heating_toast->Destroy(); + m_idel_heating_toast = nullptr; + } + + m_idel_heating_toast = new wxPopupWindow(this); + m_idel_heating_toast->SetBackgroundColour(wxColour(0, 0, 0)); + wxStaticText *textCtrl = new wxStaticText(m_idel_heating_toast, wxID_ANY, text, wxPoint(10, 10)); + textCtrl->SetForegroundColour(*wxWHITE); + // Start a one-shot timer for 3 seconds to dismiss + wxSize textSize = textCtrl->GetBestSize(); + m_idel_heating_toast->SetSize(textSize + wxSize(20, 20)); + + wxRect anchor = m_text_idel_heating_protection->GetScreenRect(); + wxPoint pos = anchor.GetBottomLeft(); + pos.y += FromDIP(40); + + m_idel_heating_toast->Move(pos); + m_idel_heating_toast->Show(true); + + m_idel_heating_toast_timer.Stop(); + m_idel_heating_toast_timer.StartOnce(3000); +} + }} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/SafetyOptionsDialog.hpp b/src/slic3r/GUI/SafetyOptionsDialog.hpp index 165dd3bd82..a39ddb77ab 100644 --- a/src/slic3r/GUI/SafetyOptionsDialog.hpp +++ b/src/slic3r/GUI/SafetyOptionsDialog.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "GUI_Utils.hpp" #include "wxExtensions.hpp" @@ -26,11 +27,21 @@ class SafetyOptionsDialog : public DPIDialog protected: // settings wxScrolledWindow* m_scrollwindow; - CheckBox* m_cb_open_door; - Label* text_open_door; - SwitchBoard* open_door_switch_board; - wxBoxSizer* create_settings_group(wxWindow* parent); + CheckBox* m_cb_open_door; + CheckBox* m_cb_idel_heating_protection; + Label* m_text_open_door; + Label* m_text_idel_heating_protection; + Label* m_text_idel_heating_protection_caption; + SwitchBoard* m_open_door_switch_board; + wxPanel* m_idel_heating_container { nullptr }; + + // toast for idle heating unavailable + wxPopupWindow *m_idel_heating_toast{nullptr}; + wxTimer m_idel_heating_toast_timer; + bool m_idel_protect_unavailable { false }; + + wxBoxSizer* create_settings_group(wxWindow* parent); bool print_halt = false; public: @@ -45,7 +56,9 @@ public: bool Show(bool show) override; private: - void UpdateOptionOpenDoorCheck(MachineObject *obj); + void updateOpenDoorCheck(MachineObject *obj); + void updateIdelHeatingProtect(MachineObject *obj); + void show_idel_heating_toast(const wxString &text); }; }} // namespace Slic3r::GUI