Add Sidebar::sync_filaments_from_creality_cfs explicit-pull path

The agent fetch_filament_info() path does not fire for Creality
K-series hosts because Sidebar::build_filament_ams_list()
short-circuits when no MachineObject is bound. MachineObject is a
BBL cloud-connected-printer concept that does not apply to LAN
Moonraker-style hosts like the K2 -- the AMS-sync icon click was a
no-op for them.

Mirror what Creality Print own slicer does (explicit Auto Mapping
button bypassing the BBL plumbing): when the user clicks the
existing AMS-sync icon and host_type=crealityprint, dispatch to a
new Sidebar::sync_filaments_from_creality_cfs() that reads the
active printer host config, confirms the printer is a CFS-capable
K-series board, queries boxsInfo over the printer WS on port 9999,
scores each loaded slot against the user filament presets and
builds a filament_ams_list entry with the matched filament_id,
colour and slot indices, then routes through
PresetBundle::sync_ams_list so the filament combo widgets get the
same rebuild as BBL printers and runs the BBL post-sync refresh
sequence (on_filament_count_change + combo update + select_preset
+ export_selections + update_dynamic_filament_list).

No new UI surface -- the existing AMS-sync icon does the right
thing per host_type. Match-and-resolve logic is hoisted out of the
agent anonymous namespace into public statics so the sidebar can
call it without duplicating scoring rules.
This commit is contained in:
grant0013
2026-05-19 11:06:54 +00:00
parent 7514cf4012
commit 251f5faefa
4 changed files with 250 additions and 17 deletions

View File

@@ -27,6 +27,8 @@ bool has_visible_base_preset(const PresetCollection& filaments, const std::strin
return false;
}
} // namespace
// Score visible compatible filament presets against the CFS spool metadata and
// return the best-matching filament_id. Scoring:
// +20 preset name contains brand_name as a substring
@@ -38,10 +40,10 @@ bool has_visible_base_preset(const PresetCollection& filaments, const std::strin
// Requires the preset's declared filament_type to equal the spool's base type
// (PLA/PETG/ABS/...) so we never auto-pick a PETG preset for a PLA spool.
// Falls back to filaments.filament_id_by_type(base_type) when nothing scores.
std::string match_filament_preset(const PresetCollection& filaments,
const std::string& vendor,
const std::string& brand_name,
const std::string& base_type)
std::string CrealityPrintAgent::match_filament_preset(const PresetCollection& filaments,
const std::string& vendor,
const std::string& brand_name,
const std::string& base_type)
{
auto to_lower = [](std::string s) {
for (auto& c : s) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
@@ -112,8 +114,6 @@ std::string match_filament_preset(const PresetCollection& filaments,
return matches.front().preset->filament_id;
}
} // namespace
CrealityPrintAgent::CrealityPrintAgent(std::string log_dir)
: MoonrakerPrinterAgent(std::move(log_dir))
{
@@ -131,8 +131,6 @@ AgentInfo CrealityPrintAgent::get_agent_info_static()
std::string CrealityPrintAgent::normalize_filament_type(const std::string& filament_type)
{
// Strip subtype suffixes ("PLA Silk", "PLA+", "ABS Pro") to base type so the
// preset_bundle->filaments.filament_id_by_type() lookup succeeds.
static const std::vector<std::string> bases = {
"PETG", "PET", "PLA", "ABS", "ASA", "TPU", "PC", "PA", "PVA", "HIPS"
};

View File

@@ -8,6 +8,8 @@
namespace Slic3r {
class PresetCollection;
// Filament sync for Creality K-series printers with CFS.
//
// Inherits MoonrakerPrinterAgent for all communication / certificates / discovery /
@@ -19,19 +21,15 @@ namespace Slic3r {
// Model detection delegated to CrealityPrint::supports_multi_color_print() (PR #13291).
// For non-CFS K-series boards or when the WS query fails, falls back to the base
// MoonrakerPrinterAgent behaviour.
//
// The CFS-slot parser and preset matcher are also exposed as public statics so the
// Sidebar's manual "Sync from CFS" path can reuse them without going through the
// agent dispatch (which only fires when a MachineObject is bound — a BBL concept that
// doesn't apply to Moonraker-style hosts).
class CrealityPrintAgent final : public MoonrakerPrinterAgent
{
public:
explicit CrealityPrintAgent(std::string log_dir);
~CrealityPrintAgent() override = default;
static AgentInfo get_agent_info_static();
AgentInfo get_agent_info() override { return get_agent_info_static(); }
bool fetch_filament_info(std::string dev_id) override;
private:
struct CFSSlot
{
int box_id = 0; // CFS unit index (0 for first box, 1 for chained second box)
@@ -42,12 +40,31 @@ private:
std::string vendor; // "Creality", "eSUN", or "" if unknown
};
explicit CrealityPrintAgent(std::string log_dir);
~CrealityPrintAgent() override = default;
static AgentInfo get_agent_info_static();
AgentInfo get_agent_info() override { return get_agent_info_static(); }
bool fetch_filament_info(std::string dev_id) override;
// Parse the boxsInfo JSON returned by CrealityPrint::query_boxes_info() into
// a flat list of loaded slots, plus the count of CFS boxes the printer reports.
static bool parse_cfs_response(const std::string& response,
std::vector<CFSSlot>& slots,
int& box_count,
std::string& error);
// Strip PLA/PETG/... subtype suffixes ("PLA Silk", "PLA+", "ABS Pro") to base
// type so the preset_bundle->filaments.filament_id_by_type() lookup succeeds.
static std::string normalize_filament_type(const std::string& filament_type);
// Score visible compatible filament presets against the CFS spool metadata and
// return the best-matching filament_id. See implementation for scoring details.
static std::string match_filament_preset(const PresetCollection& filaments,
const std::string& vendor,
const std::string& brand_name,
const std::string& base_type);
};
} // namespace Slic3r