diff --git a/src/libslic3r/LifecycleEvents.hpp b/src/libslic3r/LifecycleEvents.hpp index e1abc795c1..f3e6f32392 100644 --- a/src/libslic3r/LifecycleEvents.hpp +++ b/src/libslic3r/LifecycleEvents.hpp @@ -49,11 +49,10 @@ namespace Slic3r // Printer/device PrintStateChanged, - DeviceOnlineChanged, + DeviceOnline, + DeviceOffline, DeviceDiscovered, DeviceSelected, - DeviceConnected, - DeviceDisconnected, UploadStarted, UploadFinished, @@ -141,11 +140,10 @@ namespace Slic3r case LifecycleEvent::PresetSaved: return "PresetSaved"; case LifecycleEvent::PrintStateChanged: return "PrintStateChanged"; - case LifecycleEvent::DeviceOnlineChanged: return "DeviceOnlineChanged"; + case LifecycleEvent::DeviceOnline: return "DeviceOnline"; + case LifecycleEvent::DeviceOffline: return "DeviceOffline"; case LifecycleEvent::DeviceDiscovered: return "DeviceDiscovered"; case LifecycleEvent::DeviceSelected: return "DeviceSelected"; - case LifecycleEvent::DeviceConnected: return "DeviceConnected"; - case LifecycleEvent::DeviceDisconnected: return "DeviceDisconnected"; case LifecycleEvent::UploadStarted: return "UploadStarted"; case LifecycleEvent::UploadFinished: return "UploadFinished"; diff --git a/src/slic3r/GUI/DeviceCore/DevManager.cpp b/src/slic3r/GUI/DeviceCore/DevManager.cpp index 0a456a9267..c03f0cfe59 100644 --- a/src/slic3r/GUI/DeviceCore/DevManager.cpp +++ b/src/slic3r/GUI/DeviceCore/DevManager.cpp @@ -357,7 +357,7 @@ namespace Slic3r obj->last_alive = Slic3r::Utils::get_current_time_utc(); // Route through set_online_state() (rather than writing m_is_online directly) so the - // DeviceOnlineChanged lifecycle event fires consistently; same effective value/behavior + // DeviceOnline lifecycle event fires consistently; same effective value/behavior // here since the object was already online in the common case. obj->set_online_state(true); obj->set_dev_name(dev_name); @@ -380,7 +380,7 @@ namespace Slic3r // Discovery establishes the initial reachability state. Do not report it as an // online transition; DeviceDiscovered below is the lifecycle event for a new // device. Subsequent updates route through set_online_state(), so a known device - // still emits DeviceOnlineChanged when its reachability actually changes. + // still emits DeviceOnline/DeviceOffline when its reachability actually changes. obj->m_is_online = true; //load access code diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 7a52c648ef..6bd690e9a6 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -2657,11 +2657,10 @@ int MachineObject::connect(bool use_openssl) int MachineObject::disconnect() { if (m_agent) { - LifecycleEventContext ctx; - ctx.name = dev_id; - ctx.code = LifecycleEvtCode::Ok; - fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx); - return m_agent->disconnect_printer(); + const int result = m_agent->disconnect_printer(); + if (result == 0) + set_online_state(false); + return result; } return -1; } @@ -2699,7 +2698,7 @@ void MachineObject::set_online_state(bool on_off) ctx.name = dev_id; ctx.code = LifecycleEvtCode::Ok; ctx.msg = on_off ? "online" : "offline"; - fire_lifecycle_event(LifecycleEvent::DeviceOnlineChanged, ctx); + fire_lifecycle_event(on_off ? LifecycleEvent::DeviceOnline : LifecycleEvent::DeviceOffline, ctx); } } @@ -2827,13 +2826,6 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ parse_msg_count++; std::chrono::system_clock::time_point clock_start = std::chrono::system_clock::now(); - this->set_online_state(true); - - std::chrono::system_clock::time_point curr_time = std::chrono::system_clock::now(); - auto diff1 = std::chrono::duration_cast(curr_time - last_update_time); - - /* update last received time */ - last_update_time = std::chrono::system_clock::now(); json j_pre; bool parse_ok = false; @@ -2846,8 +2838,29 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ /* post process payload */ sanitizeToUtf8(payload); BOOST_LOG_TRIVIAL(info) << "parse_json: sanitize to utf8"; + try { + j_pre = json::parse(payload); + parse_ok = true; + } + catch (...) {} } + bool client_disconnected = false; + if (parse_ok && j_pre.is_object() && j_pre.contains("event") && j_pre["event"].is_object() && + j_pre["event"].contains("event") && j_pre["event"]["event"].is_string()) { + client_disconnected = j_pre["event"]["event"].get() == "client.disconnected"; + } + + // A disconnect notification is a transport message too, but it must not first mark an + // already-offline device as online through the generic message-received path. + set_online_state(!client_disconnected); + + std::chrono::system_clock::time_point curr_time = std::chrono::system_clock::now(); + auto diff1 = std::chrono::duration_cast(curr_time - last_update_time); + + /* update last received time */ + last_update_time = std::chrono::system_clock::now(); + try { bool restored_json = false; json j; @@ -4618,24 +4631,6 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ } } - // event info - try { - if (j.contains("event")) { - if (j["event"].contains("event")) { - if (j["event"]["event"].get() == "client.disconnected") { - set_online_state(false); - LifecycleEventContext ctx; - ctx.name = dev_id; - ctx.code = LifecycleEvtCode::Ok; - fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx); - } - else if (j["event"]["event"].get() == "client.connected") - set_online_state(true); - } - } - } - catch (...) {} - if (!key_field_only) { BOOST_LOG_TRIVIAL(trace) << "parse_json m_active_state =" << m_active_state; parse_state_changed_event(); diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 914c8f7868..ca3b7c3c44 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -897,6 +897,7 @@ public: bool is_connected(); bool is_connecting(); + // Emits DeviceOnline or DeviceOffline only when the reachability state changes. void set_online_state(bool on_off); bool is_online() { return m_is_online; } bool is_info_ready(bool check_version = true) const; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 5303502b69..29bab18aeb 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2183,10 +2183,7 @@ void GUI_App::init_networking_callbacks() if (m_agent) m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer()); - LifecycleEventContext ctx; - ctx.name = obj->get_dev_id(); - ctx.code = LifecycleEvtCode::Ok; - fire_lifecycle_event(LifecycleEvent::DeviceConnected, ctx); + obj->set_online_state(true); } }); }); @@ -2226,10 +2223,7 @@ void GUI_App::init_networking_callbacks() event.SetInt(0); event.SetString(obj->get_dev_id()); - LifecycleEventContext ctx; - ctx.name = obj->get_dev_id(); - ctx.code = LifecycleEvtCode::Ok; - fire_lifecycle_event(LifecycleEvent::DeviceConnected, ctx); + obj->set_online_state(true); } else if (state == ConnectStatus::ConnectStatusFailed) { // Orca: only update status if same device id if (m_device_manager->selected_machine != dev_id) return; @@ -2246,21 +2240,13 @@ void GUI_App::init_networking_callbacks() } event.SetInt(-1); - { - LifecycleEventContext ctx; - ctx.name = dev_id; - ctx.code = LifecycleEvtCode::Ok; - fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx); - } + obj->set_online_state(false); } else if (state == ConnectStatus::ConnectStatusLost) { m_device_manager->set_selected_machine(""); event.SetInt(-1); BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = lost"; - LifecycleEventContext ctx; - ctx.name = dev_id; - ctx.code = LifecycleEvtCode::Ok; - fire_lifecycle_event(LifecycleEvent::DeviceDisconnected, ctx); + obj->set_online_state(false); } else { event.SetInt(-1); BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = " << state; diff --git a/src/slic3r/plugin/PythonPluginBridge.cpp b/src/slic3r/plugin/PythonPluginBridge.cpp index c2587ceb56..a88695005c 100644 --- a/src/slic3r/plugin/PythonPluginBridge.cpp +++ b/src/slic3r/plugin/PythonPluginBridge.cpp @@ -401,11 +401,10 @@ void bind_python_api(pybind11::module_& m) .value("PresetSelected", LifecycleEvent::PresetSelected) .value("PresetSaved", LifecycleEvent::PresetSaved) .value("PrintStateChanged", LifecycleEvent::PrintStateChanged) - .value("DeviceOnlineChanged", LifecycleEvent::DeviceOnlineChanged) + .value("DeviceOnline", LifecycleEvent::DeviceOnline) + .value("DeviceOffline", LifecycleEvent::DeviceOffline) .value("DeviceDiscovered", LifecycleEvent::DeviceDiscovered) .value("DeviceSelected", LifecycleEvent::DeviceSelected) - .value("DeviceConnected", LifecycleEvent::DeviceConnected) - .value("DeviceDisconnected", LifecycleEvent::DeviceDisconnected) .value("UploadStarted", LifecycleEvent::UploadStarted) .value("UploadFinished", LifecycleEvent::UploadFinished) .value("PrintJobStarted", LifecycleEvent::PrintJobStarted)