mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 10:32:20 +00:00
refactor
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include "libslic3r/Preset.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/DeviceCore/DevFilaSystem.h"
|
||||
#include "slic3r/GUI/DeviceCore/DevManager.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/asio/connect.hpp>
|
||||
@@ -454,7 +456,239 @@ int MoonrakerPrinterAgent::set_queue_on_main_fn(QueueOnMainFn fn)
|
||||
return BAMBU_NETWORK_SUCCESS;
|
||||
}
|
||||
|
||||
bool MoonrakerPrinterAgent::fetch_filament_info(std::string dev_id) { return false; }
|
||||
void MoonrakerPrinterAgent::build_ams_payload(int ams_count, const std::vector<AmsTrayData>& trays)
|
||||
{
|
||||
|
||||
// Look up MachineObject via DeviceManager
|
||||
auto* dev_manager = GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev_manager) {
|
||||
return;
|
||||
}
|
||||
MachineObject* obj = dev_manager->get_my_machine(device_info.dev_id);
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Color normalization helper (handles #RRGGBB, 0xRRGGBB -> RRGGBBAA)
|
||||
auto normalize_color = [](const std::string& color) -> std::string {
|
||||
std::string value = color;
|
||||
boost::trim(value);
|
||||
|
||||
// Remove 0x or 0X prefix if present
|
||||
if (value.size() >= 2 && (value.rfind("0x", 0) == 0 || value.rfind("0X", 0) == 0)) {
|
||||
value = value.substr(2);
|
||||
}
|
||||
// Remove # prefix if present
|
||||
if (!value.empty() && value[0] == '#') {
|
||||
value = value.substr(1);
|
||||
}
|
||||
|
||||
// Extract only hex digits
|
||||
std::string normalized;
|
||||
for (char c : value) {
|
||||
if (std::isxdigit(static_cast<unsigned char>(c))) {
|
||||
normalized.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(c))));
|
||||
}
|
||||
}
|
||||
|
||||
// If 6 hex digits, add FF alpha
|
||||
if (normalized.size() == 6) {
|
||||
normalized += "FF";
|
||||
}
|
||||
|
||||
// Validate length - return default if invalid
|
||||
if (normalized.size() != 8) {
|
||||
return "00000000";
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
|
||||
// Build BBL-format JSON for DevFilaSystemParser::ParseV1_0
|
||||
nlohmann::json ams_json = nlohmann::json::object();
|
||||
nlohmann::json ams_array = nlohmann::json::array();
|
||||
|
||||
// Calculate ams_exist_bits and tray_exist_bits
|
||||
unsigned long ams_exist_bits = 0;
|
||||
unsigned long tray_exist_bits = 0;
|
||||
|
||||
for (int ams_id = 0; ams_id < ams_count; ++ams_id) {
|
||||
ams_exist_bits |= (1 << ams_id);
|
||||
|
||||
nlohmann::json ams_unit = nlohmann::json::object();
|
||||
ams_unit["id"] = std::to_string(ams_id);
|
||||
ams_unit["info"] = "2100"; // AMS_LITE type (2), main extruder (0)
|
||||
|
||||
nlohmann::json tray_array = nlohmann::json::array();
|
||||
for (int slot_id = 0; slot_id < 4; ++slot_id) {
|
||||
int slot_index = ams_id * 4 + slot_id;
|
||||
|
||||
// Find tray with matching slot_index
|
||||
const AmsTrayData* tray = nullptr;
|
||||
for (const auto& t : trays) {
|
||||
if (t.slot_index == slot_index) {
|
||||
tray = &t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json tray_json = nlohmann::json::object();
|
||||
tray_json["id"] = std::to_string(slot_id);
|
||||
tray_json["tag_uid"] = "0000000000000000";
|
||||
|
||||
if (tray && tray->has_filament) {
|
||||
tray_exist_bits |= (1 << slot_index);
|
||||
|
||||
tray_json["tray_info_idx"] = tray->tray_info_idx;
|
||||
tray_json["tray_type"] = tray->tray_type;
|
||||
tray_json["tray_color"] = normalize_color(tray->tray_color);
|
||||
|
||||
// Add temperature data if provided
|
||||
if (tray->bed_temp > 0) {
|
||||
tray_json["bed_temp"] = std::to_string(tray->bed_temp);
|
||||
}
|
||||
if (tray->nozzle_temp > 0) {
|
||||
tray_json["nozzle_temp_max"] = std::to_string(tray->nozzle_temp);
|
||||
}
|
||||
} else {
|
||||
tray_json["tray_info_idx"] = "";
|
||||
tray_json["tray_type"] = "";
|
||||
tray_json["tray_color"] = "00000000";
|
||||
}
|
||||
|
||||
tray_array.push_back(tray_json);
|
||||
}
|
||||
ams_unit["tray"] = tray_array;
|
||||
ams_array.push_back(ams_unit);
|
||||
}
|
||||
|
||||
// Format as hex strings (matching BBL protocol)
|
||||
std::ostringstream ams_exist_ss;
|
||||
ams_exist_ss << std::hex << std::uppercase << ams_exist_bits;
|
||||
std::ostringstream tray_exist_ss;
|
||||
tray_exist_ss << std::hex << std::uppercase << tray_exist_bits;
|
||||
|
||||
ams_json["ams"] = ams_array;
|
||||
ams_json["ams_exist_bits"] = ams_exist_ss.str();
|
||||
ams_json["tray_exist_bits"] = tray_exist_ss.str();
|
||||
|
||||
// Wrap in the expected structure for ParseV1_0
|
||||
nlohmann::json print_json = nlohmann::json::object();
|
||||
print_json["ams"] = ams_json;
|
||||
|
||||
// Call the parser to populate DevFilaSystem
|
||||
DevFilaSystemParser::ParseV1_0(print_json, obj, obj->GetFilaSystem(), false);
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::build_ams_payload: Parsed " << trays.size() << " trays";
|
||||
|
||||
// Set push counters so is_info_ready() returns true for pull-mode agents.
|
||||
if (obj->m_push_count == 0) {
|
||||
obj->m_push_count = 1;
|
||||
}
|
||||
if (obj->m_full_msg_count == 0) {
|
||||
obj->m_full_msg_count = 1;
|
||||
}
|
||||
obj->last_push_time = std::chrono::system_clock::now();
|
||||
}
|
||||
|
||||
bool MoonrakerPrinterAgent::fetch_filament_info(std::string dev_id)
|
||||
{
|
||||
// Fetch AFC lane data from Moonraker database (inline)
|
||||
std::string url = join_url(device_info.base_url, "/server/database/item?namespace=lane_data");
|
||||
|
||||
std::string response_body;
|
||||
bool success = false;
|
||||
std::string http_error;
|
||||
|
||||
auto http = Http::get(url);
|
||||
if (!device_info.api_key.empty()) {
|
||||
http.header("X-Api-Key", device_info.api_key);
|
||||
}
|
||||
http.timeout_connect(5)
|
||||
.timeout_max(10)
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
if (status == 200) {
|
||||
response_body = body;
|
||||
success = true;
|
||||
} else {
|
||||
http_error = "HTTP error: " + std::to_string(status);
|
||||
}
|
||||
})
|
||||
.on_error([&](std::string body, std::string err, unsigned status) {
|
||||
http_error = err;
|
||||
if (status > 0) {
|
||||
http_error += " (HTTP " + std::to_string(status) + ")";
|
||||
}
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
if (!success) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_filament_info: Failed to fetch lane data: " << http_error;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto json = nlohmann::json::parse(response_body, nullptr, false, true);
|
||||
if (json.is_discarded()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_filament_info: Invalid JSON response";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expected structure: { "result": { "namespace": "lane_data", "value": { "lane1": {...}, ... } } }
|
||||
if (!json.contains("result") || !json["result"].contains("value") || !json["result"]["value"].is_object()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "MoonrakerPrinterAgent::fetch_filament_info: Unexpected JSON structure or no lane_data found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse response into AmsTrayData
|
||||
const auto& value = json["result"]["value"];
|
||||
std::vector<AmsTrayData> trays;
|
||||
int max_lane_index = 0;
|
||||
|
||||
for (const auto& [lane_key, lane_obj] : value.items()) {
|
||||
if (!lane_obj.is_object()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract lane index from the "lane" field (tool number, 1-based)
|
||||
std::string lane_str = lane_obj.value("lane", "");
|
||||
int lane_index = -1;
|
||||
if (!lane_str.empty()) {
|
||||
try {
|
||||
lane_index = std::stoi(lane_str) - 1; // Convert to 0-based
|
||||
} catch (...) {
|
||||
lane_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lane_index < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AmsTrayData tray;
|
||||
tray.slot_index = lane_index;
|
||||
tray.tray_color = lane_obj.value("color", "");
|
||||
tray.tray_type = lane_obj.value("material", "");
|
||||
tray.bed_temp = lane_obj.value("bed_temp", 0);
|
||||
tray.nozzle_temp = lane_obj.value("nozzle_temp", 0);
|
||||
tray.has_filament = !tray.tray_type.empty();
|
||||
tray.tray_info_idx = ""; // AFC doesn't provide setting IDs
|
||||
|
||||
max_lane_index = std::max(max_lane_index, lane_index);
|
||||
trays.push_back(tray);
|
||||
}
|
||||
|
||||
if (trays.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::fetch_filament_info: No AFC lanes found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate AMS count from max lane index (4 trays per AMS unit)
|
||||
int ams_count = (max_lane_index + 4) / 4;
|
||||
|
||||
// Build and parse the AMS payload
|
||||
build_ams_payload(ams_count, trays);
|
||||
return true;
|
||||
}
|
||||
|
||||
int MoonrakerPrinterAgent::handle_request(const std::string& dev_id, const std::string& json_str)
|
||||
{
|
||||
|
||||
@@ -88,6 +88,20 @@ protected:
|
||||
bool use_ssl = false;
|
||||
} device_info;
|
||||
|
||||
// Shared tray data for AMS payload building (used by derived classes like QidiPrinterAgent)
|
||||
struct AmsTrayData {
|
||||
int slot_index = 0; // 0-based slot index
|
||||
bool has_filament = false;
|
||||
std::string tray_type; // Material type (e.g., "PLA", "ASA")
|
||||
std::string tray_color; // Raw color (#RRGGBB, 0xRRGGBB, or RRGGBBAA)
|
||||
std::string tray_info_idx; // Setting ID (optional)
|
||||
int bed_temp = 0; // Optional
|
||||
int nozzle_temp = 0; // Optional
|
||||
};
|
||||
|
||||
// Build ams JSON and call parser
|
||||
void build_ams_payload(int ams_count, const std::vector<AmsTrayData>& trays);
|
||||
|
||||
// Methods that derived classes may need to override or access
|
||||
virtual bool init_device_info(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl);
|
||||
virtual bool fetch_device_info(const std::string& base_url, const std::string& api_key, MoonrakerDeviceInfo& info, std::string& error) const;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "QidiPrinterAgent.hpp"
|
||||
#include "Http.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/DeviceCore/DevFilaSystem.h"
|
||||
#include "slic3r/GUI/DeviceCore/DevManager.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@@ -26,129 +23,43 @@ AgentInfo QidiPrinterAgent::get_agent_info_static()
|
||||
|
||||
bool QidiPrinterAgent::fetch_filament_info(std::string dev_id)
|
||||
{
|
||||
// Look up MachineObject via DeviceManager
|
||||
auto* dev_manager = GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev_manager) {
|
||||
BOOST_LOG_TRIVIAL(error) << "QidiPrinterAgent::fetch_filament_info: DeviceManager is null";
|
||||
return false;
|
||||
}
|
||||
MachineObject* obj = dev_manager->get_my_machine(dev_id);
|
||||
if (!obj) {
|
||||
BOOST_LOG_TRIVIAL(error) << "QidiPrinterAgent::fetch_filament_info: MachineObject not found for dev_id=" << dev_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<QidiSlotInfo> slots;
|
||||
int box_count = 0;
|
||||
std::string error;
|
||||
if (!fetch_slot_info(device_info.base_url, device_info.api_key, slots, box_count, error)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "QidiPrinterAgent::fetch_filament_info: Failed to fetch slot info: " << error;
|
||||
return false;
|
||||
std::string error;
|
||||
|
||||
// 1. Fetch device info and infer series_id
|
||||
std::string series_id;
|
||||
{
|
||||
MoonrakerDeviceInfo info;
|
||||
if (fetch_device_info(device_info.base_url, device_info.api_key, info, error)) {
|
||||
series_id = infer_series_id(info.model_id, info.dev_name);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Fetch filament dictionary
|
||||
QidiFilamentDict dict;
|
||||
if (!fetch_filament_dict(device_info.base_url, device_info.api_key, dict, error)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "QidiPrinterAgent::fetch_filament_info: Failed to fetch filament dict: " << error;
|
||||
}
|
||||
|
||||
std::string series_id;
|
||||
{
|
||||
MoonrakerDeviceInfo info;
|
||||
std::string device_error;
|
||||
if (fetch_device_info(device_info.base_url, device_info.api_key, info, device_error)) {
|
||||
series_id = infer_series_id(info.model_id, info.dev_name);
|
||||
}
|
||||
// 3. Fetch slot info and build AmsTrayData directly
|
||||
std::vector<AmsTrayData> trays;
|
||||
int box_count = 0;
|
||||
if (!fetch_slot_info(device_info.base_url, device_info.api_key, dict, series_id, trays, box_count, error)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "QidiPrinterAgent::fetch_filament_info: Failed to fetch slot info: " << error;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto build_setting_id = [&](const QidiSlotInfo& slot, const std::string& tray_type) {
|
||||
const int vendor = (slot.vendor_type == 1) ? 1 : 0;
|
||||
if (is_numeric(series_id) && slot.filament_type > 0) {
|
||||
return "QD_" + series_id + "_" + std::to_string(vendor) + "_" + std::to_string(slot.filament_type);
|
||||
}
|
||||
return map_filament_type_to_setting_id(tray_type);
|
||||
};
|
||||
|
||||
// Build BBL-format JSON for DevFilaSystemParser::ParseV1_0
|
||||
// The expected format matches BBL's print.push_status AMS subset
|
||||
nlohmann::json ams_json = nlohmann::json::object();
|
||||
nlohmann::json ams_array = nlohmann::json::array();
|
||||
|
||||
// Calculate ams_exist_bits and tray_exist_bits
|
||||
unsigned long ams_exist_bits = 0;
|
||||
unsigned long tray_exist_bits = 0;
|
||||
|
||||
for (int ams_id = 0; ams_id < box_count; ++ams_id) {
|
||||
ams_exist_bits |= (1 << ams_id);
|
||||
|
||||
nlohmann::json ams_unit = nlohmann::json::object();
|
||||
ams_unit["id"] = std::to_string(ams_id);
|
||||
ams_unit["info"] = "2100"; // AMS_LITE type (2), main extruder (0)
|
||||
|
||||
nlohmann::json tray_array = nlohmann::json::array();
|
||||
for (int slot_id = 0; slot_id < 4; ++slot_id) {
|
||||
const int slot_index = ams_id * 4 + slot_id;
|
||||
const QidiSlotInfo slot = slot_index < static_cast<int>(slots.size()) ? slots[slot_index] : QidiSlotInfo{};
|
||||
|
||||
nlohmann::json tray_json = nlohmann::json::object();
|
||||
tray_json["id"] = std::to_string(slot_id);
|
||||
tray_json["tag_uid"] = "0000000000000000";
|
||||
|
||||
if (slot.filament_exists) {
|
||||
tray_exist_bits |= (1 << slot_index);
|
||||
|
||||
std::string filament_type = "PLA";
|
||||
auto filament_it = dict.filaments.find(slot.filament_type);
|
||||
if (filament_it != dict.filaments.end()) {
|
||||
filament_type = filament_it->second;
|
||||
}
|
||||
std::string tray_type = normalize_filament_type(filament_type);
|
||||
std::string setting_id = build_setting_id(slot, tray_type);
|
||||
|
||||
std::string color = "FFFFFFFF";
|
||||
auto color_it = dict.colors.find(slot.color_index);
|
||||
if (color_it != dict.colors.end()) {
|
||||
color = normalize_color(color_it->second);
|
||||
}
|
||||
|
||||
tray_json["tray_info_idx"] = setting_id;
|
||||
tray_json["tray_type"] = tray_type;
|
||||
tray_json["tray_color"] = color;
|
||||
} else {
|
||||
tray_json["tray_info_idx"] = "";
|
||||
tray_json["tray_type"] = "";
|
||||
tray_json["tray_color"] = "00000000";
|
||||
}
|
||||
|
||||
tray_array.push_back(tray_json);
|
||||
}
|
||||
ams_unit["tray"] = tray_array;
|
||||
ams_array.push_back(ams_unit);
|
||||
}
|
||||
|
||||
// Format as hex strings (matching BBL protocol)
|
||||
std::ostringstream ams_exist_ss;
|
||||
ams_exist_ss << std::hex << std::uppercase << ams_exist_bits;
|
||||
std::ostringstream tray_exist_ss;
|
||||
tray_exist_ss << std::hex << std::uppercase << tray_exist_bits;
|
||||
|
||||
ams_json["ams"] = ams_array;
|
||||
ams_json["ams_exist_bits"] = ams_exist_ss.str();
|
||||
ams_json["tray_exist_bits"] = tray_exist_ss.str();
|
||||
|
||||
// Wrap in the expected structure for ParseV1_0
|
||||
nlohmann::json print_json = nlohmann::json::object();
|
||||
print_json["ams"] = ams_json;
|
||||
|
||||
// Call the parser to populate DevFilaSystem
|
||||
DevFilaSystemParser::ParseV1_0(print_json, obj, obj->GetFilaSystem(), false);
|
||||
// 4. Build the AMS payload
|
||||
build_ams_payload(box_count, trays);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QidiPrinterAgent::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 QidiPrinterAgent::fetch_slot_info(const std::string& base_url,
|
||||
const std::string& api_key,
|
||||
const QidiFilamentDict& dict,
|
||||
const std::string& series_id,
|
||||
std::vector<AmsTrayData>& trays,
|
||||
int& box_count,
|
||||
std::string& error)
|
||||
{
|
||||
std::string url = join_url(base_url, "/printer/objects/query?save_variables=variables");
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
@@ -207,26 +118,58 @@ bool QidiPrinterAgent::fetch_slot_info(const std::string& base_url,
|
||||
}
|
||||
|
||||
const int max_slots = box_count * 4;
|
||||
slots.clear();
|
||||
slots.reserve(max_slots);
|
||||
trays.clear();
|
||||
trays.reserve(max_slots);
|
||||
|
||||
// Lambda to build setting_id from slot data
|
||||
auto build_setting_id = [&](int filament_type_idx, int vendor_type, const std::string& tray_type) {
|
||||
const int vendor = (vendor_type == 1) ? 1 : 0;
|
||||
if (is_numeric(series_id) && filament_type_idx > 0) {
|
||||
return "QD_" + series_id + "_" + std::to_string(vendor) + "_" + std::to_string(filament_type_idx);
|
||||
}
|
||||
return map_filament_type_to_setting_id(tray_type);
|
||||
};
|
||||
|
||||
for (int i = 0; i < max_slots; ++i) {
|
||||
QidiSlotInfo slot;
|
||||
slot.slot_index = i;
|
||||
slot.color_index = variables.value("color_slot" + std::to_string(i), 1);
|
||||
slot.filament_type = variables.value("filament_slot" + std::to_string(i), 1);
|
||||
slot.vendor_type = variables.value("vendor_slot" + std::to_string(i), 0);
|
||||
AmsTrayData tray;
|
||||
tray.slot_index = i;
|
||||
|
||||
// Read slot variables
|
||||
const int color_index = variables.value("color_slot" + std::to_string(i), 1);
|
||||
const int filament_type = variables.value("filament_slot" + std::to_string(i), 1);
|
||||
const int vendor_type = variables.value("vendor_slot" + std::to_string(i), 0);
|
||||
|
||||
// Check filament presence via runout sensor
|
||||
std::string box_stepper_key = "box_stepper slot" + std::to_string(i);
|
||||
slot.filament_exists = false;
|
||||
tray.has_filament = false;
|
||||
if (status.contains(box_stepper_key)) {
|
||||
auto& box_stepper = status[box_stepper_key];
|
||||
if (box_stepper.contains("runout_button") && !box_stepper["runout_button"].is_null()) {
|
||||
int runout_button = box_stepper["runout_button"].get<int>();
|
||||
slot.filament_exists = (runout_button == 0);
|
||||
int runout_button = box_stepper["runout_button"].template get<int>();
|
||||
tray.has_filament = (runout_button == 0);
|
||||
}
|
||||
}
|
||||
slots.push_back(slot);
|
||||
|
||||
if (tray.has_filament) {
|
||||
// Look up filament type name from dictionary
|
||||
std::string filament_name = "PLA";
|
||||
auto filament_it = dict.filaments.find(filament_type);
|
||||
if (filament_it != dict.filaments.end()) {
|
||||
filament_name = filament_it->second;
|
||||
}
|
||||
tray.tray_type = normalize_filament_type(filament_name);
|
||||
tray.tray_info_idx = build_setting_id(filament_type, vendor_type, tray.tray_type);
|
||||
|
||||
// Look up color from dictionary
|
||||
auto color_it = dict.colors.find(color_index);
|
||||
if (color_it != dict.colors.end()) {
|
||||
tray.tray_color = color_it->second;
|
||||
} else {
|
||||
tray.tray_color = "FFFFFFFF";
|
||||
}
|
||||
}
|
||||
|
||||
trays.push_back(tray);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -348,31 +291,6 @@ void QidiPrinterAgent::parse_filament_sections(const std::string& content, std::
|
||||
}
|
||||
}
|
||||
|
||||
std::string QidiPrinterAgent::normalize_color(const std::string& color)
|
||||
{
|
||||
std::string value = color;
|
||||
boost::trim(value);
|
||||
if (value.rfind("0x", 0) == 0 || value.rfind("0X", 0) == 0) {
|
||||
value = value.substr(2);
|
||||
}
|
||||
if (!value.empty() && value[0] == '#') {
|
||||
value = value.substr(1);
|
||||
}
|
||||
std::string normalized;
|
||||
for (char c : value) {
|
||||
if (std::isxdigit(static_cast<unsigned char>(c))) {
|
||||
normalized.push_back(static_cast<char>(std::toupper(static_cast<unsigned char>(c))));
|
||||
}
|
||||
}
|
||||
if (normalized.size() == 6) {
|
||||
normalized += "FF";
|
||||
}
|
||||
if (normalized.size() != 8) {
|
||||
return "00000000";
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
std::string QidiPrinterAgent::map_filament_type_to_setting_id(const std::string& filament_type)
|
||||
{
|
||||
std::string upper = filament_type;
|
||||
|
||||
@@ -22,16 +22,6 @@ public:
|
||||
bool fetch_filament_info(std::string dev_id) override;
|
||||
|
||||
private:
|
||||
// Qidi-specific device info (extends base MoonrakerDeviceInfo with model_id)
|
||||
struct QidiSlotInfo
|
||||
{
|
||||
int slot_index = 0;
|
||||
int color_index = 0;
|
||||
int filament_type = 0;
|
||||
int vendor_type = 0;
|
||||
bool filament_exists = false;
|
||||
};
|
||||
|
||||
struct QidiFilamentDict
|
||||
{
|
||||
std::map<int, std::string> colors;
|
||||
@@ -39,11 +29,13 @@ private:
|
||||
};
|
||||
|
||||
// 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_slot_info(const std::string& base_url,
|
||||
const std::string& api_key,
|
||||
const QidiFilamentDict& dict,
|
||||
const std::string& series_id,
|
||||
std::vector<AmsTrayData>& trays,
|
||||
int& box_count,
|
||||
std::string& error);
|
||||
bool fetch_filament_dict(const std::string& base_url, const std::string& api_key, QidiFilamentDict& dict, std::string& error) const;
|
||||
std::string normalize_filament_type(const std::string& filament_type);
|
||||
std::string infer_series_id(const std::string& model_id, const std::string& dev_name);
|
||||
@@ -52,7 +44,6 @@ private:
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user