mirror of
https://github.com/ClusterM/open-bamboo-networking.git
synced 2026-10-22 11:02:26 -05:00
215 lines
8.4 KiB
C++
215 lines
8.4 KiB
C++
#include "print_params_io.hpp"
|
|
|
|
#include <fstream>
|
|
#include <stdexcept>
|
|
#include <unordered_set>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
namespace obn::plugin_runner {
|
|
|
|
namespace {
|
|
|
|
using json = nlohmann::json;
|
|
|
|
// Per-type setters. Each returns true if it actually mutated `dst`; the
|
|
// caller decides what to log.
|
|
bool set_string(const json& src, const char* key, std::string& dst,
|
|
std::vector<std::string>& warnings)
|
|
{
|
|
auto it = src.find(key);
|
|
if (it == src.end()) return false;
|
|
if (!it->is_string()) {
|
|
warnings.emplace_back(std::string("'") + key + "' must be a string, ignoring");
|
|
return false;
|
|
}
|
|
dst = it->get<std::string>();
|
|
return true;
|
|
}
|
|
|
|
bool set_int(const json& src, const char* key, int& dst,
|
|
std::vector<std::string>& warnings)
|
|
{
|
|
auto it = src.find(key);
|
|
if (it == src.end()) return false;
|
|
if (!it->is_number_integer()) {
|
|
warnings.emplace_back(std::string("'") + key + "' must be an integer, ignoring");
|
|
return false;
|
|
}
|
|
dst = it->get<int>();
|
|
return true;
|
|
}
|
|
|
|
bool set_bool(const json& src, const char* key, bool& dst,
|
|
std::vector<std::string>& warnings)
|
|
{
|
|
auto it = src.find(key);
|
|
if (it == src.end()) return false;
|
|
if (!it->is_boolean()) {
|
|
warnings.emplace_back(std::string("'") + key + "' must be a boolean, ignoring");
|
|
return false;
|
|
}
|
|
dst = it->get<bool>();
|
|
return true;
|
|
}
|
|
|
|
// Allow-list of every PrintParams field this loader knows how to set.
|
|
// Anything else in the JSON triggers a `params_warning` event so users
|
|
// notice typos instead of silently sending defaults. Keep in sync with
|
|
// `BBL::PrintParams` in include/obn/bambu_networking.hpp (the snapshots
|
|
// under tools/abi_snapshot/v<MM.mm.pp>/ are the canonical record per
|
|
// ABI version) and with the per-field setter calls in
|
|
// load_print_params_overrides() below.
|
|
const std::unordered_set<std::string> kKnownKeys = {
|
|
"dev_id", "task_name", "project_name", "preset_name", "filename",
|
|
"config_filename", "plate_index", "ftp_folder", "ftp_file",
|
|
"ftp_file_md5", "nozzle_mapping", "ams_mapping", "ams_mapping2",
|
|
"ams_mapping_info", "nozzles_info", "connection_type", "comments",
|
|
"origin_profile_id", "stl_design_id", "origin_model_id",
|
|
"print_type", "dst_file", "dev_name", "dev_ip", "use_ssl_for_ftp",
|
|
"use_ssl_for_mqtt", "username", "password", "task_bed_leveling",
|
|
"task_flow_cali", "task_vibration_cali", "task_layer_inspect",
|
|
"task_record_timelapse",
|
|
#if ABI_VERSION >= 0x020503
|
|
"task_timelapse_use_internal",
|
|
#endif
|
|
"task_use_ams", "task_bed_type", "extra_options", "auto_bed_leveling",
|
|
"auto_flow_cali", "auto_offset_cali",
|
|
#if ABI_VERSION >= 0x020400
|
|
"extruder_cali_manual_mode",
|
|
#endif
|
|
"task_ext_change_assist", "try_emmc_print",
|
|
#if ABI_VERSION >= 0x020701
|
|
"svc_context",
|
|
#endif
|
|
#if ABI_VERSION >= 0x020801
|
|
"slicer_uid",
|
|
#endif
|
|
#if ABI_VERSION >= 0x020802
|
|
"queue_plate_id",
|
|
#endif
|
|
};
|
|
|
|
void warn_unknown(const json& src, std::vector<std::string>& warnings)
|
|
{
|
|
for (auto it = src.begin(); it != src.end(); ++it) {
|
|
const std::string& key = it.key();
|
|
if (kKnownKeys.find(key) == kKnownKeys.end()) {
|
|
warnings.emplace_back("unknown key '" + key + "' in params JSON — ignoring");
|
|
}
|
|
}
|
|
}
|
|
|
|
void apply_overlay(const json& j, BBL::PrintParams& p,
|
|
std::vector<std::string>& w)
|
|
{
|
|
set_string(j, "dev_id", p.dev_id, w);
|
|
set_string(j, "task_name", p.task_name, w);
|
|
set_string(j, "project_name", p.project_name, w);
|
|
set_string(j, "preset_name", p.preset_name, w);
|
|
set_string(j, "filename", p.filename, w);
|
|
set_string(j, "config_filename", p.config_filename, w);
|
|
set_int (j, "plate_index", p.plate_index, w);
|
|
set_string(j, "ftp_folder", p.ftp_folder, w);
|
|
set_string(j, "ftp_file", p.ftp_file, w);
|
|
set_string(j, "ftp_file_md5", p.ftp_file_md5, w);
|
|
set_string(j, "nozzle_mapping", p.nozzle_mapping, w);
|
|
set_string(j, "ams_mapping", p.ams_mapping, w);
|
|
set_string(j, "ams_mapping2", p.ams_mapping2, w);
|
|
set_string(j, "ams_mapping_info", p.ams_mapping_info, w);
|
|
set_string(j, "nozzles_info", p.nozzles_info, w);
|
|
set_string(j, "connection_type", p.connection_type, w);
|
|
set_string(j, "comments", p.comments, w);
|
|
set_int (j, "origin_profile_id", p.origin_profile_id, w);
|
|
set_int (j, "stl_design_id", p.stl_design_id, w);
|
|
set_string(j, "origin_model_id", p.origin_model_id, w);
|
|
set_string(j, "print_type", p.print_type, w);
|
|
set_string(j, "dst_file", p.dst_file, w);
|
|
set_string(j, "dev_name", p.dev_name, w);
|
|
|
|
set_string(j, "dev_ip", p.dev_ip, w);
|
|
set_bool (j, "use_ssl_for_ftp", p.use_ssl_for_ftp, w);
|
|
set_bool (j, "use_ssl_for_mqtt", p.use_ssl_for_mqtt, w);
|
|
set_string(j, "username", p.username, w);
|
|
set_string(j, "password", p.password, w);
|
|
|
|
set_bool (j, "task_bed_leveling", p.task_bed_leveling, w);
|
|
set_bool (j, "task_flow_cali", p.task_flow_cali, w);
|
|
set_bool (j, "task_vibration_cali", p.task_vibration_cali, w);
|
|
set_bool (j, "task_layer_inspect", p.task_layer_inspect, w);
|
|
set_bool (j, "task_record_timelapse", p.task_record_timelapse, w);
|
|
#if ABI_VERSION >= 0x020503
|
|
set_bool (j, "task_timelapse_use_internal", p.task_timelapse_use_internal, w);
|
|
#else
|
|
if (j.contains("task_timelapse_use_internal")) {
|
|
w.emplace_back("'task_timelapse_use_internal' present but ABI < 0x020503; "
|
|
"skipping (rebuild plugin_runner with newer --abi)");
|
|
}
|
|
#endif
|
|
set_bool (j, "task_use_ams", p.task_use_ams, w);
|
|
set_string(j, "task_bed_type", p.task_bed_type, w);
|
|
set_string(j, "extra_options", p.extra_options, w);
|
|
set_int (j, "auto_bed_leveling", p.auto_bed_leveling, w);
|
|
set_int (j, "auto_flow_cali", p.auto_flow_cali, w);
|
|
set_int (j, "auto_offset_cali", p.auto_offset_cali, w);
|
|
#if ABI_VERSION >= 0x020400
|
|
set_int (j, "extruder_cali_manual_mode", p.extruder_cali_manual_mode, w);
|
|
#else
|
|
if (j.contains("extruder_cali_manual_mode")) {
|
|
w.emplace_back("'extruder_cali_manual_mode' present but ABI < 0x020400; "
|
|
"skipping (rebuild plugin_runner with newer --abi)");
|
|
}
|
|
#endif
|
|
set_bool (j, "task_ext_change_assist", p.task_ext_change_assist, w);
|
|
set_bool (j, "try_emmc_print", p.try_emmc_print, w);
|
|
#if ABI_VERSION >= 0x020701
|
|
set_string(j, "svc_context", p.svc_context, w);
|
|
#else
|
|
if (j.contains("svc_context")) {
|
|
w.emplace_back("'svc_context' present but ABI < 0x020701; "
|
|
"skipping (rebuild plugin_runner with newer --abi)");
|
|
}
|
|
#endif
|
|
#if ABI_VERSION >= 0x020801
|
|
set_string(j, "slicer_uid", p.slicer_uid, w);
|
|
#else
|
|
if (j.contains("slicer_uid")) {
|
|
w.emplace_back("'slicer_uid' present but ABI < 0x020801; "
|
|
"skipping (rebuild plugin_runner with newer --abi)");
|
|
}
|
|
#endif
|
|
#if ABI_VERSION >= 0x020802
|
|
set_string(j, "queue_plate_id", p.queue_plate_id, w);
|
|
#else
|
|
if (j.contains("queue_plate_id")) {
|
|
w.emplace_back("'queue_plate_id' present but ABI < 0x020802; "
|
|
"skipping (rebuild plugin_runner with newer --abi)");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void load_print_params_from_json(const std::string& json_path,
|
|
BBL::PrintParams& out,
|
|
std::vector<std::string>& warnings)
|
|
{
|
|
std::ifstream ifs(json_path);
|
|
if (!ifs) {
|
|
throw std::runtime_error("cannot open " + json_path + " for reading");
|
|
}
|
|
json j;
|
|
try {
|
|
ifs >> j;
|
|
} catch (const std::exception& e) {
|
|
throw std::runtime_error("failed to parse " + json_path + ": " + e.what());
|
|
}
|
|
if (!j.is_object()) {
|
|
throw std::runtime_error(json_path + " must contain a JSON object at the top level");
|
|
}
|
|
warn_unknown(j, warnings);
|
|
apply_overlay(j, out, warnings);
|
|
}
|
|
|
|
} // namespace obn::plugin_runner
|