mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-19 13:41:03 +00:00
Subclass of MoonrakerPrinterAgent for K-series Creality printers (K2, K2 Plus, K2 Pro) with CFS support. Registers in NetworkAgentFactory under host_type=crealityprint. Overrides fetch_filament_info() to defer to base when the host is not a CFS-capable K-series board, otherwise query the boxsInfo WebSocket on port 9999, parse the box hierarchy into CFSSlot[], and publish each loaded slot as an AmsTrayData entry via build_ams_payload() so they surface in Orca filament UI. boxsInfo schema reference (verified against K2 Combo F021 firmware v1.1.260206): materialBoxs[].materials[] fields: id, state, vendor, type, name, color, pressure, rfid, percent. state=1 means loaded; box.type=0 is a CFS unit, type=1 is the external spool holder (handled by the upload dialog). Accepted CFS boxes are renumbered sequentially since the K2 raw box.id has gaps for the external spool holder. Model detection is delegated to CrealityPrint::supports_multi_color_print() added in PR #13291.
193 lines
6.9 KiB
C++
193 lines
6.9 KiB
C++
#include "NetworkAgentFactory.hpp"
|
|
#include "IPrinterAgent.hpp"
|
|
#include "ICloudServiceAgent.hpp"
|
|
#include "BBLPrinterAgent.hpp"
|
|
#include "OrcaPrinterAgent.hpp"
|
|
#include "QidiPrinterAgent.hpp"
|
|
#include "SnapmakerPrinterAgent.hpp"
|
|
#include "MoonrakerPrinterAgent.hpp"
|
|
#include "CrealityPrintAgent.hpp"
|
|
#include <boost/log/trivial.hpp>
|
|
#include <map>
|
|
#include <mutex>
|
|
|
|
namespace Slic3r {
|
|
namespace {
|
|
|
|
static std::mutex s_registry_mutex;
|
|
|
|
std::map<std::string, PrinterAgentInfo>& get_printer_agents()
|
|
{
|
|
static std::map<std::string, PrinterAgentInfo> agents;
|
|
return agents;
|
|
}
|
|
|
|
std::map<std::string, std::shared_ptr<IPrinterAgent>>& get_printer_agent_cache()
|
|
{
|
|
static std::map<std::string, std::shared_ptr<IPrinterAgent>> cache;
|
|
return cache;
|
|
}
|
|
|
|
// Helper to register a printer agent type with the standard factory pattern.
|
|
// AgentTypes that take a log_dir constructor arg use the default; BBLPrinterAgent
|
|
// (no log_dir) is registered separately.
|
|
template<typename T>
|
|
void register_agent()
|
|
{
|
|
auto info = T::get_agent_info_static();
|
|
NetworkAgentFactory::register_printer_agent(
|
|
info.id, info.name,
|
|
[](std::shared_ptr<ICloudServiceAgent> cloud_agent,
|
|
const std::string& log_dir) -> std::shared_ptr<IPrinterAgent> {
|
|
auto agent = std::make_shared<T>(log_dir);
|
|
if (cloud_agent)
|
|
agent->set_cloud_agent(cloud_agent);
|
|
return agent;
|
|
});
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
bool NetworkAgentFactory::register_printer_agent(const std::string& id, const std::string& display_name, PrinterAgentFactory factory)
|
|
{
|
|
std::lock_guard<std::mutex> lock(s_registry_mutex);
|
|
auto& agents = get_printer_agents();
|
|
return agents.emplace(id, PrinterAgentInfo(id, display_name, std::move(factory))).second;
|
|
}
|
|
|
|
bool NetworkAgentFactory::is_printer_agent_registered(const std::string& id)
|
|
{
|
|
std::lock_guard<std::mutex> lock(s_registry_mutex);
|
|
auto& agents = get_printer_agents();
|
|
return agents.find(id) != agents.end();
|
|
}
|
|
|
|
const PrinterAgentInfo* NetworkAgentFactory::get_printer_agent_info(const std::string& id)
|
|
{
|
|
std::lock_guard<std::mutex> lock(s_registry_mutex);
|
|
auto& agents = get_printer_agents();
|
|
auto it = agents.find(id);
|
|
return (it != agents.end()) ? &it->second : nullptr;
|
|
}
|
|
|
|
std::vector<PrinterAgentInfo> NetworkAgentFactory::get_registered_printer_agents()
|
|
{
|
|
std::lock_guard<std::mutex> lock(s_registry_mutex);
|
|
auto& agents = get_printer_agents();
|
|
std::vector<PrinterAgentInfo> result;
|
|
result.reserve(agents.size());
|
|
|
|
for (const auto& pair : agents) {
|
|
result.push_back(pair.second);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
std::shared_ptr<IPrinterAgent> NetworkAgentFactory::create_printer_agent_by_id(const std::string& id,
|
|
std::shared_ptr<ICloudServiceAgent> cloud_agent,
|
|
const std::string& log_dir)
|
|
{
|
|
std::lock_guard<std::mutex> lock(s_registry_mutex);
|
|
|
|
// Check cache first
|
|
auto& cache = get_printer_agent_cache();
|
|
auto cache_it = cache.find(id);
|
|
if (cache_it != cache.end()) {
|
|
BOOST_LOG_TRIVIAL(info) << "Reusing cached printer agent: " << id;
|
|
if (cloud_agent)
|
|
cache_it->second->set_cloud_agent(cloud_agent);
|
|
return cache_it->second;
|
|
}
|
|
|
|
// Not cached — create via factory
|
|
auto& agents = get_printer_agents();
|
|
auto it = agents.find(id);
|
|
|
|
if (it == agents.end()) {
|
|
BOOST_LOG_TRIVIAL(warning) << "Unknown printer agent ID: " << id;
|
|
return nullptr;
|
|
}
|
|
|
|
auto agent = it->second.factory(cloud_agent, log_dir);
|
|
if (agent) {
|
|
BOOST_LOG_TRIVIAL(info) << "Created and cached printer agent: " << id;
|
|
cache[id] = agent;
|
|
}
|
|
return agent;
|
|
}
|
|
|
|
void NetworkAgentFactory::clear_printer_agent_cache()
|
|
{
|
|
std::lock_guard<std::mutex> lock(s_registry_mutex);
|
|
auto& cache = get_printer_agent_cache();
|
|
for (auto& pair : cache) {
|
|
if (pair.second)
|
|
pair.second->disconnect_printer();
|
|
}
|
|
cache.clear();
|
|
BOOST_LOG_TRIVIAL(info) << "Printer agent cache cleared";
|
|
}
|
|
|
|
void NetworkAgentFactory::register_all_agents()
|
|
{
|
|
register_agent<OrcaPrinterAgent>();
|
|
register_agent<QidiPrinterAgent>();
|
|
register_agent<SnapmakerPrinterAgent>();
|
|
register_agent<CrealityPrintAgent>(); // Must come BEFORE MoonrakerPrinterAgent —
|
|
// CrealityPrintAgent extends Moonraker behaviour
|
|
// for K-series boards with CFS support.
|
|
register_agent<MoonrakerPrinterAgent>();
|
|
|
|
// BBLPrinterAgent takes no constructor args, so register manually
|
|
{
|
|
auto info = BBLPrinterAgent::get_agent_info_static();
|
|
register_printer_agent(info.id, info.name,
|
|
[](std::shared_ptr<ICloudServiceAgent> cloud_agent,
|
|
const std::string& /*log_dir*/) -> std::shared_ptr<IPrinterAgent> {
|
|
auto agent = std::make_shared<BBLPrinterAgent>();
|
|
if (cloud_agent)
|
|
agent->set_cloud_agent(cloud_agent);
|
|
return agent;
|
|
});
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<NetworkAgent> create_agent_from_config(const std::string& log_dir, AppConfig* app_config)
|
|
{
|
|
if (!app_config)
|
|
return std::make_unique<NetworkAgent>(nullptr, nullptr);
|
|
|
|
// Always create Orca cloud agent as the primary provider
|
|
auto cloud_agent = NetworkAgentFactory::create_cloud_agent(ORCA_CLOUD_PROVIDER, log_dir);
|
|
if (!cloud_agent) {
|
|
BOOST_LOG_TRIVIAL(error) << "Failed to create cloud agent";
|
|
}
|
|
|
|
auto agent = std::make_unique<NetworkAgent>(std::move(cloud_agent), nullptr);
|
|
|
|
if (agent) {
|
|
// create orca cloud agent first
|
|
auto* orca_cloud = dynamic_cast<OrcaCloudServiceAgent*>(agent->get_cloud_agent().get());
|
|
if (orca_cloud) {
|
|
orca_cloud->configure_urls(app_config);
|
|
}
|
|
|
|
// Initialize third-party cloud agents from config
|
|
auto providers = app_config->get_cloud_providers();
|
|
for (const auto& provider : providers) {
|
|
if (provider == ORCA_CLOUD_PROVIDER)
|
|
continue; // Primary agent already created above
|
|
auto third_party_agent = NetworkAgentFactory::create_cloud_agent(provider, log_dir);
|
|
if (third_party_agent) {
|
|
agent->add_cloud_agent(provider, std::move(third_party_agent));
|
|
BOOST_LOG_TRIVIAL(info) << "Initialized third-party cloud agent: " << provider;
|
|
}
|
|
}
|
|
}
|
|
|
|
return agent;
|
|
}
|
|
|
|
} // namespace Slic3r
|