mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-27 12:52:07 +00:00
ENH: clean codes about device
JIRA: [STUDIO-13609] Change-Id: I591de7033360b9570600006cfbce2148a8d031d5 (cherry picked from commit e9c774be8f4c89b8dafa14ef56913612fb68bd0c)
This commit is contained in:
52
src/slic3r/GUI/DeviceCore/CMakeLists.txt
Normal file
52
src/slic3r/GUI/DeviceCore/CMakeLists.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
# GUI/DeviceCore
|
||||
# usage -- none GUI structure about device
|
||||
# date -- 2025.07.14
|
||||
# status -- Building
|
||||
|
||||
list(APPEND SLIC3R_GUI_SOURCES
|
||||
GUI/DeviceCore/DevBed.cpp
|
||||
GUI/DeviceCore/DevBed.h
|
||||
GUI/DeviceCore/DevConfig.h
|
||||
GUI/DeviceCore/DevConfig.cpp
|
||||
GUI/DeviceCore/DevConfigUtil.h
|
||||
GUI/DeviceCore/DevConfigUtil.cpp
|
||||
GUI/DeviceCore/DevCtrl.h
|
||||
GUI/DeviceCore/DevCtrl.cpp
|
||||
GUI/DeviceCore/DevDefs.h
|
||||
GUI/DeviceCore/DevExtruderSystem.h
|
||||
GUI/DeviceCore/DevExtruderSystem.cpp
|
||||
GUI/DeviceCore/DevExtruderSystemCtrl.cpp
|
||||
GUI/DeviceCore/DevFan.cpp
|
||||
GUI/DeviceCore/DevFan.h
|
||||
GUI/DeviceCore/DevFilaAmsSetting.h
|
||||
GUI/DeviceCore/DevFilaAmsSetting.cpp
|
||||
GUI/DeviceCore/DevFilaBlackList.h
|
||||
GUI/DeviceCore/DevFilaBlackList.cpp
|
||||
GUI/DeviceCore/DevFilaSystem.h
|
||||
GUI/DeviceCore/DevFilaSystem.cpp
|
||||
GUI/DeviceCore/DevFirmware.h
|
||||
GUI/DeviceCore/DevFirmware.cpp
|
||||
GUI/DeviceCore/DevPrintOptions.h
|
||||
GUI/DeviceCore/DevPrintOptions.cpp
|
||||
GUI/DeviceCore/DevPrintTaskInfo.h
|
||||
GUI/DeviceCore/DevPrintTaskInfo.cpp
|
||||
GUI/DeviceCore/DevHMS.h
|
||||
GUI/DeviceCore/DevHMS.cpp
|
||||
GUI/DeviceCore/DevStorage.h
|
||||
GUI/DeviceCore/DevStorage.cpp
|
||||
GUI/DeviceCore/DevInfo.h
|
||||
GUI/DeviceCore/DevInfo.cpp
|
||||
GUI/DeviceCore/DevLamp.h
|
||||
GUI/DeviceCore/DevLamp.cpp
|
||||
GUI/DeviceCore/DevLampCtrl.cpp
|
||||
GUI/DeviceCore/DevManager.h
|
||||
GUI/DeviceCore/DevManager.cpp
|
||||
GUI/DeviceCore/DevMapping.h
|
||||
GUI/DeviceCore/DevMapping.cpp
|
||||
GUI/DeviceCore/DevNozzleSystem.h
|
||||
GUI/DeviceCore/DevNozzleSystem.cpp
|
||||
GUI/DeviceCore/DevUtil.h
|
||||
GUI/DeviceCore/DevUtil.cpp
|
||||
|
||||
)
|
||||
set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE)
|
||||
25
src/slic3r/GUI/DeviceCore/DevBed.cpp
Normal file
25
src/slic3r/GUI/DeviceCore/DevBed.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "DevBed.h"
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void DevBed::ParseV1_0(const json &print_json, DevBed *system)
|
||||
{
|
||||
if (print_json.contains("bed_temper")) {
|
||||
if (print_json["bed_temper"].is_number()) { system->bed_temp = print_json["bed_temper"].get<float>(); }
|
||||
}
|
||||
if (print_json.contains("bed_target_temper")) {
|
||||
if (print_json["bed_target_temper"].is_number()) { system->bed_temp_target = print_json["bed_target_temper"].get<float>(); }
|
||||
}
|
||||
}
|
||||
|
||||
void DevBed::ParseV2_0(const json &print_json, DevBed *system)
|
||||
{
|
||||
if (print_json.contains("bed_temp") && print_json["bed_temp"].is_number()) {
|
||||
int bed_temp_bits = print_json["bed_temp"].get<int>();
|
||||
system->bed_temp = system->m_owner->get_flag_bits(bed_temp_bits, 0, 16);
|
||||
system->bed_temp_target = system->m_owner->get_flag_bits(bed_temp_bits, 16, 16);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
30
src/slic3r/GUI/DeviceCore/DevBed.h
Normal file
30
src/slic3r/GUI/DeviceCore/DevBed.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class MachineObject;
|
||||
|
||||
class DevBed
|
||||
{
|
||||
public:
|
||||
DevBed(MachineObject *obj) : m_owner(obj), bed_temp(0.0f), bed_temp_target(0.0f) {}
|
||||
|
||||
float GetBedTemp() { return bed_temp; };
|
||||
float GetBedTempTarget() { return bed_temp_target; };
|
||||
|
||||
public:
|
||||
|
||||
static void ParseV1_0(const json &print_json, DevBed *system);
|
||||
static void ParseV2_0(const json &print_json, DevBed *system);
|
||||
|
||||
private:
|
||||
|
||||
float bed_temp;
|
||||
float bed_temp_target;
|
||||
|
||||
MachineObject* m_owner = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
54
src/slic3r/GUI/DeviceCore/DevConfig.cpp
Normal file
54
src/slic3r/GUI/DeviceCore/DevConfig.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "DevConfig.h"
|
||||
#include "DevUtil.h"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
void DevConfig::ParseConfig(const json& print_json)
|
||||
{
|
||||
ParseChamberConfig(print_json);
|
||||
ParsePrintOptionsConfig(print_json);
|
||||
ParseCalibrationConfig(print_json);
|
||||
|
||||
}
|
||||
|
||||
void DevConfig::ParseChamberConfig(const json& print_json)
|
||||
{
|
||||
DevJsonValParser::ParseVal(print_json, "support_chamber_temp_edit", m_support_chamber_edit);
|
||||
if (m_support_chamber_edit)
|
||||
{
|
||||
if (print_json.contains("support_chamber_temp_edit_range"))
|
||||
{
|
||||
const auto &support_champer_range = print_json["support_chamber_temp_edit_range"];
|
||||
if (support_champer_range.is_array() && support_champer_range.size() > 1) {
|
||||
m_chamber_temp_edit_min = support_champer_range[0];
|
||||
m_chamber_temp_edit_max = support_champer_range[1];
|
||||
}
|
||||
}
|
||||
|
||||
DevJsonValParser::ParseVal(print_json, "support_chamber_temp_switch_heating", m_chamber_temp_switch_heat);
|
||||
}
|
||||
}
|
||||
|
||||
void DevConfig::ParsePrintOptionsConfig(const json& print_json)
|
||||
{
|
||||
DevJsonValParser::ParseVal(print_json, "support_first_layer_inspect", m_support_first_layer_inspect);
|
||||
DevJsonValParser::ParseVal(print_json, "support_save_remote_print_file_to_storage", m_support_save_remote_print_file_to_storage);
|
||||
DevJsonValParser::ParseVal(print_json, "support_ai_monitoring", m_support_ai_monitor);
|
||||
DevJsonValParser::ParseVal(print_json, "support_print_without_sd", m_support_print_without_sd);
|
||||
DevJsonValParser::ParseVal(print_json, "support_print_all", m_support_print_all);
|
||||
}
|
||||
|
||||
void DevConfig::ParseCalibrationConfig(const json& print_json)
|
||||
{
|
||||
DevJsonValParser::ParseVal(print_json, "support_lidar_calibration", m_support_calibration_lidar);
|
||||
DevJsonValParser::ParseVal(print_json, "support_nozzle_offset_calibration", m_support_calibration_nozzle_offset);
|
||||
DevJsonValParser::ParseVal(print_json, "support_high_tempbed_calibration", m_support_calibration_high_temp_bed);
|
||||
DevJsonValParser::ParseVal(print_json, "support_pa_calibration_auto", m_support_calibration_pa_flow_auto);
|
||||
}
|
||||
|
||||
}
|
||||
77
src/slic3r/GUI/DeviceCore/DevConfig.h
Normal file
77
src/slic3r/GUI/DeviceCore/DevConfig.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
//Previous definitions
|
||||
class MachineObject;
|
||||
|
||||
|
||||
class DevConfig
|
||||
{
|
||||
public:
|
||||
DevConfig(MachineObject* obj) : m_obj(obj) {};
|
||||
~DevConfig() = default;
|
||||
|
||||
public:
|
||||
// chamber
|
||||
bool SupportChamberEdit() const { return m_support_chamber_edit; }
|
||||
int GetChamberTempEditMin() const { return m_chamber_temp_edit_min; }
|
||||
int GetChamberTempEditMax() const { return m_chamber_temp_edit_max; }
|
||||
int GetChamberTempSwitchHeat() const { return m_chamber_temp_switch_heat; }
|
||||
|
||||
// print options
|
||||
bool SupportFirstLayerInspect() const { return m_support_first_layer_inspect; }
|
||||
bool SupportSaveRemotePrintFileToStorage() const { return m_support_save_remote_print_file_to_storage; }
|
||||
bool SupportAIMonitor() const { return m_support_ai_monitor; }
|
||||
|
||||
bool SupportPrintWithoutSD() const { return m_support_print_without_sd; }
|
||||
bool SupportPrintAllPlates() const { return m_support_print_all; }
|
||||
|
||||
// calibration options
|
||||
bool SupportCalibrationLidar() const { return m_support_calibration_lidar; }
|
||||
bool SupportCalibrationNozzleOffset() const { return m_support_calibration_nozzle_offset; }
|
||||
bool SupportCalibrationHighTempBed() const { return m_support_calibration_high_temp_bed; }
|
||||
|
||||
bool SupportCalibrationPA_FlowAuto() const { return m_support_calibration_pa_flow_auto; }
|
||||
|
||||
public:
|
||||
/*Setters*/
|
||||
void ParseConfig(const json& print_json);
|
||||
|
||||
void ParseChamberConfig(const json& print_json); // chamber
|
||||
void ParsePrintOptionsConfig(const json& print_json); // print options
|
||||
void ParseCalibrationConfig(const json& print_json); //cali
|
||||
|
||||
private:
|
||||
MachineObject* m_obj;
|
||||
|
||||
/*configure vals*/
|
||||
// chamber
|
||||
bool m_support_chamber_edit = false;
|
||||
int m_chamber_temp_edit_min = 0;
|
||||
int m_chamber_temp_edit_max = 60;
|
||||
int m_chamber_temp_switch_heat = LONG_MAX; /* the min temp to start heating, default to LONG_MAX */
|
||||
|
||||
// print options
|
||||
bool m_support_first_layer_inspect = false;
|
||||
bool m_support_save_remote_print_file_to_storage = false;
|
||||
bool m_support_ai_monitor = false;
|
||||
|
||||
bool m_support_print_without_sd = false;
|
||||
bool m_support_print_all = false;
|
||||
|
||||
// calibration options
|
||||
bool m_support_calibration_lidar = false;
|
||||
bool m_support_calibration_nozzle_offset = false;
|
||||
bool m_support_calibration_high_temp_bed = false; // High-temperature Heatbed Calibration
|
||||
|
||||
bool m_support_calibration_pa_flow_auto = false;// PA flow calibration. used in SendPrint
|
||||
};
|
||||
|
||||
};
|
||||
167
src/slic3r/GUI/DeviceCore/DevConfigUtil.cpp
Normal file
167
src/slic3r/GUI/DeviceCore/DevConfigUtil.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#include "DevConfigUtil.h"
|
||||
|
||||
#include <wx/dir.h>
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
std::string DevPrinterConfigUtil::m_resource_file_path = "";
|
||||
|
||||
|
||||
std::map<std::string, std::string> DevPrinterConfigUtil::get_all_model_id_with_name()
|
||||
{
|
||||
{
|
||||
std::map<std::string, std::string> models;
|
||||
|
||||
wxDir dir(m_resource_file_path + "/printers/");
|
||||
if (!dir.IsOpened())
|
||||
{
|
||||
return models;
|
||||
}
|
||||
|
||||
wxString filename;
|
||||
std::vector<wxString> m_files;
|
||||
bool hasFile = dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES);
|
||||
while (hasFile)
|
||||
{
|
||||
m_files.push_back(filename);
|
||||
hasFile = dir.GetNext(&filename);
|
||||
}
|
||||
|
||||
for (wxString file : m_files)
|
||||
{
|
||||
if (!file.Lower().ends_with(".json")) continue;
|
||||
|
||||
std::string config_file = m_resource_file_path + "/printers/" + file.ToStdString();
|
||||
boost::nowide::ifstream json_file(config_file.c_str());
|
||||
|
||||
try
|
||||
{
|
||||
json jj;
|
||||
if (json_file.is_open())
|
||||
{
|
||||
json_file >> jj;
|
||||
if (jj.contains("00.00.00.00"))
|
||||
{
|
||||
json const& printer = jj["00.00.00.00"];
|
||||
|
||||
std::string model_id;
|
||||
std::string display_name;
|
||||
if (printer.contains("model_id")) { model_id = printer["model_id"].get<std::string>(); }
|
||||
if (printer.contains("display_name")) { display_name = printer["display_name"].get<std::string>(); }
|
||||
models[display_name] = model_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
return models;
|
||||
}
|
||||
}
|
||||
|
||||
PrinterArch DevPrinterConfigUtil::get_printer_arch(std::string type_str)
|
||||
{
|
||||
const std::string& arch_str = get_value_from_config<std::string>(type_str, "printer_arch");
|
||||
if (arch_str == "i3")
|
||||
{
|
||||
return PrinterArch::ARCH_I3;
|
||||
}
|
||||
else if (arch_str == "core_xy")
|
||||
{
|
||||
return PrinterArch::ARCH_CORE_XY;
|
||||
}
|
||||
|
||||
return PrinterArch::ARCH_CORE_XY;
|
||||
}
|
||||
|
||||
std::string DevPrinterConfigUtil::get_printer_ext_img(const std::string& type_str, int pos)
|
||||
{
|
||||
const auto& vec = get_value_from_config<std::vector<std::string>>(type_str, "printer_ext_image");
|
||||
return (vec.size() > pos) ? vec[pos] : std::string();
|
||||
};
|
||||
|
||||
std::string DevPrinterConfigUtil::get_fan_text(const std::string& type_str, const std::string& key)
|
||||
{
|
||||
std::vector<std::string> filaments;
|
||||
std::string config_file = m_resource_file_path + "/printers/" + type_str + ".json";
|
||||
boost::nowide::ifstream json_file(config_file.c_str());
|
||||
try
|
||||
{
|
||||
json jj;
|
||||
if (json_file.is_open())
|
||||
{
|
||||
json_file >> jj;
|
||||
if (jj.contains("00.00.00.00"))
|
||||
{
|
||||
json const& printer = jj["00.00.00.00"];
|
||||
if (printer.contains("fan") && printer["fan"].contains(key))
|
||||
{
|
||||
return printer["fan"][key].get<std::string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<std::string>> DevPrinterConfigUtil::get_all_subseries(std::string type_str)
|
||||
{
|
||||
std::map<std::string, std::vector<std::string>> subseries;
|
||||
std::vector<wxString> m_files;
|
||||
|
||||
wxDir dir(m_resource_file_path + "/printers/");
|
||||
if (!dir.IsOpened()) { return subseries; }
|
||||
|
||||
wxString filename;
|
||||
bool hasFile = dir.GetFirst(&filename, "*.json", wxDIR_FILES);
|
||||
while (hasFile)
|
||||
{
|
||||
m_files.push_back(filename);
|
||||
hasFile = dir.GetNext(&filename);
|
||||
}
|
||||
|
||||
for (wxString file : m_files)
|
||||
{
|
||||
std::string config_file = m_resource_file_path + "/printers/" + file.ToStdString();
|
||||
boost::nowide::ifstream json_file(config_file.c_str());
|
||||
|
||||
try
|
||||
{
|
||||
json jj;
|
||||
if (json_file.is_open())
|
||||
{
|
||||
json_file >> jj;
|
||||
if (jj.contains("00.00.00.00"))
|
||||
{
|
||||
|
||||
json const& printer = jj["00.00.00.00"];
|
||||
if (printer.contains("subseries"))
|
||||
{
|
||||
std::vector<std::string> subs;
|
||||
|
||||
std::string model_id = printer["model_id"].get<std::string>();
|
||||
if (model_id == type_str || type_str.empty())
|
||||
{
|
||||
for (auto res : printer["subseries"])
|
||||
{
|
||||
subs.emplace_back(res.get<std::string>());
|
||||
}
|
||||
}
|
||||
subseries.insert(make_pair(model_id, subs));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
return subseries;
|
||||
}
|
||||
|
||||
};
|
||||
174
src/slic3r/GUI/DeviceCore/DevConfigUtil.h
Normal file
174
src/slic3r/GUI/DeviceCore/DevConfigUtil.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @file DevConfigUtil.h
|
||||
* @brief Parses configuration files and provides access to printer options.
|
||||
*
|
||||
* This class loads a configuration file and allows querying options by key.
|
||||
* The configuration file format is expected to be key-value pairs (e.g., INI or simple text).
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "slic3r/GUI/DeviceCore/DevDefs.h"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
class dePrinterConfigFactory
|
||||
{
|
||||
public:
|
||||
dePrinterConfigFactory() = default;
|
||||
~dePrinterConfigFactory() = default;
|
||||
};
|
||||
|
||||
|
||||
class DevPrinterConfigUtil
|
||||
{
|
||||
public:
|
||||
DevPrinterConfigUtil() = default;
|
||||
~DevPrinterConfigUtil() = default;
|
||||
|
||||
public:
|
||||
static void InitFilePath(const std::string& res_file_path) { m_resource_file_path = res_file_path; };
|
||||
|
||||
/*printer*/
|
||||
// info
|
||||
static std::map<std::string, std::string> get_all_model_id_with_name();
|
||||
static std::string get_printer_type(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "printer_type"); }
|
||||
static std::string get_printer_display_name(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "display_name"); }
|
||||
static std::string get_printer_series_str(std::string type_str) { return get_value_from_config<std::string>(type_str, "printer_series"); }
|
||||
static PrinterArch get_printer_arch(std::string type_str);
|
||||
|
||||
// images
|
||||
static std::string get_printer_thumbnail_img(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "printer_thumbnail_image"); }
|
||||
static std::string get_printer_connect_help_img(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "printer_connect_help_image"); }
|
||||
static std::string get_printer_auto_pa_cali_image(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "auto_pa_cali_thumbnail_image"); }
|
||||
|
||||
/*media*/
|
||||
static std::string get_ftp_folder(std::string type_str) { return get_value_from_config<std::string>(type_str, "ftp_folder"); }
|
||||
static std::vector<std::string> get_resolution_supported(std::string type_str) { return get_value_from_config<std::vector<std::string>>(type_str, "camera_resolution"); }
|
||||
static std::vector<std::string> get_compatible_machine(std::string type_str) { return get_value_from_config<std::vector<std::string>>(type_str, "compatible_machine"); }
|
||||
static std::map<std::string, std::vector<std::string>> get_all_subseries(std::string type_str = "");
|
||||
|
||||
/*ams*/
|
||||
static std::string get_printer_use_ams_type(std::string type_str) { return get_value_from_config<std::string>(type_str, "use_ams_type"); }
|
||||
static std::string get_printer_ams_img(const std::string& type_str) { return get_value_from_config<std::string>(type_str, "printer_use_ams_image"); }
|
||||
static std::string get_printer_ext_img(const std::string& type_str, int pos);//printer_ext_image
|
||||
|
||||
/*fan*/
|
||||
static std::string get_fan_text(const std::string& type_str, const std::string& key);
|
||||
|
||||
/*extruder*/
|
||||
static bool get_printer_can_set_nozzle(std::string type_str) { return get_value_from_config<bool>(type_str, "enable_set_nozzle_info"); }// can set nozzle from studio
|
||||
|
||||
/*calibration*/
|
||||
static std::vector<std::string> get_unsupport_auto_cali_filaments(std::string type_str) { return get_value_from_config<std::vector<std::string>>(type_str, "auto_cali_not_support_filaments"); }
|
||||
|
||||
/*detection*/
|
||||
static bool support_wrapping_detection(const std::string& type_str) { return get_value_from_config<bool>(type_str, "support_wrapping_deteciton"); }
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
static T get_value_from_config(const std::string& type_str, const std::string& item)
|
||||
{
|
||||
std::string config_file = m_resource_file_path + "/printers/" + type_str + ".json";
|
||||
boost::nowide::ifstream json_file(config_file.c_str());
|
||||
try
|
||||
{
|
||||
nlohmann::json jj;
|
||||
if (json_file.is_open())
|
||||
{
|
||||
json_file >> jj;
|
||||
if (jj.contains("00.00.00.00"))
|
||||
{
|
||||
nlohmann::json const& printer = jj["00.00.00.00"];
|
||||
if (printer.contains(item))
|
||||
{
|
||||
return printer[item].get<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) { assert(0 && "get_value_from_config failed"); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " failed"; }// there are file errors
|
||||
return T();
|
||||
};
|
||||
|
||||
static nlohmann::json get_json_from_config(const std::string& type_str, const std::string& key1, const std::string& key2 = std::string())
|
||||
{
|
||||
std::string config_file = m_resource_file_path + "/printers/" + type_str + ".json";
|
||||
boost::nowide::ifstream json_file(config_file.c_str());
|
||||
try
|
||||
{
|
||||
nlohmann::json jj;
|
||||
if (json_file.is_open())
|
||||
{
|
||||
json_file >> jj;
|
||||
if (jj.contains("00.00.00.00"))
|
||||
{
|
||||
nlohmann::json const& printer = jj["00.00.00.00"];
|
||||
if (printer.contains(key1))
|
||||
{
|
||||
nlohmann::json const& key1_item = printer[key1];
|
||||
if (key2.empty())
|
||||
{
|
||||
return key1_item;
|
||||
}
|
||||
|
||||
if (key1_item.contains(key2))
|
||||
{
|
||||
return key1_item[key2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) { assert(0 && "get_json_from_config failed"); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " failed"; }// there are file errors
|
||||
return nlohmann::json();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::string m_resource_file_path; // Path to the configuration file
|
||||
};
|
||||
|
||||
/*special transform*/
|
||||
static std::string _parse_printer_type(const std::string& type_str)
|
||||
{
|
||||
if (type_str.compare("3DPrinter-X1") == 0)
|
||||
{
|
||||
return "BL-P002";
|
||||
}
|
||||
else if (type_str.compare("3DPrinter-X1-Carbon") == 0)
|
||||
{
|
||||
return "BL-P001";
|
||||
}
|
||||
else if (type_str.compare("BL-P001") == 0)
|
||||
{
|
||||
return type_str;
|
||||
}
|
||||
else if (type_str.compare("BL-P002") == 0)
|
||||
{
|
||||
return type_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string result = DevPrinterConfigUtil::get_printer_type(type_str);
|
||||
if (!result.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0 && __FUNCTION__);
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Unsupported printer type: " << type_str;
|
||||
return type_str;
|
||||
}
|
||||
|
||||
};// namespace Slic3r
|
||||
26
src/slic3r/GUI/DeviceCore/DevCtrl.cpp
Normal file
26
src/slic3r/GUI/DeviceCore/DevCtrl.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevCtrl.h"
|
||||
|
||||
// TODO: remove this include
|
||||
#include "DevUtil.h"
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
int DevCtrl::command_select_extruder(int id)
|
||||
{
|
||||
json j;
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["command"] = "select_extruder";
|
||||
j["print"]["extruder_index"] = id;
|
||||
int rtn = m_obj->publish_json(j, 1);
|
||||
if (rtn == 0)
|
||||
{
|
||||
m_obj->targ_nozzle_id_from_pc = id;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
26
src/slic3r/GUI/DeviceCore/DevCtrl.h
Normal file
26
src/slic3r/GUI/DeviceCore/DevCtrl.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
//Previous definitions
|
||||
class MachineObject;
|
||||
|
||||
|
||||
class DevCtrl
|
||||
{
|
||||
MachineObject* m_obj;
|
||||
public:
|
||||
DevCtrl(MachineObject* obj) : m_obj(obj) {};
|
||||
~DevCtrl() = default;
|
||||
|
||||
public:
|
||||
/*extruder system*/
|
||||
int command_select_extruder(int id);
|
||||
};
|
||||
|
||||
};
|
||||
99
src/slic3r/GUI/DeviceCore/DevDefs.h
Normal file
99
src/slic3r/GUI/DeviceCore/DevDefs.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @file DevDefs.h
|
||||
* @brief Common definitions, macros, and constants for printer modules.
|
||||
* Enhance building and including.
|
||||
*
|
||||
* This file provides shared macros, constants, and enumerations for all printer-related
|
||||
* modules, including printer types, status, binding states, connection types, and error codes.
|
||||
* It is intended to be included wherever printer-specific definitions are required.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
enum PrinterArch
|
||||
{
|
||||
ARCH_CORE_XY,
|
||||
ARCH_I3,
|
||||
};
|
||||
|
||||
enum PrinterSeries
|
||||
{
|
||||
SERIES_X1 = 0,
|
||||
SERIES_P1P,
|
||||
SERIES_UNKNOWN,
|
||||
};
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
/*AMS*/
|
||||
enum AmsStatusMain
|
||||
{
|
||||
AMS_STATUS_MAIN_IDLE = 0x00,
|
||||
AMS_STATUS_MAIN_FILAMENT_CHANGE = 0x01,
|
||||
AMS_STATUS_MAIN_RFID_IDENTIFYING = 0x02,
|
||||
AMS_STATUS_MAIN_ASSIST = 0x03,
|
||||
AMS_STATUS_MAIN_CALIBRATION = 0x04,
|
||||
AMS_STATUS_MAIN_SELF_CHECK = 0x10,
|
||||
AMS_STATUS_MAIN_DEBUG = 0x20,
|
||||
AMS_STATUS_MAIN_UNKNOWN = 0xFF,
|
||||
};
|
||||
|
||||
// Slots and Tray
|
||||
#define VIRTUAL_TRAY_MAIN_ID 255
|
||||
#define VIRTUAL_TRAY_DEPUTY_ID 254
|
||||
|
||||
#define VIRTUAL_AMS_MAIN_ID_STR "255"
|
||||
#define VIRTUAL_AMS_DEPUTY_ID_STR "254"
|
||||
|
||||
#define INVALID_AMS_TEMPERATURE std::numeric_limits<float>::min()
|
||||
|
||||
/* Extruder*/
|
||||
#define MAIN_EXTRUDER_ID 0
|
||||
#define DEPUTY_EXTRUDER_ID 1
|
||||
#define UNIQUE_EXTRUDER_ID MAIN_EXTRUDER_ID
|
||||
#define INVALID_EXTRUDER_ID -1
|
||||
|
||||
|
||||
/* Nozzle*/
|
||||
enum NozzleFlowType
|
||||
{
|
||||
NONE_FLOWTYPE,
|
||||
S_FLOW,
|
||||
H_FLOW
|
||||
};
|
||||
|
||||
/*Print speed*/
|
||||
enum DevPrintingSpeedLevel
|
||||
{
|
||||
SPEED_LEVEL_INVALID = 0,
|
||||
SPEED_LEVEL_SILENCE = 1,
|
||||
SPEED_LEVEL_NORMAL = 2,
|
||||
SPEED_LEVEL_RAPID = 3,
|
||||
SPEED_LEVEL_RAMPAGE = 4,
|
||||
SPEED_LEVEL_COUNT
|
||||
};
|
||||
|
||||
/*Upgrade*/
|
||||
enum class DevFirmwareUpgradingState : int
|
||||
{
|
||||
DC = -1,
|
||||
UpgradingUnavaliable = 0,
|
||||
UpgradingAvaliable = 1,
|
||||
UpgradingInProgress = 2,
|
||||
UpgradingFinished = 3
|
||||
};
|
||||
|
||||
class devPrinterUtil
|
||||
{
|
||||
public:
|
||||
devPrinterUtil() = delete;
|
||||
~devPrinterUtil() = delete;
|
||||
|
||||
public:
|
||||
static bool IsVirtualSlot(int ams_id) { return (ams_id == VIRTUAL_TRAY_MAIN_ID || ams_id == VIRTUAL_TRAY_DEPUTY_ID);}
|
||||
static bool IsVirtualSlot(const std::string& ams_id) { return (ams_id == VIRTUAL_AMS_MAIN_ID_STR || ams_id == VIRTUAL_AMS_DEPUTY_ID_STR); }
|
||||
};
|
||||
|
||||
};// namespace Slic3r
|
||||
287
src/slic3r/GUI/DeviceCore/DevExtruderSystem.cpp
Normal file
287
src/slic3r/GUI/DeviceCore/DevExtruderSystem.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevExtruderSystem.h"
|
||||
#include "DevNozzleSystem.h"
|
||||
|
||||
// TODO: remove this include
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
|
||||
#include "DevUtil.h"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
wxString DevExtder::GetDisplayLoc() const
|
||||
{
|
||||
if (system->GetTotalExtderCount() == 2)
|
||||
{
|
||||
if (m_ext_id == MAIN_EXTRUDER_ID)
|
||||
{
|
||||
return _L("right");
|
||||
}
|
||||
else
|
||||
{
|
||||
return _L("left");
|
||||
}
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
wxString DevExtder::GetDisplayName() const
|
||||
{
|
||||
if (system->GetTotalExtderCount() == 2)
|
||||
{
|
||||
if (m_ext_id == MAIN_EXTRUDER_ID)
|
||||
{
|
||||
return _L("right extruder");
|
||||
}
|
||||
else
|
||||
{
|
||||
return _L("left extruder");
|
||||
}
|
||||
}
|
||||
|
||||
return _L("extruder");
|
||||
}
|
||||
|
||||
NozzleType DevExtder::GetNozzleType() const
|
||||
{
|
||||
return system->Owner()->GetNozzleSystem()->GetNozzle(m_current_nozzle_id).m_nozzle_type;
|
||||
}
|
||||
|
||||
NozzleFlowType DevExtder::GetNozzleFlowType() const
|
||||
{
|
||||
return system->Owner()->GetNozzleSystem()->GetNozzle(m_current_nozzle_id).m_nozzle_flow;
|
||||
}
|
||||
|
||||
float DevExtder::GetNozzleDiameter() const
|
||||
{
|
||||
return system->Owner()->GetNozzleSystem()->GetNozzle(m_current_nozzle_id).m_diameter;
|
||||
}
|
||||
|
||||
DevExtderSystem::DevExtderSystem(MachineObject* obj)
|
||||
: m_owner(obj)
|
||||
{
|
||||
// default to have one extruder
|
||||
m_total_extder_count = 1;
|
||||
DevExtder ext(this, MAIN_EXTRUDER_ID);
|
||||
m_extders.emplace_back(ext);
|
||||
}
|
||||
|
||||
bool DevExtderSystem::CanQuitSwitching() const
|
||||
{
|
||||
if (!IsSwitchingFailed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return !m_owner->is_in_printing() && !m_owner->is_in_printing_pause();
|
||||
}
|
||||
|
||||
std::optional<DevExtder> DevExtderSystem::GetCurrentExtder() const
|
||||
{
|
||||
return GetExtderById(m_current_extder_id);
|
||||
}
|
||||
|
||||
std::optional<DevExtder> DevExtderSystem::GetLoadingExtder() const
|
||||
{
|
||||
if (m_current_loading_extder_id != INVALID_EXTRUDER_ID)
|
||||
{
|
||||
return GetExtderById(m_current_loading_extder_id);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<DevExtder> DevExtderSystem::GetExtderById(int extder_id) const
|
||||
{
|
||||
if (extder_id >= m_extders.size())
|
||||
{
|
||||
assert(false && "Invalid extruder ID");
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "No extruder found for " << extder_id;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return m_extders[extder_id];
|
||||
}
|
||||
|
||||
std::string DevExtderSystem::GetCurrentAmsId() const
|
||||
{
|
||||
auto cur_extder = GetCurrentExtder();
|
||||
return cur_extder ? cur_extder->GetSlotNow().ams_id : DevAmsSlotInfo().ams_id;
|
||||
}
|
||||
|
||||
std::string DevExtderSystem::GetCurrentSlotId() const
|
||||
{
|
||||
auto cur_extder = GetCurrentExtder();
|
||||
return cur_extder ? GetCurrentExtder()->GetSlotNow().slot_id : DevAmsSlotInfo().slot_id;
|
||||
}
|
||||
|
||||
std::string DevExtderSystem::GetTargetAmsId() const
|
||||
{
|
||||
auto cur_extder = GetCurrentExtder();
|
||||
return cur_extder ? GetCurrentExtder()->GetSlotTarget().ams_id : DevAmsSlotInfo().ams_id;
|
||||
}
|
||||
|
||||
std::string DevExtderSystem::GetTargetSlotId() const
|
||||
{
|
||||
auto cur_extder = GetCurrentExtder();
|
||||
return cur_extder ? GetCurrentExtder()->GetSlotTarget().slot_id : DevAmsSlotInfo().slot_id;
|
||||
}
|
||||
|
||||
bool DevExtderSystem::HasFilamentBackup() const
|
||||
{
|
||||
for (const auto& ext : m_extders)
|
||||
{
|
||||
if (ext.HasFilamBackup())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExtderSystemParser::ParseV1_0(const nlohmann::json& print_json, DevExtderSystem* system)
|
||||
{
|
||||
if (system->GetTotalExtderCount() != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (print_json.contains("nozzle_temper") && print_json["nozzle_temper"].is_number())
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_cur_temp = print_json["nozzle_temper"].get<float>();
|
||||
}
|
||||
|
||||
if (print_json.contains("nozzle_target_temper") && print_json["nozzle_target_temper"].is_number())
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_target_temp = print_json["nozzle_target_temper"].get<float>();
|
||||
}
|
||||
|
||||
if (print_json.contains("ams") && print_json["ams"].contains("tray_tar"))
|
||||
{
|
||||
const std::string& tray_tar = print_json["ams"]["tray_tar"].get<std::string>();
|
||||
if (!tray_tar.empty())
|
||||
{
|
||||
int tray_tar_int = atoi(tray_tar.c_str());
|
||||
if (tray_tar_int == VIRTUAL_TRAY_MAIN_ID || tray_tar_int == VIRTUAL_TRAY_DEPUTY_ID)
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_star.ams_id = std::to_string(VIRTUAL_TRAY_MAIN_ID);
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_star.slot_id = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tray_tar_int >= 0x80 && tray_tar_int <= 0x87)
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_star.ams_id = std::to_string(tray_tar_int);
|
||||
}
|
||||
else
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_star.ams_id = std::to_string(tray_tar_int >> 2);
|
||||
}
|
||||
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_star.slot_id = std::to_string(tray_tar_int & 0x3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (print_json.contains("ams") && print_json["ams"].contains("tray_now"))
|
||||
{
|
||||
const std::string& tray_now = print_json["ams"]["tray_now"].get<std::string>();
|
||||
if (!tray_now.empty())
|
||||
{
|
||||
int tray_now_int = atoi(tray_now.c_str());
|
||||
if (tray_now_int == VIRTUAL_TRAY_MAIN_ID || tray_now_int == VIRTUAL_TRAY_DEPUTY_ID)
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_snow.ams_id = std::to_string(VIRTUAL_TRAY_MAIN_ID);
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_snow.slot_id = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tray_now_int >= 0x80 && tray_now_int <= 0x87)
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_snow.ams_id = std::to_string(tray_now_int);
|
||||
}
|
||||
else
|
||||
{
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_snow.ams_id = std::to_string(tray_now_int >> 2);
|
||||
}
|
||||
|
||||
system->m_extders[MAIN_EXTRUDER_ID].m_snow.slot_id = std::to_string(tray_now_int & 0x3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system->m_current_busy_for_loading = false;
|
||||
system->m_current_loading_extder_id = INVALID_EXTRUDER_ID;
|
||||
if (!system->m_extders[MAIN_EXTRUDER_ID].m_star.ams_id.empty())
|
||||
{
|
||||
system->m_current_busy_for_loading = (system->m_extders[MAIN_EXTRUDER_ID].m_snow == system->m_extders[MAIN_EXTRUDER_ID].m_star);
|
||||
if (system->m_current_busy_for_loading)
|
||||
{
|
||||
system->m_current_loading_extder_id = MAIN_EXTRUDER_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExtderSystemParser::ParseV2_0(const nlohmann::json& extruder_json, DevExtderSystem* system)
|
||||
{
|
||||
system->m_total_extder_count = DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 0, 4);
|
||||
if (system->m_current_extder_id != DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 4, 4))
|
||||
{
|
||||
system->Owner()->targ_nozzle_id_from_pc = INVALID_EXTRUDER_ID;
|
||||
system->m_current_extder_id = DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 4, 4);
|
||||
}
|
||||
else if (system->m_switch_extder_state == ES_SWITCHING_FAILED)
|
||||
{
|
||||
system->Owner()->targ_nozzle_id_from_pc = INVALID_EXTRUDER_ID;
|
||||
}
|
||||
|
||||
system->m_target_extder_id = DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 8, 4);
|
||||
system->m_switch_extder_state = (DevExtderSwitchState)DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 12, 3);
|
||||
system->m_current_loading_extder_id = DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 15, 4);
|
||||
system->m_current_busy_for_loading = DevUtil::get_flag_bits(extruder_json["state"].get<int>(), 19);
|
||||
|
||||
system->m_extders.clear();
|
||||
for (auto it = extruder_json["info"].begin(); it != extruder_json["info"].cend(); it++)
|
||||
{
|
||||
|
||||
DevExtder extder_obj(system);
|
||||
|
||||
const auto& njon = it.value();
|
||||
extder_obj.SetExtId(njon["id"].get<int>());
|
||||
|
||||
extder_obj.m_filam_bak.clear();
|
||||
const json& filam_bak_items = njon["filam_bak"];
|
||||
for (const auto& filam_bak_item : filam_bak_items)
|
||||
{
|
||||
const auto& filam_bak_val = filam_bak_item.get<int>();
|
||||
extder_obj.m_filam_bak.emplace_back(filam_bak_val);
|
||||
}
|
||||
|
||||
extder_obj.m_ext_has_filament = (DevUtil::get_flag_bits(njon["info"].get<int>(), 1) != 0);
|
||||
extder_obj.m_buffer_has_filament = (DevUtil::get_flag_bits(njon["info"].get<int>(), 2) != 0);
|
||||
extder_obj.m_has_nozzle = (DevUtil::get_flag_bits(njon["info"].get<int>(), 3) != 0);
|
||||
extder_obj.m_cur_temp = DevUtil::get_flag_bits(njon["temp"].get<int>(), 0, 16);
|
||||
extder_obj.m_target_temp = DevUtil::get_flag_bits(njon["temp"].get<int>(), 16, 16);
|
||||
|
||||
extder_obj.m_spre.slot_id = std::to_string(DevUtil::get_flag_bits(njon["spre"].get<int>(), 0, 8));
|
||||
extder_obj.m_spre.ams_id = std::to_string(DevUtil::get_flag_bits(njon["spre"].get<int>(), 8, 8));
|
||||
|
||||
extder_obj.m_snow.slot_id = std::to_string(DevUtil::get_flag_bits(njon["snow"].get<int>(), 0, 8));
|
||||
extder_obj.m_snow.ams_id = std::to_string(DevUtil::get_flag_bits(njon["snow"].get<int>(), 8, 8));
|
||||
|
||||
extder_obj.m_star.slot_id = std::to_string(DevUtil::get_flag_bits(njon["star"].get<int>(), 0, 8));
|
||||
extder_obj.m_star.ams_id = std::to_string(DevUtil::get_flag_bits(njon["star"].get<int>(), 8, 8));
|
||||
|
||||
extder_obj.m_ams_stat = DevUtil::get_flag_bits(njon["stat"].get<int>(), 0, 16);
|
||||
extder_obj.m_rfid_stat = DevUtil::get_flag_bits(njon["stat"].get<int>(), 16, 16);
|
||||
|
||||
//current nozzle info
|
||||
extder_obj.m_current_nozzle_id = njon["hnow"].get<int>();
|
||||
system->m_extders.push_back(extder_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
189
src/slic3r/GUI/DeviceCore/DevExtruderSystem.h
Normal file
189
src/slic3r/GUI/DeviceCore/DevExtruderSystem.h
Normal file
@@ -0,0 +1,189 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "DevDefs.h"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
//Previous definitions
|
||||
class MachineObject;
|
||||
class DevExtderSystem;
|
||||
|
||||
struct DevAmsSlotInfo
|
||||
{
|
||||
std::string ams_id;
|
||||
std::string slot_id;
|
||||
|
||||
public:
|
||||
bool operator==(const DevAmsSlotInfo& other) const { return ams_id == other.ams_id && slot_id == other.slot_id;}
|
||||
};
|
||||
|
||||
enum DevExtderSwitchState
|
||||
{
|
||||
ES_IDLE = 0,
|
||||
ES_BUSY,
|
||||
ES_SWITCHING,
|
||||
ES_SWITCHING_FAILED
|
||||
};
|
||||
|
||||
class DevExtder
|
||||
{
|
||||
friend class MachineObject;
|
||||
friend class ExtderSystemParser;
|
||||
public:
|
||||
DevExtder(DevExtderSystem* owner/*should not be nullptr*/, int id = -1) : system(owner), m_ext_id(id){};
|
||||
|
||||
public:
|
||||
// Ext
|
||||
int GetExtId() const { return m_ext_id; }
|
||||
|
||||
// display
|
||||
wxString GetDisplayLoc() const;
|
||||
wxString GetDisplayName() const;
|
||||
|
||||
// installed nozzle info
|
||||
bool HasNozzleInstalled() const = delete;//{ return m_has_nozzle; }
|
||||
|
||||
int GetNozzleId() const { return m_current_nozzle_id; }
|
||||
int GetTargetNozzleId() const = delete;//{ return m_target_nozzle_id; }
|
||||
NozzleType GetNozzleType() const;
|
||||
NozzleFlowType GetNozzleFlowType() const;
|
||||
float GetNozzleDiameter() const;
|
||||
|
||||
// temperature
|
||||
int GetCurrentTemp() const { return m_cur_temp; }
|
||||
int GetTargetTemp() const { return m_target_temp; }
|
||||
|
||||
// filament
|
||||
bool HasFilamentInExt() const { return m_ext_has_filament; }
|
||||
bool HasFilamentInBuffer() const = delete; //{ return m_buffer_has_filament; }
|
||||
bool HasFilamBackup() const { return !m_filam_bak.empty(); }
|
||||
std::vector<int> GetFilamBackup() const { return m_filam_bak; }
|
||||
|
||||
// ams binding on current extruder
|
||||
const DevAmsSlotInfo& GetSlotPre() const { return m_spre; }
|
||||
const DevAmsSlotInfo& GetSlotNow() const { return m_snow; }
|
||||
const DevAmsSlotInfo& GetSlotTarget() const { return m_star; }
|
||||
|
||||
private:
|
||||
void SetExtId(int val) { m_ext_id = val; }
|
||||
|
||||
private:
|
||||
DevExtderSystem* system = nullptr;
|
||||
|
||||
// extruder id
|
||||
int m_ext_id; // 0-right 1-left
|
||||
|
||||
// current nozzle
|
||||
bool m_has_nozzle = false;
|
||||
int m_current_nozzle_id = 0; // nozzle id now. for some machine, the extruder may have serveral nozzles
|
||||
int m_target_nozzle_id = 0; // target nozzle id
|
||||
|
||||
// temperature
|
||||
int m_cur_temp = 0;
|
||||
int m_target_temp = 0;
|
||||
|
||||
// filament
|
||||
bool m_ext_has_filament = false;
|
||||
bool m_buffer_has_filament = false;
|
||||
std::vector<int> m_filam_bak;// the refill filam
|
||||
|
||||
// binded ams
|
||||
DevAmsSlotInfo m_spre; // tray_pre
|
||||
DevAmsSlotInfo m_snow; // tray_now
|
||||
DevAmsSlotInfo m_star; // tray_tar
|
||||
|
||||
int m_ams_stat = 0;
|
||||
int m_rfid_stat = 0;
|
||||
};
|
||||
|
||||
// ExtderSystem is the extruder management system for the device.
|
||||
// It consists of multiple extruders (Extder) and nozzles.
|
||||
// Each extruder can be associated with different nozzles, and the number of extruders
|
||||
// does not necessarily equal the number of nozzles.
|
||||
// Note: The IDs of extruders and nozzles may not match or correspond one-to-one.
|
||||
class DevExtderSystem
|
||||
{
|
||||
friend class MachineObject;
|
||||
friend class ExtderSystemParser;
|
||||
public:
|
||||
DevExtderSystem(MachineObject* obj);
|
||||
~DevExtderSystem() = default;
|
||||
|
||||
public:
|
||||
MachineObject* Owner() const { return m_owner; }
|
||||
|
||||
// access extder info
|
||||
int GetTotalExtderCount() const { assert(m_extders.size() == m_total_extder_count); return m_total_extder_count; }
|
||||
int GetTotalExtderSize() const { return static_cast<int>(m_extders.size()); }
|
||||
int GetCurrentExtderId() const { return m_current_extder_id; }
|
||||
int GetTargetExtderId() const = delete;//{ return m_target_extder_id; }
|
||||
|
||||
// switching
|
||||
DevExtderSwitchState GetSwitchState() const { return m_switch_extder_state; }
|
||||
bool IsSwitching() const { return m_switch_extder_state == DevExtderSwitchState::ES_SWITCHING;};
|
||||
bool IsSwitchingFailed() const { return m_switch_extder_state == DevExtderSwitchState::ES_SWITCHING_FAILED; };
|
||||
bool CanQuitSwitching() const;
|
||||
bool CanRetrySwitching() const { return IsSwitchingFailed(); };
|
||||
|
||||
int CtrlRetrySwitching();
|
||||
int CtrlQuitSwitching();
|
||||
|
||||
std::optional<DevExtder> GetCurrentExtder() const;
|
||||
std::optional<DevExtder> GetLoadingExtder() const;
|
||||
std::optional<DevExtder> GetExtderById(int extder_id) const;
|
||||
const std::vector<DevExtder>& GetExtruders() const { return m_extders;};
|
||||
|
||||
// get nozzle info which is installed on the extruder
|
||||
NozzleType GetNozzleType(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetNozzleType() : NozzleType::ntUndefine; }
|
||||
NozzleFlowType GetNozzleFlowType(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetNozzleFlowType() : NozzleFlowType::NONE_FLOWTYPE;; }
|
||||
float GetNozzleDiameter(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetNozzleDiameter() : 0.0; }
|
||||
int GetNozzleTempCurrent(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetCurrentTemp() : 0; }
|
||||
int GetNozzleTempTarget(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetTargetTemp() : 0; }
|
||||
|
||||
// get slot info which is connected to the extruder
|
||||
std::string GetCurrentAmsId() const;
|
||||
std::string GetCurrentSlotId() const;
|
||||
std::string GetTargetAmsId() const;
|
||||
std::string GetTargetSlotId() const;
|
||||
|
||||
// filament
|
||||
bool IsBusyLoading() const { return m_current_busy_for_loading; }
|
||||
int GetLoadingExtderId() const { return m_current_loading_extder_id; }
|
||||
bool HasFilamentBackup() const;
|
||||
bool HasFilamentInExt(int exter_id) { return GetExtderById(exter_id) ? GetExtderById(exter_id)->HasFilamentInExt() : false; }
|
||||
|
||||
protected:
|
||||
void AddExtder(const DevExtder& ext) { m_extders[ext.GetExtId()] = ext; };
|
||||
|
||||
private:
|
||||
MachineObject* m_owner = nullptr;
|
||||
|
||||
// extruders
|
||||
int m_total_extder_count = 1;
|
||||
std::vector<DevExtder> m_extders;
|
||||
|
||||
// current extruder and swtching info
|
||||
int m_current_extder_id = MAIN_EXTRUDER_ID;
|
||||
|
||||
// switching
|
||||
DevExtderSwitchState m_switch_extder_state = DevExtderSwitchState::ES_IDLE;
|
||||
int m_target_extder_id = MAIN_EXTRUDER_ID;
|
||||
|
||||
// loading extruder
|
||||
bool m_current_busy_for_loading{ false };
|
||||
int m_current_loading_extder_id = INVALID_EXTRUDER_ID;
|
||||
};
|
||||
|
||||
class ExtderSystemParser
|
||||
{
|
||||
public:
|
||||
static void ParseV1_0(const nlohmann::json& extruder_json, DevExtderSystem* system);
|
||||
static void ParseV2_0(const nlohmann::json& extruder_json, DevExtderSystem* system);
|
||||
};
|
||||
|
||||
};
|
||||
22
src/slic3r/GUI/DeviceCore/DevExtruderSystemCtrl.cpp
Normal file
22
src/slic3r/GUI/DeviceCore/DevExtruderSystemCtrl.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevExtruderSystem.h"
|
||||
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
int DevExtderSystem::CtrlRetrySwitching()
|
||||
{
|
||||
if (m_owner) { return m_owner->command_ams_control("resume"); }
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DevExtderSystem::CtrlQuitSwitching()
|
||||
{
|
||||
if (m_owner) { return m_owner->command_ams_control("abort"); }
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
219
src/slic3r/GUI/DeviceCore/DevFan.cpp
Normal file
219
src/slic3r/GUI/DeviceCore/DevFan.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevFan.h"
|
||||
#include <wx/app.h>
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
using namespace nlohmann;
|
||||
|
||||
void Slic3r::DevFan::converse_to_duct(bool is_suppt_part_fun, bool is_suppt_aux_fun, bool is_suppt_cham_fun)
|
||||
{
|
||||
m_air_duct_data.modes.clear();
|
||||
m_air_duct_data.parts.clear();
|
||||
m_air_duct_data.curren_mode = -1; // def mode
|
||||
|
||||
if (is_suppt_part_fun) {
|
||||
AirParts part_fan;
|
||||
part_fan.type = int(AirDuctType::AIR_FAN_TYPE);
|
||||
part_fan.id = int(AIR_FUN::FAN_COOLING_0_AIRDOOR);
|
||||
part_fan.func = int(AIR_FUN::FAN_COOLING_0_AIRDOOR);
|
||||
part_fan.state = 0;
|
||||
part_fan.range_start = 0;
|
||||
part_fan.range_end = 100;
|
||||
m_air_duct_data.parts.push_back(part_fan);
|
||||
}
|
||||
|
||||
if (is_suppt_aux_fun) {
|
||||
AirParts aux_fan;
|
||||
aux_fan.type = int(AirDuctType::AIR_FAN_TYPE);
|
||||
aux_fan.id = int(AIR_FUN::FAN_REMOTE_COOLING_0_IDX);
|
||||
aux_fan.func = int(AIR_FUN::FAN_REMOTE_COOLING_0_IDX);
|
||||
aux_fan.state = 0;
|
||||
aux_fan.range_start = 0;
|
||||
aux_fan.range_end = 100;
|
||||
m_air_duct_data.parts.push_back(aux_fan);
|
||||
}
|
||||
|
||||
if (is_suppt_aux_fun) {
|
||||
AirParts chamber_fan;
|
||||
chamber_fan.type = int(AirDuctType::AIR_FAN_TYPE);
|
||||
chamber_fan.id = int(AIR_FUN::FAN_CHAMBER_0_IDX);
|
||||
chamber_fan.func = int(AIR_FUN::FAN_CHAMBER_0_IDX);
|
||||
chamber_fan.state = 0;
|
||||
chamber_fan.range_start = 0;
|
||||
chamber_fan.range_end = 100;
|
||||
m_air_duct_data.parts.push_back(chamber_fan);
|
||||
}
|
||||
}
|
||||
|
||||
static std::string _get_string_from_fantype(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case 1: return "cooling_fan";
|
||||
case 2: return "big_cooling_fan";
|
||||
case 3: return "chamber_fan";
|
||||
default: return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// Old protocol
|
||||
int Slic3r::DevFan::command_control_fan(int fan_type, int val)
|
||||
{
|
||||
std::string gcode = (boost::format("M106 P%1% S%2% \n") % (int) fan_type % (val)).str();
|
||||
return m_owner->publish_gcode(gcode);
|
||||
}
|
||||
|
||||
// New protocol
|
||||
int Slic3r::DevFan::command_control_fan_new(int fan_id, int val)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "New protocol of fan setting(set speed), fan_id = " << fan_id;
|
||||
json j;
|
||||
j["print"]["command"] = "set_fan";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["fan_index"] = fan_id;
|
||||
|
||||
j["print"]["speed"] = val;
|
||||
BOOST_LOG_TRIVIAL(info) << "MachineObject::command_control_fan_val, set the speed of fan, fan_id = " << fan_id;
|
||||
return m_owner->publish_json(j);
|
||||
}
|
||||
|
||||
|
||||
int Slic3r::DevFan::command_handle_response(const json &response)
|
||||
{
|
||||
if (!response.contains("sequence_id")) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ", error reponse.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string reply = response["sequence_id"].get<std::string>();
|
||||
auto it = m_callback_list.find(reply);
|
||||
if (it != m_callback_list.end()) {
|
||||
if (it->second) it->second(response);
|
||||
m_callback_list.erase(it);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Slic3r::DevFan::command_control_air_duct(int mode_id, int submode, const CommandCallBack& cb)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "MachineObject::command_control_air_duct, set air duct, d = " << mode_id;
|
||||
m_callback_list[std::to_string(m_owner->m_sequence_id)] = cb;
|
||||
json j;
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["command"] = "set_airduct";
|
||||
j["print"]["modeId"] = mode_id;
|
||||
j["print"]["submode"] = submode;
|
||||
|
||||
return m_owner->publish_json(j);
|
||||
}
|
||||
|
||||
void Slic3r::DevFan::ParseV1_0(const json &print_json)
|
||||
{
|
||||
if (print_json.contains("fan_gear")) {
|
||||
fan_gear = print_json["fan_gear"].get<std::uint32_t>();
|
||||
big_fan2_speed = (int) ((fan_gear & 0x00FF0000) >> 16);
|
||||
big_fan1_speed = (int) ((fan_gear & 0x0000FF00) >> 8);
|
||||
cooling_fan_speed = (int) ((fan_gear & 0x000000FF) >> 0);
|
||||
} else {
|
||||
if (print_json.contains("cooling_fan_speed")) {
|
||||
cooling_fan_speed = stoi(print_json["cooling_fan_speed"].get<std::string>());
|
||||
cooling_fan_speed = round(floor(cooling_fan_speed / float(1.5)) * float(25.5));
|
||||
} else {
|
||||
cooling_fan_speed = 0;
|
||||
}
|
||||
if (print_json.contains("big_fan1_speed")) {
|
||||
big_fan1_speed = stoi(print_json["big_fan1_speed"].get<std::string>());
|
||||
big_fan1_speed = round(floor(big_fan1_speed / float(1.5)) * float(25.5));
|
||||
} else {
|
||||
big_fan1_speed = 0;
|
||||
}
|
||||
if (print_json.contains("big_fan2_speed")) {
|
||||
big_fan2_speed = stoi(print_json["big_fan2_speed"].get<std::string>());
|
||||
big_fan2_speed = round(floor(big_fan2_speed / float(1.5)) * float(25.5));
|
||||
} else {
|
||||
big_fan2_speed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_json.contains("heatbreak_fan_speed")) { heatbreak_fan_speed = stoi(print_json["heatbreak_fan_speed"].get<std::string>()); }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Slic3r::DevFan::ParseV2_0(const json &print_json) {
|
||||
|
||||
if (print_json.contains("support_aux_fan")) {
|
||||
if (print_json["support_aux_fan"].is_boolean())
|
||||
is_support_aux_fan = print_json["support_aux_fan"].get<bool>();
|
||||
}
|
||||
|
||||
if (print_json.contains("support_chamber_fan")) {
|
||||
if (print_json["support_chamber_fan"].is_boolean())
|
||||
is_support_chamber_fan = print_json["support_chamber_fan"].get<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Slic3r::DevFan::ParseV3_0(const json &device)
|
||||
{
|
||||
if (device.contains("airduct")) {
|
||||
m_air_duct_data.curren_mode = -1;
|
||||
m_air_duct_data.modes.clear();
|
||||
m_air_duct_data.parts.clear();
|
||||
|
||||
m_air_duct_data.curren_mode = device["airduct"]["modeCur"].get<int>();
|
||||
|
||||
const json &airduct = device["airduct"];
|
||||
if (airduct.contains("modeCur")) { m_air_duct_data.curren_mode = airduct["modeCur"].get<int>(); }
|
||||
if (airduct.contains("subMode")) { m_air_duct_data.m_sub_mode = airduct["subMode"].get<int>(); }
|
||||
if (airduct.contains("modeList") && airduct["modeList"].is_array()) {
|
||||
auto list = airduct["modeList"].get<std::vector<json>>();
|
||||
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
// only show 2 mode for o
|
||||
if (m_owner->is_series_o() && i >= 2) { break; }
|
||||
|
||||
json mode_json = list[i];
|
||||
AirMode mode;
|
||||
if (mode_json.contains("modeId")) mode.id = mode_json["modeId"].get<int>();
|
||||
if (mode_json.contains("ctrl")) {
|
||||
for (auto it_mode_ctrl = mode_json["ctrl"].begin(); it_mode_ctrl != mode_json["ctrl"].end(); it_mode_ctrl++) {
|
||||
mode.ctrl.push_back((*it_mode_ctrl).get<int>() >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode_json.contains("off")) {
|
||||
for (auto it_mode_off = mode_json["off"].begin(); it_mode_off != mode_json["off"].end(); *it_mode_off++) {
|
||||
mode.off.push_back((*it_mode_off).get<int>() >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (AIR_DUCT(mode.id) == AIR_DUCT::AIR_DUCT_EXHAUST) { continue; } /*STUDIO-12796*/
|
||||
m_air_duct_data.modes[mode.id] = mode;
|
||||
}
|
||||
}
|
||||
|
||||
if (airduct.contains("parts") && airduct["parts"].is_array()) {
|
||||
for (auto it_part = airduct["parts"].begin(); it_part != airduct["parts"].end(); it_part++) {
|
||||
int state = (*it_part)["state"].get<int>();
|
||||
int range = (*it_part)["range"].get<int>();
|
||||
|
||||
AirParts part;
|
||||
part.type = m_owner->get_flag_bits((*it_part)["id"].get<int>(), 0, 4);
|
||||
part.id = m_owner->get_flag_bits((*it_part)["id"].get<int>(), 4, 9);
|
||||
part.func = (*it_part)["func"].get<int>();
|
||||
part.state = m_owner->get_flag_bits(state, 0, 8);
|
||||
part.range_start = m_owner->get_flag_bits(range, 0, 16);
|
||||
part.range_end = m_owner->get_flag_bits(range, 16, 16);
|
||||
|
||||
m_air_duct_data.parts.push_back(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
150
src/slic3r/GUI/DeviceCore/DevFan.h
Normal file
150
src/slic3r/GUI/DeviceCore/DevFan.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class MachineObject;
|
||||
|
||||
enum AirDuctType { AIR_FAN_TYPE, AIR_DOOR_TYPE };
|
||||
typedef std::function<void(const json &)> CommandCallBack;
|
||||
|
||||
|
||||
|
||||
enum AIR_FUN {
|
||||
FAN_HEAT_BREAK_0_IDX = 0,
|
||||
FAN_COOLING_0_AIRDOOR = 1,
|
||||
FAN_REMOTE_COOLING_0_IDX = 2,
|
||||
FAN_CHAMBER_0_IDX = 3,
|
||||
FAN_HEAT_BREAK_1_IDX = 4,
|
||||
FAN_MC_BOARD_0_IDX = 5,
|
||||
FAN_INNNER_LOOP_FAN_0_IDX = 6,
|
||||
FAN_TOTAL_COUNT = 7
|
||||
};
|
||||
|
||||
enum AIR_DOOR { AIR_DOOR_FUNC_CHAMBER = 0, AIR_DOOR_FUNC_INNERLOOP, AIR_DOOR_FUNC_TOP };
|
||||
|
||||
|
||||
enum AIR_DUCT {
|
||||
AIR_DUCT_NONE = -1,
|
||||
AIR_DUCT_COOLING_FILT = 0,
|
||||
AIR_DUCT_HEATING_INTERNAL_FILT,
|
||||
AIR_DUCT_EXHAUST,
|
||||
AIR_DUCT_FULL_COOLING,
|
||||
AIR_DUCT_INIT = 0xFF // Initial mode, only used within mc
|
||||
};
|
||||
|
||||
struct AirParts
|
||||
{
|
||||
int type{0};
|
||||
int id{0};
|
||||
int func{0};
|
||||
int state{0}; // 100%
|
||||
int range_start{0}; // 100%
|
||||
int range_end{0}; // 100%
|
||||
|
||||
public:
|
||||
bool operator ==(const AirParts& other) const
|
||||
{
|
||||
return (type == other.type) && (id == other.id) && (func == other.func) && (state == other.state) && (range_start == other.range_start) && (range_end == other.range_end);
|
||||
};
|
||||
};
|
||||
|
||||
struct AirMode
|
||||
{
|
||||
int id{-1};
|
||||
std::vector<int> ctrl;
|
||||
// If the fan is off, it cannot be controlled and is displayed as off
|
||||
std::vector<int> off;
|
||||
// If the fan is not off or ctrl, it will be displayed as auto
|
||||
|
||||
public:
|
||||
bool operator ==(const AirMode& other) const
|
||||
{
|
||||
return (id == other.id) && (ctrl == other.ctrl) && (off == other.off);
|
||||
};
|
||||
};
|
||||
|
||||
struct AirDuctData
|
||||
{
|
||||
int curren_mode{0};
|
||||
std::unordered_map<int, AirMode> modes;
|
||||
std::vector<AirParts> parts;
|
||||
|
||||
int m_sub_mode = -1;// the submode of airduct, for cooling: 0-filter, 1-cooling
|
||||
bool m_support_cooling_filter = false;// support switch filter on cooling mode or not
|
||||
|
||||
public:
|
||||
bool operator ==(const AirDuctData& other) const
|
||||
{
|
||||
return (curren_mode == other.curren_mode) && (modes == other.modes) && (parts == other.parts) &&
|
||||
(m_sub_mode == other.m_sub_mode) && (m_support_cooling_filter == other.m_support_cooling_filter);
|
||||
};
|
||||
|
||||
bool operator !=(const AirDuctData& other) const
|
||||
{
|
||||
return !(operator==(other));
|
||||
};
|
||||
|
||||
bool IsSupportCoolingFilter() const { return m_support_cooling_filter; }
|
||||
bool IsCoolingFilerOn() const { return m_sub_mode == 0; }
|
||||
};
|
||||
|
||||
class DevFan
|
||||
{
|
||||
public:
|
||||
DevFan(MachineObject *obj) : m_owner(obj){};
|
||||
public:
|
||||
|
||||
enum FanType {//if have devPrinter , delete?
|
||||
COOLING_FAN = 1,
|
||||
BIG_COOLING_FAN = 2,
|
||||
CHAMBER_FAN = 3,
|
||||
EXHAUST_FAN,
|
||||
FILTER_FAN,
|
||||
};
|
||||
|
||||
bool is_at_heating_mode() const { return m_air_duct_data.curren_mode == AIR_DUCT_HEATING_INTERNAL_FILT; };
|
||||
|
||||
void SetSupportCoolingFilter(bool enable) { m_air_duct_data.m_support_cooling_filter = enable; }
|
||||
AirDuctData GetAirDuctData() { return m_air_duct_data; };
|
||||
|
||||
void converse_to_duct(bool is_suppt_part_fun, bool is_suppt_aux_fun, bool is_suppt_cham_fun); // Convert the data to duct type to make the newand old protocols consistent
|
||||
int command_handle_response(const json &response);
|
||||
int command_control_fan(int fan_type, int val); // Old protocol
|
||||
int command_control_fan_new(int fan_id, int val); // New protocol
|
||||
int command_control_air_duct(int mode_id, int submode, const CommandCallBack& cb);
|
||||
|
||||
void ParseV1_0(const json &print_json);
|
||||
void ParseV2_0(const json &print_json);
|
||||
void ParseV3_0(const json &print_json);
|
||||
|
||||
public:
|
||||
bool GetSupportAuxFanData() { return is_support_aux_fan; };
|
||||
bool GetSupportChamberFan() { return is_support_aux_fan; };
|
||||
int GetHeatBreakFanSpeed() { return heatbreak_fan_speed; }
|
||||
int GetCoolingFanSpeed() { return cooling_fan_speed; }
|
||||
int GetBigFan1Speed() { return big_fan1_speed; }
|
||||
int GetBigFan2Speed() { return big_fan2_speed; }
|
||||
uint32_t GetFanGear() { return fan_gear; }
|
||||
|
||||
|
||||
private:
|
||||
AirDuctData m_air_duct_data;
|
||||
|
||||
bool is_support_aux_fan{false};
|
||||
bool is_support_chamber_fan{false};
|
||||
|
||||
int heatbreak_fan_speed = 0;
|
||||
int cooling_fan_speed = 0;
|
||||
int big_fan1_speed = 0;
|
||||
int big_fan2_speed = 0;
|
||||
uint32_t fan_gear = 0;
|
||||
|
||||
std::map<std::string, CommandCallBack> m_callback_list;
|
||||
|
||||
MachineObject *m_owner = nullptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Slic3r
|
||||
13
src/slic3r/GUI/DeviceCore/DevFilaAmsSetting.cpp
Normal file
13
src/slic3r/GUI/DeviceCore/DevFilaAmsSetting.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "DevFilaAmsSetting.h"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void DevAmsSystemSetting::Reset()
|
||||
{
|
||||
SetDetectOnInsertEnabled(false);
|
||||
SetDetectOnPowerupEnabled(false);
|
||||
SetDetectRemainEnabled(false);
|
||||
SetAutoRefillEnabled(false);
|
||||
}
|
||||
|
||||
}
|
||||
35
src/slic3r/GUI/DeviceCore/DevFilaAmsSetting.h
Normal file
35
src/slic3r/GUI/DeviceCore/DevFilaAmsSetting.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
class DevFilaSystem;
|
||||
class DevAmsSystemSetting
|
||||
{
|
||||
public:
|
||||
DevAmsSystemSetting(DevFilaSystem* owner) : m_owner(owner) {};
|
||||
|
||||
public:
|
||||
// getters
|
||||
bool IsDetectOnInsertEnabled() const { return m_enable_detect_on_insert; };
|
||||
bool IsDetectOnPowerupEnabled() const { return m_enable_detect_on_powerup; }
|
||||
bool IsDetectRemainEnabled() const { return m_enable_detect_remain; }
|
||||
bool IsAutoRefillEnabled() const { return m_enable_auto_refill; }
|
||||
|
||||
// setters
|
||||
void Reset();
|
||||
void SetDetectOnInsertEnabled(bool enable) { m_enable_detect_on_insert = enable; }
|
||||
void SetDetectOnPowerupEnabled(bool enable) { m_enable_detect_on_powerup = enable; }
|
||||
void SetDetectRemainEnabled(bool enable) { m_enable_detect_remain = enable; }
|
||||
void SetAutoRefillEnabled(bool enable) { m_enable_auto_refill = enable; }
|
||||
|
||||
private:
|
||||
DevFilaSystem* m_owner = nullptr;
|
||||
|
||||
bool m_enable_detect_on_insert = false;
|
||||
bool m_enable_detect_on_powerup = false;
|
||||
bool m_enable_detect_remain = false;
|
||||
bool m_enable_auto_refill = false;
|
||||
};
|
||||
|
||||
}// namespace Slic3r
|
||||
259
src/slic3r/GUI/DeviceCore/DevFilaBlackList.cpp
Normal file
259
src/slic3r/GUI/DeviceCore/DevFilaBlackList.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "DevFilaBlackList.h"
|
||||
#include "DevFilaSystem.h"
|
||||
#include "DevManager.h"
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
json DevFilaBlacklist::filaments_blacklist = json::object();
|
||||
|
||||
|
||||
bool DevFilaBlacklist::load_filaments_blacklist_config()
|
||||
{
|
||||
if (!filaments_blacklist.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
filaments_blacklist = json::object();
|
||||
|
||||
std::string config_file = Slic3r::resources_dir() + "/printers/filaments_blacklist.json";
|
||||
boost::nowide::ifstream json_file(config_file.c_str());
|
||||
|
||||
try {
|
||||
if (json_file.is_open()) {
|
||||
json_file >> filaments_blacklist;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(error) << "load filaments blacklist config failed";
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "load filaments blacklist config failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::string _get_filament_name_from_ams(int ams_id, int slot_id)
|
||||
{
|
||||
std::string name;
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) { return name; }
|
||||
|
||||
MachineObject* obj = dev->get_selected_machine();
|
||||
if (obj == nullptr) { return name; }
|
||||
|
||||
if (ams_id < 0 || slot_id < 0)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const auto tray = obj->GetFilaSystem()->GetAmsTray(std::to_string(ams_id), std::to_string(slot_id));
|
||||
if (!tray) { return name; }
|
||||
|
||||
std::string filament_id = tray->setting_id;
|
||||
|
||||
PresetBundle* preset_bundle = GUI::wxGetApp().preset_bundle;
|
||||
auto option = preset_bundle->get_filament_by_filament_id(filament_id);
|
||||
name = option ? option->filament_name : "";
|
||||
return name;
|
||||
}
|
||||
|
||||
// moved from tao.wang and zhimin.zeng
|
||||
void check_filaments(std::string model_id,
|
||||
std::string tag_vendor,
|
||||
std::string tag_type,
|
||||
int ams_id,
|
||||
int slot_id,
|
||||
std::string tag_name,
|
||||
bool& in_blacklist,
|
||||
std::string& ac,
|
||||
wxString& info,
|
||||
wxString& wiki_url)
|
||||
{
|
||||
if (tag_name.empty())
|
||||
{
|
||||
tag_name = _get_filament_name_from_ams(ams_id, slot_id);
|
||||
}
|
||||
|
||||
in_blacklist = false;
|
||||
std::transform(tag_vendor.begin(), tag_vendor.end(), tag_vendor.begin(), ::tolower);
|
||||
std::transform(tag_type.begin(), tag_type.end(), tag_type.begin(), ::tolower);
|
||||
std::transform(tag_name.begin(), tag_name.end(), tag_name.begin(), ::tolower);
|
||||
|
||||
DevFilaBlacklist::load_filaments_blacklist_config();
|
||||
if (DevFilaBlacklist::filaments_blacklist.contains("blacklist"))
|
||||
{
|
||||
for (auto filament_item : DevFilaBlacklist::filaments_blacklist["blacklist"])
|
||||
{
|
||||
|
||||
std::string vendor = filament_item.contains("vendor") ? filament_item["vendor"].get<std::string>() : "";
|
||||
std::string type = filament_item.contains("type") ? filament_item["type"].get<std::string>() : "";
|
||||
std::string type_suffix = filament_item.contains("type_suffix") ? filament_item["type_suffix"].get<std::string>() : "";
|
||||
std::string name = filament_item.contains("name") ? filament_item["name"].get<std::string>() : "";
|
||||
std::string slot = filament_item.contains("slot") ? filament_item["slot"].get<std::string>() : "";
|
||||
std::vector<std::string> model_ids = filament_item.contains("model_id") ? filament_item["model_id"].get<std::vector<std::string>>() : std::vector<std::string>();
|
||||
std::string action = filament_item.contains("action") ? filament_item["action"].get<std::string>() : "";
|
||||
std::string description = filament_item.contains("description") ? filament_item["description"].get<std::string>() : "";
|
||||
|
||||
// check model id
|
||||
if (!model_ids.empty() && std::find(model_ids.begin(), model_ids.end(), model_id) == model_ids.end()) { continue; }
|
||||
|
||||
// check vendor
|
||||
std::transform(vendor.begin(), vendor.end(), vendor.begin(), ::tolower);
|
||||
if (!vendor.empty())
|
||||
{
|
||||
if ((vendor == "bambu lab" && (tag_vendor == vendor)) ||
|
||||
(vendor == "third party" && (tag_vendor != "bambu lab")))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check type
|
||||
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
|
||||
if (!type.empty() && (type != tag_type)) { continue; }
|
||||
|
||||
// check type suffix
|
||||
std::transform(type_suffix.begin(), type_suffix.end(), type_suffix.begin(), ::tolower);
|
||||
if (!type_suffix.empty())
|
||||
{
|
||||
if (tag_type.length() < type_suffix.length()) { continue; }
|
||||
if ((tag_type.substr(tag_type.length() - type_suffix.length()) != type_suffix)) { continue; }
|
||||
}
|
||||
|
||||
// check name
|
||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||
if (!name.empty() && (name != tag_name)) { continue; }
|
||||
|
||||
// check loc
|
||||
if (!slot.empty())
|
||||
{
|
||||
bool is_virtual_slot = devPrinterUtil::IsVirtualSlot(ams_id);
|
||||
bool check_virtual_slot = (slot == "ext");
|
||||
bool check_ams_slot = (slot == "ams");
|
||||
if (is_virtual_slot && !check_virtual_slot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (!is_virtual_slot && !check_ams_slot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI::wxGetApp().app_config->get("skip_ams_blacklist_check") == "true") {
|
||||
action = "warning";
|
||||
}
|
||||
|
||||
in_blacklist = true;
|
||||
ac = action;
|
||||
info = _L(description);
|
||||
wiki_url = filament_item.contains("wiki") ? filament_item["wiki"].get<std::string>() : "";
|
||||
return;
|
||||
|
||||
// Using in description
|
||||
L("TPU is not supported by AMS.");
|
||||
L("Damp PVA will become flexible and get stuck inside AMS, please take care to dry it before use.");
|
||||
L("Damp PVA is flexible and may get stuck in extruder. Dry it before use.");
|
||||
L("The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite.");
|
||||
L("CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution.");
|
||||
L("PPS-CF is brittle and could break in bended PTFE tube above Toolhead.");
|
||||
L("PPA-CF is brittle and could break in bended PTFE tube above Toolhead.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DevFilaBlacklist::check_filaments_in_blacklist(std::string model_id,
|
||||
std::string tag_vendor,
|
||||
std::string tag_type,
|
||||
const std::string& filament_id,
|
||||
int ams_id,
|
||||
int slot_id,
|
||||
std::string tag_name,
|
||||
bool& in_blacklist,
|
||||
std::string& ac,
|
||||
wxString& info)
|
||||
{
|
||||
wxString wiki_url;
|
||||
check_filaments_in_blacklist_url(model_id, tag_vendor, tag_type, filament_id, ams_id, slot_id, tag_name, in_blacklist, ac, info, wiki_url);
|
||||
}
|
||||
|
||||
|
||||
bool check_filaments_printable(const std::string &tag_vendor, const std::string &tag_type, const std::string& filament_id, int ams_id, bool &in_blacklist, std::string &ac, wxString &info)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MachineObject *obj = dev->get_selected_machine();
|
||||
if (obj == nullptr || !obj->is_multi_extruders()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Preset *printer_preset = GUI::get_printer_preset(obj);
|
||||
if (!printer_preset)
|
||||
return true;
|
||||
|
||||
ConfigOptionInts *physical_extruder_map_op = dynamic_cast<ConfigOptionInts *>(printer_preset->config.option("physical_extruder_map"));
|
||||
if (!physical_extruder_map_op)
|
||||
return true;
|
||||
std::vector<int> physical_extruder_maps = physical_extruder_map_op->values;
|
||||
int obj_extruder_id = obj->get_extruder_id_by_ams_id(std::to_string(ams_id));
|
||||
int extruder_idx = obj_extruder_id;
|
||||
for (int index = 0; index < physical_extruder_maps.size(); ++index) {
|
||||
if (physical_extruder_maps[index] == obj_extruder_id) {
|
||||
extruder_idx = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PresetBundle *preset_bundle = GUI::wxGetApp().preset_bundle;
|
||||
std::optional<FilamentBaseInfo> filament_info = preset_bundle->get_filament_by_filament_id(filament_id, printer_preset->name);
|
||||
if (filament_info.has_value() && !(filament_info->filament_printable >> extruder_idx & 1)) {
|
||||
wxString extruder_name = extruder_idx == 0 ? _L("left") : _L("right");
|
||||
ac = "prohibition";
|
||||
info = wxString::Format(_L("%s is not supported by %s extruder."), tag_type, extruder_name);
|
||||
in_blacklist = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DevFilaBlacklist::check_filaments_in_blacklist_url(std::string model_id, std::string tag_vendor, std::string tag_type, const std::string& filament_id, int ams_id, int slot_id, std::string tag_name, bool& in_blacklist, std::string& ac, wxString& info, wxString& wiki_url)
|
||||
{
|
||||
if (ams_id < 0 || slot_id < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_filaments_printable(tag_vendor, tag_type, filament_id, ams_id, in_blacklist, ac, info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
check_filaments(model_id, tag_vendor, tag_type, ams_id, slot_id, tag_name, in_blacklist, ac, info, wiki_url);
|
||||
}
|
||||
|
||||
}
|
||||
17
src/slic3r/GUI/DeviceCore/DevFilaBlackList.h
Normal file
17
src/slic3r/GUI/DeviceCore/DevFilaBlackList.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
class DevFilaBlacklist
|
||||
{
|
||||
public:
|
||||
static bool load_filaments_blacklist_config();
|
||||
static void check_filaments_in_blacklist(std::string model_id, std::string tag_vendor, std::string tag_type, const std::string& filament_id, int ams_id, int slot_id, std::string tag_name, bool& in_blacklist, std::string& ac, wxString& info);
|
||||
static void check_filaments_in_blacklist_url(std::string model_id, std::string tag_vendor, std::string tag_type, const std::string& filament_id, int ams_id, int slot_id, std::string tag_name, bool& in_blacklist, std::string& ac, wxString& info, wxString& wiki_url);
|
||||
|
||||
public:
|
||||
static json filaments_blacklist;
|
||||
};// class DevFilaBlacklist
|
||||
|
||||
}// namespace Slic3r
|
||||
719
src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp
Normal file
719
src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp
Normal file
@@ -0,0 +1,719 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevFilaSystem.h"
|
||||
|
||||
// TODO: remove this include
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
|
||||
#include "DevUtil.h"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r {
|
||||
static int _hex_digit_to_int(const char c) { return (c >= '0' && c <= '9') ? c - '0' : (c >= 'A' && c <= 'F') ? c - 'A' + 10 : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : -1; }
|
||||
|
||||
wxColour DevAmsTray::decode_color(const std::string &color)
|
||||
{
|
||||
std::array<int, 4> ret = {0, 0, 0, 0};
|
||||
const char * c = color.data();
|
||||
if (color.size() == 8) {
|
||||
for (size_t j = 0; j < 4; ++j) {
|
||||
int digit1 = _hex_digit_to_int(*c++);
|
||||
int digit2 = _hex_digit_to_int(*c++);
|
||||
if (digit1 == -1 || digit2 == -1) break;
|
||||
ret[j] = static_cast<float>(digit1 * 16 + digit2);
|
||||
}
|
||||
} else { return wxColour(255, 255, 255, 255); }
|
||||
|
||||
return wxColour(ret[0], ret[1], ret[2], ret[3]);
|
||||
}
|
||||
|
||||
void DevAmsTray::UpdateColorFromStr(const std::string& color)
|
||||
{
|
||||
if (color.empty()) return;
|
||||
if (this->color != color)
|
||||
{
|
||||
wx_color = "#" + wxString::FromUTF8(color);
|
||||
this->color = color;
|
||||
}
|
||||
}
|
||||
|
||||
wxColour DevAmsTray::get_color() { return decode_color(color); }
|
||||
|
||||
void DevAmsTray::reset()
|
||||
{
|
||||
tag_uid = "";
|
||||
setting_id = "";
|
||||
filament_setting_id = "";
|
||||
type = "";
|
||||
sub_brands = "";
|
||||
color = "";
|
||||
weight = "";
|
||||
diameter = "";
|
||||
temp = "";
|
||||
time = "";
|
||||
bed_temp_type = "";
|
||||
bed_temp = "";
|
||||
nozzle_temp_max = "";
|
||||
nozzle_temp_min = "";
|
||||
xcam_info = "";
|
||||
uuid = "";
|
||||
k = 0.0f;
|
||||
n = 0.0f;
|
||||
is_bbl = false;
|
||||
hold_count = 0;
|
||||
remain = 0;
|
||||
}
|
||||
|
||||
|
||||
bool DevAmsTray::is_tray_info_ready()
|
||||
{
|
||||
if (color.empty()) return false;
|
||||
if (type.empty()) return false;
|
||||
//if (setting_id.empty()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DevAmsTray::is_unset_third_filament()
|
||||
{
|
||||
if (this->is_bbl) return false;
|
||||
return (color.empty() || type.empty());
|
||||
}
|
||||
|
||||
std::string DevAmsTray::get_display_filament_type()
|
||||
{
|
||||
if (type == "PLA-S") return "Sup.PLA";
|
||||
if (type == "PA-S") return "Sup.PA";
|
||||
if (type == "ABS-S") return "Sup.ABS";
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string DevAmsTray::get_filament_type()
|
||||
{
|
||||
if (type == "Sup.PLA") { return "PLA-S"; }
|
||||
if (type == "Sup.PA") { return "PA-S"; }
|
||||
if (type == "Sup.ABS") { return "ABS-S"; }
|
||||
if (type == "Support W") { return "PLA-S"; }
|
||||
if (type == "Support G") { return "PA-S"; }
|
||||
if (type == "Support") { if (setting_id == "GFS00") { type = "PLA-S"; } else if (setting_id == "GFS01") { type = "PA-S"; } else { return "PLA-S"; } }
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
DevAms::DevAms(const std::string& ams_id, int extruder_id, AmsType type)
|
||||
{
|
||||
m_ams_id = ams_id;
|
||||
m_ext_id = extruder_id;
|
||||
m_ams_type = type;
|
||||
}
|
||||
|
||||
DevAms::DevAms(const std::string& ams_id, int nozzle_id, int type)
|
||||
{
|
||||
m_ams_id = ams_id;
|
||||
m_ext_id = nozzle_id;
|
||||
m_ams_type = (AmsType)type;
|
||||
assert(DUMMY < type && m_ams_type <= N3S);
|
||||
}
|
||||
|
||||
DevAms::~DevAms()
|
||||
{
|
||||
for (auto it = m_trays.begin(); it != m_trays.end(); it++)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
delete it->second;
|
||||
it->second = nullptr;
|
||||
}
|
||||
}
|
||||
m_trays.clear();
|
||||
}
|
||||
|
||||
static unordered_map<int, wxString> s_ams_display_formats = {
|
||||
{DevAms::AMS, "AMS-%d"},
|
||||
{DevAms::AMS_LITE, "AMS Lite-%d"},
|
||||
{DevAms::N3F, "AMS 2 PRO-%d"},
|
||||
{DevAms::N3S, "AMS HT-%d"}
|
||||
};
|
||||
|
||||
wxString DevAms::GetDisplayName() const
|
||||
{
|
||||
wxString ams_display_format;
|
||||
auto iter = s_ams_display_formats.find(m_ams_type);
|
||||
if (iter != s_ams_display_formats.end())
|
||||
{
|
||||
ams_display_format = iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0 && __FUNCTION__);
|
||||
ams_display_format = "AMS-%d";
|
||||
}
|
||||
|
||||
int num_id;
|
||||
try
|
||||
{
|
||||
num_id = std::stoi(GetAmsId());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
assert(0 && __FUNCTION__);
|
||||
BOOST_LOG_TRIVIAL(error) << "Invalid AMS ID: " << GetAmsId() << ", error: " << e.what();
|
||||
num_id = 0;
|
||||
}
|
||||
|
||||
int loc = (num_id > 127) ? (num_id - 127) : (num_id + 1);
|
||||
return wxString::Format(ams_display_format, loc);
|
||||
}
|
||||
|
||||
int DevAms::GetSlotCount() const
|
||||
{
|
||||
if (m_ams_type == AMS || m_ams_type == AMS_LITE || m_ams_type == N3F)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
else if (m_ams_type == N3S)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
DevAmsTray* DevAms::GetTray(const std::string& tray_id) const
|
||||
{
|
||||
auto it = m_trays.find(tray_id);
|
||||
if (it != m_trays.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DevFilaSystem::~DevFilaSystem()
|
||||
{
|
||||
for (auto it = amsList.begin(); it != amsList.end(); it++)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
delete it->second;
|
||||
it->second = nullptr;
|
||||
}
|
||||
}
|
||||
amsList.clear();
|
||||
}
|
||||
|
||||
DevAms* DevFilaSystem::GetAmsById(const std::string& ams_id) const
|
||||
{
|
||||
auto it = amsList.find(ams_id);
|
||||
if (it != amsList.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DevAmsTray* DevFilaSystem::GetAmsTray(const std::string& ams_id, const std::string& tray_id) const
|
||||
{
|
||||
auto it = amsList.find(ams_id);
|
||||
if (it == amsList.end()) return nullptr;
|
||||
if (!it->second) return nullptr;
|
||||
return it->second->GetTray(tray_id);;
|
||||
}
|
||||
|
||||
void DevFilaSystem::CollectAmsColors(std::vector<wxColour>& ams_colors) const
|
||||
{
|
||||
ams_colors.clear();
|
||||
ams_colors.reserve(amsList.size());
|
||||
for (auto ams = amsList.begin(); ams != amsList.end(); ams++)
|
||||
{
|
||||
for (auto tray = ams->second->GetTrays().begin(); tray != ams->second->GetTrays().end(); tray++)
|
||||
{
|
||||
if (tray->second->is_tray_info_ready())
|
||||
{
|
||||
auto ams_color = DevAmsTray::decode_color(tray->second->color);
|
||||
ams_colors.emplace_back(ams_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DevFilaSystem::GetExtruderIdByAmsId(const std::string& ams_id) const
|
||||
{
|
||||
auto it = amsList.find(ams_id);
|
||||
if (it != amsList.end())
|
||||
{
|
||||
return it->second->GetExtruderId();
|
||||
}
|
||||
else if (stoi(ams_id) == VIRTUAL_TRAY_MAIN_ID)
|
||||
{
|
||||
return MAIN_EXTRUDER_ID;
|
||||
}
|
||||
else if (stoi(ams_id) == VIRTUAL_TRAY_DEPUTY_ID)
|
||||
{
|
||||
return DEPUTY_EXTRUDER_ID;
|
||||
}
|
||||
|
||||
assert(false && __FUNCTION__);
|
||||
return 0; // not found
|
||||
}
|
||||
|
||||
bool DevFilaSystem::IsAmsSettingUp() const
|
||||
{
|
||||
int setting_up_stat = DevUtil::get_flag_bits(m_ams_cali_stat, 0, 8);
|
||||
if (setting_up_stat == 0x01 || setting_up_stat == 0x02 || setting_up_stat == 0x03 || setting_up_stat == 0x04)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DevFilaSystem::IsBBL_Filament(std::string tag_uid)
|
||||
{
|
||||
if (tag_uid.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tag_uid.length(); i++)
|
||||
{
|
||||
if (tag_uid[i] != '0') { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaSystem* system, bool key_field_only)
|
||||
{
|
||||
if (jj.contains("ams"))
|
||||
{
|
||||
if (jj["ams"].contains("ams"))
|
||||
{
|
||||
if (jj["ams"].contains("ams_exist_bits"))
|
||||
{
|
||||
obj->ams_exist_bits = stol(jj["ams"]["ams_exist_bits"].get<std::string>(), nullptr, 16);
|
||||
}
|
||||
|
||||
if (jj["ams"].contains("tray_exist_bits"))
|
||||
{
|
||||
obj->tray_exist_bits = stol(jj["ams"]["tray_exist_bits"].get<std::string>(), nullptr, 16);
|
||||
}
|
||||
|
||||
if (jj["ams"].contains("cali_stat")) { system->m_ams_cali_stat = jj["ams"]["cali_stat"].get<int>(); }
|
||||
|
||||
if (!key_field_only)
|
||||
{
|
||||
if (jj["ams"].contains("tray_read_done_bits"))
|
||||
{
|
||||
obj->tray_read_done_bits = stol(jj["ams"]["tray_read_done_bits"].get<std::string>(), nullptr, 16);
|
||||
}
|
||||
if (jj["ams"].contains("tray_reading_bits"))
|
||||
{
|
||||
obj->tray_reading_bits = stol(jj["ams"]["tray_reading_bits"].get<std::string>(), nullptr, 16);
|
||||
}
|
||||
if (jj["ams"].contains("tray_is_bbl_bits"))
|
||||
{
|
||||
obj->tray_is_bbl_bits = stol(jj["ams"]["tray_is_bbl_bits"].get<std::string>(), nullptr, 16);
|
||||
}
|
||||
if (jj["ams"].contains("version"))
|
||||
{
|
||||
if (jj["ams"]["version"].is_number())
|
||||
{
|
||||
obj->ams_version = jj["ams"]["version"].get<int>();
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (jj["ams"].contains("ams_rfid_status")) { }
|
||||
#endif
|
||||
|
||||
if (time(nullptr) - obj->ams_user_setting_start > HOLD_TIME_3SEC)
|
||||
{
|
||||
if (jj["ams"].contains("insert_flag"))
|
||||
{
|
||||
system->m_ams_system_setting.SetDetectOnInsertEnabled(jj["ams"]["insert_flag"].get<bool>());
|
||||
}
|
||||
if (jj["ams"].contains("power_on_flag"))
|
||||
{
|
||||
system->m_ams_system_setting.SetDetectOnPowerupEnabled(jj["ams"]["power_on_flag"].get<bool>());
|
||||
}
|
||||
if (jj["ams"].contains("calibrate_remain_flag"))
|
||||
{
|
||||
system->m_ams_system_setting.SetDetectRemainEnabled(jj["ams"]["calibrate_remain_flag"].get<bool>());
|
||||
}
|
||||
}
|
||||
|
||||
json j_ams = jj["ams"]["ams"];
|
||||
std::set<std::string> ams_id_set;
|
||||
|
||||
for (auto it = system->amsList.begin(); it != system->amsList.end(); it++)
|
||||
{
|
||||
ams_id_set.insert(it->first);
|
||||
}
|
||||
|
||||
for (auto it = j_ams.begin(); it != j_ams.end(); it++)
|
||||
{
|
||||
if (!it->contains("id")) continue;
|
||||
std::string ams_id = (*it)["id"].get<std::string>();
|
||||
|
||||
int extuder_id = MAIN_EXTRUDER_ID; // Default nozzle id
|
||||
int type_id = 1; // 0:dummy 1:ams 2:ams-lite 3:n3f 4:n3s
|
||||
|
||||
/*ams info*/
|
||||
if (it->contains("info"))
|
||||
{
|
||||
const std::string& info = (*it)["info"].get<std::string>();
|
||||
type_id = DevUtil::get_flag_bits(info, 0, 4);
|
||||
extuder_id = DevUtil::get_flag_bits(info, 8, 4);
|
||||
}
|
||||
|
||||
/*AMS without initialization*/
|
||||
if (extuder_id == 0xE)
|
||||
{
|
||||
ams_id_set.erase(ams_id);
|
||||
system->amsList.erase(ams_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
ams_id_set.erase(ams_id);
|
||||
DevAms* curr_ams = nullptr;
|
||||
auto ams_it = system->amsList.find(ams_id);
|
||||
if (ams_it == system->amsList.end())
|
||||
{
|
||||
DevAms* new_ams = new DevAms(ams_id, extuder_id, type_id);
|
||||
system->amsList.insert(std::make_pair(ams_id, new_ams));
|
||||
// new ams added event
|
||||
curr_ams = new_ams;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (extuder_id != ams_it->second->GetExtruderId())
|
||||
{
|
||||
ams_it->second->m_ext_id = extuder_id;
|
||||
}
|
||||
|
||||
curr_ams = ams_it->second;
|
||||
}
|
||||
if (!curr_ams) continue;
|
||||
|
||||
/*set ams type flag*/
|
||||
curr_ams->SetAmsType(type_id);
|
||||
|
||||
|
||||
/*set ams exist flag*/
|
||||
try
|
||||
{
|
||||
if (!ams_id.empty())
|
||||
{
|
||||
int ams_id_int = atoi(ams_id.c_str());
|
||||
|
||||
if (type_id < 4)
|
||||
{
|
||||
curr_ams->m_exist = (obj->ams_exist_bits & (1 << ams_id_int)) != 0 ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_ams->m_exist = DevUtil::get_flag_bits(obj->ams_exist_bits, 4 + (ams_id_int - 128));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if (it->contains("dry_time") && (*it)["dry_time"].is_number())
|
||||
{
|
||||
curr_ams->m_left_dry_time = (*it)["dry_time"].get<int>();
|
||||
}
|
||||
|
||||
if (it->contains("humidity"))
|
||||
{
|
||||
std::string humidity = (*it)["humidity"].get<std::string>();
|
||||
|
||||
try
|
||||
{
|
||||
curr_ams->m_humidity_level = atoi(humidity.c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (it->contains("humidity_raw"))
|
||||
{
|
||||
std::string humidity_raw = (*it)["humidity_raw"].get<std::string>();
|
||||
|
||||
try
|
||||
{
|
||||
curr_ams->m_humidity_percent = atoi(humidity_raw.c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
if (curr_ams->GetHumidityPercent() != -1)
|
||||
{
|
||||
if (curr_ams->GetHumidityPercent() < 20)
|
||||
{
|
||||
curr_ams->m_humidity_level = 5;
|
||||
}
|
||||
else if (curr_ams->GetHumidityPercent() < 40)
|
||||
{
|
||||
curr_ams->m_humidity_level = 4;
|
||||
}
|
||||
else if (curr_ams->GetHumidityPercent() < 60)
|
||||
{
|
||||
curr_ams->m_humidity_level = 3;
|
||||
}
|
||||
else if (curr_ams->GetHumidityPercent() < 80)
|
||||
{
|
||||
curr_ams->m_humidity_level = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_ams->m_humidity_level = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (it->contains("temp"))
|
||||
{
|
||||
std::string temp = (*it)["temp"].get<std::string>();
|
||||
try
|
||||
{
|
||||
curr_ams->m_current_temperature = DevUtil::string_to_float(temp);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
curr_ams->m_current_temperature = INVALID_AMS_TEMPERATURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (it->contains("tray"))
|
||||
{
|
||||
std::set<std::string> tray_id_set;
|
||||
for (auto it = curr_ams->GetTrays().cbegin(); it != curr_ams->GetTrays().cend(); it++)
|
||||
{
|
||||
tray_id_set.insert(it->first);
|
||||
}
|
||||
for (auto tray_it = (*it)["tray"].begin(); tray_it != (*it)["tray"].end(); tray_it++)
|
||||
{
|
||||
if (!tray_it->contains("id")) continue;
|
||||
std::string tray_id = (*tray_it)["id"].get<std::string>();
|
||||
tray_id_set.erase(tray_id);
|
||||
// compare tray_list
|
||||
DevAmsTray* curr_tray = nullptr;
|
||||
auto tray_iter = curr_ams->GetTrays().find(tray_id);
|
||||
if (tray_iter == curr_ams->GetTrays().end())
|
||||
{
|
||||
DevAmsTray* new_tray = new DevAmsTray(tray_id);
|
||||
curr_ams->m_trays.insert(std::make_pair(tray_id, new_tray));
|
||||
curr_tray = new_tray;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_tray = tray_iter->second;
|
||||
}
|
||||
if (!curr_tray) continue;
|
||||
|
||||
if (curr_tray->hold_count > 0)
|
||||
{
|
||||
curr_tray->hold_count--;
|
||||
continue;
|
||||
}
|
||||
|
||||
curr_tray->id = (*tray_it)["id"].get<std::string>();
|
||||
if (tray_it->contains("tag_uid"))
|
||||
curr_tray->tag_uid = (*tray_it)["tag_uid"].get<std::string>();
|
||||
else
|
||||
curr_tray->tag_uid = "0";
|
||||
if (tray_it->contains("tray_info_idx") && tray_it->contains("tray_type"))
|
||||
{
|
||||
curr_tray->setting_id = (*tray_it)["tray_info_idx"].get<std::string>();
|
||||
//std::string type = (*tray_it)["tray_type"].get<std::string>();
|
||||
std::string type = MachineObject::setting_id_to_type(curr_tray->setting_id, (*tray_it)["tray_type"].get<std::string>());
|
||||
if (curr_tray->setting_id == "GFS00")
|
||||
{
|
||||
curr_tray->type = "PLA-S";
|
||||
}
|
||||
else if (curr_tray->setting_id == "GFS01")
|
||||
{
|
||||
curr_tray->type = "PA-S";
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_tray->type = type;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_tray->setting_id = "";
|
||||
curr_tray->type = "";
|
||||
}
|
||||
if (tray_it->contains("tray_sub_brands"))
|
||||
curr_tray->sub_brands = (*tray_it)["tray_sub_brands"].get<std::string>();
|
||||
else
|
||||
curr_tray->sub_brands = "";
|
||||
if (tray_it->contains("tray_weight"))
|
||||
curr_tray->weight = (*tray_it)["tray_weight"].get<std::string>();
|
||||
else
|
||||
curr_tray->weight = "";
|
||||
if (tray_it->contains("tray_diameter"))
|
||||
curr_tray->diameter = (*tray_it)["tray_diameter"].get<std::string>();
|
||||
else
|
||||
curr_tray->diameter = "";
|
||||
if (tray_it->contains("tray_temp"))
|
||||
curr_tray->temp = (*tray_it)["tray_temp"].get<std::string>();
|
||||
else
|
||||
curr_tray->temp = "";
|
||||
if (tray_it->contains("tray_time"))
|
||||
curr_tray->time = (*tray_it)["tray_time"].get<std::string>();
|
||||
else
|
||||
curr_tray->time = "";
|
||||
if (tray_it->contains("bed_temp_type"))
|
||||
curr_tray->bed_temp_type = (*tray_it)["bed_temp_type"].get<std::string>();
|
||||
else
|
||||
curr_tray->bed_temp_type = "";
|
||||
if (tray_it->contains("bed_temp"))
|
||||
curr_tray->bed_temp = (*tray_it)["bed_temp"].get<std::string>();
|
||||
else
|
||||
curr_tray->bed_temp = "";
|
||||
if (tray_it->contains("tray_color"))
|
||||
{
|
||||
auto color = (*tray_it)["tray_color"].get<std::string>();
|
||||
curr_tray->UpdateColorFromStr(color);
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_tray->color = "";
|
||||
}
|
||||
if (tray_it->contains("nozzle_temp_max"))
|
||||
{
|
||||
curr_tray->nozzle_temp_max = (*tray_it)["nozzle_temp_max"].get<std::string>();
|
||||
}
|
||||
else
|
||||
curr_tray->nozzle_temp_max = "";
|
||||
if (tray_it->contains("nozzle_temp_min"))
|
||||
curr_tray->nozzle_temp_min = (*tray_it)["nozzle_temp_min"].get<std::string>();
|
||||
else
|
||||
curr_tray->nozzle_temp_min = "";
|
||||
if (tray_it->contains("xcam_info"))
|
||||
curr_tray->xcam_info = (*tray_it)["xcam_info"].get<std::string>();
|
||||
else
|
||||
curr_tray->xcam_info = "";
|
||||
if (tray_it->contains("tray_uuid"))
|
||||
curr_tray->uuid = (*tray_it)["tray_uuid"].get<std::string>();
|
||||
else
|
||||
curr_tray->uuid = "0";
|
||||
|
||||
if (tray_it->contains("ctype"))
|
||||
curr_tray->ctype = (*tray_it)["ctype"].get<int>();
|
||||
else
|
||||
curr_tray->ctype = 0;
|
||||
curr_tray->cols.clear();
|
||||
if (tray_it->contains("cols"))
|
||||
{
|
||||
if ((*tray_it)["cols"].is_array())
|
||||
{
|
||||
for (auto it = (*tray_it)["cols"].begin(); it != (*tray_it)["cols"].end(); it++)
|
||||
{
|
||||
curr_tray->cols.push_back(it.value().get<std::string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tray_it->contains("remain"))
|
||||
{
|
||||
curr_tray->remain = (*tray_it)["remain"].get<int>();
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_tray->remain = -1;
|
||||
}
|
||||
int ams_id_int = 0;
|
||||
int tray_id_int = 0;
|
||||
try
|
||||
{
|
||||
if (!ams_id.empty() && !curr_tray->id.empty())
|
||||
{
|
||||
ams_id_int = atoi(ams_id.c_str());
|
||||
tray_id_int = atoi(curr_tray->id.c_str());
|
||||
|
||||
if (type_id < 4)
|
||||
{
|
||||
curr_tray->is_exists = (obj->tray_exist_bits & (1 << (ams_id_int * 4 + tray_id_int))) != 0 ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_tray->is_exists = DevUtil::get_flag_bits(obj->tray_exist_bits, 16 + (ams_id_int - 128));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
if (tray_it->contains("setting_id"))
|
||||
{
|
||||
curr_tray->filament_setting_id = (*tray_it)["setting_id"].get<std::string>();
|
||||
}
|
||||
auto curr_time = std::chrono::system_clock::now();
|
||||
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - obj->extrusion_cali_set_hold_start);
|
||||
if (diff.count() > HOLD_TIMEOUT || diff.count() < 0
|
||||
|| ams_id_int != (obj->extrusion_cali_set_tray_id / 4)
|
||||
|| tray_id_int != (obj->extrusion_cali_set_tray_id % 4))
|
||||
{
|
||||
if (tray_it->contains("k"))
|
||||
{
|
||||
curr_tray->k = (*tray_it)["k"].get<float>();
|
||||
}
|
||||
if (tray_it->contains("n"))
|
||||
{
|
||||
curr_tray->n = (*tray_it)["n"].get<float>();
|
||||
}
|
||||
}
|
||||
|
||||
std::string temp = tray_it->dump();
|
||||
|
||||
if (tray_it->contains("cali_idx"))
|
||||
{
|
||||
curr_tray->cali_idx = (*tray_it)["cali_idx"].get<int>();
|
||||
}
|
||||
}
|
||||
// remove not in trayList
|
||||
for (auto tray_it = tray_id_set.begin(); tray_it != tray_id_set.end(); tray_it++)
|
||||
{
|
||||
std::string tray_id = *tray_it;
|
||||
auto tray = curr_ams->GetTrays().find(tray_id);
|
||||
if (tray != curr_ams->GetTrays().end())
|
||||
{
|
||||
curr_ams->m_trays.erase(tray_id);
|
||||
BOOST_LOG_TRIVIAL(trace) << "parse_json: remove ams_id=" << ams_id << ", tray_id=" << tray_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove not in amsList
|
||||
for (auto it = ams_id_set.begin(); it != ams_id_set.end(); it++)
|
||||
{
|
||||
std::string ams_id = *it;
|
||||
auto ams = system->amsList.find(ams_id);
|
||||
if (ams != system->amsList.end())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(trace) << "parse_json: remove ams_id=" << ams_id;
|
||||
system->amsList.erase(ams_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
190
src/slic3r/GUI/DeviceCore/DevFilaSystem.h
Normal file
190
src/slic3r/GUI/DeviceCore/DevFilaSystem.h
Normal file
@@ -0,0 +1,190 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
#include "DevDefs.h"
|
||||
#include "DevFilaAmsSetting.h"
|
||||
|
||||
#include <map>
|
||||
#include <wx/string.h>
|
||||
#include <wx/colour.h>
|
||||
|
||||
#define HOLD_COUNT_MAX 3
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
class MachineObject;
|
||||
|
||||
class DevAmsTray
|
||||
{
|
||||
public:
|
||||
DevAmsTray(std::string tray_id)
|
||||
{
|
||||
is_bbl = false;
|
||||
id = tray_id;
|
||||
}
|
||||
|
||||
static wxColour decode_color(const std::string& color);
|
||||
|
||||
bool operator==(DevAmsTray const& o) const
|
||||
{
|
||||
return id == o.id && type == o.type && filament_setting_id == o.filament_setting_id && color == o.color;
|
||||
}
|
||||
bool operator!=(DevAmsTray const& o) const { return !operator==(o); }
|
||||
|
||||
std::string id;
|
||||
std::string tag_uid; // tag_uid
|
||||
std::string setting_id; // tray_info_idx
|
||||
std::string filament_setting_id; // setting_id
|
||||
std::string type;
|
||||
std::string sub_brands;
|
||||
std::string color;
|
||||
std::vector<std::string> cols;
|
||||
std::string weight;
|
||||
std::string diameter;
|
||||
std::string temp;
|
||||
std::string time;
|
||||
std::string bed_temp_type;
|
||||
std::string bed_temp;
|
||||
std::string nozzle_temp_max;
|
||||
std::string nozzle_temp_min;
|
||||
std::string xcam_info;
|
||||
std::string uuid;
|
||||
int ctype = 0;
|
||||
float k = 0.0f; // k range: 0 ~ 0.5
|
||||
float n = 0.0f; // k range: 0.6 ~ 2.0
|
||||
int cali_idx = -1; // - 1 means default
|
||||
|
||||
wxColour wx_color;
|
||||
bool is_bbl;
|
||||
bool is_exists = false;
|
||||
int hold_count = 0;
|
||||
int remain = 0; // filament remain: 0 ~ 100
|
||||
|
||||
void set_hold_count() { hold_count = HOLD_COUNT_MAX; }
|
||||
void UpdateColorFromStr(const std::string& color);
|
||||
wxColour get_color();
|
||||
|
||||
void reset();
|
||||
|
||||
bool is_tray_info_ready();
|
||||
bool is_unset_third_filament();
|
||||
std::string get_display_filament_type();
|
||||
std::string get_filament_type();
|
||||
};
|
||||
|
||||
class DevAms
|
||||
{
|
||||
friend class DevFilaSystemParser;
|
||||
public:
|
||||
enum AmsType : int
|
||||
{
|
||||
DUMMY = 0,
|
||||
AMS = 1, // AMS
|
||||
AMS_LITE = 2, // AMS-Lite
|
||||
N3F = 3, // N3F
|
||||
N3S = 4, // N3S
|
||||
};
|
||||
|
||||
public:
|
||||
DevAms(const std::string& ams_id, int extruder_id, AmsType type);
|
||||
DevAms(const std::string& ams_id, int nozzle_id, int type);
|
||||
~DevAms();
|
||||
|
||||
public:
|
||||
std::string GetAmsId() const { return m_ams_id; }
|
||||
wxString GetDisplayName() const; // display
|
||||
|
||||
void SetAmsType(int type) { m_ams_type = (AmsType)type; }
|
||||
void SetAmsType(AmsType type) { m_ams_type = type; }
|
||||
AmsType GetAmsType() const { return m_ams_type; }
|
||||
|
||||
// exist or not
|
||||
bool IsExist() const { return m_exist; }
|
||||
|
||||
// slots
|
||||
int GetSlotCount() const;
|
||||
DevAmsTray* GetTray(const std::string& tray_id) const;
|
||||
const std::map<std::string, DevAmsTray*>& GetTrays() const { return m_trays; }
|
||||
|
||||
// installed on the extruder
|
||||
int GetExtruderId() const { return m_ext_id; }
|
||||
|
||||
// temperature and humidity
|
||||
float GetCurrentTemperature() const { return m_current_temperature; }
|
||||
|
||||
bool SupportHumidity() const { return (m_ams_type == AMS) || (m_ams_type == N3F) || (m_ams_type == N3S);}
|
||||
int GetHumidityLevel() const { return m_humidity_level; }
|
||||
int GetHumidityPercent() const { return m_humidity_percent; }
|
||||
|
||||
bool SupportDrying() const { return m_ams_type > AMS_LITE; }
|
||||
int GetLeftDryTime() const { return m_left_dry_time; }
|
||||
|
||||
private:
|
||||
AmsType m_ams_type = AmsType::AMS;
|
||||
std::string m_ams_id;
|
||||
int m_ext_id;//extruder id
|
||||
bool m_exist = false;
|
||||
|
||||
// slots and trays
|
||||
std::map<std::string, DevAmsTray*> m_trays;//id -> DevAmsTray*
|
||||
|
||||
// temperature and humidity
|
||||
float m_current_temperature = INVALID_AMS_TEMPERATURE; // the temperature
|
||||
int m_humidity_level = 5;
|
||||
int m_humidity_percent = -1; // the percentage, -1 means invalid. eg. 100 means 100%
|
||||
int m_left_dry_time = 0;
|
||||
};
|
||||
|
||||
class DevFilaSystem
|
||||
{
|
||||
friend class DevFilaSystemParser;
|
||||
public:
|
||||
DevFilaSystem(MachineObject* owner) { m_owner = owner;};
|
||||
~DevFilaSystem();
|
||||
|
||||
public:
|
||||
bool HasAms() const { return !amsList.empty(); }
|
||||
bool IsAmsSettingUp() const;
|
||||
|
||||
/* ams */
|
||||
DevAms* GetAmsById(const std::string& ams_id) const;
|
||||
std::map<std::string, DevAms*>& GetAmsList() { return amsList; }
|
||||
int GetAmsCount() const { return amsList.size(); }
|
||||
|
||||
/* tray*/
|
||||
DevAmsTray* GetAmsTray(const std::string& ams_id, const std::string& tray_id) const;
|
||||
void CollectAmsColors(std::vector<wxColour>& ams_colors) const;
|
||||
|
||||
// extruder
|
||||
int GetExtruderIdByAmsId(const std::string& ams_id) const;
|
||||
|
||||
/* AMS settings*/
|
||||
DevAmsSystemSetting& GetAmsSystemSetting() { return m_ams_system_setting; }
|
||||
bool IsDetectOnInsertEnabled() const { return m_ams_system_setting.IsDetectOnInsertEnabled(); };
|
||||
bool IsDetectOnPowerupEnabled() const { return m_ams_system_setting.IsDetectOnPowerupEnabled(); }
|
||||
bool IsDetectRemainEnabled() const { return m_ams_system_setting.IsDetectRemainEnabled(); }
|
||||
bool IsAutoRefillEnabled() const { return m_ams_system_setting.IsAutoRefillEnabled(); }
|
||||
|
||||
public:
|
||||
static bool IsBBL_Filament(std::string tag_uid);
|
||||
|
||||
private:
|
||||
MachineObject* m_owner;
|
||||
|
||||
/* ams properties */
|
||||
int m_ams_cali_stat = 0;
|
||||
|
||||
std::map<std::string, DevAms*> amsList; // key: ams[id], start with 0
|
||||
|
||||
DevAmsSystemSetting m_ams_system_setting{ this };
|
||||
};// class DevFilaSystem
|
||||
|
||||
|
||||
class DevFilaSystemParser
|
||||
{
|
||||
public:
|
||||
static void ParseV1_0(const json& print_json, MachineObject* obj, DevFilaSystem* system, bool key_field_only);
|
||||
};
|
||||
|
||||
}// namespace Slic3r
|
||||
2
src/slic3r/GUI/DeviceCore/DevFirmware.cpp
Normal file
2
src/slic3r/GUI/DeviceCore/DevFirmware.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "DevFirmware.h"
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
57
src/slic3r/GUI/DeviceCore/DevFirmware.h
Normal file
57
src/slic3r/GUI/DeviceCore/DevFirmware.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
//Previous definitions
|
||||
class MachineObject;
|
||||
|
||||
enum PrinterFirmwareType
|
||||
{
|
||||
FIRMWARE_TYPE_ENGINEER = 0,
|
||||
FIRMWARE_TYPE_PRODUCTION,
|
||||
FIRMEARE_TYPE_UKNOWN,
|
||||
};
|
||||
|
||||
|
||||
class FirmwareInfo
|
||||
{
|
||||
public:
|
||||
std::string module_type; // ota or ams
|
||||
std::string version;
|
||||
std::string url;
|
||||
std::string name;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
|
||||
class DevFirmwareVersionInfo
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
wxString product_name;
|
||||
std::string sn;
|
||||
std::string hw_ver;
|
||||
std::string sw_ver;
|
||||
std::string sw_new_ver;
|
||||
int firmware_flag = 0;
|
||||
|
||||
public:
|
||||
bool isValid() const { return !sn.empty(); }
|
||||
bool isAirPump() const { return product_name.Contains("Air Pump"); }
|
||||
bool isLaszer() const { return product_name.Contains("Laser"); }
|
||||
bool isCuttingModule() const { return product_name.Contains("Cutting Module"); }
|
||||
};
|
||||
|
||||
|
||||
class DevFirmware
|
||||
{
|
||||
public:
|
||||
DevFirmware(MachineObject* obj) : m_owner(obj) {}
|
||||
|
||||
private:
|
||||
MachineObject* m_owner = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
67
src/slic3r/GUI/DeviceCore/DevHMS.cpp
Normal file
67
src/slic3r/GUI/DeviceCore/DevHMS.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//#include "D:/dev/bamboo_slicer/build_release/src/slic3r/CMakeFiles/libslic3r_gui.dir/Release/cmake_pch.hxx"
|
||||
#include "DevHMS.h"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
bool DevHMSItem::parse_hms_info(unsigned attr, unsigned code)
|
||||
{
|
||||
bool result = true;
|
||||
unsigned int model_id_int = (attr >> 24) & 0xFF;
|
||||
this->m_module_id = (ModuleID)model_id_int;
|
||||
this->m_module_num = (attr >> 16) & 0xFF;
|
||||
this->m_part_id = (attr >> 8) & 0xFF;
|
||||
this->m_reserved = (attr >> 0) & 0xFF;
|
||||
unsigned msg_level_int = code >> 16;
|
||||
if (msg_level_int < (unsigned)HMS_MSG_LEVEL_MAX)
|
||||
{
|
||||
this->m_msg_level = (HMSMessageLevel)msg_level_int;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_msg_level = HMS_UNKNOWN;
|
||||
}
|
||||
|
||||
this->m_msg_code = code & 0xFFFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string DevHMSItem::get_long_error_code() const
|
||||
{
|
||||
char buf[64];
|
||||
::sprintf(buf, "%02X%02X%02X00000%1X%04X",
|
||||
this->m_module_id,
|
||||
this->m_module_num,
|
||||
this->m_part_id,
|
||||
(int)this->m_msg_level,
|
||||
this->m_msg_code);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
void DevHMS::ParseHMSItems(const json& hms_json)
|
||||
{
|
||||
m_hms_list.clear();
|
||||
|
||||
try
|
||||
{
|
||||
if (hms_json.is_array())
|
||||
{
|
||||
for (auto it = hms_json.begin(); it != hms_json.end(); it++)
|
||||
{
|
||||
DevHMSItem item;
|
||||
if ((*it).contains("attr") && (*it).contains("code"))
|
||||
{
|
||||
unsigned attr = (*it)["attr"].get<unsigned>();
|
||||
unsigned code = (*it)["code"].get<unsigned>();
|
||||
item.parse_hms_info(attr, code);
|
||||
}
|
||||
m_hms_list.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
assert(false && "Parse HMS items failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/slic3r/GUI/DeviceCore/DevHMS.h
Normal file
84
src/slic3r/GUI/DeviceCore/DevHMS.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
#include <map>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
// Previous definitions
|
||||
class MachineObject;
|
||||
class DevHMSItem;
|
||||
|
||||
class DevHMS
|
||||
{
|
||||
public:
|
||||
DevHMS(MachineObject* obj) : m_object(obj) {}
|
||||
|
||||
public:
|
||||
void ParseHMSItems(const json& hms_json);
|
||||
const std::vector<DevHMSItem>& GetHMSItems() const { return m_hms_list; };
|
||||
|
||||
private:
|
||||
MachineObject* m_object = nullptr;
|
||||
|
||||
// all hms for this machine
|
||||
std::vector<DevHMSItem> m_hms_list;
|
||||
};
|
||||
|
||||
enum HMSMessageLevel
|
||||
{
|
||||
HMS_UNKNOWN = 0,
|
||||
HMS_FATAL = 1,
|
||||
HMS_SERIOUS = 2,
|
||||
HMS_COMMON = 3,
|
||||
HMS_INFO = 4,
|
||||
HMS_MSG_LEVEL_MAX,
|
||||
};
|
||||
|
||||
enum ModuleID
|
||||
{
|
||||
MODULE_UKNOWN = 0x00,
|
||||
MODULE_01 = 0x01,
|
||||
MODULE_02 = 0x02,
|
||||
MODULE_MC = 0x03,
|
||||
MODULE_04 = 0x04,
|
||||
MODULE_MAINBOARD = 0x05,
|
||||
MODULE_06 = 0x06,
|
||||
MODULE_AMS = 0x07,
|
||||
MODULE_TH = 0x08,
|
||||
MODULE_09 = 0x09,
|
||||
MODULE_10 = 0x0A,
|
||||
MODULE_11 = 0x0B,
|
||||
MODULE_XCAM = 0x0C,
|
||||
MODULE_13 = 0x0D,
|
||||
MODULE_14 = 0x0E,
|
||||
MODULE_15 = 0x0F,
|
||||
MODULE_MAX = 0x10
|
||||
};
|
||||
|
||||
class DevHMSItem
|
||||
{
|
||||
public:
|
||||
std::string get_long_error_code() const;
|
||||
HMSMessageLevel get_level() const { return m_msg_level; }
|
||||
|
||||
void set_read() { m_already_read = true; };
|
||||
bool has_read() const { return m_already_read; };
|
||||
|
||||
protected:
|
||||
friend void DevHMS::ParseHMSItems(const json& hms_json);
|
||||
bool parse_hms_info(unsigned attr, unsigned code);
|
||||
|
||||
private:
|
||||
ModuleID m_module_id;
|
||||
unsigned m_module_num;
|
||||
unsigned m_part_id;
|
||||
unsigned m_reserved;
|
||||
HMSMessageLevel m_msg_level = HMS_UNKNOWN;
|
||||
int m_msg_code = 0;
|
||||
bool m_already_read = false;
|
||||
};
|
||||
|
||||
};// End of namespace Slic3r
|
||||
7
src/slic3r/GUI/DeviceCore/DevInfo.cpp
Normal file
7
src/slic3r/GUI/DeviceCore/DevInfo.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "DevInfo.h"
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
}
|
||||
37
src/slic3r/GUI/DeviceCore/DevInfo.h
Normal file
37
src/slic3r/GUI/DeviceCore/DevInfo.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class MachineObject;
|
||||
|
||||
/* some static info of machine*/ /*TODO*/
|
||||
class DevInfo
|
||||
{
|
||||
public:
|
||||
DevInfo(MachineObject* obj) : m_owner(obj) {};
|
||||
|
||||
public:
|
||||
//std::string GetDevName() const { return m_dev_name; }
|
||||
//std::string GetDevId() const { return m_dev_id; }
|
||||
//std::string GetDevIP() const { return m_dev_ip; }
|
||||
//std::string GetPrinterTypeStr() const { return m_printer_type_str; }
|
||||
//std::string GetPrinterSignal() const { return m_printer_signal; }
|
||||
//std::string GetConnectType() const { return m_connect_type; }
|
||||
//std::string GetBindState() const { return m_bind_state; }
|
||||
|
||||
private:
|
||||
//std::string m_dev_name;
|
||||
//std::string m_dev_id;
|
||||
//std::string m_dev_ip;
|
||||
//std::string m_printer_type_str;
|
||||
//std::string m_printer_signal;
|
||||
//std::string m_connect_type;
|
||||
//std::string m_bind_state;
|
||||
|
||||
MachineObject* m_owner = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
18
src/slic3r/GUI/DeviceCore/DevLamp.cpp
Normal file
18
src/slic3r/GUI/DeviceCore/DevLamp.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "DevLamp.h"
|
||||
|
||||
static Slic3r::DevLamp::LIGHT_EFFECT _light_effect_parse(std::string effect_str)
|
||||
{
|
||||
if (effect_str.compare("on") == 0)
|
||||
return Slic3r::DevLamp::LIGHT_EFFECT_ON;
|
||||
else if (effect_str.compare("off") == 0)
|
||||
return Slic3r::DevLamp::LIGHT_EFFECT_OFF;
|
||||
else if (effect_str.compare("flashing") == 0)
|
||||
return Slic3r::DevLamp::LIGHT_EFFECT_FLASHING;
|
||||
|
||||
return Slic3r::DevLamp::LIGHT_EFFECT_UNKOWN;
|
||||
}
|
||||
|
||||
void Slic3r::DevLamp::SetChamberLight(const std::string& status)
|
||||
{
|
||||
m_chamber_light = _light_effect_parse(status);
|
||||
}
|
||||
42
src/slic3r/GUI/DeviceCore/DevLamp.h
Normal file
42
src/slic3r/GUI/DeviceCore/DevLamp.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
class MachineObject;
|
||||
class DevLamp
|
||||
{
|
||||
public:
|
||||
DevLamp(MachineObject* obj) : m_owner(obj) {};
|
||||
|
||||
public:
|
||||
enum LIGHT_EFFECT
|
||||
{
|
||||
LIGHT_EFFECT_ON,
|
||||
LIGHT_EFFECT_OFF,
|
||||
LIGHT_EFFECT_FLASHING,
|
||||
LIGHT_EFFECT_UNKOWN,
|
||||
};
|
||||
|
||||
public:
|
||||
void SetChamberLight(const std::string& status);
|
||||
void SetChamberLight(LIGHT_EFFECT effect) { m_chamber_light = effect; }
|
||||
bool IsChamberLightOn() const { return m_chamber_light == LIGHT_EFFECT_ON || m_chamber_light == LIGHT_EFFECT_FLASHING; }
|
||||
|
||||
void SetLampCloseRecheck(bool enable) { m_lamp_close_recheck = enable;};
|
||||
bool HasLampCloseRecheck() const { return m_lamp_close_recheck; }
|
||||
|
||||
public:
|
||||
void CtrlSetChamberLight(LIGHT_EFFECT effect);
|
||||
|
||||
private:
|
||||
int command_set_chamber_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000);
|
||||
int command_set_chamber_light2(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000);
|
||||
|
||||
private:
|
||||
MachineObject* m_owner = nullptr;
|
||||
|
||||
bool m_lamp_close_recheck = false;
|
||||
LIGHT_EFFECT m_chamber_light = LIGHT_EFFECT_UNKOWN;
|
||||
};
|
||||
}
|
||||
64
src/slic3r/GUI/DeviceCore/DevLampCtrl.cpp
Normal file
64
src/slic3r/GUI/DeviceCore/DevLampCtrl.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevLamp.h"
|
||||
|
||||
// TODO: remove this include
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
|
||||
static std::string _light_effect_str(DevLamp::LIGHT_EFFECT effect)
|
||||
{
|
||||
switch (effect)
|
||||
{
|
||||
case Slic3r::DevLamp::LIGHT_EFFECT_ON:
|
||||
return "on";
|
||||
case Slic3r::DevLamp::LIGHT_EFFECT_OFF:
|
||||
return "off";
|
||||
case Slic3r::DevLamp::LIGHT_EFFECT_FLASHING:
|
||||
return "flashing";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void DevLamp::CtrlSetChamberLight(LIGHT_EFFECT effect)
|
||||
{
|
||||
// copied from others, TODO CHECK
|
||||
command_set_chamber_light(effect);
|
||||
command_set_chamber_light2(effect);
|
||||
}
|
||||
|
||||
int DevLamp::command_set_chamber_light(LIGHT_EFFECT effect, int on_time, int off_time, int loops, int interval)
|
||||
{
|
||||
json j;
|
||||
j["system"]["command"] = "ledctrl";
|
||||
j["system"]["led_node"] = "chamber_light";
|
||||
j["system"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["system"]["led_mode"] = _light_effect_str(effect);
|
||||
j["system"]["led_on_time"] = on_time;
|
||||
j["system"]["led_off_time"] = off_time;
|
||||
j["system"]["loop_times"] = loops;
|
||||
j["system"]["interval_time"] = interval;
|
||||
return m_owner->publish_json(j);
|
||||
}
|
||||
|
||||
int DevLamp::command_set_chamber_light2(LIGHT_EFFECT effect, int on_time, int off_time, int loops, int interval)
|
||||
{
|
||||
json j;
|
||||
j["system"]["command"] = "ledctrl";
|
||||
j["system"]["led_node"] = "chamber_light2";
|
||||
j["system"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["system"]["led_mode"] = _light_effect_str(effect);
|
||||
j["system"]["led_on_time"] = on_time;
|
||||
j["system"]["led_off_time"] = off_time;
|
||||
j["system"]["loop_times"] = loops;
|
||||
j["system"]["interval_time"] = interval;
|
||||
return m_owner->publish_json(j);
|
||||
}
|
||||
|
||||
}
|
||||
876
src/slic3r/GUI/DeviceCore/DevManager.cpp
Normal file
876
src/slic3r/GUI/DeviceCore/DevManager.cpp
Normal file
@@ -0,0 +1,876 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevManager.h"
|
||||
#include "DevUtil.h"
|
||||
|
||||
// TODO: remove this include
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
|
||||
#include "libslic3r/Time.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
DeviceManager::DeviceManager(NetworkAgent* agent)
|
||||
{
|
||||
m_agent = agent;
|
||||
m_refresher = new DeviceManagerRefresher(this);
|
||||
|
||||
DevPrinterConfigUtil::InitFilePath(resources_dir());
|
||||
|
||||
// Load saved local machines
|
||||
if (agent) {
|
||||
AppConfig* config = GUI::wxGetApp().app_config;
|
||||
const auto local_machines = config->get_local_machines();
|
||||
for (auto& it : local_machines) {
|
||||
const auto& m = it.second;
|
||||
MachineObject* obj = new MachineObject(this, m_agent, m.dev_name, m.dev_id, m.dev_ip);
|
||||
obj->printer_type = m.printer_type;
|
||||
obj->dev_connection_type = "lan";
|
||||
obj->bind_state = "free";
|
||||
obj->bind_sec_link = "secure";
|
||||
obj->m_is_online = true;
|
||||
obj->last_alive = Slic3r::Utils::get_current_time_utc();
|
||||
obj->set_access_code(config->get("access_code", m.dev_id), false);
|
||||
obj->set_user_access_code(config->get("user_access_code", m.dev_id), false);
|
||||
if (obj->has_access_right()) {
|
||||
localMachineList.insert(std::make_pair(m.dev_id, obj));
|
||||
} else {
|
||||
config->erase_local_machine(m.dev_id);
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::update_local_machine(const MachineObject& m)
|
||||
{
|
||||
AppConfig* config = GUI::wxGetApp().app_config;
|
||||
if (config) {
|
||||
if (m.is_lan_mode_printer()) {
|
||||
if (m.has_access_right()) {
|
||||
BBLocalMachine local_machine;
|
||||
local_machine.dev_id = m.get_dev_id();
|
||||
local_machine.dev_name = m.get_dev_name();
|
||||
local_machine.dev_ip = m.get_dev_ip();
|
||||
local_machine.printer_type = m.printer_type;
|
||||
config->update_local_machine(local_machine);
|
||||
}
|
||||
} else {
|
||||
config->erase_local_machine(m.get_dev_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeviceManager::~DeviceManager()
|
||||
{
|
||||
delete m_refresher;
|
||||
|
||||
for (auto it = localMachineList.begin(); it != localMachineList.end(); it++)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
delete it->second;
|
||||
it->second = nullptr;
|
||||
}
|
||||
}
|
||||
localMachineList.clear();
|
||||
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
delete it->second;
|
||||
it->second = nullptr;
|
||||
}
|
||||
}
|
||||
userMachineList.clear();
|
||||
}
|
||||
|
||||
|
||||
void DeviceManager::EnableMultiMachine(bool enable)
|
||||
{
|
||||
m_agent->enable_multi_machine(enable);
|
||||
m_enable_mutil_machine = enable;
|
||||
}
|
||||
|
||||
void DeviceManager::start_refresher() { m_refresher->Start(); }
|
||||
void DeviceManager::stop_refresher() { m_refresher->Stop(); }
|
||||
|
||||
|
||||
void DeviceManager::keep_alive()
|
||||
{
|
||||
MachineObject* obj = this->get_selected_machine();
|
||||
if (obj)
|
||||
{
|
||||
if (obj->keep_alive_count == 0)
|
||||
{
|
||||
obj->last_keep_alive = std::chrono::system_clock::now();
|
||||
}
|
||||
obj->keep_alive_count++;
|
||||
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
|
||||
auto internal = std::chrono::duration_cast<std::chrono::milliseconds>(start - obj->last_keep_alive);
|
||||
if (internal.count() > TIMEOUT_FOR_KEEPALIVE && (internal.count() < 1000 * 60 * 60 * 300))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "keep alive = " << internal.count() << ", count = " << obj->keep_alive_count;
|
||||
obj->command_request_push_all();
|
||||
obj->last_keep_alive = start;
|
||||
}
|
||||
else if (obj->m_push_count == 0)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "keep alive = " << internal.count() << ", push_count = 0, count = " << obj->keep_alive_count;
|
||||
obj->command_request_push_all();
|
||||
obj->last_keep_alive = start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::check_pushing()
|
||||
{
|
||||
keep_alive();
|
||||
MachineObject* obj = this->get_selected_machine();
|
||||
|
||||
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
|
||||
auto internal = std::chrono::duration_cast<std::chrono::milliseconds>(start - obj->last_update_time);
|
||||
|
||||
if (obj && !obj->is_support_mqtt_alive)
|
||||
{
|
||||
if (internal.count() > TIMEOUT_FOR_STRAT && internal.count() < 1000 * 60 * 60 * 300)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "command_pushing: diff = " << internal.count();
|
||||
obj->command_pushing("start");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::on_machine_alive(std::string json_str)
|
||||
{
|
||||
try {
|
||||
json j = json::parse(json_str);
|
||||
std::string dev_name = j["dev_name"].get<std::string>();
|
||||
std::string dev_id = j["dev_id"].get<std::string>();
|
||||
std::string dev_ip = j["dev_ip"].get<std::string>();
|
||||
std::string printer_type_str= j["dev_type"].get<std::string>();
|
||||
std::string printer_signal = j["dev_signal"].get<std::string>();
|
||||
std::string connect_type = j["connect_type"].get<std::string>();
|
||||
std::string bind_state = j["bind_state"].get<std::string>();
|
||||
|
||||
if (connect_type == "farm") {
|
||||
connect_type ="lan";
|
||||
bind_state = "free";
|
||||
}
|
||||
|
||||
std::string sec_link = "";
|
||||
std::string ssdp_version = "";
|
||||
if (j.contains("sec_link")) {
|
||||
sec_link = j["sec_link"].get<std::string>();
|
||||
}
|
||||
if (j.contains("ssdp_version")) {
|
||||
ssdp_version = j["ssdp_version"].get<std::string>();
|
||||
}
|
||||
std::string connection_name = "";
|
||||
if (j.contains("connection_name")) {
|
||||
connection_name = j["connection_name"].get<std::string>();
|
||||
}
|
||||
|
||||
MachineObject* obj;
|
||||
|
||||
/* update userMachineList info */
|
||||
auto it = userMachineList.find(dev_id);
|
||||
if (it != userMachineList.end()) {
|
||||
if (it->second->get_dev_ip() != dev_ip ||
|
||||
it->second->bind_state != bind_state ||
|
||||
it->second->bind_sec_link != sec_link ||
|
||||
it->second->dev_connection_type != connect_type ||
|
||||
it->second->bind_ssdp_version != ssdp_version)
|
||||
{
|
||||
if (it->second->bind_state != bind_state) {
|
||||
OnMachineBindStateChanged(it->second, bind_state);
|
||||
}
|
||||
|
||||
it->second->set_dev_ip(dev_ip);
|
||||
it->second->bind_state = bind_state;
|
||||
it->second->bind_sec_link = sec_link;
|
||||
it->second->dev_connection_type = connect_type;
|
||||
it->second->bind_ssdp_version = ssdp_version;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " UpdateUserMachineInfo"
|
||||
<< ", dev_id= " << dev_id
|
||||
<< ", ip = " <<dev_ip
|
||||
<< ", printer_name= " << dev_name
|
||||
<< ", con_type= " << connect_type << ", signal= " << printer_signal
|
||||
<< ", bind_state= " << bind_state;
|
||||
}
|
||||
}
|
||||
|
||||
/* update localMachineList */
|
||||
it = localMachineList.find(dev_id);
|
||||
if (it != localMachineList.end()) {
|
||||
// update properties
|
||||
/* ip changed */
|
||||
obj = it->second;
|
||||
|
||||
if (obj->get_dev_ip().compare(dev_ip) != 0) {
|
||||
if ( connection_name.empty() ) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MachineObject IP changed from " << obj->get_dev_ip()
|
||||
<< " to " << dev_ip;
|
||||
obj->set_dev_ip(dev_ip);
|
||||
}
|
||||
else {
|
||||
if ( obj->dev_connection_name.empty() || obj->dev_connection_name.compare(connection_name) == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MachineObject IP changed from " << obj->get_dev_ip()
|
||||
<< " to " << dev_ip << " connection_name is " << connection_name;
|
||||
if(obj->dev_connection_name.empty()){obj->dev_connection_name = connection_name;}
|
||||
obj->set_dev_ip(dev_ip);
|
||||
}
|
||||
}
|
||||
/* ip changed reconnect mqtt */
|
||||
}
|
||||
|
||||
if (obj->wifi_signal != printer_signal ||
|
||||
obj->dev_connection_type != connect_type ||
|
||||
obj->bind_state != bind_state ||
|
||||
obj->bind_sec_link != sec_link ||
|
||||
obj->bind_ssdp_version != ssdp_version ||
|
||||
obj->printer_type != _parse_printer_type(printer_type_str))
|
||||
{
|
||||
if (obj->dev_connection_type != connect_type ||
|
||||
obj->bind_state != bind_state ||
|
||||
obj->bind_sec_link != sec_link ||
|
||||
obj->bind_ssdp_version != ssdp_version ||
|
||||
obj->printer_type != _parse_printer_type(printer_type_str))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " UpdateLocalMachineInfo"
|
||||
<< ", dev_id= " << dev_id
|
||||
<< ", ip = " << dev_ip
|
||||
<< ", printer_name= " << dev_name
|
||||
<< ", con_type= " << connect_type << ", signal= " << printer_signal
|
||||
<< ", bind_state= " << bind_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " UpdateLocalMachineInfo_WIFI"
|
||||
<< ", dev_id= " << dev_id
|
||||
<< ", ip = " << dev_ip
|
||||
<< ", printer_name= " << dev_name
|
||||
<< ", con_type= " << connect_type << ", signal= " << printer_signal
|
||||
<< ", bind_state= " << bind_state;
|
||||
}
|
||||
|
||||
obj->wifi_signal = printer_signal;
|
||||
obj->dev_connection_type = connect_type;
|
||||
obj->bind_state = bind_state;
|
||||
obj->bind_sec_link = sec_link;
|
||||
obj->bind_ssdp_version = ssdp_version;
|
||||
obj->printer_type = _parse_printer_type(printer_type_str);
|
||||
}
|
||||
|
||||
// U0 firmware
|
||||
if (obj->dev_connection_type.empty() && obj->bind_state.empty())
|
||||
obj->bind_state = "free";
|
||||
|
||||
obj->last_alive = Slic3r::Utils::get_current_time_utc();
|
||||
obj->m_is_online = true;
|
||||
|
||||
/* if (!obj->dev_ip.empty()) {
|
||||
Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, obj->dev_ip);
|
||||
Slic3r::GUI::wxGetApp().app_config->save();
|
||||
}*/
|
||||
}
|
||||
else {
|
||||
/* insert a new machine */
|
||||
obj = new MachineObject(this, m_agent, dev_name, dev_id, dev_ip);
|
||||
obj->printer_type = _parse_printer_type(printer_type_str);
|
||||
obj->wifi_signal = printer_signal;
|
||||
obj->dev_connection_type = connect_type;
|
||||
obj->bind_state = bind_state;
|
||||
obj->bind_sec_link = sec_link;
|
||||
obj->dev_connection_name = connection_name;
|
||||
obj->bind_ssdp_version = ssdp_version;
|
||||
obj->m_is_online = true;
|
||||
|
||||
//load access code
|
||||
AppConfig* config = Slic3r::GUI::wxGetApp().app_config;
|
||||
if (config) {
|
||||
obj->set_access_code(Slic3r::GUI::wxGetApp().app_config->get("access_code", dev_id), false);
|
||||
obj->set_user_access_code(Slic3r::GUI::wxGetApp().app_config->get("user_access_code", dev_id), false);
|
||||
}
|
||||
localMachineList.insert(std::make_pair(dev_id, obj));
|
||||
|
||||
/* if (!obj->dev_ip.empty()) {
|
||||
Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, obj->dev_ip);
|
||||
Slic3r::GUI::wxGetApp().app_config->save();
|
||||
}*/
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " New Machine, dev_id= " << dev_id
|
||||
<< ", ip = " << dev_ip <<", printer_name = " << dev_name
|
||||
<< ", con_type= " << connect_type <<", signal= " << printer_signal << ", bind_state= " << bind_state;
|
||||
}
|
||||
update_local_machine(*obj);
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
MachineObject* DeviceManager::insert_local_device(const BBLocalMachine& machine, std::string connection_type, std::string bind_state, std::string version, std::string access_code)
|
||||
{
|
||||
MachineObject* obj;
|
||||
auto it = localMachineList.find(machine.dev_id);
|
||||
if (it != localMachineList.end()) {
|
||||
obj = it->second;
|
||||
} else {
|
||||
obj = new MachineObject(this, m_agent, machine.dev_name, machine.dev_id, machine.dev_ip);
|
||||
localMachineList.insert(std::make_pair(machine.dev_id, obj));
|
||||
}
|
||||
obj->printer_type = _parse_printer_type(machine.printer_type);
|
||||
obj->dev_connection_type = connection_type == "farm" ? "lan":connection_type;
|
||||
obj->bind_state = connection_type == "farm" ? "free":bind_state;
|
||||
obj->bind_sec_link = "secure";
|
||||
obj->bind_ssdp_version = version;
|
||||
obj->m_is_online = true;
|
||||
obj->last_alive = Slic3r::Utils::get_current_time_utc();
|
||||
obj->set_access_code(access_code, false);
|
||||
obj->set_user_access_code(access_code, false);
|
||||
|
||||
update_local_machine(*obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
int DeviceManager::query_bind_status(std::string& msg)
|
||||
{
|
||||
if (!m_agent)
|
||||
{
|
||||
msg = "";
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "DeviceManager::query_bind_status";
|
||||
std::map<std::string, MachineObject*>::iterator it;
|
||||
std::vector<std::string> query_list;
|
||||
for (it = localMachineList.begin(); it != localMachineList.end(); it++)
|
||||
{
|
||||
query_list.push_back(it->first);
|
||||
}
|
||||
|
||||
unsigned int http_code;
|
||||
std::string http_body;
|
||||
int result = m_agent->query_bind_status(query_list, &http_code, &http_body);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
msg = (boost::format("code=%1%,body=%2") % http_code % http_body).str();
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = "";
|
||||
try
|
||||
{
|
||||
json j = json::parse(http_body);
|
||||
if (j.contains("bind_list"))
|
||||
{
|
||||
|
||||
for (auto& item : j["bind_list"])
|
||||
{
|
||||
auto it = localMachineList.find(item["dev_id"].get<std::string>());
|
||||
if (it != localMachineList.end())
|
||||
{
|
||||
if (!item["user_id"].is_null())
|
||||
it->second->bind_user_id = item["user_id"].get<std::string>();
|
||||
if (!item["user_name"].is_null())
|
||||
it->second->bind_user_name = item["user_name"].get<std::string>();
|
||||
else
|
||||
it->second->bind_user_name = "Free";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MachineObject* DeviceManager::get_user_machine(std::string dev_id)
|
||||
{
|
||||
if (!m_agent || !m_agent->is_user_login())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::map<std::string, MachineObject*>::iterator it = userMachineList.find(dev_id);
|
||||
if (it == userMachineList.end()) return nullptr;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
MachineObject* DeviceManager::get_my_machine(std::string dev_id)
|
||||
{
|
||||
auto list = get_my_machine_list();
|
||||
auto it = list.find(dev_id);
|
||||
if (it != list.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DeviceManager::clean_user_info()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(trace) << "DeviceManager::clean_user_info";
|
||||
// reset selected_machine
|
||||
selected_machine = "";
|
||||
local_selected_machine = "";
|
||||
|
||||
// clean user list
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
if (it->second)
|
||||
{
|
||||
it->second->set_access_code("");
|
||||
delete it->second;
|
||||
it->second = nullptr;
|
||||
}
|
||||
}
|
||||
userMachineList.clear();
|
||||
}
|
||||
|
||||
bool DeviceManager::set_selected_machine(std::string dev_id)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "set_selected_machine=" << dev_id;
|
||||
auto my_machine_list = get_my_machine_list();
|
||||
auto it = my_machine_list.find(dev_id);
|
||||
|
||||
// disconnect last
|
||||
auto last_selected = my_machine_list.find(selected_machine);
|
||||
if (last_selected != my_machine_list.end())
|
||||
{
|
||||
if (last_selected->second->connection_type() == "lan")
|
||||
{
|
||||
m_agent->disconnect_printer();
|
||||
}
|
||||
}
|
||||
|
||||
// connect curr
|
||||
if (it != my_machine_list.end())
|
||||
{
|
||||
if (selected_machine == dev_id)
|
||||
{
|
||||
if (it->second->connection_type() != "lan")
|
||||
{
|
||||
// only reset update time
|
||||
it->second->reset_update_time();
|
||||
|
||||
// check subscribe state
|
||||
Slic3r::GUI::wxGetApp().on_start_subscribe_again(dev_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// lan mode printer reconnect printer
|
||||
if (m_agent)
|
||||
{
|
||||
m_agent->disconnect_printer();
|
||||
it->second->reset();
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
it->second->connect(Slic3r::GUI::wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false);
|
||||
#else
|
||||
it->second->connect(it->second->local_use_ssl_for_mqtt);
|
||||
#endif
|
||||
it->second->set_lan_mode_connection_state(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_agent)
|
||||
{
|
||||
if (it->second->connection_type() != "lan" || it->second->connection_type().empty())
|
||||
{
|
||||
if (m_agent->get_user_selected_machine() == dev_id)
|
||||
{
|
||||
it->second->reset_update_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "static: set_selected_machine: same dev_id = " << dev_id;
|
||||
m_agent->set_user_selected_machine(dev_id);
|
||||
it->second->reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "static: set_selected_machine: same dev_id = empty";
|
||||
it->second->reset();
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
it->second->connect(Slic3r::GUI::wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false);
|
||||
#else
|
||||
it->second->connect(it->second->local_use_ssl_for_mqtt);
|
||||
#endif
|
||||
m_agent->set_user_selected_machine(dev_id);
|
||||
it->second->set_lan_mode_connection_state(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& data : it->second->m_nozzle_filament_data)
|
||||
{
|
||||
data.second.checked_filament.clear();
|
||||
}
|
||||
}
|
||||
selected_machine = dev_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
MachineObject* DeviceManager::get_selected_machine()
|
||||
{
|
||||
if (selected_machine.empty()) return nullptr;
|
||||
|
||||
MachineObject* obj = get_user_machine(selected_machine);
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
// return local machine has access code
|
||||
auto it = localMachineList.find(selected_machine);
|
||||
if (it != localMachineList.end())
|
||||
{
|
||||
if (it->second->has_access_right())
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DeviceManager::add_user_subscribe()
|
||||
{
|
||||
/* user machine */
|
||||
std::vector<std::string> dev_list;
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
dev_list.push_back(it->first);
|
||||
BOOST_LOG_TRIVIAL(trace) << "add_user_subscribe: " << it->first;
|
||||
}
|
||||
m_agent->add_subscribe(dev_list);
|
||||
}
|
||||
|
||||
|
||||
void DeviceManager::del_user_subscribe()
|
||||
{
|
||||
/* user machine */
|
||||
std::vector<std::string> dev_list;
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
dev_list.push_back(it->first);
|
||||
BOOST_LOG_TRIVIAL(trace) << "del_user_subscribe: " << it->first;
|
||||
}
|
||||
m_agent->del_subscribe(dev_list);
|
||||
}
|
||||
|
||||
void DeviceManager::subscribe_device_list(std::vector<std::string> dev_list)
|
||||
{
|
||||
std::vector<std::string> unsub_list;
|
||||
subscribe_list_cache.clear();
|
||||
for (auto& it : subscribe_list_cache)
|
||||
{
|
||||
if (it != selected_machine)
|
||||
{
|
||||
unsub_list.push_back(it);
|
||||
BOOST_LOG_TRIVIAL(trace) << "subscribe_device_list: unsub dev id = " << it;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(trace) << "subscribe_device_list: unsub_list size = " << unsub_list.size();
|
||||
|
||||
if (!selected_machine.empty())
|
||||
{
|
||||
subscribe_list_cache.push_back(selected_machine);
|
||||
}
|
||||
for (auto& it : dev_list)
|
||||
{
|
||||
subscribe_list_cache.push_back(it);
|
||||
BOOST_LOG_TRIVIAL(trace) << "subscribe_device_list: sub dev id = " << it;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(trace) << "subscribe_device_list: sub_list size = " << subscribe_list_cache.size();
|
||||
if (!unsub_list.empty())
|
||||
m_agent->del_subscribe(unsub_list);
|
||||
if (!dev_list.empty())
|
||||
m_agent->add_subscribe(subscribe_list_cache);
|
||||
}
|
||||
|
||||
std::map<std::string, MachineObject*> DeviceManager::get_my_machine_list()
|
||||
{
|
||||
std::map<std::string, MachineObject*> result;
|
||||
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
if (it->second && !it->second->is_lan_mode_printer())
|
||||
{
|
||||
result.insert(std::make_pair(it->first, it->second));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = localMachineList.begin(); it != localMachineList.end(); it++)
|
||||
{
|
||||
if (it->second && it->second->has_access_right() && it->second->is_avaliable() && it->second->is_lan_mode_printer())
|
||||
{
|
||||
// remove redundant in userMachineList
|
||||
if (result.find(it->first) == result.end())
|
||||
{
|
||||
result.emplace(std::make_pair(it->first, it->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::map<std::string, MachineObject*> DeviceManager::get_my_cloud_machine_list()
|
||||
{
|
||||
std::map<std::string, MachineObject*> result;
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
if (it->second && !it->second->is_lan_mode_printer()) { result.emplace(*it); }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string DeviceManager::get_first_online_user_machine() const
|
||||
{
|
||||
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
|
||||
{
|
||||
if (it->second && it->second->is_online())
|
||||
{
|
||||
return it->second->get_dev_id();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void DeviceManager::modify_device_name(std::string dev_id, std::string dev_name)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(trace) << "modify_device_name";
|
||||
if (m_agent)
|
||||
{
|
||||
int result = m_agent->modify_printer_name(dev_id, dev_name);
|
||||
if (result == 0)
|
||||
{
|
||||
update_user_machine_list_info();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::parse_user_print_info(std::string body)
|
||||
{
|
||||
if (device_subseries.size() <= 0) {
|
||||
device_subseries = DevPrinterConfigUtil::get_all_subseries();
|
||||
if (device_subseries.size() <= 0) {
|
||||
device_subseries.insert(std::pair<std::string, std::vector<std::string>>("", std::vector<std::string>()));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "DeviceManager::parse_user_print_info";
|
||||
std::lock_guard<std::mutex> lock(listMutex);
|
||||
std::set<std::string> new_list;
|
||||
try
|
||||
{
|
||||
json j = json::parse(body);
|
||||
|
||||
#if !BBL_RELEASE_TO_PUBLIC
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": " << j;
|
||||
#endif
|
||||
|
||||
if (j.contains("devices") && !j["devices"].is_null())
|
||||
{
|
||||
for (auto& elem : j["devices"])
|
||||
{
|
||||
MachineObject* obj = nullptr;
|
||||
std::string dev_id;
|
||||
if (!elem["dev_id"].is_null())
|
||||
{
|
||||
dev_id = elem["dev_id"].get<std::string>();
|
||||
new_list.insert(dev_id);
|
||||
}
|
||||
std::map<std::string, MachineObject*>::iterator iter = userMachineList.find(dev_id);
|
||||
if (iter != userMachineList.end())
|
||||
{
|
||||
/* update field */
|
||||
obj = iter->second;
|
||||
obj->set_dev_id(dev_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = new MachineObject(this, m_agent, "", "", "");
|
||||
if (m_agent)
|
||||
{
|
||||
obj->set_bind_status(m_agent->get_user_name());
|
||||
}
|
||||
|
||||
if (obj->get_dev_ip().empty())
|
||||
{
|
||||
obj->get_dev_ip() = Slic3r::GUI::wxGetApp().app_config->get("ip_address", dev_id);
|
||||
}
|
||||
userMachineList.insert(std::make_pair(dev_id, obj));
|
||||
}
|
||||
|
||||
if (!obj) continue;
|
||||
|
||||
if (!elem["dev_id"].is_null())
|
||||
obj->set_dev_id(elem["dev_id"].get<std::string>());
|
||||
if (!elem["dev_name"].is_null())
|
||||
obj->set_dev_name(elem["dev_name"].get<std::string>());
|
||||
if (!elem["dev_online"].is_null())
|
||||
obj->m_is_online = elem["dev_online"].get<bool>();
|
||||
if (elem.contains("dev_model_name") && !elem["dev_model_name"].is_null()) {
|
||||
auto printer_type = elem["dev_model_name"].get<std::string>();
|
||||
for (const std::pair<std::string, std::vector<std::string>> &pair : device_subseries) {
|
||||
auto it = std::find(pair.second.begin(), pair.second.end(), printer_type);
|
||||
if (it != pair.second.end())
|
||||
{
|
||||
obj->printer_type = Slic3r::_parse_printer_type(pair.first);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->printer_type = Slic3r::_parse_printer_type(printer_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!elem["task_status"].is_null())
|
||||
obj->iot_print_status = elem["task_status"].get<std::string>();
|
||||
if (elem.contains("dev_product_name") && !elem["dev_product_name"].is_null())
|
||||
obj->dev_product_name = elem["dev_product_name"].get<std::string>();
|
||||
if (elem.contains("dev_access_code") && !elem["dev_access_code"].is_null())
|
||||
{
|
||||
std::string acc_code = elem["dev_access_code"].get<std::string>();
|
||||
acc_code.erase(std::remove(acc_code.begin(), acc_code.end(), '\n'), acc_code.end());
|
||||
obj->set_access_code(acc_code);
|
||||
}
|
||||
}
|
||||
|
||||
//remove MachineObject from userMachineList
|
||||
std::map<std::string, MachineObject*>::iterator iterat;
|
||||
for (iterat = userMachineList.begin(); iterat != userMachineList.end(); )
|
||||
{
|
||||
if (new_list.find(iterat->first) == new_list.end())
|
||||
{
|
||||
iterat = userMachineList.erase(iterat);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterat++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " exception=" << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::update_user_machine_list_info()
|
||||
{
|
||||
if (!m_agent) return;
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "update_user_machine_list_info";
|
||||
unsigned int http_code;
|
||||
std::string body;
|
||||
int result = m_agent->get_user_print_info(&http_code, &body);
|
||||
if (result == 0)
|
||||
{
|
||||
parse_user_print_info(body);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::load_last_machine()
|
||||
{
|
||||
// Get all available machines, include cloud machines and lan machines that have access right
|
||||
auto all_machines = get_my_machine_list();
|
||||
if (all_machines.empty())
|
||||
return;
|
||||
|
||||
// Then connect to the machine we last selected if available
|
||||
const std::string last_monitor_machine = m_agent ? m_agent->get_user_selected_machine() : "";
|
||||
const auto last_machine = all_machines.find(last_monitor_machine);
|
||||
if (last_machine != all_machines.end()) {
|
||||
this->set_selected_machine(last_machine->second->get_dev_id());
|
||||
} else {
|
||||
// If not, then select the first available one
|
||||
this->set_selected_machine(all_machines.begin()->second->get_dev_id());
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::OnMachineBindStateChanged(MachineObject* obj, const std::string& new_state)
|
||||
{
|
||||
if (!obj) { return; }
|
||||
if (obj->get_dev_id() == selected_machine)
|
||||
{
|
||||
if (new_state == "free") { OnSelectedMachineLost(); }
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::OnSelectedMachineLost()
|
||||
{
|
||||
GUI::wxGetApp().sidebar().update_sync_status(nullptr);
|
||||
GUI::wxGetApp().sidebar().load_ams_list(string(), nullptr);
|
||||
}
|
||||
|
||||
void DeviceManager::reload_printer_settings()
|
||||
{
|
||||
for (auto obj : this->userMachineList) { obj.second->reload_printer_settings(); };
|
||||
}
|
||||
|
||||
|
||||
DeviceManagerRefresher::DeviceManagerRefresher(DeviceManager* manger) : wxObject()
|
||||
{
|
||||
m_manager = manger;
|
||||
m_timer = new wxTimer();
|
||||
m_timer->Bind(wxEVT_TIMER, &DeviceManagerRefresher::on_timer, this);
|
||||
}
|
||||
|
||||
DeviceManagerRefresher::~DeviceManagerRefresher()
|
||||
{
|
||||
m_timer->Stop();
|
||||
delete m_timer;
|
||||
}
|
||||
|
||||
void DeviceManagerRefresher::on_timer(wxTimerEvent& event)
|
||||
{
|
||||
if (!m_manager) { return; }
|
||||
|
||||
NetworkAgent* agent = m_manager->get_agent();
|
||||
if (!agent) { return; }
|
||||
|
||||
// reset to active
|
||||
Slic3r::GUI::wxGetApp().reset_to_active();
|
||||
|
||||
MachineObject* obj = m_manager->get_selected_machine();
|
||||
if (!obj) { return; }
|
||||
|
||||
// check valid machine
|
||||
if (obj && m_manager->get_my_machine(obj->get_dev_id()) == nullptr)
|
||||
{
|
||||
m_manager->set_selected_machine("");
|
||||
agent->set_user_selected_machine("");
|
||||
return;
|
||||
}
|
||||
|
||||
// do some refresh
|
||||
if (Slic3r::GUI::wxGetApp().is_user_login())
|
||||
{
|
||||
m_manager->check_pushing();
|
||||
try
|
||||
{
|
||||
agent->refresh_connection();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// certificate
|
||||
agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
|
||||
}
|
||||
}
|
||||
125
src/slic3r/GUI/DeviceCore/DevManager.h
Normal file
125
src/slic3r/GUI/DeviceCore/DevManager.h
Normal file
@@ -0,0 +1,125 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
//Previous definitions
|
||||
struct BBLocalMachine;
|
||||
class MachineObject;
|
||||
class NetworkAgent;
|
||||
|
||||
class DeviceManagerRefresher;
|
||||
class DeviceManager
|
||||
{
|
||||
friend class GUI_App;
|
||||
friend class DeviceManagerRefresher;
|
||||
private:
|
||||
NetworkAgent* m_agent{ nullptr };
|
||||
DeviceManagerRefresher* m_refresher{ nullptr };
|
||||
|
||||
bool m_enable_mutil_machine = false;
|
||||
|
||||
std::mutex listMutex;
|
||||
std::string selected_machine; /* dev_id */
|
||||
std::string local_selected_machine; /* dev_id */
|
||||
std::map<std::string, MachineObject*> localMachineList; /* dev_id -> MachineObject*, localMachine SSDP */
|
||||
std::map<std::string, MachineObject*> userMachineList; /* dev_id -> MachineObject* cloudMachine of User */
|
||||
|
||||
public:
|
||||
DeviceManager(NetworkAgent* agent = nullptr);
|
||||
~DeviceManager();
|
||||
|
||||
public:
|
||||
NetworkAgent* get_agent() const { return m_agent; }
|
||||
void set_agent(NetworkAgent* agent) { m_agent = agent; }
|
||||
|
||||
void start_refresher();
|
||||
void stop_refresher();
|
||||
|
||||
MachineObject* get_selected_machine();
|
||||
bool set_selected_machine(std::string dev_id);
|
||||
|
||||
// local machine
|
||||
void set_local_selected_machine(std::string dev_id) { local_selected_machine = dev_id; };
|
||||
MachineObject* get_local_selected_machine() const { return get_local_machine(local_selected_machine); }
|
||||
|
||||
// local machine list
|
||||
void erase_local_machine(std::string dev_id) { localMachineList.erase(dev_id); }
|
||||
std::map<std::string, MachineObject*> get_local_machinelist() const { return localMachineList; }
|
||||
MachineObject* get_local_machine(std::string dev_id) const
|
||||
{
|
||||
auto it = localMachineList.find(dev_id);
|
||||
return (it != localMachineList.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
// user machine
|
||||
std::map<std::string, MachineObject*> get_user_machinelist() const { return userMachineList; }
|
||||
std::string get_first_online_user_machine() const;
|
||||
void erase_user_machine(std::string dev_id) { userMachineList.erase(dev_id); }
|
||||
void clean_user_info();
|
||||
|
||||
void load_last_machine();
|
||||
void update_user_machine_list_info();
|
||||
void parse_user_print_info(std::string body);
|
||||
void reload_printer_settings();
|
||||
|
||||
MachineObject* get_user_machine(std::string dev_id);
|
||||
|
||||
// subscribe
|
||||
void add_user_subscribe();
|
||||
void del_user_subscribe();
|
||||
void subscribe_device_list(std::vector<std::string> dev_list);
|
||||
|
||||
/* my machine*/
|
||||
MachineObject* get_my_machine(std::string dev_id);
|
||||
std::map<std::string, MachineObject*> get_my_machine_list();
|
||||
std::map<std::string, MachineObject*> get_my_cloud_machine_list();
|
||||
void modify_device_name(std::string dev_id, std::string dev_name);
|
||||
|
||||
/* create machine or update machine properties */
|
||||
void on_machine_alive(std::string json_str);
|
||||
int query_bind_status(std::string& msg);
|
||||
|
||||
// mutil-device
|
||||
void EnableMultiMachine(bool enable = true);
|
||||
bool IsMultiMachineEnabled() const { return m_enable_mutil_machine; }
|
||||
std::vector<std::string> subscribe_list_cache;//multiple machine subscribe list cache
|
||||
std::map<std::string, std::vector<std::string>> device_subseries;
|
||||
|
||||
private:
|
||||
void keep_alive();
|
||||
void check_pushing();
|
||||
|
||||
void OnMachineBindStateChanged(MachineObject* obj, const std::string& new_state);
|
||||
void OnSelectedMachineLost();
|
||||
|
||||
|
||||
/*TODO*/
|
||||
public:
|
||||
// to remove
|
||||
MachineObject* insert_local_device(const BBLocalMachine& machine, std::string connection_type, std::string bind_state, std::string version, std::string access_code);
|
||||
static void update_local_machine(const MachineObject& m);
|
||||
};
|
||||
|
||||
class DeviceManagerRefresher : public wxObject
|
||||
{
|
||||
wxTimer* m_timer{ nullptr };
|
||||
int m_timer_interval_msec = 1000;
|
||||
|
||||
DeviceManager* m_manager{ nullptr };
|
||||
|
||||
public:
|
||||
DeviceManagerRefresher(DeviceManager* manger);
|
||||
~DeviceManagerRefresher();
|
||||
|
||||
public:
|
||||
void Start() { m_timer->Start(m_timer_interval_msec); }
|
||||
void Stop() { m_timer->Stop(); }
|
||||
|
||||
protected:
|
||||
virtual void on_timer(wxTimerEvent& event);
|
||||
};
|
||||
};
|
||||
364
src/slic3r/GUI/DeviceCore/DevMapping.cpp
Normal file
364
src/slic3r/GUI/DeviceCore/DevMapping.cpp
Normal file
@@ -0,0 +1,364 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "DevMapping.h"
|
||||
#include "DevFilaSystem.h"
|
||||
#include "DevUtil.h"
|
||||
|
||||
// TODO: remove this include
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GuiColor.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
bool DevMappingUtil::is_valid_mapping_result(const MachineObject* obj, std::vector<FilamentInfo>& result, bool check_empty_slot)
|
||||
{
|
||||
if (result.empty()) return false;
|
||||
|
||||
for (int i = 0; i < result.size(); i++)
|
||||
{
|
||||
// invalid mapping result
|
||||
if (result[i].tray_id < 0)
|
||||
{
|
||||
if (result[i].ams_id.empty() && result[i].slot_id.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
auto ams_item = obj->GetFilaSystem()->GetAmsById(result[i].ams_id);
|
||||
if (ams_item == nullptr)
|
||||
{
|
||||
if ((result[i].ams_id != std::to_string(VIRTUAL_TRAY_MAIN_ID)) &&
|
||||
(result[i].ams_id != std::to_string(VIRTUAL_TRAY_DEPUTY_ID)))
|
||||
{
|
||||
result[i].tray_id = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (check_empty_slot)
|
||||
{
|
||||
auto tray_item = ams_item->GetTrays().find(result[i].slot_id);
|
||||
if (tray_item == ams_item->GetTrays().end())
|
||||
{
|
||||
result[i].tray_id = -1;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tray_item->second->is_exists)
|
||||
{
|
||||
result[i].tray_id = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// calc distance map
|
||||
struct DisValue {
|
||||
int tray_id;
|
||||
float distance;
|
||||
bool is_same_color = true;
|
||||
bool is_type_match = true;
|
||||
};
|
||||
|
||||
static void _parse_tray_info(int ams_id, int slot_id, DevAmsTray tray, FilamentInfo& result)
|
||||
{
|
||||
result.color = tray.color;
|
||||
result.type = tray.get_filament_type();
|
||||
result.filament_id = tray.setting_id;
|
||||
result.ctype = tray.ctype;
|
||||
result.colors = tray.cols;
|
||||
|
||||
/*for new ams mapping*/
|
||||
result.ams_id = std::to_string(ams_id);
|
||||
result.slot_id = std::to_string(slot_id);
|
||||
|
||||
if (ams_id == VIRTUAL_TRAY_MAIN_ID || ams_id == VIRTUAL_TRAY_DEPUTY_ID)
|
||||
{
|
||||
result.tray_id = atoi(tray.id.c_str());
|
||||
result.id = atoi(tray.id.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
result.id = ams_id * 4 + slot_id;
|
||||
}
|
||||
}
|
||||
|
||||
int DevMappingUtil::ams_filament_mapping(const MachineObject* obj, const std::vector<FilamentInfo>& filaments, std::vector<FilamentInfo>& result, std::vector<bool> map_opt, std::vector<int> exclude_id, bool nozzle_has_ams_then_ignore_ext)
|
||||
{
|
||||
if (filaments.empty())
|
||||
return -1;
|
||||
|
||||
/////////////////////////
|
||||
// Step 1: collect filaments in machine
|
||||
std::map<int, FilamentInfo> tray_filaments; // tray_index : tray_color
|
||||
bool left_nozzle_has_ams = false, right_nozzle_has_ams = false;
|
||||
|
||||
const auto& ams_list = obj->GetFilaSystem()->GetAmsList();
|
||||
for (auto ams = ams_list.begin(); ams != ams_list.end(); ams++)
|
||||
{
|
||||
std::string ams_id = ams->second->GetAmsId();
|
||||
auto ams_type = ams->second->GetAmsType();
|
||||
for (auto tray = ams->second->GetTrays().begin(); tray != ams->second->GetTrays().end(); tray++)
|
||||
{
|
||||
int ams_id = atoi(ams->first.c_str());
|
||||
int tray_id = atoi(tray->first.c_str());
|
||||
int tray_index = 0;
|
||||
if (ams_type == DevAms::AMS || ams_type == DevAms::AMS_LITE || ams_type == DevAms::N3F)
|
||||
{
|
||||
tray_index = ams_id * 4 + tray_id;
|
||||
}
|
||||
else if (ams_type == DevAms::N3S)
|
||||
{
|
||||
tray_index = ams_id + tray_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// skip exclude id
|
||||
for (int i = 0; i < exclude_id.size(); i++)
|
||||
{
|
||||
if (tray_index == exclude_id[i])
|
||||
continue;
|
||||
}
|
||||
// push
|
||||
FilamentInfo info;
|
||||
if (tray->second->is_tray_info_ready())
|
||||
{
|
||||
_parse_tray_info(ams_id, tray_id, *(tray->second), info);
|
||||
}
|
||||
|
||||
//first: left,nozzle=1,map=1 second: right,nozzle=0,map=2
|
||||
bool right_ams_valid = ams->second->GetExtruderId() == 0 && map_opt[MappingOption::USE_RIGHT_AMS];
|
||||
bool left_ams_valid = ams->second->GetExtruderId() == 1 && map_opt[MappingOption::USE_LEFT_AMS];
|
||||
if (right_ams_valid || left_ams_valid)
|
||||
{
|
||||
tray_filaments.emplace(std::make_pair(tray_index, info));
|
||||
if (right_ams_valid)
|
||||
{
|
||||
right_nozzle_has_ams = true;
|
||||
}
|
||||
if (left_ams_valid)
|
||||
{
|
||||
left_nozzle_has_ams = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map_opt[MappingOption::USE_RIGHT_EXT] || map_opt[MappingOption::USE_LEFT_EXT])
|
||||
{
|
||||
for (auto tray : obj->vt_slot)
|
||||
{
|
||||
bool right_ext_valid = (tray.id == std::to_string(VIRTUAL_TRAY_MAIN_ID) && map_opt[MappingOption::USE_RIGHT_EXT]);
|
||||
bool left_ext_valid = (tray.id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID) && map_opt[MappingOption::USE_LEFT_EXT]);
|
||||
if (right_ext_valid || left_ext_valid)
|
||||
{
|
||||
if (nozzle_has_ams_then_ignore_ext)
|
||||
{
|
||||
if (right_ext_valid && right_nozzle_has_ams)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (left_ext_valid && left_nozzle_has_ams)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
FilamentInfo info;
|
||||
_parse_tray_info(atoi(tray.id.c_str()), 0, tray, info);
|
||||
tray_filaments.emplace(std::make_pair(info.tray_id, info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Step 2: collect the distances of filaments_in_slicing to filaments_in_machine
|
||||
char buffer[256];
|
||||
std::vector<std::vector<DisValue>> distance_map;
|
||||
|
||||
// print title
|
||||
::sprintf(buffer, "F(id)");
|
||||
std::string line = std::string(buffer);
|
||||
for (auto tray = tray_filaments.begin(); tray != tray_filaments.end(); tray++)
|
||||
{
|
||||
::sprintf(buffer, " AMS%02d", tray->second.id + 1);
|
||||
line += std::string(buffer);
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "ams_mapping_distance:" << line;// Print the collected filaments
|
||||
|
||||
for (int i = 0; i < filaments.size(); i++)
|
||||
{
|
||||
std::vector<DisValue> rol;
|
||||
::sprintf(buffer, "F(%02d)", filaments[i].id + 1);
|
||||
line = std::string(buffer);
|
||||
for (auto tray = tray_filaments.begin(); tray != tray_filaments.end(); tray++)
|
||||
{
|
||||
DisValue val;
|
||||
val.tray_id = tray->second.id;
|
||||
wxColour c = wxColour(filaments[i].color);
|
||||
wxColour tray_c = DevAmsTray::decode_color(tray->second.color);
|
||||
val.distance = GUI::calc_color_distance(c, tray_c);
|
||||
if (filaments[i].type != tray->second.type)
|
||||
{
|
||||
val.distance = 999999;
|
||||
val.is_type_match = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c.Alpha() != tray_c.Alpha())
|
||||
val.distance = 999999;
|
||||
val.is_type_match = true;
|
||||
}
|
||||
::sprintf(buffer, " %6.0f", val.distance);
|
||||
line += std::string(buffer);
|
||||
rol.push_back(val);
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "ams_mapping_distance:" << line;
|
||||
distance_map.push_back(rol);
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Step 3: do mapping algorithm
|
||||
|
||||
// setup the mapping result
|
||||
for (int i = 0; i < filaments.size(); i++)
|
||||
{
|
||||
FilamentInfo info;
|
||||
info.id = filaments[i].id;
|
||||
info.tray_id = -1;
|
||||
info.type = filaments[i].type;
|
||||
info.filament_id = filaments[i].filament_id;
|
||||
result.push_back(info);
|
||||
}
|
||||
|
||||
// traverse the mapping
|
||||
std::set<int> picked_src;
|
||||
std::set<int> picked_tar;
|
||||
for (int k = 0; k < distance_map.size(); k++)
|
||||
{
|
||||
float min_val = INT_MAX;
|
||||
int picked_src_idx = -1;
|
||||
int picked_tar_idx = -1;
|
||||
for (int i = 0; i < distance_map.size(); i++)
|
||||
{
|
||||
if (picked_src.find(i) != picked_src.end())
|
||||
continue;
|
||||
|
||||
// try to mapping to different tray
|
||||
for (int j = 0; j < distance_map[i].size(); j++)
|
||||
{
|
||||
if (picked_tar.find(j) != picked_tar.end())
|
||||
{
|
||||
if (distance_map[i][j].is_same_color
|
||||
&& distance_map[i][j].is_type_match
|
||||
&& distance_map[i][j].distance < (float)0.0001)
|
||||
{
|
||||
min_val = distance_map[i][j].distance;
|
||||
picked_src_idx = i;
|
||||
picked_tar_idx = j;
|
||||
tray_filaments[picked_tar_idx].distance = min_val;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (distance_map[i][j].is_same_color
|
||||
&& distance_map[i][j].is_type_match)
|
||||
{
|
||||
if (min_val > distance_map[i][j].distance)
|
||||
{
|
||||
|
||||
min_val = distance_map[i][j].distance;
|
||||
picked_src_idx = i;
|
||||
picked_tar_idx = j;
|
||||
tray_filaments[picked_tar_idx].distance = min_val;
|
||||
}
|
||||
else if (min_val == distance_map[i][j].distance && filaments[picked_src_idx].filament_id != tray_filaments[picked_tar_idx].filament_id && filaments[i].filament_id == tray_filaments[j].filament_id)
|
||||
{
|
||||
|
||||
picked_src_idx = i;
|
||||
picked_tar_idx = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// take a retry to mapping to used tray
|
||||
if (picked_src_idx < 0 || picked_tar_idx < 0)
|
||||
{
|
||||
for (int j = 0; j < distance_map[i].size(); j++)
|
||||
{
|
||||
if (distance_map[i][j].is_same_color && distance_map[i][j].is_type_match)
|
||||
{
|
||||
if (min_val > distance_map[i][j].distance)
|
||||
{
|
||||
min_val = distance_map[i][j].distance;
|
||||
picked_src_idx = i;
|
||||
picked_tar_idx = j;
|
||||
tray_filaments[picked_tar_idx].distance = min_val;
|
||||
}
|
||||
else if (min_val == distance_map[i][j].distance && filaments[picked_src_idx].filament_id != tray_filaments[picked_tar_idx].filament_id && filaments[i].filament_id == tray_filaments[j].filament_id)
|
||||
{
|
||||
picked_src_idx = i;
|
||||
picked_tar_idx = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (picked_src_idx >= 0 && picked_tar_idx >= 0)
|
||||
{
|
||||
auto tray = tray_filaments.find(distance_map[k][picked_tar_idx].tray_id);
|
||||
|
||||
if (tray != tray_filaments.end())
|
||||
{
|
||||
result[picked_src_idx].tray_id = tray->first;
|
||||
|
||||
result[picked_src_idx].color = tray->second.color;
|
||||
result[picked_src_idx].type = tray->second.type;
|
||||
result[picked_src_idx].distance = tray->second.distance;
|
||||
result[picked_src_idx].filament_id = tray->second.filament_id;
|
||||
result[picked_src_idx].ctype = tray->second.ctype;
|
||||
result[picked_src_idx].colors = tray->second.colors;
|
||||
|
||||
/*for new ams mapping*/
|
||||
result[picked_src_idx].ams_id = tray->second.ams_id;
|
||||
result[picked_src_idx].slot_id = tray->second.slot_id;
|
||||
}
|
||||
|
||||
::sprintf(buffer, "ams_mapping, picked F(%02d) AMS(%02d), distance=%6.0f", picked_src_idx + 1, picked_tar_idx + 1,
|
||||
distance_map[picked_src_idx][picked_tar_idx].distance);
|
||||
BOOST_LOG_TRIVIAL(info) << std::string(buffer);
|
||||
picked_src.insert(picked_src_idx);
|
||||
picked_tar.insert(picked_tar_idx);
|
||||
}
|
||||
}
|
||||
|
||||
//check ams mapping result
|
||||
if (DevMappingUtil::is_valid_mapping_result(obj, result, true))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for (auto it = result.begin(); it != result.end(); it++) {//This code has never been effective before 2025.03.18
|
||||
if (it->distance >= 6000) {
|
||||
it->tray_id = -1;
|
||||
}
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
33
src/slic3r/GUI/DeviceCore/DevMapping.h
Normal file
33
src/slic3r/GUI/DeviceCore/DevMapping.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
#include "libslic3r/ProjectTask.hpp"
|
||||
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
//Previous definitions
|
||||
class MachineObject;
|
||||
|
||||
enum MappingOption
|
||||
{
|
||||
USE_LEFT_AMS = 0,
|
||||
USE_RIGHT_AMS,
|
||||
USE_LEFT_EXT,
|
||||
USE_RIGHT_EXT
|
||||
};
|
||||
|
||||
class DevMappingUtil
|
||||
{
|
||||
public:
|
||||
DevMappingUtil() = delete;
|
||||
~DevMappingUtil() = delete;
|
||||
|
||||
public:
|
||||
static bool is_valid_mapping_result(const MachineObject* obj, std::vector<FilamentInfo>& result, bool check_empty_slot = false);
|
||||
|
||||
static int ams_filament_mapping(const MachineObject* obj, const std::vector<FilamentInfo>& filaments, std::vector<FilamentInfo>& result, std::vector<bool> map_opt, std::vector<int> exclude_id = std::vector<int>(), bool nozzle_has_ams_then_ignore_ext = false);
|
||||
};
|
||||
|
||||
};
|
||||
129
src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp
Normal file
129
src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#include "DevExtruderSystem.h"
|
||||
#include "DevNozzleSystem.h"
|
||||
#include "DevUtil.h"
|
||||
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
DevNozzle DevNozzleSystem::GetNozzle(int id) const
|
||||
{
|
||||
if (m_nozzles.find(id) != m_nozzles.end())
|
||||
{
|
||||
return m_nozzles.at(id);
|
||||
}
|
||||
|
||||
return DevNozzle();
|
||||
}
|
||||
|
||||
void DevNozzleSystem::Reset()
|
||||
{
|
||||
m_nozzles.clear();
|
||||
m_extder_exist = 0;
|
||||
m_state = 0; // idle state
|
||||
}
|
||||
|
||||
|
||||
static unordered_map<string, NozzleFlowType> _str2_nozzle_flow_type = {
|
||||
{"S", NozzleFlowType::S_FLOW},
|
||||
{"H", NozzleFlowType::H_FLOW},
|
||||
{"A", NozzleFlowType::S_FLOW},
|
||||
{"X", NozzleFlowType::S_FLOW}
|
||||
};
|
||||
|
||||
static unordered_map<string, NozzleType> _str2_nozzle_type = {
|
||||
{"00", NozzleType::ntStainlessSteel},
|
||||
{"01", NozzleType::ntHardenedSteel},
|
||||
{"05", NozzleType::ntTungstenCarbide}
|
||||
};
|
||||
|
||||
static void s_parse_nozzle_type(const std::string& nozzle_type_str, DevNozzle& nozzle)
|
||||
{
|
||||
if (NozzleTypeStrToEumn.count(nozzle_type_str) != 0)
|
||||
{
|
||||
nozzle.m_nozzle_type = NozzleTypeStrToEumn[nozzle_type_str];
|
||||
}
|
||||
else if (nozzle_type_str.length() >= 4)
|
||||
{
|
||||
const std::string& flow_type_str = nozzle_type_str.substr(1, 1);
|
||||
if (_str2_nozzle_flow_type.count(flow_type_str) != 0)
|
||||
{
|
||||
nozzle.m_nozzle_flow = _str2_nozzle_flow_type[flow_type_str];
|
||||
}
|
||||
const std::string& type_str = nozzle_type_str.substr(2, 2);
|
||||
if (_str2_nozzle_type.count(type_str) != 0)
|
||||
{
|
||||
nozzle.m_nozzle_type = _str2_nozzle_type[type_str];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DevNozzleSystemParser::ParseV1_0(const nlohmann::json& nozzletype_json,
|
||||
const nlohmann::json& diameter_json,
|
||||
DevNozzleSystem* system)
|
||||
{
|
||||
//Since both the old and new protocols push data.
|
||||
// assert(system->m_nozzles.size() < 2);
|
||||
DevNozzle nozzle;
|
||||
nozzle.m_nozzle_id = 0;
|
||||
nozzle.m_nozzle_flow = NozzleFlowType::S_FLOW; // default flow type
|
||||
|
||||
{
|
||||
float nozzle_diameter = 0.0f;
|
||||
if (diameter_json.is_number_float())
|
||||
{
|
||||
nozzle_diameter = diameter_json.get<float>();
|
||||
}
|
||||
else if (diameter_json.is_string())
|
||||
{
|
||||
nozzle_diameter = DevUtil::string_to_float(diameter_json.get<std::string>());
|
||||
}
|
||||
|
||||
if (nozzle_diameter == 0.0f)
|
||||
{
|
||||
nozzle.m_diameter = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
nozzle.m_diameter = round(nozzle_diameter * 10) / 10;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (nozzletype_json.is_string())
|
||||
{
|
||||
s_parse_nozzle_type(nozzletype_json.get<std::string>(), nozzle);
|
||||
}
|
||||
}
|
||||
|
||||
system->m_nozzles.emplace(0, nozzle);
|
||||
}
|
||||
|
||||
|
||||
void DevNozzleSystemParser::ParseV2_0(const json& nozzle_json, DevNozzleSystem* system)
|
||||
{
|
||||
system->Reset();
|
||||
|
||||
if (nozzle_json.contains("exist"))
|
||||
{
|
||||
system->m_extder_exist = DevUtil::get_flag_bits(nozzle_json["exist"].get<int>(), 0, 16);
|
||||
}
|
||||
|
||||
if (nozzle_json.contains("state"))
|
||||
{
|
||||
system->m_state = DevUtil::get_flag_bits(nozzle_json["state"].get<int>(), 0, 4);
|
||||
}
|
||||
|
||||
for (auto it = nozzle_json["info"].begin(); it != nozzle_json["info"].end(); it++)
|
||||
{
|
||||
DevNozzle nozzle_obj;
|
||||
const auto& njon = it.value();
|
||||
nozzle_obj.m_nozzle_id = njon["id"].get<int>();
|
||||
nozzle_obj.m_diameter = njon["diameter"].get<float>();
|
||||
s_parse_nozzle_type(njon["type"].get<std::string>(), nozzle_obj);
|
||||
system->m_nozzles[nozzle_obj.m_nozzle_id] = nozzle_obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
50
src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
Normal file
50
src/slic3r/GUI/DeviceCore/DevNozzleSystem.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include "libslic3r/CommonDefs.hpp"
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <map>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
// Previous definitions
|
||||
class MachineObject;
|
||||
|
||||
struct DevNozzle
|
||||
{
|
||||
int m_nozzle_id = -1;
|
||||
NozzleFlowType m_nozzle_flow = NozzleFlowType::S_FLOW;// 0-common 1-high flow
|
||||
NozzleType m_nozzle_type = NozzleType::ntUndefine;// 0-stainless_steel 1-hardened_steel 5-tungsten_carbide
|
||||
float m_diameter = 0.4f;// 0.2mm 0.4mm 0.6mm 0.8mm
|
||||
};
|
||||
|
||||
class DevNozzleSystem
|
||||
{
|
||||
friend class DevNozzleSystemParser;
|
||||
public:
|
||||
DevNozzleSystem(MachineObject* owner) : m_owner(owner) {}
|
||||
|
||||
public:
|
||||
bool ContainsNozzle(int id) const { return m_nozzles.find(id) != m_nozzles.end(); }
|
||||
DevNozzle GetNozzle(int id) const;
|
||||
const std::map<int, DevNozzle>& GetNozzles() const { return m_nozzles;}
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
MachineObject* m_owner = nullptr;
|
||||
|
||||
int m_extder_exist = 0; //0- none exist 1-exist, unused
|
||||
int m_state = 0; //0-idle 1-checking, unused
|
||||
std::map<int, DevNozzle> m_nozzles;
|
||||
|
||||
};
|
||||
|
||||
class DevNozzleSystemParser
|
||||
{
|
||||
public:
|
||||
static void ParseV1_0(const nlohmann::json& nozzletype_json, const nlohmann::json& diameter_json, DevNozzleSystem* system);
|
||||
static void ParseV2_0(const json& nozzle_json, DevNozzleSystem* system);
|
||||
};
|
||||
};
|
||||
280
src/slic3r/GUI/DeviceCore/DevPrintOptions.cpp
Normal file
280
src/slic3r/GUI/DeviceCore/DevPrintOptions.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
#include "DevPrintOptions.h"
|
||||
#include "DevUtil.h"
|
||||
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
void DevPrintOptionsParser::Parse(DevPrintOptions* opts, const nlohmann::json& print_json)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (print_json.contains("spd_lvl"))
|
||||
{
|
||||
opts->m_speed_level = static_cast<DevPrintingSpeedLevel>(print_json["spd_lvl"].get<int>());
|
||||
}
|
||||
|
||||
if (print_json.contains("cfg"))
|
||||
{
|
||||
const std::string& cfg = print_json["cfg"].get<std::string>();
|
||||
opts->m_speed_level = (DevPrintingSpeedLevel)DevUtil::get_flag_bits(cfg, 8, 3);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "DevPrintOptionsParser::Parse: Failed to parse print options from JSON." << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void DevPrintOptionsParser::ParseDetectionV1_0(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json)
|
||||
{
|
||||
try {
|
||||
if (print_json.contains("xcam")) {
|
||||
if (time(nullptr) - opts->xcam_ai_monitoring_hold_start > HOLD_TIME_3SEC) {
|
||||
if (print_json["xcam"].contains("printing_monitor")) {
|
||||
// new protocol
|
||||
opts->xcam_ai_monitoring = print_json["xcam"]["printing_monitor"].get<bool>();
|
||||
} else {
|
||||
// old version protocol
|
||||
if (print_json["xcam"].contains("spaghetti_detector")) {
|
||||
opts->xcam_ai_monitoring = print_json["xcam"]["spaghetti_detector"].get<bool>();
|
||||
if (print_json["xcam"].contains("print_halt")) {
|
||||
bool print_halt = print_json["xcam"]["print_halt"].get<bool>();
|
||||
if (print_halt) { opts->xcam_ai_monitoring_sensitivity = "medium"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (print_json["xcam"].contains("halt_print_sensitivity")) {
|
||||
opts->xcam_ai_monitoring_sensitivity = print_json["xcam"]["halt_print_sensitivity"].get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
if (time(nullptr) - opts->xcam_first_layer_hold_start > HOLD_TIME_3SEC) {
|
||||
if (print_json["xcam"].contains("first_layer_inspector")) { opts->xcam_first_layer_inspector = print_json["xcam"]["first_layer_inspector"].get<bool>(); }
|
||||
}
|
||||
|
||||
if (time(nullptr) - opts->xcam_buildplate_marker_hold_start > HOLD_TIME_3SEC) {
|
||||
if (print_json["xcam"].contains("buildplate_marker_detector")) {
|
||||
opts->xcam_buildplate_marker_detector = print_json["xcam"]["buildplate_marker_detector"].get<bool>();
|
||||
obj->is_support_build_plate_marker_detect = true;
|
||||
} else {
|
||||
obj->is_support_build_plate_marker_detect = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DevPrintOptionsParser::ParseDetectionV1_1(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json,bool enable)
|
||||
{
|
||||
if (print_json["module_name"].get<std::string>() == "first_layer_inspector") {
|
||||
if (time(nullptr) - opts->xcam_first_layer_hold_start > HOLD_TIME_3SEC) {
|
||||
opts->xcam_first_layer_inspector = enable;
|
||||
}
|
||||
} else if (print_json["module_name"].get<std::string>() == "buildplate_marker_detector") {
|
||||
if (time(nullptr) - opts->xcam_buildplate_marker_hold_start > HOLD_TIME_3SEC) {
|
||||
opts->xcam_buildplate_marker_detector = enable;
|
||||
}
|
||||
} else if (print_json["module_name"].get<std::string>() == "printing_monitor") {
|
||||
if (time(nullptr) - opts->xcam_ai_monitoring_hold_start > HOLD_TIME_3SEC) {
|
||||
opts->xcam_ai_monitoring = enable;
|
||||
if (print_json.contains("halt_print_sensitivity")) {
|
||||
opts->xcam_ai_monitoring_sensitivity = print_json["halt_print_sensitivity"].get<std::string>();
|
||||
}
|
||||
}
|
||||
} else if (print_json["module_name"].get<std::string>() == "spaghetti_detector") {
|
||||
if (time(nullptr) - opts->xcam_ai_monitoring_hold_start > HOLD_TIME_3SEC) {
|
||||
// old protocol
|
||||
opts->xcam_ai_monitoring = enable;
|
||||
if (print_json.contains("print_halt")) {
|
||||
if (print_json["print_halt"].get<bool>()) { opts->xcam_ai_monitoring_sensitivity = "medium"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevPrintOptionsParser::ParseDetectionV1_2(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json) {
|
||||
|
||||
try {
|
||||
if (print_json.contains("option")) {
|
||||
if (print_json["option"].is_number()) {
|
||||
int option = print_json["option"].get<int>();
|
||||
if (time(nullptr) - opts->xcam_auto_recovery_hold_start > HOLD_TIME_3SEC) { opts->xcam_auto_recovery_step_loss = ((option & 0x01) != 0); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (time(nullptr) - opts->xcam_auto_recovery_hold_start > HOLD_TIME_3SEC) {
|
||||
if (print_json.contains("auto_recovery")) { opts->xcam_auto_recovery_step_loss = print_json["auto_recovery"].get<bool>(); }
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
}
|
||||
|
||||
void DevPrintOptionsParser::ParseDetectionV2_0(DevPrintOptions *opts, std::string print_json)
|
||||
{
|
||||
|
||||
if (time(nullptr) - opts->xcam_first_layer_hold_start > HOLD_TIME_3SEC) {
|
||||
opts->xcam_first_layer_inspector = DevUtil::get_flag_bits(print_json, 12);
|
||||
}
|
||||
|
||||
if (time(nullptr) - opts->xcam_ai_monitoring_hold_start > HOLD_COUNT_MAX) {
|
||||
opts->xcam_ai_monitoring = DevUtil::get_flag_bits(print_json, 15);
|
||||
|
||||
switch (DevUtil::get_flag_bits(print_json, 13, 2)) {
|
||||
case 0: opts->xcam_ai_monitoring_sensitivity = "never_halt"; break;
|
||||
case 1: opts->xcam_ai_monitoring_sensitivity = "low"; break;
|
||||
case 2: opts->xcam_ai_monitoring_sensitivity = "medium"; break;
|
||||
case 3: opts->xcam_ai_monitoring_sensitivity = "high"; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (time(nullptr) - opts->xcam_auto_recovery_hold_start > HOLD_COUNT_MAX){
|
||||
opts->xcam_auto_recovery_step_loss =DevUtil::get_flag_bits(print_json, 16);
|
||||
}
|
||||
|
||||
if (time(nullptr) - opts->xcam_prompt_sound_hold_start > HOLD_TIME_3SEC) {
|
||||
opts->xcam_allow_prompt_sound = DevUtil::get_flag_bits(print_json, 22);
|
||||
}
|
||||
|
||||
if (time(nullptr) - opts->xcam_filament_tangle_detect_hold_start > HOLD_TIME_3SEC) {
|
||||
opts->xcam_filament_tangle_detect = DevUtil::get_flag_bits(print_json, 23);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DevPrintOptions::SetPrintingSpeedLevel(DevPrintingSpeedLevel speed_level)
|
||||
{
|
||||
if (speed_level >= SPEED_LEVEL_INVALID && speed_level < SPEED_LEVEL_COUNT)
|
||||
{
|
||||
m_speed_level = speed_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_speed_level = SPEED_LEVEL_INVALID; // Reset to invalid if out of range
|
||||
}
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_xcam_control_ai_monitoring(bool on_off, std::string lvl)
|
||||
{
|
||||
bool print_halt = (lvl == "never_halt") ? false : true;
|
||||
|
||||
xcam_ai_monitoring = on_off;
|
||||
xcam_ai_monitoring_hold_start = time(nullptr);
|
||||
xcam_ai_monitoring_sensitivity = lvl;
|
||||
return command_xcam_control("printing_monitor", on_off, m_obj, lvl);
|
||||
|
||||
}
|
||||
int DevPrintOptions::command_xcam_control_buildplate_marker_detector(bool on_off)
|
||||
{
|
||||
xcam_buildplate_marker_detector = on_off;
|
||||
xcam_buildplate_marker_hold_start = time(nullptr);
|
||||
return command_xcam_control("buildplate_marker_detector", on_off ,m_obj);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_xcam_control_first_layer_inspector(bool on_off, bool print_halt)
|
||||
{
|
||||
xcam_first_layer_inspector = on_off;
|
||||
xcam_first_layer_hold_start = time(nullptr);
|
||||
return command_xcam_control("first_layer_inspector", on_off, m_obj);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_xcam_control_auto_recovery_step_loss(bool on_off)
|
||||
{
|
||||
xcam_auto_recovery_step_loss = on_off;
|
||||
xcam_auto_recovery_hold_start = time(nullptr);
|
||||
return command_set_printing_option(on_off, m_obj);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_xcam_control_allow_prompt_sound(bool on_off)
|
||||
{
|
||||
xcam_allow_prompt_sound = on_off;
|
||||
xcam_prompt_sound_hold_start = time(nullptr);
|
||||
return command_set_prompt_sound(on_off, m_obj);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_xcam_control_filament_tangle_detect(bool on_off)
|
||||
{
|
||||
xcam_filament_tangle_detect = on_off;
|
||||
xcam_filament_tangle_detect_hold_start = time(nullptr);
|
||||
return command_set_filament_tangle_detect(on_off, m_obj);
|
||||
}
|
||||
|
||||
void DevPrintOptions::parse_auto_recovery_step_loss_status(int flag) {
|
||||
if (time(nullptr) - xcam_auto_recovery_hold_start > HOLD_TIME_3SEC) {
|
||||
xcam_auto_recovery_step_loss = ((flag >> 4) & 0x1) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DevPrintOptions::parse_allow_prompt_sound_status(int flag)
|
||||
{
|
||||
if (time(nullptr) - xcam_prompt_sound_hold_start > HOLD_TIME_3SEC) {
|
||||
xcam_allow_prompt_sound = ((flag >> 17) & 0x1) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DevPrintOptions::parse_filament_tangle_detect_status(int flag)
|
||||
{
|
||||
if (time(nullptr) - xcam_filament_tangle_detect_hold_start > HOLD_TIME_3SEC) {
|
||||
xcam_filament_tangle_detect = ((flag >> 20) & 0x1) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_xcam_control(std::string module_name, bool on_off , MachineObject *obj, std::string lvl)
|
||||
{
|
||||
json j;
|
||||
j["xcam"]["command"] = "xcam_control_set";
|
||||
j["xcam"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["xcam"]["module_name"] = module_name;
|
||||
j["xcam"]["control"] = on_off;
|
||||
j["xcam"]["enable"] = on_off; // old protocol
|
||||
j["xcam"]["print_halt"] = true; // old protocol
|
||||
if (!lvl.empty()) { j["xcam"]["halt_print_sensitivity"] = lvl; }
|
||||
BOOST_LOG_TRIVIAL(info) << "command:xcam_control_set" << ", module_name:" << module_name << ", control:" << on_off << ", halt_print_sensitivity:" << lvl;
|
||||
return obj->publish_json(j);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_set_printing_option(bool auto_recovery, MachineObject *obj)
|
||||
{
|
||||
json j;
|
||||
j["print"]["command"] = "print_option";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["option"] = (int) auto_recovery;
|
||||
j["print"]["auto_recovery"] = auto_recovery;
|
||||
|
||||
return obj->publish_json(j);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_set_prompt_sound(bool prompt_sound, MachineObject *obj)
|
||||
{
|
||||
json j;
|
||||
j["print"]["command"] = "print_option";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["sound_enable"] = prompt_sound;
|
||||
|
||||
return obj->publish_json(j);
|
||||
}
|
||||
|
||||
int DevPrintOptions::command_set_filament_tangle_detect(bool filament_tangle_detect, MachineObject *obj)
|
||||
{
|
||||
json j;
|
||||
j["print"]["command"] = "print_option";
|
||||
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
|
||||
j["print"]["filament_tangle_detect"] = filament_tangle_detect;
|
||||
|
||||
return obj->publish_json(j);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
// namespace Slic3r
|
||||
91
src/slic3r/GUI/DeviceCore/DevPrintOptions.h
Normal file
91
src/slic3r/GUI/DeviceCore/DevPrintOptions.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "DevDefs.h"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class MachineObject;
|
||||
|
||||
class DevPrintOptions
|
||||
{
|
||||
friend class DevPrintOptionsParser;
|
||||
public:
|
||||
DevPrintOptions(MachineObject* obj): m_obj(obj) {}
|
||||
|
||||
|
||||
public:
|
||||
void SetPrintingSpeedLevel(DevPrintingSpeedLevel speed_level);
|
||||
DevPrintingSpeedLevel GetPrintingSpeedLevel() const { return m_speed_level;}
|
||||
|
||||
// detect options
|
||||
int command_xcam_control_ai_monitoring(bool on_off, std::string lvl);
|
||||
int command_xcam_control_first_layer_inspector(bool on_off, bool print_halt);
|
||||
int command_xcam_control_buildplate_marker_detector(bool on_off);
|
||||
int command_xcam_control_auto_recovery_step_loss(bool on_off);
|
||||
int command_xcam_control_allow_prompt_sound(bool on_off);
|
||||
int command_xcam_control_filament_tangle_detect(bool on_off);
|
||||
|
||||
|
||||
int command_xcam_control(std::string module_name, bool on_off, MachineObject *obj ,std::string lvl = "");
|
||||
// set print option
|
||||
int command_set_printing_option(bool auto_recovery, MachineObject *obj);
|
||||
// set prompt sound
|
||||
int command_set_prompt_sound(bool prompt_sound, MachineObject *obj);
|
||||
// set fliament tangle detect
|
||||
int command_set_filament_tangle_detect(bool fliament_tangle_detect, MachineObject *obj);
|
||||
|
||||
|
||||
void parse_auto_recovery_step_loss_status(int flag);
|
||||
void parse_allow_prompt_sound_status(int flag);
|
||||
void parse_filament_tangle_detect_status(int flag);
|
||||
|
||||
bool GetAiMonitoring() const { return xcam_ai_monitoring; };
|
||||
bool GetFirstLayerInspector() const{ return xcam_first_layer_inspector; };
|
||||
bool GetBuildplateMarkerDetector() const { return xcam_buildplate_marker_detector; };
|
||||
bool GetAutoRecoveryStepLoss() const { return xcam_auto_recovery_step_loss; };
|
||||
bool GetAllowPromptSound() const { return xcam_allow_prompt_sound; };
|
||||
bool GetFilamentTangleDetect() const { return xcam_filament_tangle_detect; };
|
||||
|
||||
string GetAiMonitoringSensitivity() const { return xcam_ai_monitoring_sensitivity; };
|
||||
|
||||
|
||||
private:
|
||||
// print option
|
||||
DevPrintingSpeedLevel m_speed_level = SPEED_LEVEL_INVALID;
|
||||
|
||||
// detect options
|
||||
bool xcam_ai_monitoring{false};
|
||||
|
||||
std::string xcam_ai_monitoring_sensitivity;
|
||||
bool xcam_buildplate_marker_detector{false};
|
||||
bool xcam_first_layer_inspector{false};
|
||||
bool xcam_auto_recovery_step_loss{false};
|
||||
bool xcam_allow_prompt_sound{false};
|
||||
bool xcam_filament_tangle_detect{false};
|
||||
time_t xcam_ai_monitoring_hold_start = 0;
|
||||
time_t xcam_buildplate_marker_hold_start = 0;
|
||||
time_t xcam_first_layer_hold_start = 0;
|
||||
time_t xcam_auto_recovery_hold_start = 0;
|
||||
time_t xcam_prompt_sound_hold_start = 0;
|
||||
time_t xcam_filament_tangle_detect_hold_start = 0;
|
||||
|
||||
MachineObject* m_obj;/*owner*/
|
||||
};
|
||||
|
||||
class DevPrintOptionsParser
|
||||
{
|
||||
public:
|
||||
static void Parse(DevPrintOptions* opts, const nlohmann::json& print_json);
|
||||
|
||||
//V1 stands for parse_json; V2 stands for parse_new_json
|
||||
static void ParseDetectionV1_0(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json);
|
||||
static void ParseDetectionV1_1(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json, bool enable);
|
||||
static void ParseDetectionV1_2(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json);
|
||||
|
||||
static void ParseDetectionV2_0(DevPrintOptions *opts, std::string print_json);
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
1
src/slic3r/GUI/DeviceCore/DevPrintTaskInfo.cpp
Normal file
1
src/slic3r/GUI/DeviceCore/DevPrintTaskInfo.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "DevPrintTaskInfo.h"
|
||||
24
src/slic3r/GUI/DeviceCore/DevPrintTaskInfo.h
Normal file
24
src/slic3r/GUI/DeviceCore/DevPrintTaskInfo.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
// TODO classes to handle dev print task management and ratings
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
struct DevPrintTaskRatingInfo
|
||||
{
|
||||
bool request_successful;
|
||||
int http_code;
|
||||
int rating_id;
|
||||
int start_count;
|
||||
bool success_printed;
|
||||
std::string content;
|
||||
std::vector<std::string> image_url_paths;
|
||||
};
|
||||
|
||||
class DevPrintTaskInfo
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
}// end namespace Slic3r
|
||||
34
src/slic3r/GUI/DeviceCore/DevStorage.cpp
Normal file
34
src/slic3r/GUI/DeviceCore/DevStorage.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "DevStorage.h"
|
||||
#include "slic3r/GUI/DeviceManager.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
DevStorage::SdcardState Slic3r::DevStorage::set_sdcard_state(int state)
|
||||
|
||||
{
|
||||
if (state < DevStorage::NO_SDCARD || state > DevStorage::SDCARD_STATE_NUM) {
|
||||
m_sdcard_state = DevStorage::NO_SDCARD;
|
||||
} else {
|
||||
m_sdcard_state = DevStorage::SdcardState(state);
|
||||
}
|
||||
return m_sdcard_state;
|
||||
}
|
||||
|
||||
void DevStorage::ParseV1_0(const json &print_json, DevStorage *system)
|
||||
{
|
||||
if (system)
|
||||
{
|
||||
if (print_json.contains("sdcard")) {
|
||||
if (print_json["sdcard"].get<bool>())
|
||||
system->m_sdcard_state = DevStorage::SdcardState::HAS_SDCARD_NORMAL;
|
||||
else
|
||||
system->m_sdcard_state = DevStorage::SdcardState::NO_SDCARD;
|
||||
} else {
|
||||
system->m_sdcard_state = DevStorage::SdcardState::NO_SDCARD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Slic3r
|
||||
36
src/slic3r/GUI/DeviceCore/DevStorage.h
Normal file
36
src/slic3r/GUI/DeviceCore/DevStorage.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "slic3r/Utils/json_diff.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class MachineObject;
|
||||
|
||||
|
||||
class DevStorage
|
||||
{
|
||||
public:
|
||||
DevStorage(MachineObject *obj) : m_owner(obj){}
|
||||
|
||||
public:
|
||||
|
||||
enum SdcardState : int {
|
||||
NO_SDCARD = 0,
|
||||
HAS_SDCARD_NORMAL = 1,
|
||||
HAS_SDCARD_ABNORMAL = 2,
|
||||
HAS_SDCARD_READONLY = 3,
|
||||
SDCARD_STATE_NUM = 4
|
||||
};
|
||||
|
||||
/* sdcard */
|
||||
SdcardState get_sdcard_state() const { return m_sdcard_state; };
|
||||
SdcardState set_sdcard_state(int state);
|
||||
|
||||
static void ParseV1_0(const json &print_json, DevStorage *system);
|
||||
|
||||
private:
|
||||
MachineObject *m_owner;
|
||||
SdcardState m_sdcard_state { NO_SDCARD };
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
114
src/slic3r/GUI/DeviceCore/DevUtil.cpp
Normal file
114
src/slic3r/GUI/DeviceCore/DevUtil.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "DevUtil.h"
|
||||
#include "fast_float/fast_float.h"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
int DevUtil::get_flag_bits(std::string str, int start, int count)
|
||||
{
|
||||
try
|
||||
{
|
||||
unsigned long long decimal_value = std::stoull(str, nullptr, 16);
|
||||
unsigned long long mask = (1ULL << count) - 1;
|
||||
int flag = (decimal_value >> start) & mask;
|
||||
return flag;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DevUtil::get_flag_bits(int num, int start, int count, int base)
|
||||
{
|
||||
try
|
||||
{
|
||||
unsigned long long mask = (1ULL << count) - 1;
|
||||
unsigned long long value;
|
||||
if (base == 10)
|
||||
{
|
||||
value = static_cast<unsigned long long>(num);
|
||||
}
|
||||
else if (base == 16)
|
||||
{
|
||||
value = static_cast<unsigned long long>(std::stoul(std::to_string(num), nullptr, 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("Unsupported base");
|
||||
}
|
||||
|
||||
int flag = (value >> start) & mask;
|
||||
return flag;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float DevUtil::string_to_float(const std::string& str_value)
|
||||
{
|
||||
float value = 0.0f;
|
||||
|
||||
try
|
||||
{
|
||||
fast_float::from_chars(str_value.c_str(), str_value.c_str() + str_value.size(), value);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed";
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string DevUtil::convertToIp(long long ip)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << ((ip >> 0) & 0xFF) << "." << ((ip >> 8) & 0xFF) << "." << ((ip >> 16) & 0xFF) << "." << ((ip >> 24) & 0xFF);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string DevJsonValParser::get_longlong_val(const nlohmann::json& j)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (j.is_number())
|
||||
{
|
||||
return std::to_string(j.get<long long>());
|
||||
}
|
||||
else if (j.is_string())
|
||||
{
|
||||
return j.get<std::string>();
|
||||
}
|
||||
}
|
||||
catch (const nlohmann::json::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
};// namespace Slic3r
|
||||
71
src/slic3r/GUI/DeviceCore/DevUtil.h
Normal file
71
src/slic3r/GUI/DeviceCore/DevUtil.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file DevUtil.h
|
||||
* @brief Provides common static utility methods for general use.
|
||||
*
|
||||
* This class offers a collection of static helper functions such as string manipulation,
|
||||
* file operations, and other frequently used utilities.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
class DevUtil
|
||||
{
|
||||
public:
|
||||
DevUtil() = delete;
|
||||
DevUtil(const DevUtil&) = delete;
|
||||
DevUtil& operator=(const DevUtil&) = delete;
|
||||
|
||||
public:
|
||||
static int get_flag_bits(std::string str, int start, int count = 1);
|
||||
static int get_flag_bits(int num, int start, int count = 1, int base = 10);
|
||||
|
||||
static float string_to_float(const std::string& str_value);
|
||||
|
||||
static std::string convertToIp(long long ip);
|
||||
};
|
||||
|
||||
|
||||
class DevJsonValParser
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
static void ParseVal(const nlohmann::json& j, const std::string& key, T& val)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (j.contains(key)) { val = j[key].get<T>(); }
|
||||
}
|
||||
catch (const nlohmann::json::exception& e)
|
||||
{
|
||||
assert(0 && __FUNCTION__);
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void ParseVal(const nlohmann::json& j, const std::string& key, T& val, T default_val)
|
||||
{
|
||||
try
|
||||
{
|
||||
j.contains(key) ? (val = j[key].get<T>()) : (val = default_val);
|
||||
}
|
||||
catch (const nlohmann::json::exception& e)
|
||||
{
|
||||
assert(0 && __FUNCTION__);
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static std::string get_longlong_val(const nlohmann::json& j);
|
||||
};
|
||||
|
||||
}; // namespace Slic3r
|
||||
Reference in New Issue
Block a user