mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-23 08:53:05 +00:00
Merge branch 'feat/printer-agent-infra' into refactor/connect-printer-api
This commit is contained in:
@@ -997,8 +997,8 @@ elseif (WIN32)
|
||||
find_library(LIBAVCODEC_LIBRARY NAMES avcodec PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBSWSCALE_LIBRARY NAMES swscale PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
find_library(LIBAVUTIL_LIBRARY NAMES avutil PATHS ${CMAKE_PREFIX_PATH}/lib NO_DEFAULT_PATH)
|
||||
if (NOT LIBAVCODEC_LIBRARY OR NOT LIBSWSCALE_LIBRARY OR NOT LIBAVUTIL_LIBRARY)
|
||||
message(FATAL_ERROR "FFmpeg (avcodec/swscale/avutil) not found under ${CMAKE_PREFIX_PATH}/lib. Rebuild the deps.")
|
||||
if (NOT LIBAVFORMAT_LIBRARY OR NOT LIBAVCODEC_LIBRARY OR NOT LIBSWSCALE_LIBRARY OR NOT LIBAVUTIL_LIBRARY)
|
||||
message(FATAL_ERROR "FFmpeg (avformat/avcodec/swscale/avutil) not found under ${CMAKE_PREFIX_PATH}/lib. Rebuild the deps.")
|
||||
endif ()
|
||||
target_link_libraries(libslic3r_gui ${LIBAVFORMAT_LIBRARY} ${LIBAVCODEC_LIBRARY} ${LIBSWSCALE_LIBRARY} ${LIBAVUTIL_LIBRARY})
|
||||
target_include_directories(libslic3r_gui SYSTEM PRIVATE ${CMAKE_PREFIX_PATH}/include)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "PrePrintChecker.hpp"
|
||||
|
||||
#include "DeviceCore/DevConfig.h"
|
||||
#include "DeviceCore/DevConfigUtil.h"
|
||||
@@ -1639,19 +1640,6 @@ void CalibrationPresetPage::update_combobox_filaments(MachineObject* obj)
|
||||
select_default_compatible_filament();
|
||||
}
|
||||
|
||||
bool CalibrationPresetPage::is_blocking_printing()
|
||||
{
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
|
||||
MachineObject* obj_ = dev->get_selected_machine();
|
||||
if (obj_ == nullptr) return true;
|
||||
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
const auto source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
}
|
||||
|
||||
bool CalibrationPresetPage::is_nozzle_info_synced() const
|
||||
{
|
||||
if (!curr_obj || !curr_obj->is_info_ready())
|
||||
@@ -1733,11 +1721,13 @@ void CalibrationPresetPage::update_show_status()
|
||||
}
|
||||
}
|
||||
|
||||
//if (is_blocking_printing()) {
|
||||
// show_status(CaliPresetPageStatus::CaliPresetStatusUnsupportedPrinter);
|
||||
// return;
|
||||
//}
|
||||
//else
|
||||
bool has_optional_printer_model = DevPrinterConfigUtil::is_optional_printer_model_id(obj_->printer_type);
|
||||
if (PresetBundle *preset_bundle = wxGetApp().preset_bundle) {
|
||||
has_optional_printer_model = has_optional_printer_model ||
|
||||
DevPrinterConfigUtil::is_optional_printer_model_id(
|
||||
preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle));
|
||||
}
|
||||
|
||||
if (obj_->is_connecting() || !obj_->is_connected()) {
|
||||
show_status(CaliPresetPageStatus::CaliPresetStatusInConnecting);
|
||||
return;
|
||||
@@ -1789,7 +1779,9 @@ void CalibrationPresetPage::update_show_status()
|
||||
return;
|
||||
}
|
||||
|
||||
show_status(CaliPresetPageStatus::CaliPresetStatusNormal);
|
||||
show_status(has_optional_printer_model ?
|
||||
CaliPresetPageStatus::CaliPresetStatusOptionalPrinterModel :
|
||||
CaliPresetPageStatus::CaliPresetStatusNormal);
|
||||
}
|
||||
|
||||
|
||||
@@ -1843,6 +1835,10 @@ void CalibrationPresetPage::show_status(CaliPresetPageStatus status)
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
else if (status == CaliPresetPageStatus::CaliPresetStatusOptionalPrinterModel) {
|
||||
update_print_status_msg(PrePrintChecker::get_pre_state_msg(PrintDialogStatus::PrintStatusOptionalPrinterModel), true);
|
||||
Enable_Send_Button(true);
|
||||
}
|
||||
else if (status == CaliPresetPageStatus::CaliPresetStatusNoUserLogin) {
|
||||
wxString msg_text = _L("No login account, only printers in LAN mode are displayed.");
|
||||
update_print_status_msg(msg_text, false);
|
||||
|
||||
@@ -152,7 +152,8 @@ enum CaliPresetPageStatus
|
||||
CaliPresetStatusInConnecting,
|
||||
CaliPresetStatusFilamentIncompatible,
|
||||
CaliPresetStatusLanModeSDcardNotAvailable,
|
||||
CaliPresetStatusDifferentNozzleDiameters
|
||||
CaliPresetStatusDifferentNozzleDiameters,
|
||||
CaliPresetStatusOptionalPrinterModel
|
||||
};
|
||||
|
||||
class CalibrationPresetPage : public CalibrationWizardPage
|
||||
@@ -268,7 +269,6 @@ protected:
|
||||
bool is_nozzle_info_synced() const;
|
||||
void show_status(CaliPresetPageStatus status);
|
||||
void Enable_Send_Button(bool enable);
|
||||
bool is_blocking_printing();
|
||||
bool need_check_sdcard(MachineObject* obj);
|
||||
|
||||
CaliPresetPageStatus get_status() { return m_page_status; }
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "DevManager.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "DevManager.h"
|
||||
#include <libslic3r/AppConfig.hpp>
|
||||
#include "CloudProvider.hpp"
|
||||
#include "DevUtil.h"
|
||||
|
||||
@@ -48,10 +49,12 @@ namespace {
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
DeviceManager::DeviceManager(NetworkAgent* agent)
|
||||
DeviceManager::DeviceManager(NetworkAgent* agent, bool enable_refresher, AppConfig* app_config)
|
||||
{
|
||||
m_agent = agent;
|
||||
m_refresher = new DeviceManagerRefresher(this);
|
||||
m_agent = agent;
|
||||
m_app_config = app_config;
|
||||
if (enable_refresher)
|
||||
m_refresher = new DeviceManagerRefresher(this);
|
||||
|
||||
DevPrinterConfigUtil::InitFilePath(resources_dir());
|
||||
|
||||
@@ -62,9 +65,14 @@ namespace Slic3r
|
||||
}
|
||||
}
|
||||
|
||||
AppConfig* DeviceManager::get_app_config() const
|
||||
{
|
||||
return m_app_config ? m_app_config : GUI::wxGetApp().app_config;
|
||||
}
|
||||
|
||||
void DeviceManager::load_local_machines_from_config()
|
||||
{
|
||||
AppConfig* config = GUI::wxGetApp().app_config;
|
||||
AppConfig* config = get_app_config();
|
||||
if (!config)
|
||||
return;
|
||||
const auto local_machines = config->get_local_machines();
|
||||
@@ -90,9 +98,8 @@ namespace Slic3r
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::update_local_machine(const MachineObject& m)
|
||||
void DeviceManager::update_local_machine(const MachineObject& m, AppConfig* config)
|
||||
{
|
||||
AppConfig* config = GUI::wxGetApp().app_config;
|
||||
if (config) {
|
||||
if (m.is_lan_mode_printer()) {
|
||||
if (m.has_access_right()) {
|
||||
@@ -113,7 +120,8 @@ namespace Slic3r
|
||||
|
||||
DeviceManager::~DeviceManager()
|
||||
{
|
||||
delete m_refresher;
|
||||
if (m_refresher)
|
||||
delete m_refresher;
|
||||
|
||||
for (auto it = localMachineList.begin(); it != localMachineList.end(); it++)
|
||||
{
|
||||
@@ -173,14 +181,22 @@ namespace Slic3r
|
||||
return printer_agent ? printer_agent->get_agent_info().id : "";
|
||||
}
|
||||
|
||||
std::string DeviceManager::get_current_cloud_provider() const
|
||||
{
|
||||
const std::string agent_id = get_current_printer_agent_id();
|
||||
if (!agent_id.empty())
|
||||
return agent_id == BBL_PRINTER_AGENT_ID ? BBL_CLOUD_PROVIDER : ORCA_CLOUD_PROVIDER;
|
||||
return GUI::wxGetApp().get_printer_cloud_provider();
|
||||
}
|
||||
|
||||
void DeviceManager::EnableMultiMachine(bool enable)
|
||||
{
|
||||
m_agent->enable_multi_machine(enable);
|
||||
m_enable_mutil_machine = enable;
|
||||
}
|
||||
|
||||
void DeviceManager::start_refresher() { m_refresher->Start(); }
|
||||
void DeviceManager::stop_refresher() { m_refresher->Stop(); }
|
||||
void DeviceManager::start_refresher() { if (m_refresher) m_refresher->Start(); }
|
||||
void DeviceManager::stop_refresher() { if (m_refresher) m_refresher->Stop(); }
|
||||
|
||||
|
||||
void DeviceManager::keep_alive()
|
||||
@@ -297,6 +313,8 @@ namespace Slic3r
|
||||
|
||||
/* update localMachineList */
|
||||
it = localMachineList.find(dev_id);
|
||||
AppConfig* config = get_app_config();
|
||||
|
||||
if (it != localMachineList.end()) {
|
||||
// update properties
|
||||
/* ip changed */
|
||||
@@ -386,7 +404,6 @@ namespace Slic3r
|
||||
obj->m_is_online = true;
|
||||
|
||||
//load access code
|
||||
AppConfig* config = Slic3r::GUI::wxGetApp().app_config;
|
||||
if (config) {
|
||||
obj->set_access_code(get_access_code_with_legacy_fallback(config, dev_id, obj->printer_agent_id), false);
|
||||
}
|
||||
@@ -400,7 +417,7 @@ namespace Slic3r
|
||||
<< ", ip = " << dev_ip <<", printer_name = " << dev_name
|
||||
<< ", con_type= " << connect_type <<", signal= " << printer_signal << ", bind_state= " << bind_state;
|
||||
}
|
||||
update_local_machine(*obj);
|
||||
update_local_machine(*obj, config);
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
@@ -435,11 +452,16 @@ namespace Slic3r
|
||||
obj->last_alive = Slic3r::Utils::get_current_time_utc();
|
||||
obj->set_access_code(access_code, false);
|
||||
|
||||
update_local_machine(*obj);
|
||||
update_local_machine(*obj, get_app_config());
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void DeviceManager::update_local_machine(const MachineObject& m)
|
||||
{
|
||||
update_local_machine(m, GUI::wxGetApp().app_config);
|
||||
}
|
||||
|
||||
int DeviceManager::query_bind_status(std::string& msg, const std::string& provider)
|
||||
{
|
||||
if (!m_agent)
|
||||
@@ -573,13 +595,13 @@ namespace Slic3r
|
||||
<< " cur_selected=" << selected_machine;
|
||||
auto my_machine_list = get_my_machine_list(get_current_printer_agent_id());
|
||||
auto it = my_machine_list.find(dev_id);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: set_selected_machine lookup dev_id=" << dev_id
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: set_selected_machine lookup dev_id=" << dev_id
|
||||
<< " found=" << (it != my_machine_list.end())
|
||||
<< " my_machine_count=" << my_machine_list.size()
|
||||
<< " current_agent=" << get_current_printer_agent_id()
|
||||
<< " provider=" << GUI::wxGetApp().get_printer_cloud_provider();
|
||||
if (it != my_machine_list.end() && it->second) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: target machine dev_id=" << it->second->get_dev_id()
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: target machine dev_id=" << it->second->get_dev_id()
|
||||
<< " printer_agent_id=" << it->second->printer_agent_id
|
||||
<< " connection_type=" << it->second->connection_type()
|
||||
<< " dev_connection_type=" << it->second->dev_connection_type;
|
||||
@@ -598,7 +620,7 @@ namespace Slic3r
|
||||
}
|
||||
else if (last_selected->second->connection_type() == "cloud") {
|
||||
const int result = m_agent->set_user_selected_machine("");
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: cleared previous cloud selection dev_id="
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: cleared previous cloud selection dev_id="
|
||||
<< selected_machine << " result=" << result;
|
||||
}
|
||||
}
|
||||
@@ -635,7 +657,8 @@ namespace Slic3r
|
||||
it->second->reset();
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
it->second->connect(Slic3r::GUI::wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false);
|
||||
AppConfig* config = get_app_config();
|
||||
it->second->connect(config && config->get("enable_ssl_for_mqtt") == "true");
|
||||
#else
|
||||
it->second->connect(it->second->local_use_ssl);
|
||||
#endif
|
||||
@@ -652,7 +675,7 @@ namespace Slic3r
|
||||
// diff dev_id, cloud => set_user_selected_machine(new)
|
||||
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: select new cloud machine, dev_id =" << dev_id;
|
||||
const int result = m_agent->set_user_selected_machine(dev_id);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: set new cloud selection dev_id="
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: set new cloud selection dev_id="
|
||||
<< dev_id << " result=" << result;
|
||||
it->second->reset();
|
||||
}
|
||||
@@ -661,7 +684,8 @@ namespace Slic3r
|
||||
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: select new lan machine, dev_id =" << dev_id;
|
||||
it->second->reset();
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
it->second->connect(Slic3r::GUI::wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false);
|
||||
AppConfig* config = get_app_config();
|
||||
it->second->connect(config && config->get("enable_ssl_for_mqtt") == "true");
|
||||
#else
|
||||
it->second->connect(it->second->local_use_ssl);
|
||||
#endif
|
||||
@@ -681,7 +705,7 @@ namespace Slic3r
|
||||
|
||||
selected_machine = dev_id;
|
||||
record_user_last_machine(selected_machine);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: DeviceManager selection complete selected_machine="
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: DeviceManager selection complete selected_machine="
|
||||
<< selected_machine;
|
||||
return true;
|
||||
}
|
||||
@@ -714,7 +738,7 @@ namespace Slic3r
|
||||
BOOST_LOG_TRIVIAL(trace) << "add_user_subscribe: " << it->first;
|
||||
}
|
||||
const int result = m_agent->add_subscribe(dev_list);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: add_user_subscribe count=" << dev_list.size()
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: add_user_subscribe count=" << dev_list.size()
|
||||
<< " result=" << result;
|
||||
}
|
||||
|
||||
@@ -729,7 +753,7 @@ namespace Slic3r
|
||||
BOOST_LOG_TRIVIAL(trace) << "del_user_subscribe: " << it->first;
|
||||
}
|
||||
const int result = m_agent->del_subscribe(dev_list);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: del_user_subscribe count=" << dev_list.size()
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: del_user_subscribe count=" << dev_list.size()
|
||||
<< " result=" << result;
|
||||
}
|
||||
|
||||
@@ -851,14 +875,15 @@ namespace Slic3r
|
||||
json j = json::parse(body);
|
||||
|
||||
const bool has_request_context = j.contains("provider") && j.contains("agent_id") && j.contains("generation");
|
||||
const std::string current_provider = get_current_cloud_provider();
|
||||
const std::string provider = j.contains("provider") ? j["provider"].get<std::string>()
|
||||
: GUI::wxGetApp().get_printer_cloud_provider();
|
||||
: current_provider;
|
||||
const std::string agent_id = j.contains("agent_id") ? j["agent_id"].get<std::string>()
|
||||
: get_current_printer_agent_id();
|
||||
const std::uint64_t generation = j.value("generation", std::uint64_t(0));
|
||||
|
||||
if (has_request_context &&
|
||||
(provider != GUI::wxGetApp().get_printer_cloud_provider() ||
|
||||
(provider != current_provider ||
|
||||
agent_id != get_current_printer_agent_id() ||
|
||||
generation != (m_agent ? m_agent->get_user_machine_list_generation() : 0))) {
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ": ignoring stale response provider="
|
||||
@@ -903,7 +928,8 @@ namespace Slic3r
|
||||
|
||||
if (obj->get_dev_ip().empty())
|
||||
{
|
||||
obj->get_dev_ip() = Slic3r::GUI::wxGetApp().app_config->get("ip_address", dev_id);
|
||||
if (AppConfig* config = get_app_config())
|
||||
obj->get_dev_ip() = config->get("ip_address", dev_id);
|
||||
}
|
||||
userMachineList.insert(std::make_pair(dev_id, obj));
|
||||
}
|
||||
@@ -948,7 +974,7 @@ namespace Slic3r
|
||||
obj->set_access_code(acc_code);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: parsed cloud machine dev_id=" << dev_id
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: parsed cloud machine dev_id=" << dev_id
|
||||
<< " name=" << obj->get_dev_name()
|
||||
<< " agent_id=" << obj->printer_agent_id
|
||||
<< " connection_type=" << obj->connection_type()
|
||||
@@ -968,7 +994,7 @@ namespace Slic3r
|
||||
iterat++;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: parse_user_print_info complete provider=" << provider
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: parse_user_print_info complete provider=" << provider
|
||||
<< " parsed_count=" << new_list.size()
|
||||
<< " stored_count=" << userMachineList.size();
|
||||
}
|
||||
@@ -987,29 +1013,29 @@ namespace Slic3r
|
||||
unsigned int http_code;
|
||||
std::string body;
|
||||
int result = m_agent->get_user_print_info(&http_code, &body, provider);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: get_user_print_info provider=" << provider
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: get_user_print_info provider=" << provider
|
||||
<< " result=" << result << " http_code=" << http_code
|
||||
<< " body_bytes=" << body.size();
|
||||
if (result == 0)
|
||||
{
|
||||
// parse_user_print_info and on_machine_alive (SSDP for discovery) both mutate the same userMachineList map.
|
||||
// on_machine_alive mutates the map on the UI thread, do the same for parse_user_print_info.
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: queueing parse_user_print_info on UI thread";
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: queueing parse_user_print_info on UI thread";
|
||||
Slic3r::GUI::wxGetApp().CallAfter([this, body]() { parse_user_print_info(body); });
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::record_user_last_machine(const std::string& dev_id)
|
||||
{
|
||||
if (Slic3r::GUI::wxGetApp().app_config) {
|
||||
Slic3r::GUI::wxGetApp().app_config->set("user_last_selected_machine", dev_id);
|
||||
if (AppConfig* config = get_app_config()) {
|
||||
config->set("user_last_selected_machine", dev_id);
|
||||
}
|
||||
}
|
||||
|
||||
std::string DeviceManager::get_user_last_machine() const
|
||||
{
|
||||
if (Slic3r::GUI::wxGetApp().app_config) {
|
||||
const auto& user_last_machine = Slic3r::GUI::wxGetApp().app_config->get("user_last_selected_machine");
|
||||
if (AppConfig* config = get_app_config()) {
|
||||
const auto& user_last_machine = config->get("user_last_selected_machine");
|
||||
if (!user_last_machine.empty()) {
|
||||
return user_last_machine;
|
||||
} else if (m_agent) {
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Slic3r
|
||||
struct BBLocalMachine;
|
||||
class MachineObject;
|
||||
class NetworkAgent;
|
||||
class AppConfig;
|
||||
|
||||
namespace GUI {
|
||||
class GUI_App;
|
||||
@@ -24,6 +25,7 @@ class DeviceManager
|
||||
friend class DeviceManagerRefresher;
|
||||
private:
|
||||
NetworkAgent* m_agent{ nullptr };
|
||||
AppConfig* m_app_config{ nullptr };
|
||||
DeviceManagerRefresher* m_refresher{ nullptr };
|
||||
|
||||
bool m_enable_mutil_machine = false;
|
||||
@@ -35,11 +37,13 @@ private:
|
||||
std::map<std::string, MachineObject*> userMachineList; /* dev_id -> MachineObject* cloudMachine of User */
|
||||
|
||||
public:
|
||||
DeviceManager(NetworkAgent* agent = nullptr);
|
||||
DeviceManager(NetworkAgent* agent = nullptr, bool enable_refresher = true,
|
||||
AppConfig* app_config = nullptr);
|
||||
~DeviceManager();
|
||||
|
||||
public:
|
||||
NetworkAgent* get_agent() const { return m_agent; }
|
||||
AppConfig* get_app_config() const;
|
||||
void set_agent(NetworkAgent* agent);
|
||||
|
||||
void start_refresher();
|
||||
@@ -121,6 +125,7 @@ private:
|
||||
|
||||
void keep_alive();
|
||||
void check_pushing();
|
||||
std::string get_current_cloud_provider() const;
|
||||
|
||||
void OnMachineBindStateChanged(MachineObject* obj, const std::string& new_state);
|
||||
void OnSelectedMachineChanged(const std::string& pre_dev_id, const std::string& new_dev_id);
|
||||
@@ -133,14 +138,15 @@ public:
|
||||
std::string connection_type, std::string bind_state, std::string version,
|
||||
std::string access_code);
|
||||
static void update_local_machine(const MachineObject& m);
|
||||
static void update_local_machine(const MachineObject& m, AppConfig* config);
|
||||
};
|
||||
|
||||
class DeviceManagerRefresher : public wxObject
|
||||
{
|
||||
wxTimer* m_timer{ nullptr };
|
||||
int m_timer_interval_msec = 5000;
|
||||
wxTimer* m_timer{nullptr};
|
||||
int m_timer_interval_msec = 5000;
|
||||
|
||||
DeviceManager* m_manager{ nullptr };
|
||||
DeviceManager* m_manager{nullptr};
|
||||
|
||||
public:
|
||||
DeviceManagerRefresher(DeviceManager* manger);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ReleaseNote.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <charconv>
|
||||
#include <codecvt>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
@@ -477,7 +478,7 @@ void MachineObject::set_access_code(std::string code, bool only_refresh)
|
||||
{
|
||||
this->access_code = code;
|
||||
if (only_refresh) {
|
||||
AppConfig* config = GUI::wxGetApp().app_config;
|
||||
AppConfig* config = m_manager ? m_manager->get_app_config() : GUI::wxGetApp().app_config;
|
||||
if (config) {
|
||||
if (is_lan_mode_printer()) {
|
||||
// why: LAN codes are scoped via BBLocalMachine::access_code, keyed by dev_id and
|
||||
@@ -490,7 +491,7 @@ void MachineObject::set_access_code(std::string code, bool only_refresh)
|
||||
// fresh from the cloud API's current response, so there's no cross-agent leakage
|
||||
// risk to guard against there.
|
||||
if (!code.empty()) {
|
||||
DeviceManager::update_local_machine(*this);
|
||||
DeviceManager::update_local_machine(*this, config);
|
||||
} else {
|
||||
// Only patch an existing record's code - don't persist a brand-new
|
||||
// never-bound entry just because set_access_code("") was called on it.
|
||||
@@ -2603,9 +2604,14 @@ void MachineObject::set_print_state(std::string status)
|
||||
// why: printer agents can report progress without BBL cloud task identity.
|
||||
void MachineObject::update_print_progress(const json& value)
|
||||
{
|
||||
if (value.is_string())
|
||||
mc_print_percent = stoi(value.get<std::string>());
|
||||
else if (value.is_number_integer())
|
||||
if (value.is_string()) {
|
||||
const std::string progress = value.get<std::string>();
|
||||
int parsed_progress;
|
||||
const auto result = std::from_chars(progress.data(), progress.data() + progress.size(), parsed_progress);
|
||||
if (result.ec != std::errc{} || result.ptr != progress.data() + progress.size())
|
||||
return;
|
||||
mc_print_percent = parsed_progress;
|
||||
} else if (value.is_number_integer())
|
||||
mc_print_percent = value.get<int>();
|
||||
else
|
||||
return;
|
||||
@@ -4650,7 +4656,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
|
||||
if (diff.count() > 10.0f) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "parse_json timeout = " << diff.count();
|
||||
}
|
||||
DeviceManager::update_local_machine(*this);
|
||||
DeviceManager::update_local_machine(*this, m_manager ? m_manager->get_app_config() : GUI::wxGetApp().app_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+14
-12
@@ -2383,19 +2383,21 @@ GUI_App::~GUI_App()
|
||||
|
||||
bool GUI_App::is_blocking_printing(MachineObject *obj_)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
if (obj_ == nullptr) {
|
||||
obj_ = dev->get_selected_machine();
|
||||
}
|
||||
|
||||
if (!obj_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
std::string source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
const std::string source_model = preset_bundle
|
||||
? preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle)
|
||||
: std::string();
|
||||
return is_blocking_printing(obj_, source_model);
|
||||
}
|
||||
|
||||
bool GUI_App::is_blocking_printing(MachineObject *obj_, const std::string& source_model)
|
||||
{
|
||||
DeviceManager *dev = getDeviceManager();
|
||||
if (!dev) return true;
|
||||
if (obj_ == nullptr)
|
||||
obj_ = dev->get_selected_machine();
|
||||
if (!obj_)
|
||||
return false;
|
||||
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
}
|
||||
|
||||
@@ -368,6 +368,7 @@ public:
|
||||
EAppMode get_app_mode() const { return m_app_mode; }
|
||||
Slic3r::DeviceManager* getDeviceManager() { return m_device_manager; }
|
||||
bool is_blocking_printing(MachineObject *obj_ = nullptr);
|
||||
bool is_blocking_printing(MachineObject *obj_, const std::string& source_model);
|
||||
Slic3r::TaskManager* getTaskManager() { return m_task_manager; }
|
||||
HMSQuery* get_hms_query() { return hms_query; }
|
||||
NetworkAgent* getAgent() { return m_agent; }
|
||||
|
||||
@@ -261,7 +261,7 @@ void MonitorPanel::msw_rescale()
|
||||
|
||||
void MonitorPanel::select_machine(std::string machine_sn)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: MonitorPanel::select_machine queueing machine_sn=" << machine_sn;
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: MonitorPanel::select_machine queueing machine_sn=" << machine_sn;
|
||||
wxCommandEvent *event = new wxCommandEvent(wxEVT_COMMAND_CHOICE_SELECTED);
|
||||
event->SetString(machine_sn);
|
||||
wxQueueEvent(this, event);
|
||||
@@ -280,7 +280,7 @@ void MonitorPanel::on_select_printer(wxCommandEvent& event)
|
||||
{
|
||||
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
const std::string requested_dev_id = event.GetString().ToStdString();
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: MonitorPanel::on_select_printer requested_dev_id="
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: MonitorPanel::on_select_printer requested_dev_id="
|
||||
<< requested_dev_id << " device_manager=" << (dev ? "set" : "null");
|
||||
if (!dev) return;
|
||||
|
||||
@@ -289,7 +289,7 @@ void MonitorPanel::on_select_printer(wxCommandEvent& event)
|
||||
}
|
||||
|
||||
const bool selected = dev->set_selected_machine(requested_dev_id);
|
||||
BOOST_LOG_TRIVIAL(info) << "Orca diagnostic: MonitorPanel::on_select_printer set_selected_machine result="
|
||||
BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: MonitorPanel::on_select_printer set_selected_machine result="
|
||||
<< selected << " selected_dev_id="
|
||||
<< (dev->get_selected_machine() ? dev->get_selected_machine()->get_dev_id() : "<null>");
|
||||
if (!selected)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "DeviceCore/DevConfigUtil.h"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
@@ -52,7 +51,7 @@ void DeviceItem::sync_state()
|
||||
state_printable = 6;
|
||||
}
|
||||
|
||||
if (is_blocking_printing(obj_)) {
|
||||
if (wxGetApp().is_blocking_printing(obj_)) {
|
||||
state_printable = 5;
|
||||
}
|
||||
|
||||
@@ -105,18 +104,6 @@ void DeviceItem::unselected()
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceItem::is_blocking_printing(MachineObject* obj_)
|
||||
{
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
std::string source_model = "";
|
||||
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
}
|
||||
|
||||
void DeviceItem::update_item(const DeviceItem* item)
|
||||
{
|
||||
// Except for the selected status, everything else is updated
|
||||
|
||||
@@ -59,7 +59,6 @@ public:
|
||||
|
||||
void selected();
|
||||
void unselected();
|
||||
bool is_blocking_printing(MachineObject* obj_);
|
||||
void update_item(const DeviceItem* item);
|
||||
};
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
void add_with_checkbox(PrintDialogStatus state, wxString msg, wxString checkbox_label, bool checked, std::function<void(bool)> checkbox_callback);
|
||||
static ::std::string get_print_status_info(PrintDialogStatus status);
|
||||
|
||||
wxString get_pre_state_msg(PrintDialogStatus status);
|
||||
static wxString get_pre_state_msg(PrintDialogStatus status);
|
||||
static bool is_error(PrintDialogStatus status) { return (PrintStatusErrorBegin < status) && (PrintStatusErrorEnd > status); };
|
||||
static bool is_error_printer(PrintDialogStatus status) { return (PrintStatusPrinterErrorBegin < status) && (PrintStatusPrinterErrorEnd > status); };
|
||||
static bool is_error_filament(PrintDialogStatus status) { return (PrintStatusFilamentErrorBegin < status) && (PrintStatusFilamentErrorEnd > status); };
|
||||
|
||||
@@ -2518,23 +2518,13 @@ void SelectMachineDialog::on_cancel(wxCloseEvent &event)
|
||||
|
||||
bool SelectMachineDialog::is_blocking_printing(MachineObject* obj_)
|
||||
{
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
auto target_model = obj_->printer_type;
|
||||
std::string source_model = "";
|
||||
if (m_print_type == PrintFromType::FROM_NORMAL)
|
||||
return wxGetApp().is_blocking_printing(obj_);
|
||||
|
||||
if (m_print_type == PrintFromType::FROM_NORMAL) {
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
|
||||
|
||||
}else if (m_print_type == PrintFromType::FROM_SDCARD_VIEW) {
|
||||
if (m_required_data_plate_data_list.size() > 0) {
|
||||
source_model = m_required_data_plate_data_list[m_print_plate_idx]->printer_model_id;
|
||||
}
|
||||
}
|
||||
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
std::string source_model;
|
||||
if (m_print_type == PrintFromType::FROM_SDCARD_VIEW && !m_required_data_plate_data_list.empty())
|
||||
source_model = m_required_data_plate_data_list[m_print_plate_idx]->printer_model_id;
|
||||
return wxGetApp().is_blocking_printing(obj_, source_model);
|
||||
}
|
||||
|
||||
static std::unordered_set<int> _get_used_nozzle_idxes()
|
||||
|
||||
@@ -738,7 +738,7 @@ void SendMultiMachinePage::on_send(wxCommandEvent& event)
|
||||
|
||||
if (obj && obj->is_online() && !obj->can_abort() && !obj->is_in_upgrading() && it->second->get_state_selected() == 1 && it->second->state_printable <= 2) {
|
||||
|
||||
if (!it->second->is_blocking_printing(obj)) {
|
||||
if (!wxGetApp().is_blocking_printing(obj)) {
|
||||
PrintParams params = request_params(obj);
|
||||
print_params.push_back(params);
|
||||
}
|
||||
|
||||
@@ -1277,7 +1277,7 @@ void SendToPrinterDialog::update_show_status()
|
||||
reset_timeout();
|
||||
|
||||
// reading done
|
||||
if (is_blocking_printing(obj_)) {
|
||||
if (wxGetApp().is_blocking_printing(obj_)) {
|
||||
show_status(PrintDialogStatus::PrintStatusUnsupportedPrinter);
|
||||
return;
|
||||
}
|
||||
@@ -1342,16 +1342,6 @@ void SendToPrinterDialog::update_show_status()
|
||||
}
|
||||
}
|
||||
|
||||
bool SendToPrinterDialog::is_blocking_printing(MachineObject* obj_)
|
||||
{
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
auto source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
}
|
||||
|
||||
void SendToPrinterDialog::Enable_Refresh_Button(bool en)
|
||||
{
|
||||
if (!en) {
|
||||
|
||||
@@ -181,7 +181,6 @@ public:
|
||||
void reset_timeout();
|
||||
void update_user_printer();
|
||||
void update_show_status();
|
||||
bool is_blocking_printing(MachineObject* obj_);
|
||||
void prepare(int print_plate_idx);
|
||||
void check_focus(wxWindow* window);
|
||||
void check_fcous_state(wxWindow* window);
|
||||
|
||||
@@ -1742,6 +1742,8 @@ void SyncAmsInfoDialog::show_status(PrintDialogStatus status, std::vector<wxStri
|
||||
update_print_status_msg(msg_text, true, true);
|
||||
} else if (status == PrintDialogStatus::PrintStatusAmsMappingSuccess) {
|
||||
update_print_status_msg(wxEmptyString, false, false);
|
||||
} else if (status == PrintDialogStatus::PrintStatusOptionalPrinterModel) {
|
||||
update_print_status_msg(PrePrintChecker::get_pre_state_msg(PrintDialogStatus::PrintStatusOptionalPrinterModel), true, true);
|
||||
} else if (status == PrintDialogStatus::PrintStatusAmsMappingInvalid) {
|
||||
update_print_status_msg(wxEmptyString, true, false);
|
||||
} else if (status == PrintDialogStatus::PrintStatusAmsMappingMixInvalid) {
|
||||
@@ -1861,19 +1863,13 @@ void SyncAmsInfoDialog::on_cancel(wxCloseEvent &event)
|
||||
|
||||
bool SyncAmsInfoDialog::is_blocking_printing(MachineObject *obj_)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return true;
|
||||
std::string source_model = "";
|
||||
if (m_print_type == PrintFromType::FROM_NORMAL)
|
||||
return wxGetApp().is_blocking_printing(obj_);
|
||||
|
||||
if (m_print_type == PrintFromType::FROM_NORMAL) {
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
source_model = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
|
||||
} else if (m_print_type == PrintFromType::FROM_SDCARD_VIEW) {
|
||||
if (m_required_data_plate_data_list.size() > 0) { source_model = m_required_data_plate_data_list[m_print_plate_idx]->printer_model_id; }
|
||||
}
|
||||
|
||||
return !DevPrinterConfigUtil::is_printer_model_compatible(source_model, *obj_);
|
||||
std::string source_model;
|
||||
if (m_print_type == PrintFromType::FROM_SDCARD_VIEW && !m_required_data_plate_data_list.empty())
|
||||
source_model = m_required_data_plate_data_list[m_print_plate_idx]->printer_model_id;
|
||||
return wxGetApp().is_blocking_printing(obj_, source_model);
|
||||
}
|
||||
|
||||
bool SyncAmsInfoDialog::is_same_nozzle_type(std::string &filament_type, NozzleType &tag_nozzle_type)
|
||||
@@ -2263,6 +2259,18 @@ void SyncAmsInfoDialog::update_show_status()
|
||||
|
||||
reset_timeout();
|
||||
|
||||
bool has_optional_printer_model = DevPrinterConfigUtil::is_optional_printer_model_id(obj_->printer_type);
|
||||
if (m_print_type == PrintFromType::FROM_NORMAL) {
|
||||
if (PresetBundle *preset_bundle = wxGetApp().preset_bundle) {
|
||||
has_optional_printer_model = has_optional_printer_model ||
|
||||
DevPrinterConfigUtil::is_optional_printer_model_id(
|
||||
preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle));
|
||||
}
|
||||
} else if (m_print_type == PrintFromType::FROM_SDCARD_VIEW && !m_required_data_plate_data_list.empty()) {
|
||||
has_optional_printer_model = has_optional_printer_model ||
|
||||
DevPrinterConfigUtil::is_optional_printer_model_id(m_required_data_plate_data_list[m_print_plate_idx]->printer_model_id);
|
||||
}
|
||||
|
||||
if (!obj_->GetConfig()->SupportPrintAllPlates() && m_print_plate_idx == PLATE_ALL_IDX) {
|
||||
show_status(PrintDialogStatus::PrintStatusNotSupportedPrintAll);
|
||||
return;
|
||||
@@ -2356,6 +2364,9 @@ void SyncAmsInfoDialog::update_show_status()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_optional_printer_model)
|
||||
show_status(PrintDialogStatus::PrintStatusOptionalPrinterModel);
|
||||
}
|
||||
|
||||
bool SyncAmsInfoDialog::has_timelapse_warning()
|
||||
|
||||
@@ -4,13 +4,23 @@
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
WebMediaController::WebMediaController(wxWebView* webview) : m_webview(webview)
|
||||
namespace {
|
||||
|
||||
void initialize_webview(wxWebView* webview)
|
||||
{
|
||||
if (!m_webview)
|
||||
if (!webview)
|
||||
return;
|
||||
|
||||
m_webview->SetBackgroundColour(*wxBLACK);
|
||||
m_webview->SetPage("<html><head><style>html,body{margin:0;height:100%;background:#000;}</style></head><body></body></html>", "");
|
||||
webview->SetBackgroundColour(*wxBLACK);
|
||||
webview->SetPage("<html><head><style>html,body{margin:0;height:100%;background:#000;}</style></head><body></body></html>", "");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WebMediaController::WebMediaController(wxWebView* webview)
|
||||
: m_webview(webview)
|
||||
{
|
||||
initialize_webview(m_webview);
|
||||
}
|
||||
|
||||
void WebMediaController::Load(wxURI url)
|
||||
@@ -71,6 +81,8 @@ void WebMediaController::Stop()
|
||||
if (m_webview) {
|
||||
m_webview->RunScript("if(typeof stopCameraRefresh==='function') stopCameraRefresh();");
|
||||
m_webview->Stop();
|
||||
m_webview->SetPage("", "about:blank");
|
||||
m_webview->ClearHistory();
|
||||
}
|
||||
m_url.clear();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
wxWebView* m_webview;
|
||||
wxWebView* m_webview = nullptr;
|
||||
std::string m_url;
|
||||
CameraStreamMode m_stream_mode = CameraStreamMode::http;
|
||||
};
|
||||
|
||||
@@ -950,11 +950,11 @@ std::string NetworkAgent::get_user_selected_machine()
|
||||
|
||||
int NetworkAgent::set_user_selected_machine(std::string dev_id)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "NetworkAgent::set_user_selected_machine: dev_id=" << dev_id
|
||||
BOOST_LOG_TRIVIAL(trace) << "NetworkAgent::set_user_selected_machine: dev_id=" << dev_id
|
||||
<< " printer_agent=" << (m_printer_agent ? m_printer_agent->get_agent_info().id : "<null>");
|
||||
if (m_printer_agent) {
|
||||
const int result = m_printer_agent->set_user_selected_machine(dev_id);
|
||||
BOOST_LOG_TRIVIAL(info) << "NetworkAgent::set_user_selected_machine: result=" << result;
|
||||
BOOST_LOG_TRIVIAL(trace) << "NetworkAgent::set_user_selected_machine: result=" << result;
|
||||
return result;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(warning) << "NetworkAgent::set_user_selected_machine: no printer agent";
|
||||
@@ -977,11 +977,11 @@ int NetworkAgent::stop_subscribe(std::string module)
|
||||
|
||||
int NetworkAgent::add_subscribe(std::vector<std::string> dev_list)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "NetworkAgent::add_subscribe: count=" << dev_list.size()
|
||||
BOOST_LOG_TRIVIAL(trace) << "NetworkAgent::add_subscribe: count=" << dev_list.size()
|
||||
<< " printer_agent=" << (m_printer_agent ? m_printer_agent->get_agent_info().id : "<null>");
|
||||
if (m_printer_agent) {
|
||||
const int result = m_printer_agent->add_subscribe(std::move(dev_list));
|
||||
BOOST_LOG_TRIVIAL(info) << "NetworkAgent::add_subscribe: result=" << result;
|
||||
BOOST_LOG_TRIVIAL(trace) << "NetworkAgent::add_subscribe: result=" << result;
|
||||
return result;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(warning) << "NetworkAgent::add_subscribe: no printer agent";
|
||||
@@ -990,11 +990,11 @@ int NetworkAgent::add_subscribe(std::vector<std::string> dev_list)
|
||||
|
||||
int NetworkAgent::del_subscribe(std::vector<std::string> dev_list)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "NetworkAgent::del_subscribe: count=" << dev_list.size()
|
||||
BOOST_LOG_TRIVIAL(trace) << "NetworkAgent::del_subscribe: count=" << dev_list.size()
|
||||
<< " printer_agent=" << (m_printer_agent ? m_printer_agent->get_agent_info().id : "<null>");
|
||||
if (m_printer_agent) {
|
||||
const int result = m_printer_agent->del_subscribe(std::move(dev_list));
|
||||
BOOST_LOG_TRIVIAL(info) << "NetworkAgent::del_subscribe: result=" << result;
|
||||
BOOST_LOG_TRIVIAL(trace) << "NetworkAgent::del_subscribe: result=" << result;
|
||||
return result;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(warning) << "NetworkAgent::del_subscribe: no printer agent";
|
||||
|
||||
+26
-20
@@ -25,6 +25,12 @@
|
||||
} ORCA_PY_AGENT_CATCH(name) \
|
||||
return printer_agent_failure<ret>()
|
||||
|
||||
#define ORCA_PY_AGENT_OVERRIDE_DEFAULT(ret, name, ...) \
|
||||
try { \
|
||||
ORCA_PY_OVERRIDE_AUDITED([] {}, PYBIND11_OVERRIDE, ret, PrinterAgentPluginCapability, name, ##__VA_ARGS__); \
|
||||
} ORCA_PY_AGENT_CATCH(name) \
|
||||
return printer_agent_failure<ret>()
|
||||
|
||||
namespace Slic3r {
|
||||
// NetworkAgent's no-agent answer: -1 for a status code, the empty value (false, "", none) otherwise.
|
||||
template<typename T> T printer_agent_failure()
|
||||
@@ -67,57 +73,57 @@ public:
|
||||
|
||||
int command_ams_refresh_rfid(std::string dev_id, std::string tray_id, int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_ams_refresh_rfid, dev_id, tray_id, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_ams_refresh_rfid, dev_id, tray_id, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_ams_calibrate(std::string dev_id, int ams_id, int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_ams_calibrate, dev_id, ams_id, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_ams_calibrate, dev_id, ams_id, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_ams_select_tray(std::string dev_id, std::string tray_id, int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_ams_select_tray, dev_id, tray_id, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_ams_select_tray, dev_id, tray_id, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_start_camera(std::string dev_id) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_start_camera, dev_id);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_start_camera, dev_id);
|
||||
}
|
||||
|
||||
int command_xyz_abs(std::string dev_id, int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_xyz_abs, dev_id, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_xyz_abs, dev_id, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_auto_leveling(std::string dev_id, int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_auto_leveling, dev_id, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_auto_leveling, dev_id, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_go_home(std::string dev_id, bool is_printing, bool supports_mqtt_homing,
|
||||
int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_go_home, dev_id, is_printing, supports_mqtt_homing, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_go_home, dev_id, is_printing, supports_mqtt_homing, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_set_bed(std::string dev_id, int temp, bool supports_mqtt_bed_ctrl,
|
||||
int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_set_bed, dev_id, temp, supports_mqtt_bed_ctrl, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_set_bed, dev_id, temp, supports_mqtt_bed_ctrl, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_set_nozzle(std::string dev_id, int temp, int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_set_nozzle, dev_id, temp, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_set_nozzle, dev_id, temp, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
int command_axis_control(std::string dev_id, std::string axis, double unit, double input_val,
|
||||
int speed, bool is_core_xy, bool supports_mqtt_axis_control,
|
||||
int sequence_id, bool lan_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, command_axis_control, dev_id, axis, unit, input_val, speed,
|
||||
is_core_xy, supports_mqtt_axis_control, sequence_id, lan_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, command_axis_control, dev_id, axis, unit, input_val, speed,
|
||||
is_core_xy, supports_mqtt_axis_control, sequence_id, lan_mode);
|
||||
}
|
||||
|
||||
bool start_discovery(bool start, bool sending) override
|
||||
@@ -153,22 +159,22 @@ public:
|
||||
|
||||
FilamentSyncMode get_filament_sync_mode() const override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(FilamentSyncMode, get_filament_sync_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(FilamentSyncMode, get_filament_sync_mode);
|
||||
}
|
||||
|
||||
CameraStreamMode get_camera_stream_mode() const override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(CameraStreamMode, get_camera_stream_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(CameraStreamMode, get_camera_stream_mode);
|
||||
}
|
||||
|
||||
std::string get_camera_url() const override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(std::string, get_camera_url);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(std::string, get_camera_url);
|
||||
}
|
||||
|
||||
bool fetch_filament_info(std::string dev_id, FilamentSyncMode sync_mode) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(bool, fetch_filament_info, dev_id, sync_mode);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(bool, fetch_filament_info, dev_id, sync_mode);
|
||||
}
|
||||
|
||||
int check_cert() override
|
||||
@@ -178,7 +184,7 @@ public:
|
||||
|
||||
void install_device_cert(std::string dev_id, bool lan_only) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(void, install_device_cert, dev_id, lan_only);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(void, install_device_cert, dev_id, lan_only);
|
||||
}
|
||||
|
||||
int ping_bind(std::string ping_code) override
|
||||
@@ -213,7 +219,7 @@ public:
|
||||
|
||||
int get_hms_snapshot(std::string dev_id, std::string file_name, std::function<void(std::string, int)> callback) override
|
||||
{
|
||||
ORCA_PY_AGENT_OVERRIDE(int, get_hms_snapshot, dev_id, file_name, callback);
|
||||
ORCA_PY_AGENT_OVERRIDE_DEFAULT(int, get_hms_snapshot, dev_id, file_name, callback);
|
||||
}
|
||||
|
||||
int set_server_callback(OnServerErrFn fn) override
|
||||
@@ -264,8 +270,8 @@ public:
|
||||
// request_bind_ticket returns its ticket through a std::string* out-param, which pybind11
|
||||
// cannot marshal back through a plain override. We dispatch manually: the Python plugin
|
||||
// returns a (result, ticket) tuple, which we unpack into the int result and the out-param.
|
||||
// Not required to be implemented, so a missing override falls back to the base default
|
||||
// instead of failing, mirroring what PYBIND11_OVERRIDE does for the other optional methods.
|
||||
// Not required to be implemented, so a missing override answers with the same failure value
|
||||
// as the other printer-agent operations. Leave the out-param untouched on failure.
|
||||
int request_bind_ticket(std::string* ticket) override
|
||||
{
|
||||
try {
|
||||
@@ -277,7 +283,7 @@ public:
|
||||
pybind11::function override =
|
||||
pybind11::get_override(static_cast<const PrinterAgentPluginCapability*>(this), "request_bind_ticket");
|
||||
if (!override)
|
||||
return PrinterAgentPluginCapability::request_bind_ticket(ticket);
|
||||
return printer_agent_failure<int>();
|
||||
try {
|
||||
pybind11::tuple result = override().cast<pybind11::tuple>();
|
||||
if (ticket)
|
||||
|
||||
@@ -6,6 +6,8 @@ add_executable(${_TEST_NAME}_tests
|
||||
test_dev_mapping.cpp
|
||||
test_filament_bitmap_utils.cpp
|
||||
test_device_progress.cpp
|
||||
test_device_manager_integration.cpp
|
||||
test_web_media_controller.cpp
|
||||
test_network_versions.cpp
|
||||
test_action_source.cpp
|
||||
test_plugin_host_api.cpp
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <slic3r/GUI/DeviceCore/DevManager.h>
|
||||
#include <slic3r/GUI/DeviceManager.hpp>
|
||||
#include <libslic3r/AppConfig.hpp>
|
||||
#include <slic3r/Utils/NetworkAgent.hpp>
|
||||
#include <slic3r/Utils/OrcaCloudServiceAgent.hpp>
|
||||
#include <slic3r/Utils/OrcaPrinterAgent.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using namespace Slic3r;
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace {
|
||||
|
||||
class StubCloudAgent final : public OrcaCloudServiceAgent
|
||||
{
|
||||
public:
|
||||
StubCloudAgent() : OrcaCloudServiceAgent("") {}
|
||||
|
||||
int get_user_print_info(unsigned int* http_code, std::string* http_body) override
|
||||
{
|
||||
if (http_code)
|
||||
*http_code = 200;
|
||||
if (http_body)
|
||||
*http_body = R"({"devices":[]})";
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string get_user_name() override { return "integration-test-user"; }
|
||||
};
|
||||
|
||||
class TestPrinterAgent final : public OrcaPrinterAgent
|
||||
{
|
||||
public:
|
||||
explicit TestPrinterAgent(std::string id)
|
||||
: OrcaPrinterAgent(""), m_info{std::move(id), "Integration Test Agent", "1.0", "test agent"}
|
||||
{
|
||||
}
|
||||
|
||||
AgentInfo get_agent_info() override { return m_info; }
|
||||
|
||||
private:
|
||||
AgentInfo m_info;
|
||||
};
|
||||
|
||||
struct ScopedAppConfig
|
||||
{
|
||||
AppConfig config;
|
||||
};
|
||||
|
||||
std::string machine_list_response(const std::string& provider, const std::string& agent_id,
|
||||
std::uint64_t generation, const std::string& name)
|
||||
{
|
||||
json machine;
|
||||
machine["dev_id"] = "integration-device";
|
||||
machine["dev_name"] = name;
|
||||
machine["dev_online"] = true;
|
||||
machine["task_status"] = "idle";
|
||||
|
||||
json response;
|
||||
response["provider"] = provider;
|
||||
response["agent_id"] = agent_id;
|
||||
response["generation"] = generation;
|
||||
response["devices"] = json::array({machine});
|
||||
return response.dump();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Network agent stamps user-machine responses with request context", "[DeviceManager][integration]")
|
||||
{
|
||||
auto cloud = std::make_shared<StubCloudAgent>();
|
||||
NetworkAgent network(cloud, nullptr);
|
||||
network.set_printer_agent(std::make_shared<TestPrinterAgent>("integration-agent-a"));
|
||||
|
||||
const std::uint64_t generation_before = network.get_user_machine_list_generation();
|
||||
unsigned int http_code = 0;
|
||||
std::string body;
|
||||
REQUIRE(network.get_user_print_info(&http_code, &body, ORCA_CLOUD_PROVIDER) == 0);
|
||||
|
||||
const json response = json::parse(body);
|
||||
CHECK(http_code == 200);
|
||||
CHECK(response["provider"] == ORCA_CLOUD_PROVIDER);
|
||||
CHECK(response["agent_id"] == "integration-agent-a");
|
||||
CHECK(response["generation"] == generation_before + 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Device manager ignores stale cloud machine responses", "[DeviceManager][integration]")
|
||||
{
|
||||
ScopedAppConfig app_config;
|
||||
NetworkAgent network(nullptr, std::make_shared<TestPrinterAgent>("integration-agent"));
|
||||
network.set_printer_agent(std::make_shared<TestPrinterAgent>("integration-agent"));
|
||||
DeviceManager manager(&network, false, &app_config.config);
|
||||
|
||||
const std::uint64_t current_generation = network.get_user_machine_list_generation();
|
||||
manager.parse_user_print_info(machine_list_response(ORCA_CLOUD_PROVIDER, "integration-agent",
|
||||
current_generation, "Fresh name"));
|
||||
|
||||
auto machines = manager.get_user_machinelist();
|
||||
REQUIRE(machines.size() == 1);
|
||||
REQUIRE(machines.at("integration-device") != nullptr);
|
||||
CHECK(machines.at("integration-device")->get_dev_name() == "Fresh name");
|
||||
|
||||
manager.parse_user_print_info(machine_list_response(BBL_CLOUD_PROVIDER, "integration-agent",
|
||||
current_generation, "Stale provider"));
|
||||
manager.parse_user_print_info(machine_list_response(ORCA_CLOUD_PROVIDER, "other-agent",
|
||||
current_generation, "Stale agent"));
|
||||
manager.parse_user_print_info(machine_list_response(ORCA_CLOUD_PROVIDER, "integration-agent",
|
||||
current_generation + 1, "Stale generation"));
|
||||
|
||||
machines = manager.get_user_machinelist();
|
||||
REQUIRE(machines.size() == 1);
|
||||
CHECK(machines.at("integration-device")->get_dev_name() == "Fresh name");
|
||||
}
|
||||
|
||||
TEST_CASE("Device manager filters and rehomes devices by printer-agent ownership", "[DeviceManager][integration]")
|
||||
{
|
||||
ScopedAppConfig app_config;
|
||||
auto agent_a = std::make_shared<TestPrinterAgent>("integration-agent-a");
|
||||
auto agent_b = std::make_shared<TestPrinterAgent>("integration-agent-b");
|
||||
NetworkAgent network(nullptr, agent_a);
|
||||
DeviceManager manager(&network, false, &app_config.config);
|
||||
|
||||
BBLocalMachine machine;
|
||||
machine.dev_id = "integration-lan-device";
|
||||
machine.dev_name = "Integration LAN device";
|
||||
machine.dev_ip = "192.0.2.10";
|
||||
machine.printer_type = "C11";
|
||||
|
||||
MachineObject* object = manager.insert_local_device(machine, "lan", "free", "", "access-code");
|
||||
REQUIRE(object != nullptr);
|
||||
CHECK(object->printer_agent_id == "integration-agent-a");
|
||||
CHECK(manager.get_my_machine_list("integration-agent-a").count(machine.dev_id) == 1);
|
||||
CHECK(manager.get_my_machine_list("integration-agent-b").empty());
|
||||
|
||||
network.set_printer_agent(agent_b);
|
||||
CHECK(manager.get_my_machine_list("integration-agent-b").empty());
|
||||
|
||||
manager.on_machine_alive(R"({
|
||||
"dev_name":"Rediscovered device",
|
||||
"dev_id":"integration-lan-device",
|
||||
"dev_ip":"192.0.2.10",
|
||||
"dev_type":"C11",
|
||||
"dev_signal":"strong",
|
||||
"connect_type":"lan",
|
||||
"bind_state":"free"
|
||||
})");
|
||||
|
||||
CHECK(object->printer_agent_id == "integration-agent-b");
|
||||
CHECK(manager.get_my_machine_list("integration-agent-a").empty());
|
||||
CHECK(manager.get_my_machine_list("integration-agent-b").count(machine.dev_id) == 1);
|
||||
}
|
||||
@@ -115,7 +115,7 @@ TEST_CASE("Malformed string progress leaves a fresh machine unchanged", "[Device
|
||||
MachineObject machine(nullptr, nullptr, "test", "test-device", "127.0.0.1");
|
||||
REQUIRE(machine.subtask_ == nullptr);
|
||||
|
||||
CHECK_THROWS_AS(machine.update_print_progress(json("not-a-percent")), std::invalid_argument);
|
||||
CHECK_NOTHROW(machine.update_print_progress(json("not-a-percent")));
|
||||
CHECK(machine.mc_print_percent == 0);
|
||||
CHECK(machine.subtask_ == nullptr);
|
||||
}
|
||||
|
||||
@@ -115,6 +115,22 @@ TEST_CASE("A printer agent that omits its operations answers like a missing agen
|
||||
check_answers_like_no_agent(*agent);
|
||||
}
|
||||
|
||||
TEST_CASE("A printer agent uses IPrinterAgent defaults for omitted commands", "[PluginPrinterAgent][Python]")
|
||||
{
|
||||
ScopedPluginManager plugin_system;
|
||||
if (!plugin_system.initialized)
|
||||
SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error());
|
||||
py::gil_scoped_acquire gil;
|
||||
|
||||
auto agent = make_agent(" def send_message(self, dev_id, json_str, qos, flag): return 7\n"
|
||||
" def send_message_to_printer(self, dev_id, json_str, qos, flag): return 8\n");
|
||||
REQUIRE(agent.agent);
|
||||
|
||||
CHECK(agent->command_xyz_abs("dev", 1, false) == 7);
|
||||
CHECK(agent->command_set_nozzle("dev", 200, 2, true) == 8);
|
||||
CHECK(agent->command_ams_refresh_rfid("dev", "tray", 3, false) == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
TEST_CASE("A printer agent operation returning the wrong type answers like a missing agent", "[PluginPrinterAgent][Python]")
|
||||
{
|
||||
ScopedPluginManager plugin_system;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <slic3r/GUI/WebMediaController.hpp>
|
||||
|
||||
#include <wx/webview.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
namespace {
|
||||
|
||||
class StubWebView final : public wxWebView
|
||||
{
|
||||
public:
|
||||
bool SetBackgroundColour(const wxColour&) override
|
||||
{
|
||||
events.emplace_back("background");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Create(wxWindow*, wxWindowID, const wxString&, const wxPoint&, const wxSize&, long, const wxString&) override { return true; }
|
||||
wxString GetCurrentTitle() const override { return {}; }
|
||||
wxString GetCurrentURL() const override { return {}; }
|
||||
bool IsBusy() const override { return false; }
|
||||
bool IsEditable() const override { return false; }
|
||||
void LoadURL(const wxString& url) override
|
||||
{
|
||||
events.emplace_back("url");
|
||||
loaded_url = url.ToStdString();
|
||||
}
|
||||
void Print() override {}
|
||||
void RegisterHandler(wxSharedPtr<wxWebViewHandler>) override {}
|
||||
void Reload(wxWebViewReloadFlags) override {}
|
||||
void SetEditable(bool) override {}
|
||||
void Stop() override { events.emplace_back("stop"); }
|
||||
bool CanGoBack() const override { return false; }
|
||||
bool CanGoForward() const override { return false; }
|
||||
void GoBack() override {}
|
||||
void GoForward() override {}
|
||||
void ClearHistory() override { events.emplace_back("history"); }
|
||||
void EnableHistory(bool) override {}
|
||||
wxVector<wxSharedPtr<wxWebViewHistoryItem>> GetBackwardHistory() override { return {}; }
|
||||
wxVector<wxSharedPtr<wxWebViewHistoryItem>> GetForwardHistory() override { return {}; }
|
||||
void LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem>) override {}
|
||||
bool CanSetZoomType(wxWebViewZoomType) const override { return false; }
|
||||
float GetZoomFactor() const override { return 1.0f; }
|
||||
wxWebViewZoomType GetZoomType() const override { return wxWEBVIEW_ZOOM_TYPE_LAYOUT; }
|
||||
void SetZoomFactor(float) override {}
|
||||
void SetZoomType(wxWebViewZoomType) override {}
|
||||
bool CanUndo() const override { return false; }
|
||||
bool CanRedo() const override { return false; }
|
||||
void Undo() override {}
|
||||
void Redo() override {}
|
||||
void* GetNativeBackend() const override { return nullptr; }
|
||||
|
||||
bool RunScript(const wxString& javascript, wxString*) const override
|
||||
{
|
||||
events.emplace_back("script");
|
||||
script = javascript.ToStdString();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoSetPage(const wxString& html, const wxString& base_url) override
|
||||
{
|
||||
events.emplace_back("page");
|
||||
page = html.ToStdString();
|
||||
page_base = base_url.ToStdString();
|
||||
}
|
||||
|
||||
public:
|
||||
mutable std::vector<std::string> events;
|
||||
std::string page;
|
||||
std::string page_base;
|
||||
mutable std::string script;
|
||||
std::string loaded_url;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Web media controller tears down a snapshot lifecycle", "[WebMediaController][integration]")
|
||||
{
|
||||
StubWebView view;
|
||||
WebMediaController controller(&view);
|
||||
|
||||
controller.set_mode(CameraStreamMode::http_snapshot);
|
||||
controller.Load(wxURI("http://camera.example/frame.jpg"));
|
||||
controller.Play();
|
||||
|
||||
REQUIRE(view.events.size() == 3);
|
||||
CHECK(view.events[0] == "background");
|
||||
CHECK(view.events[1] == "page");
|
||||
CHECK(view.events[2] == "page");
|
||||
CHECK(view.page.find("stopCameraRefresh") != std::string::npos);
|
||||
CHECK(view.page.find("http://camera.example/frame.jpg") != std::string::npos);
|
||||
|
||||
controller.Stop();
|
||||
|
||||
REQUIRE(view.events.size() == 7);
|
||||
CHECK(view.events[3] == "script");
|
||||
CHECK(view.events[4] == "stop");
|
||||
CHECK(view.events[5] == "page");
|
||||
CHECK(view.events[6] == "history");
|
||||
CHECK(view.script == "if(typeof stopCameraRefresh==='function') stopCameraRefresh();");
|
||||
CHECK(view.page.empty());
|
||||
CHECK(view.page_base == "about:blank");
|
||||
|
||||
controller.Play();
|
||||
CHECK(view.page.find("http://camera.example/frame.jpg") == std::string::npos);
|
||||
}
|
||||
Reference in New Issue
Block a user