refactor QidiPrinterAgent

This commit is contained in:
SoftFever 2026-01-24 22:35:43 +08:00
parent 9c6b8edcb1
commit 3da2bf1bd8
4 changed files with 101 additions and 1225 deletions

View file

@ -356,6 +356,13 @@ int MoonrakerPrinterAgent::bind_detect(std::string dev_ip, std::string sec_link,
}
detect.dev_id = info.dev_id.empty() ? dev_ip : info.dev_id;
if (!info.model_id.empty()) {
detect.model_id = info.model_id;
} else if (!config.model_id.empty()) {
detect.model_id = config.model_id;
} else {
detect.model_id = config.model_name;
}
// Prefer fetched hostname, then preset model name, then generic fallback
std::string fallback_name = config.model_name.empty() ? "Moonraker Printer" : config.model_name;
detect.dev_name = info.dev_name.empty() ? fallback_name : info.dev_name;
@ -600,7 +607,9 @@ void MoonrakerPrinterAgent::fetch_filament_info(std::string dev_id)
{
// Moonraker doesn't have standard filament tracking like Qidi
// This is a no-op for standard Moonraker installations
BOOST_LOG_TRIVIAL(debug) << "MoonrakerPrinterAgent: fetch_filament_info (no-op) - dev_id=" << dev_id;
// Note: QidiPrinterAgent overrides this method with actual implementation
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info (base class no-op) called for dev_id=" << dev_id
<< " - if you see this for Qidi printer, virtual dispatch is broken!";
}
int MoonrakerPrinterAgent::handle_request(const std::string& dev_id, const std::string& json_str)
@ -741,6 +750,7 @@ bool MoonrakerPrinterAgent::get_printhost_config(PrinthostConfig& config) const
config.api_key = host_cfg->opt_string("printhost_apikey");
config.model_name = printer_cfg.opt_string("printer_model");
config.base_url = normalize_base_url(config.host, config.port);
config.model_id = preset.get_printer_type(preset_bundle);
return !config.base_url.empty();
}
@ -797,9 +807,13 @@ bool MoonrakerPrinterAgent::fetch_device_info(const std::string& base_url,
}
nlohmann::json result = json.contains("result") ? json["result"] : json;
info.dev_name = result.value("hostname", "Moonraker Printer");
info.dev_id = result.value("hostname", "");
info.version = result.value("moonraker_version", "");
info.dev_name = result.value("machine_name", result.value("hostname", ""));
info.dev_id = result.value("machine_uuid", "");
if (info.dev_id.empty()) {
info.dev_id = result.value("serial_number", "");
}
info.model_id = result.value("model", "");
info.version = result.value("software_version", result.value("firmware_version", ""));
return true;
}
@ -1156,6 +1170,8 @@ void MoonrakerPrinterAgent::announce_printhost_device()
<< " (fetch_error=" << fetch_error << ")";
}
const std::string model_id = config.model_id;
if (auto* app_config = GUI::wxGetApp().app_config) {
const std::string access_code = api_key.empty() ? k_no_api_key : api_key;
app_config->set_str("access_code", dev_id, access_code);
@ -1168,7 +1184,7 @@ void MoonrakerPrinterAgent::announce_printhost_device()
payload["dev_name"] = dev_name;
payload["dev_id"] = dev_id;
payload["dev_ip"] = extract_host(base_url);
payload["dev_type"] = "moonraker";
payload["dev_type"] = model_id.empty() ? dev_name : model_id;
payload["dev_signal"] = "0";
payload["connect_type"] = "lan";
payload["bind_state"] = "free";

View file

@ -15,7 +15,7 @@
namespace Slic3r {
class MoonrakerPrinterAgent final : public IPrinterAgent
class MoonrakerPrinterAgent : public IPrinterAgent
{
public:
explicit MoonrakerPrinterAgent(std::string log_dir);
@ -70,16 +70,18 @@ public:
int set_queue_on_main_fn(QueueOnMainFn fn) override;
// Pull-mode agent (on-demand filament sync)
FilamentSyncMode get_filament_sync_mode() const override { return FilamentSyncMode::pull; }
void fetch_filament_info(std::string dev_id) override;
virtual FilamentSyncMode get_filament_sync_mode() const override { return FilamentSyncMode::pull; }
virtual void fetch_filament_info(std::string dev_id) override;
private:
protected:
// Types exposed for derived classes
struct PrinthostConfig
{
std::string host;
std::string port;
std::string api_key;
std::string base_url;
std::string model_id;
std::string model_name;
};
@ -87,24 +89,35 @@ private:
{
std::string dev_id;
std::string dev_name;
std::string model_id;
std::string version;
};
// Methods that derived classes may need to override or access
virtual bool get_printhost_config(PrinthostConfig& config) const;
virtual bool fetch_device_info(const std::string& base_url, const std::string& api_key, MoonrakerDeviceInfo& info, std::string& error) const;
virtual std::string get_dev_type() const { return "moonraker"; }
// Host resolution methods
std::string resolve_host(const std::string& dev_id) const;
std::string resolve_api_key(const std::string& dev_id, const std::string& fallback) const;
void store_host(const std::string& dev_id, const std::string& host, const std::string& api_key);
// State access for derived classes
mutable std::recursive_mutex state_mutex;
std::map<std::string, std::string> host_by_device;
std::map<std::string, std::string> api_key_by_device;
private:
int handle_request(const std::string& dev_id, const std::string& json_str);
int send_version_info(const std::string& dev_id);
int send_access_code(const std::string& dev_id);
bool get_printhost_config(PrinthostConfig& config) const;
bool fetch_device_info(const std::string& base_url, const std::string& api_key, MoonrakerDeviceInfo& info, std::string& error) const;
bool fetch_server_info(const std::string& base_url, const std::string& api_key, std::string& version, std::string& error) const;
bool fetch_object_list(const std::string& base_url, const std::string& api_key, std::set<std::string>& objects, std::string& error) const;
bool query_printer_status(const std::string& base_url, const std::string& api_key, nlohmann::json& status, std::string& error) const;
bool send_gcode(const std::string& dev_id, const std::string& gcode) const;
std::string resolve_host(const std::string& dev_id) const;
std::string resolve_api_key(const std::string& dev_id, const std::string& fallback) const;
void store_host(const std::string& dev_id, const std::string& host, const std::string& api_key);
void announce_printhost_device();
void dispatch_local_connect(int state, const std::string& dev_id, const std::string& msg);
void dispatch_printer_connected(const std::string& dev_id);
@ -140,9 +153,6 @@ private:
const std::string& api_key);
void finish_connection();
mutable std::recursive_mutex state_mutex;
std::map<std::string, std::string> host_by_device;
std::map<std::string, std::string> api_key_by_device;
std::string ssdp_announced_host;
std::string ssdp_announced_id;
std::shared_ptr<ICloudServiceAgent> m_cloud_agent;

File diff suppressed because it is too large Load diff

View file

@ -1,64 +1,28 @@
#ifndef __QIDI_PRINTER_AGENT_HPP__
#define __QIDI_PRINTER_AGENT_HPP__
#include "OrcaPrinterAgent.hpp"
#include "MoonrakerPrinterAgent.hpp"
#include <atomic>
#include <cstdint>
#include <map>
#include <mutex>
#include <set>
#include <string>
#include <thread>
#include <vector>
namespace Slic3r {
class QidiPrinterAgent final : public OrcaPrinterAgent
class QidiPrinterAgent final : public MoonrakerPrinterAgent
{
public:
explicit QidiPrinterAgent(std::string log_dir);
~QidiPrinterAgent() override;
~QidiPrinterAgent() override = default;
static AgentInfo get_agent_info_static();
AgentInfo get_agent_info() override { return get_agent_info_static(); }
int send_message(std::string dev_id, std::string json_str, int qos, int flag) override;
int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) override;
int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override;
int disconnect_printer() override;
bool start_discovery(bool start, bool sending) override;
int bind_detect(std::string dev_ip, std::string sec_link, detectResult& detect) override;
int set_on_ssdp_msg_fn(OnMsgArrivedFn fn) override;
int set_on_printer_connected_fn(OnPrinterConnectedFn fn) override;
int set_on_message_fn(OnMessageFn fn) override;
int set_on_local_connect_fn(OnLocalConnectedFn fn) override;
int set_on_local_message_fn(OnMessageFn fn) override;
int set_queue_on_main_fn(QueueOnMainFn fn) override;
FilamentSyncMode get_filament_sync_mode() const override { return FilamentSyncMode::pull; }
// Override filament sync (Qidi-specific implementation)
void fetch_filament_info(std::string dev_id) override;
private:
struct PrinthostConfig
{
std::string host;
std::string port;
std::string api_key;
std::string base_url;
std::string model_id;
std::string model_name;
};
struct QidiDeviceInfo
{
std::string dev_id;
std::string dev_name;
std::string model_id;
std::string version;
};
// Qidi-specific device info (extends base MoonrakerDeviceInfo with model_id)
struct QidiSlotInfo
{
int slot_index = 0;
@ -74,62 +38,15 @@ private:
std::map<int, std::string> filaments;
};
int handle_request(const std::string& dev_id, const std::string& json_str);
int send_version_info(const std::string& dev_id);
int send_access_code(const std::string& dev_id);
bool get_printhost_config(PrinthostConfig& config) const;
bool fetch_device_info(const std::string& base_url, const std::string& api_key, QidiDeviceInfo& info, std::string& error) const;
bool fetch_server_info(const std::string& base_url, const std::string& api_key, std::string& version, std::string& error) const;
bool fetch_object_list(const std::string& base_url, const std::string& api_key, std::set<std::string>& objects, std::string& error) const;
std::string resolve_host(const std::string& dev_id) const;
std::string resolve_api_key(const std::string& dev_id, const std::string& fallback) const;
void store_host(const std::string& dev_id, const std::string& host, const std::string& api_key);
bool fetch_slot_info(const std::string& base_url,
const std::string& api_key,
std::vector<QidiSlotInfo>& slots,
int& box_count,
std::string& error) const;
// Qidi-specific methods
bool fetch_slot_info(const std::string& base_url, const std::string& api_key, std::vector<QidiSlotInfo>& slots, int& box_count, std::string& error) const;
bool fetch_filament_dict(const std::string& base_url, const std::string& api_key, QidiFilamentDict& dict, std::string& error) const;
// Static helpers
static void parse_ini_section(const std::string& content, const std::string& section_name, std::map<int, std::string>& result);
static void parse_filament_sections(const std::string& content, std::map<int, std::string>& result);
static std::string normalize_color(const std::string& color);
static std::string map_filament_type_to_setting_id(const std::string& filament_type);
void announce_printhost_device();
void dispatch_local_connect(int state, const std::string& dev_id, const std::string& msg);
void dispatch_printer_connected(const std::string& dev_id);
void dispatch_message(const std::string& dev_id, const std::string& payload);
void start_status_stream(const std::string& dev_id, const std::string& base_url, const std::string& api_key);
void stop_status_stream();
void run_status_stream(std::string dev_id, std::string base_url, std::string api_key);
void handle_ws_message(const std::string& dev_id, const std::string& payload);
void update_status_cache(const nlohmann::json& updates);
nlohmann::json build_print_payload_locked(const nlohmann::json* ams_override) const;
mutable std::mutex state_mutex;
std::map<std::string, std::string> host_by_device;
std::map<std::string, std::string> api_key_by_device;
std::string ssdp_announced_host;
std::string ssdp_announced_id;
OnMsgArrivedFn on_ssdp_msg_fn;
OnPrinterConnectedFn on_printer_connected_fn;
OnLocalConnectedFn on_local_connect_fn;
OnMessageFn on_message_fn;
OnMessageFn on_local_message_fn;
QueueOnMainFn queue_on_main_fn;
mutable std::mutex payload_mutex;
nlohmann::json status_cache;
nlohmann::json last_ams_payload;
std::atomic<bool> ws_stop{false};
std::atomic<uint64_t> ws_last_emit_ms{0};
std::thread ws_thread;
};
} // namespace Slic3r