Move axis, calib, chamber, status and upgrade handling into DeviceCore

This commit is contained in:
SoftFever
2026-07-17 02:04:25 +08:00
parent 8a6609f282
commit 8d211ce878
16 changed files with 1120 additions and 5 deletions

View File

@@ -60,6 +60,19 @@ list(APPEND SLIC3R_GUI_SOURCES
GUI/DeviceCore/DevUtil.cpp
GUI/DeviceCore/DevUtilBackend.h
GUI/DeviceCore/DevUtilBackend.cpp
GUI/DeviceCore/DevAxis.h
GUI/DeviceCore/DevAxis.cpp
GUI/DeviceCore/DevAxisCtrl.cpp
GUI/DeviceCore/DevCalib.h
GUI/DeviceCore/DevCalib.cpp
GUI/DeviceCore/DevChamber.h
GUI/DeviceCore/DevChamber.cpp
GUI/DeviceCore/DevChamberCtrl.cpp
GUI/DeviceCore/DevStatus.h
GUI/DeviceCore/DevStatus.cpp
GUI/DeviceCore/DevUpgrade.h
GUI/DeviceCore/DevUpgrade.cpp
GUI/DeviceCore/DevUpgradeCtrl.cpp
)
set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE)

View File

@@ -0,0 +1,25 @@
#include "DevAxis.h"
#include "DevUtil.h"
#include "slic3r/GUI/DeviceManager.hpp"
namespace Slic3r
{
void DevAxis::ParseAxis(const json& print_json)
{
DevJsonValParser::ParseVal(print_json, "home_flag", m_home_flag);
if (print_json.contains("fun")) {
const std::string& fun = print_json["fun"].get<std::string>();
m_is_support_mqtt_homing = DevUtil::get_flag_bits(fun, 32);
m_is_support_mqtt_axis_ctrl = DevUtil::get_flag_bits(fun, 38);
}
}
bool DevAxis::IsArchCoreXY() const
{
return m_owner->get_printer_arch() == PrinterArch::ARCH_CORE_XY;
}
} // namespace Slic3r

View File

@@ -0,0 +1,39 @@
#pragma once
#include <nlohmann/json.hpp>
#include "slic3r/Utils/json_diff.hpp"
namespace Slic3r {
class MachineObject;
class DevAxis
{
public:
static std::shared_ptr<DevAxis> Create(MachineObject *obj) { return std::shared_ptr<DevAxis>( new DevAxis(obj)); }
virtual ~DevAxis() = default;
public:
bool IsAxisAtHomeX() const { return m_home_flag == 0 ? true : (m_home_flag & 1) == 1; }
bool IsAxisAtHomeY() const { return m_home_flag == 0 ? true : ((m_home_flag >> 1) & 1) == 1; }
bool IsAxisAtHomeZ() const { return m_home_flag == 0 ? true : ((m_home_flag >> 2) & 1) == 1; }
bool IsArchCoreXY() const;
public:
void ParseAxis(const json &print_json);
int Ctrl_GoHome();
int Ctrl_Axis(std::string axis, double unit = 1.0f, double input_val = 1.0f, int speed = 3000); // xyz e
protected:
DevAxis(MachineObject *obj) noexcept : m_owner(obj) {}
private:
MachineObject *m_owner = nullptr;
int m_home_flag = 0; // bit0:X, bit1:Y, bit2:Z
bool m_is_support_mqtt_axis_ctrl = false;
bool m_is_support_mqtt_homing = false;
};
} // namespace Slic3r

View File

@@ -0,0 +1,60 @@
#include "DevAxis.h"
#include "slic3r/GUI/DeviceManager.hpp"
#include "slic3r/Utils/NetworkAgent.hpp"
namespace Slic3r
{
int DevAxis::Ctrl_GoHome()
{
if (m_is_support_mqtt_homing) {
json j;
j["print"]["command"] = "back_to_center";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
return m_owner->publish_json(j);
}
// gcode command
return m_owner->is_in_printing() ? m_owner->publish_gcode("G28 X\n") : m_owner->publish_gcode("G28 \n");
}
int DevAxis::Ctrl_Axis(std::string axis, double unit, double input_val, int speed)
{
if (m_is_support_mqtt_axis_ctrl) {
int dir = input_val > 0 ? 1 : -1;
if (!IsArchCoreXY()) {
if (axis.compare("Y") == 0 || axis.compare("Z") == 0) {
dir = -dir;
}
}
json j;
j["print"]["command"] = "xyz_ctrl";
j["print"]["axis"] = axis;
j["print"]["dir"] = dir;
j["print"]["mode"] = (std::abs(input_val) >= 10) ? 1 : 0;
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
return m_owner->publish_json(j);
}
double value = input_val;
if (!IsArchCoreXY()) {
if (axis.compare("Y") == 0 || axis.compare("Z") == 0) {
value = -1.0 * input_val;
}
}
char cmd[256];
if (axis.compare("X") == 0 || axis.compare("Y") == 0 || axis.compare("Z") == 0) {
sprintf(cmd, "M211 S \nM211 X1 Y1 Z1\nM1002 push_ref_mode\nG91 \nG1 %s%0.1f F%d\nM1002 pop_ref_mode\nM211 R\n", axis.c_str(), value * unit, speed);
} else if (axis.compare("E") == 0) {
sprintf(cmd, "M83 \nG0 %s%0.1f F%d\n", axis.c_str(), value * unit, speed);
} else {
return -1;
}
// Orca: strip analytics telemetry (matches MachineObject::command_axis_control)
return m_owner->publish_gcode(cmd);
}
} // namespace Slic3r

View File

@@ -0,0 +1,327 @@
#include <boost/log/trivial.hpp>
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/UserNotification.hpp"
#include "libslic3r/PrintConfig.hpp"
#include <wx/dir.h>
#include "fast_float/fast_float.h"
#include "DevCalib.h"
#include "DevDefs.h"
#include "DevFilaSystem.h"
#include "DevConfig.h"
namespace Slic3r {
static float string_to_float(const std::string &str_value)
{
float value = 0.0;
fast_float::from_chars(str_value.c_str(), str_value.c_str() + str_value.size(), value);
return value;
}
static NozzleVolumeType convert_to_nozzle_type(const std::string &str)
{
if (str.size() < 8) {
assert(false && "invalid nozzle info");
return NozzleVolumeType::nvtStandard;
}
if (str[1] == 'S')
return NozzleVolumeType::nvtStandard;
else if (str[1] == 'H')
return NozzleVolumeType::nvtHighFlow;
else if (str[1] == 'U')
return NozzleVolumeType::nvtTPUHighFlow;
// Orca: no nvtE3DHighFlow in Orca's NozzleVolumeType; map 'B' to Standard
else
return NozzleVolumeType::nvtStandard;
}
static float get_number_flexible(const json& j, const std::string& key, float def = 0.0f)
{
if (!j.contains(key)) return def;
const auto& v = j[key];
if (v.is_number_float()) return v.get<float>();
if (v.is_number_integer()) return static_cast<float>(v.get<int>());
if (v.is_string()) return string_to_float(v.get<std::string>());
return def;
}
void from_json(const json& j, PACalibResult& cali) {
cali.extruder_id = j.value("extruder_id", 0);
cali.nozzle_volume_type = convert_to_nozzle_type(j.value("nozzle_id", "HS00-0.4"));
cali.tray_id = j.value("tray_id",0);
cali.ams_id = j.value("ams_id",0);
cali.slot_id = j.value("slot_id",0);
cali.cali_idx = j.value("cali_idx",-1);
cali.nozzle_pos_id = j.value("nozzle_pos",-1);
cali.nozzle_diameter = get_number_flexible(j, "nozzle_diameter", 0.4f);
cali.nozzle_sn = j.value("nozzle_sn","");
cali.filament_id = j.value("filament_id","");
cali.setting_id = j.value("setting_id","");
cali.name = j.value("name","");
cali.k_value = get_number_flexible(j, "k_value", 0.0f);
cali.n_coef = get_number_flexible(j, "n_coef", 0.0f);
cali.confidence = j.value("confidence", 0);
}
void from_json(const json& j, FlowRatioCalibResult& cali)
{
cali.tray_id = j.value("tray_id", 0);
cali.nozzle_diameter = string_to_float(j.value("nozzle_diameter", ""));
cali.filament_id = j.value("filament_id", "");
cali.setting_id = j.value("setting_id", "");
cali.flow_ratio = string_to_float(j.value("flow_ratio", ""));
cali.confidence = j.value("confidence", 0);
}
void DevCalib::ParseCalibVersion(const json& j, DevCalib* system)
{
if(system) system->m_calib_version = j.value("cali_version", -1);
}
bool DevCalib::IsVersionExpired() const
{
if (m_last_calib_version.has_value())
return m_last_calib_version.value() != m_calib_version;
else
return true;
}
void DevCalib::ParseSupportNewAutoCalib(int flag, DevCalib* system)
{
if(system) system->m_support_new_auto_cali = flag;
}
void DevCalib::RequestPAResult()
{
m_pa_results_status = CalibStatus::REQUEST;
}
void DevCalib::ResetPAResult()
{
m_pa_calib_results.clear();
m_pa_results_status = CalibStatus::IDLE;
}
int DevCalib::RequestPAHistory(const PACalibExtruderInfo &calib_info)
{
m_pa_calib_tab.clear();
m_pa_table_status = CalibStatus::REQUEST;
return GetOwner()->command_get_pa_calibration_tab(calib_info);
}
void DevCalib::ResetPAHistory()
{
m_pa_calib_tab.clear();
m_pa_table_status = CalibStatus::IDLE;
}
void DevCalib::RequestFlowRateResult()
{
m_flow_results_status = CalibStatus::REQUEST;
}
void DevCalib::ResetFlowRateResult()
{
m_flow_ratio_results.clear();
m_flow_results_status = CalibStatus::IDLE;
}
void calib_fail_message(MachineObject* obj, std::string cali_mode, std::string reason){
wxString info;
if (reason == "invalid nozzle_diameter" || reason == "nozzle_diameter is not supported") {
info = _L("This calibration does not support the currently selected nozzle diameter");
} else if (reason == "invalid handle_flowrate_cali param") {
info = _L("Current flowrate cali param is invalid");
} else if (reason == "nozzle_diameter is not matched") {
info = _L("Selected diameter and machine diameter do not match");
} else if (reason == "generate auto filament cali gcode failure") {
info = _L("Failed to generate cali gcode");
} else {
info = wxString(reason);
}
GUI::wxGetApp().push_notification(obj, info, _L("Calibration error"), UserNotificationStyle::UNS_WARNING_CONFIRM);
BOOST_LOG_TRIVIAL(info) << cali_mode << " result fail, reason = " << reason;
}
void DevCalib::ExtrusionCalibSetParse(const json & jj){
int tray_id = jj.value("tray_id", -1);
auto tray_ams_slot_map = GetOwner()->GetFilaSystem()->GetTrayIndexMap();
int ams_id = tray_ams_slot_map.find(tray_id) != tray_ams_slot_map.end() ? tray_ams_slot_map[tray_id].first : -1;
int slot_id = tray_ams_slot_map.find(tray_id) != tray_ams_slot_map.end() ? tray_ams_slot_map[tray_id].second : -1;
if(tray_id == VIRTUAL_TRAY_MAIN_ID) {
GetOwner()->vt_slot[MAIN_EXTRUDER_ID].k = jj.value("k_value", GetOwner()->vt_slot[MAIN_EXTRUDER_ID].k);
GetOwner()->vt_slot[MAIN_EXTRUDER_ID].n = jj.value("n_value", GetOwner()->vt_slot[MAIN_EXTRUDER_ID].n);
}else{
auto tray_item = GetOwner()->GetFilaSystem()->GetAmsTray(std::to_string(ams_id), std::to_string(slot_id));
if (tray_item) {
tray_item->k = jj.value("k_value", tray_item->k);
tray_item->n = jj.value("n_coef", tray_item->n);
}
}
GetOwner()->extrusion_cali_set_tray_id = tray_id;
GetOwner()->extrusion_cali_set_hold_start = std::chrono::system_clock::now();
}
/* calib select ack parse */
void DevCalib::ExtrusionCalibSelectParse(const json &jj){
try{
int tray_id = jj.value("tray_id", -1);
auto tray_ams_slot_map = GetOwner()->GetFilaSystem()->GetTrayIndexMap();
int default_ams_id = tray_ams_slot_map.find(tray_id) != tray_ams_slot_map.end() ? tray_ams_slot_map[tray_id].first : -1;
int default_slot_id = tray_ams_slot_map.find(tray_id) != tray_ams_slot_map.end() ? tray_ams_slot_map[tray_id].second : -1;
int ams_id = jj.value("ams_id", default_ams_id);
int slot_id = jj.value("slot_id", default_slot_id);
BOOST_LOG_TRIVIAL(trace) << "extrusion_cali_sel: illegal ams_id = " << ams_id << "slot_id = " << slot_id;
std::vector<DevAmsTray> &vt_slot = GetOwner()->vt_slot;
if (ams_id == VIRTUAL_TRAY_MAIN_ID && vt_slot.size() > 0) {
vt_slot[MAIN_EXTRUDER_ID].cali_idx = jj.value("cali_idx", vt_slot[MAIN_EXTRUDER_ID].cali_idx);
vt_slot[MAIN_EXTRUDER_ID].set_hold_count();
} else if (ams_id == VIRTUAL_TRAY_DEPUTY_ID && vt_slot.size() > 1) {
vt_slot[DEPUTY_EXTRUDER_ID].cali_idx = jj.value("cali_idx", vt_slot[DEPUTY_EXTRUDER_ID].cali_idx);
vt_slot[DEPUTY_EXTRUDER_ID].set_hold_count();
} else {
auto tray_item = GetOwner()->GetFilaSystem()->GetAmsTray(std::to_string(ams_id), std::to_string(slot_id));
if (tray_item) {
tray_item->cali_idx = jj.value("cali_idx", tray_item->cali_idx);
tray_item->set_hold_count();
}
}
} catch(...){
}
}
void DevCalib::ExtrusionCalibGetTableParse(const json &jj){
if (GetPAHistoryStatus() == CalibStatus::REQUEST ) {
m_pa_table_status = CalibStatus::WAITING;
/* request success */
if (!(jj.contains("result") && jj.contains("reason") && jj["result"].get<std::string>() == "fail")) {
SyncCalibVersion();
m_pa_table_status = CalibStatus::FINISHED;
}
try{
json filaments_json;
if(jj.contains("filaments"))
{
/* fill item->nozzle_diameter with command->nozzle_diameter */
filaments_json = jj["filaments"];
for (auto &f : filaments_json) {
if (!f.contains("nozzle_diameter") && jj.contains("nozzle_diameter")) {
f["nozzle_diameter"] = jj["nozzle_diameter"];
}
}
}
m_pa_calib_tab = filaments_json.get<std::vector<PACalibResult>>();
/* filter invalid pa_calib_tab */
m_pa_calib_tab.erase(std::remove_if(m_pa_calib_tab.begin(), m_pa_calib_tab.end(), [](auto &res) { return res.k_value < 0.0f || res.k_value > 10.0f; }), m_pa_calib_tab.end());
if (m_pa_calib_tab.empty()) { BOOST_LOG_TRIVIAL(info) << "empty pa calib history"; }
}catch(...){
m_pa_calib_tab.clear();
BOOST_LOG_TRIVIAL(error) << "pa calib history missing fields, current json:\n "<< jj.dump();
}
// notify cali history to update
}
}
void DevCalib::ExtrusionCalibGetResultParse(const json &jj)
{
m_pa_results_status = CalibStatus::WAITING;
if (!(jj.contains("result") && jj.contains("reason") && jj["result"].get<std::string>() == "fail" && jj.contains("err_code"))) {
m_pa_results_status = CalibStatus::FINISHED;
}
try {
json filaments_json;
if(jj.contains("filaments"))
{
/* fill item->nozzle_diameter with command->nozzle_diameter */
filaments_json = jj["filaments"];
for (auto &f : filaments_json) {
if (!f.contains("nozzle_diameter") && jj.contains("nozzle_diameter") ) {
f["nozzle_diameter"] = jj["nozzle_diameter"];
}
if (IsSupportNewAutoCali()) {
auto ams_id = f.value("ams_id", 0);
auto slot_id = f.value("slot_id", 0);
if(f.contains("tray_id")){
// Orca: no GetTrayIdByAmsSlotId in Orca DevFilaSystem; standard AMS tray formula
f["tray_id"] = ams_id * 4 + slot_id;
}
}
}
}
m_pa_calib_results = filaments_json.get<std::vector<PACalibResult>>();
m_pa_calib_results.erase(std::remove_if(m_pa_calib_results.begin(), m_pa_calib_results.end(), [](auto &res) { return res.k_value < 0.0f || res.k_value > 10.0f; }), m_pa_calib_results.end());
if (m_pa_calib_results.empty()) { BOOST_LOG_TRIVIAL(info) << "empty pa calib result"; }
} catch (...) {
m_pa_calib_results.clear();
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "pa calibration results missing fileds, current json: \n"<<jj.dump();
}
}
void DevCalib::FlowrateGetResultParse(const json &jj){
m_flow_results_status = CalibStatus::FINISHED;
m_flow_ratio_results.clear();
if(!jj.contains("filaments")) return;
try {
m_flow_ratio_results = jj["filaments"].get<std::vector<FlowRatioCalibResult>>();
} catch (...) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "flow ratio calibration results missing fileds, current json:\n"<<jj.dump();
}
}
void DevCalib::ParseV1_0(const json &jj, DevCalib *system, bool key_field_only)
{
if(!jj.contains("command")) return;
if (jj["command"].get<std::string>() == "extrusion_cali" || jj["command"].get<std::string>() == "flowrate_cali") {
if (jj.contains("result")) {
if (jj["result"].get<std::string>() == "success") {
} else if (jj["result"].get<std::string>() == "fail") {
std::string cali_mode = jj["command"].get<std::string>();
std::string reason = jj["reason"].get<std::string>();
calib_fail_message(system->GetOwner(), cali_mode, reason);
}
}
} else if (jj["command"].get<std::string>() == "extrusion_cali_set") {
system->ExtrusionCalibSetParse(jj);
} else if (jj["command"].get<std::string>() == "extrusion_cali_sel") {
system->ExtrusionCalibSelectParse(jj);
} else if (jj["command"].get<std::string>() == "extrusion_cali_get") {
system->ExtrusionCalibGetTableParse(jj);
} else if (jj["command"].get<std::string>() == "extrusion_cali_get_result") {
system->ExtrusionCalibGetResultParse(jj);
} else if (jj["command"].get<std::string>() == "flowrate_get_result" && !key_field_only) {
system->FlowrateGetResultParse(jj);
}
}
} // namespace Slic3r

View File

@@ -0,0 +1,127 @@
#pragma once
#include <nlohmann/json.hpp>
#include "slic3r/Utils/json_diff.hpp"
#include "DevDefs.h"
#include "libslic3r/calib.hpp" // Orca: lowercase filename (Linux case-sensitive)
namespace Slic3r {
class MachineObject;
enum class CalibStatus{
IDLE = 0,
REQUEST,
WAITING,
FINISHED,
};
enum class ManualPaCaliMethod {
PA_LINE = 0,
PA_PATTERN,
};
class DevCalib
{
protected:
bool m_support_new_auto_cali{false};
int m_calib_version {-1};
std::optional<int> m_last_calib_version;
public:
DevCalib(MachineObject *obj) : m_owner(obj){};
MachineObject* GetOwner() const {return m_owner; };
void RequestPAResult();
CalibStatus GetPAResultStatus() const {return m_pa_results_status;}
bool IsPAResultReady() const { return m_pa_results_status == CalibStatus::FINISHED;}
void ResetPAResult();
/* calib history */
int RequestPAHistory(const PACalibExtruderInfo &calib_info);
CalibStatus GetPAHistoryStatus() const {return m_pa_table_status;}
bool IsPAHistoryReady() const { return m_pa_table_status == CalibStatus::FINISHED;}
void ResetPAHistory();
void RequestFlowRateResult();
CalibStatus GetFlowRateResultStatus() const {return m_flow_results_status;}
bool IsFlowRateReady() const { return m_flow_results_status == CalibStatus::FINISHED;}
void ResetFlowRateResult();
int GetCalibVersion() const {return m_calib_version;}
void SyncCalibVersion() { if (IsVersionInited()) { m_last_calib_version = m_calib_version; } }
void ResetCalibVersion() {m_last_calib_version.reset();}
bool IsVersionExpired() const;
bool IsVersionInited() const { return m_calib_version > -1;}
bool IsSupportNewAutoCali() const {return m_support_new_auto_cali;}
public:
void SetStashCalibFinished(bool finished) {m_calib_finished = finished;}
bool GetStashCalibFinished() { return m_calib_finished;}
void SetStashFlowRatio(float ratio) { m_flow_ratio = ratio;}
float GetStashFlowRatio() const {return m_flow_ratio;}
FlowRatioCalibrationType GetFlowRatioCalibType() {return m_flow_ratio_calibration_type;}
void SetFlowRatioCalibType(const FlowRatioCalibrationType &type) { m_flow_ratio_calibration_type = type; }
ManualPaCaliMethod GetManualPaCalibMethod() {return m_manual_pa_cali_method;}
void SetManualPaCalibMethod(const ManualPaCaliMethod& method) { m_manual_pa_cali_method = method;}
NozzleDiameterType GetSelectedNozzleDiameter() {return m_selected_nozzle_diameter;}
void SetSelectedNozzleDiameter(const NozzleDiameterType& diameter) { m_selected_nozzle_diameter = diameter;}
std::vector<CaliPresetInfo> GetSelectedCalibPreset() {return m_selected_calib_preset;}
void ResetSelectedCalibPreset() { m_selected_calib_preset.clear();}
void SetSelectedCalibPreset(const std::vector<CaliPresetInfo>& preset) { m_selected_calib_preset = preset;}
std::vector<PACalibResult> GetPAHistory() const {return m_pa_calib_tab; }
std::vector<PACalibResult> GetPAResult() const {return m_pa_calib_results; }
std::vector<FlowRatioCalibResult> GetFlowRatioResult() const {return m_flow_ratio_results; }
protected:
void ExtrusionCalibSetParse(const json &jj);
void ExtrusionCalibSelectParse(const json &jj);
void ExtrusionCalibGetTableParse(const json &jj);
void ExtrusionCalibGetResultParse(const json &jj);
void FlowrateGetResultParse(const json &jj);
private:
MachineObject* m_owner{nullptr};
std::vector<PACalibResult> m_pa_calib_tab;
std::vector<PACalibResult> m_pa_calib_results;
std::vector<FlowRatioCalibResult> m_flow_ratio_results;
CalibStatus m_pa_results_status{CalibStatus::IDLE};
CalibStatus m_pa_table_status{CalibStatus::IDLE};
CalibStatus m_flow_results_status{CalibStatus::IDLE};
FlowRatioCalibrationType m_flow_ratio_calibration_type{FlowRatioCalibrationType::COMPLETE_CALIBRATION};
ManualPaCaliMethod m_manual_pa_cali_method{ManualPaCaliMethod::PA_LINE};
// calibration page selected info
// 1: record when start calibration in preset page
// 2: reset when start calibration in start page
// 3: save tray_id, filament_id, setting_id, and name, nozzle_dia
// std::vector<CaliPresetInfo> selected_cali_preset;
NozzleDiameterType m_selected_nozzle_diameter{NozzleDiameterType::NONE_DIAMETER_TYPE};
std::vector<CaliPresetInfo> m_selected_calib_preset;
// stash calibrating info
float m_flow_ratio { 0.0 };
bool m_calib_finished{false};
public:
static void ParseCalibVersion(const json& j, DevCalib* system);
static void ParseSupportNewAutoCalib(int flag, DevCalib* system);
static void ParseV1_0(const json& print_json, DevCalib* system, bool key_field_only);
};
} // namespace Slic3r

View File

@@ -0,0 +1,50 @@
#include "DevChamber.h"
#include "DevConfig.h"
#include "DevUtil.h"
#include "slic3r/GUI/DeviceManager.hpp"
namespace Slic3r {
bool DevChamber::HasChamber() const { return m_owner->GetConfig()->HasChamber(); }
bool DevChamber::SupportChamberTempDisplay() const { return m_owner->GetConfig()->SupportChamberTempDisplay();}
bool DevChamber::SupportChamberEdit() const { return m_owner->GetConfig()->SupportChamberEdit(); }
int DevChamber::GetChamberTempEditMin() const { return m_owner->GetConfig()->GetChamberTempEditMin(); }
int DevChamber::GetChamberTempEditMax() const { return m_owner->GetConfig()->GetChamberTempEditMax(); }
int DevChamber::GetChamberTempSwitchHeat() const { return m_owner->GetConfig()->GetChamberTempSwitchHeat(); }
void DevChamber::ParseChamber(const json &print_json)
{
ParseChamberV1_0(print_json);
ParseChamberV2_0(print_json);
}
void DevChamber::ParseChamberV1_0(const json &print_json)
{
DevJsonValParser::ParseVal(print_json, "chamber_temper", m_temp);
DevJsonValParser::ParseVal(print_json, "ctt", m_temp_target);
}
void DevChamber::ParseChamberV2_0(const json &print_json)
{
if (print_json.contains("device")) {
const json &device_jj = print_json["device"];
if (device_jj.contains("ctc")) {
const json &ctc = device_jj["ctc"];
int state = DevUtil::get_flag_bits(ctc["state"].get<int>(), 0, 4);
if (ctc.contains("info")) {
const json &info = ctc["info"];
m_temp = DevUtil::get_flag_bits(info["temp"].get<int>(), 0, 16);
m_temp_target = DevUtil::get_flag_bits(info["temp"].get<int>(), 16, 16);
}
}
}
}
} // namespace Slic3r

View File

@@ -0,0 +1,44 @@
#pragma once
#include <nlohmann/json.hpp>
#include "slic3r/Utils/json_diff.hpp"
namespace Slic3r {
class MachineObject;
class DevChamber
{
public:
static std::shared_ptr<DevChamber> Create(MachineObject *obj) { return std::shared_ptr<DevChamber>( new DevChamber(obj)); }
public: // getter
bool HasChamber() const;
bool SupportChamberTempDisplay() const;
bool SupportChamberEdit() const;
int GetChamberTempEditMin() const;
int GetChamberTempEditMax() const;
int GetChamberTempSwitchHeat() const;
float GetChamberTemp() const { return m_temp; };
float GetChamberTempTarget() const { return m_temp_target; };
public:
// setter
void ParseChamber(const json &print_json);
void ParseChamberV1_0(const json& print_json);
void ParseChamberV2_0(const json& print_json);
// control
int CtrlSetChamberTemp(int temp);
protected:
DevChamber(MachineObject *obj) : m_owner(obj) {}
private:
float m_temp = 0.0f;
float m_temp_target = 0.0f;
MachineObject* m_owner = nullptr;
};
} // namespace Slic3r

View File

@@ -0,0 +1,16 @@
#include "DevChamber.h"
#include "slic3r/GUI/DeviceManager.hpp"
namespace Slic3r {
int DevChamber::CtrlSetChamberTemp(int temp)
{
json j;
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["command"] = "set_ctt";
j["print"]["ctt_val"] = temp;
return m_owner->publish_json(j, 1);
}
} // namespace Slic3r

View File

@@ -0,0 +1,33 @@
#include "DevStatus.h"
#include "slic3r/GUI/DeviceManager.hpp"
#include <boost/log/trivial.hpp>
namespace Slic3r {
void DevStatus::ParseStatus(const nlohmann::json& print_jj)
{
try {
if (print_jj.contains("job")) {
const nlohmann::json& job_jj = print_jj.at("job");
if (job_jj.contains("job_state")) {
auto new_state = (DevJobState)job_jj.at("job_state").get<int>();
if (m_job_state != new_state) {
m_job_state = new_state;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": job_state-> " << (int)new_state;
}
if (m_job_state == DevJobState::JobStateFinishing) {
m_job_state = DevJobState::JobStateFinish;
}
}
}
} catch (const std::exception& e) {
#if BBL_RELEASE_TO_PUBLIC
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": get exception";
#else
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": get exception=" << e.what();
#endif
}
}
} // namespace Slic3r

View File

@@ -0,0 +1,43 @@
#pragma once
#include <optional>
#include <nlohmann/json.hpp>
#include "slic3r/Utils/json_diff.hpp"
#include "DevDefs.h"
namespace Slic3r {
enum DevJobState
{
JobStateIdle = 0,
JobStateSlicing = 1,
JobStatePrepare = 2,
JobStateStarting = 3,
JobStateRunning = 4,
JobStatePause = 5,
JobStatePausing = 6,
JobStateResuming = 7,
JobStateFinish = 8,
JobStateFailed = 9,
JobStateFinishing = 10,
JobStateStoppping = 11,
};
class MachineObject;
class DevStatus
{
public:
DevStatus(MachineObject* owner) : m_owner(owner) {};
public:
std::optional<DevJobState> GetJobState() const { return m_job_state; }
// Parse
void ParseStatus(const nlohmann::json& print_jj);
private:
MachineObject *m_owner = nullptr;
std::optional<DevJobState> m_job_state; // could be nullopt for some old firmware
};
} // namespace Slic3r

View File

@@ -0,0 +1,130 @@
#include "DevUpgrade.h"
#include "DevUtil.h"
#include "slic3r/GUI/DeviceManager.hpp"
#include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/I18N.hpp"
namespace Slic3r {
int DevUpgrade::GetUpgradeProgressInt() const
{
try {
return std::stoi(m_upgrade_progress);
} catch (const std::exception &e) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
}
return 0;
}
void DevUpgrade::ParseUpgrade_V1_0(const json &print_jj)
{
if (print_jj.contains("upgrade_state")) {
const auto &upgrade_jj = print_jj["upgrade_state"];
// status and steps
DevJsonValParser::ParseVal(upgrade_jj, "status", m_upgrade_status);
DevJsonValParser::ParseVal(upgrade_jj, "progress", m_upgrade_progress);
DevJsonValParser::ParseVal(upgrade_jj, "message", m_upgrade_message);
DevJsonValParser::ParseVal(upgrade_jj, "module", m_upgrade_module);
DevJsonValParser::ParseVal(upgrade_jj, "err_code", m_upgrade_err_code);
// version requested
DevJsonValParser::ParseVal(upgrade_jj, "new_version_state", m_upgrade_new_version_state);
DevJsonValParser::ParseVal(upgrade_jj, "consistency_request", m_upgrade_consistency_request);
DevJsonValParser::ParseVal(upgrade_jj, "force_upgrade", m_upgrade_force_upgrade);
// version info
DevJsonValParser::ParseVal(upgrade_jj, "ota_new_version_number", m_ota_new_version_number);
// version list
if (upgrade_jj.contains("new_ver_list")) {
m_new_ver_list.clear();
for (auto ver_item = upgrade_jj["new_ver_list"].begin(); ver_item != upgrade_jj["new_ver_list"].end(); ver_item++) {
DevFirmwareVersionInfo ver_info;
DevJsonValParser::ParseVal(*ver_item, "name", ver_info.name);
DevJsonValParser::ParseVal(*ver_item, "cur_ver", ver_info.sw_ver);
DevJsonValParser::ParseVal(*ver_item, "new_ver", ver_info.sw_new_ver);
m_new_ver_list[ver_info.name] = ver_info;
if (ver_info.name == "ota" && m_ota_new_version_number.empty()) { m_ota_new_version_number = ver_info.sw_new_ver; }
}
} else {
m_new_ver_list.clear();
}
// try to parse display state
ParseUpgradeDisplayState(upgrade_jj);
}
if (print_jj.contains("cfg")) {
const std::string &cfg = print_jj["cfg"].get<std::string>();
if (!cfg.empty()) { m_upgrade_force_upgrade = DevUtil::get_flag_bits(cfg, 2); }
}
}
void DevUpgrade::ParseUpgradeDisplayState(const json &upgrade_state_jj)
{
if (upgrade_state_jj.contains("dis_state")) {
if ((int) m_upgrade_display_state != upgrade_state_jj["dis_state"].get<int>()) {
DevJsonValParser::ParseVal(upgrade_state_jj, "dis_state", m_upgrade_display_state);
// update the version after upgrade finished
if (m_upgrade_display_state == DevFirmwareUpgradeState::UpgradingFinished) {
Slic3r::GUI::wxGetApp().CallAfter([this] {
m_owner->command_get_version();
});
}
// lan mode printer, hide upgrade avaliable state
if (m_upgrade_display_state == DevFirmwareUpgradeState::UpgradingAvaliable &&
m_owner->is_lan_mode_printer()) {
m_upgrade_display_state = DevFirmwareUpgradeState::UpgradingUnavaliable;
}
}
} else {
// BBS compatibility with old version
if (m_upgrade_status == "DOWNLOADING" ||
m_upgrade_status == "FLASHING" ||
m_upgrade_status == "UPGRADE_REQUEST" ||
m_upgrade_status == "PRE_FLASH_START" ||
m_upgrade_status == "PRE_FLASH_SUCCESS") {
m_upgrade_display_state = DevFirmwareUpgradeState::UpgradingInProgress;
} else if (m_upgrade_status == "UPGRADE_SUCCESS" ||
m_upgrade_status == "DOWNLOAD_FAIL" ||
m_upgrade_status == "FLASH_FAIL" ||
m_upgrade_status == "PRE_FLASH_FAIL" ||
m_upgrade_status == "UPGRADE_FAIL") {
m_upgrade_display_state = DevFirmwareUpgradeState::UpgradingFinished;
} else {
if (HasNewVersion()) {
m_upgrade_display_state = DevFirmwareUpgradeState::UpgradingAvaliable;
} else {
m_upgrade_display_state = DevFirmwareUpgradeState::UpgradingUnavaliable;
}
}
}
}
#define UpgradeNoError 0
#define UpgradeDownloadFailed -1
#define UpgradeVerfifyFailed -2
#define UpgradeFlashFailed -3
#define UpgradePrinting -4
wxString DevUpgrade::GetUpgradeErrCodeStr() const
{
switch (m_upgrade_err_code) {
case UpgradeNoError: return _L("Update successful.");
case UpgradeDownloadFailed: return _L("Downloading failed.");
case UpgradeVerfifyFailed: return _L("Verification failed.");
case UpgradeFlashFailed: return _L("Update failed.");
case UpgradePrinting: return _L("Update failed.");
default: return _L("Update failed.");
}
return "";
}
} // namespace Slic3r

View File

@@ -0,0 +1,108 @@
#pragma once
#include <nlohmann/json.hpp>
#include "slic3r/Utils/json_diff.hpp"
#include "DevDefs.h"
#include "DevFirmware.h"
namespace Slic3r {
class MachineObject;
class DevUpgrade
{
public:
static std::shared_ptr<DevUpgrade> Create(MachineObject *owner) { return std::shared_ptr<DevUpgrade>(new DevUpgrade(owner)); }
public:
// upgrade status
bool IsUpgrading() const { return m_upgrade_display_state == DevFirmwareUpgradeState::UpgradingInProgress; }
bool IsUpgradeAvaliable() const { return m_upgrade_display_state == DevFirmwareUpgradeState::UpgradingAvaliable; }
DevFirmwareUpgradeState GetUpgradeState() const { return m_upgrade_display_state; }
std::string GetUpgradeStatusStr() const { return m_upgrade_status; }
// upgrade request
bool IsUpgradeConsistencyRequest() const { return m_upgrade_consistency_request; }
bool IsUpgradeForceUpgrade() const { return m_upgrade_force_upgrade; }
bool HasNewVersion() const { return m_upgrade_new_version_state == 1; }
std::string GetOtaNewVersion() const { return m_ota_new_version_number; }
std::map<std::string, DevFirmwareVersionInfo> GetNewVersionList() const { return m_new_ver_list; }
// upgrading
std::string GetUpgradeModuleStr() const { return m_upgrade_module; }
std::string GetUpgradeProgressStr() const { return m_upgrade_progress; }
int GetUpgradeProgressInt() const;
std::string GetUpgradeMessageStr() const { return m_upgrade_message; }
wxString GetUpgradeErrCodeStr() const;
public:
// ctrls
int CtrlUpgradeConfirm();
int CtrlUpgradeConsistencyConfirm();
int CtrlUpgradeFirmware(FirmwareInfo info);
int CtrlUpgradeModule(std::string url, std::string module_type, std::string version);
// parser
void ParseUpgrade_V1_0(const json &print_jj);
void ParseUpgradeDisplayState(const json &upgrade_state_jj);
protected:
DevUpgrade(MachineObject *owner) : m_owner(owner) {}
private:
MachineObject *m_owner = nullptr;
int m_upgrade_new_version_state = 0; // 0: invalid version, 1: new version available, 2: no new version
bool m_upgrade_consistency_request = false;
bool m_upgrade_force_upgrade = false;
std::string m_ota_new_version_number;
std::map<std::string, DevFirmwareVersionInfo> m_new_ver_list; // some protcols have version list
DevFirmwareUpgradeState m_upgrade_display_state = DevFirmwareUpgradeState::DC;
int m_upgrade_err_code;
std::string m_upgrade_status;
std::string m_upgrade_progress;
std::string m_upgrade_message;
std::string m_upgrade_module;
};
#if 0 /*TODO*/
class DevUpgradeGetVersionInfo
{
public:
DevUpgradeGetVersionInfo(MachineObject* obj) : m_owner(obj) {} ;
public:
bool IsEmpty() const { m_module_version_map.empty();}
DevFirmwareVersionInfo GetAirPumpVersionInfo() const { return m_air_pump_version_info; }
DevFirmwareVersionInfo GetLaserVersionInfo() const { return m_laser_version_info; }
DevFirmwareVersionInfo GetCuttingModuleVersionInfo() const { return m_cutting_module_version_info; }
DevFirmwareVersionInfo GetExtinguishVersionInfo() const { return m_extinguish_version_info; }
DevFirmwareVersionInfo GetRotaryVersionInfo() const { return m_rotary_version_info; }
std::map<std::string, DevFirmwareVersionInfo> GetModuleVersionInfoMap() const { return m_module_version_map; }
public:
int CtrlGetVersion(bool with_retry = true);
void ParseGetVersion(const json &print_jj);
private:
MachineObject *m_owner;
// some version info
DevFirmwareVersionInfo m_air_pump_version_info;
DevFirmwareVersionInfo m_laser_version_info;
DevFirmwareVersionInfo m_cutting_module_version_info;
DevFirmwareVersionInfo m_extinguish_version_info;
DevFirmwareVersionInfo m_rotary_version_info;
std::map<std::string, DevFirmwareVersionInfo> m_module_version_map;
// ctrl retry
int m_retry_count = 0;
int m_max_retry = 3;
};
#endif
} // namespace Slic3r

View File

@@ -0,0 +1,56 @@
#include "DevUpgrade.h"
#include "DevUtil.h"
#include "slic3r/GUI/DeviceManager.hpp"
namespace Slic3r {
int DevUpgrade::CtrlUpgradeConfirm()
{
json j;
j["upgrade"]["command"] = "upgrade_confirm";
j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["upgrade"]["src_id"] = 1; // 1 for slicer
return m_owner->publish_json(j);
}
int DevUpgrade::CtrlUpgradeConsistencyConfirm()
{
json j;
j["upgrade"]["command"] = "consistency_confirm";
j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["upgrade"]["src_id"] = 1; // 1 for slicer
return m_owner->publish_json(j);
}
int DevUpgrade::CtrlUpgradeFirmware(FirmwareInfo info)
{
std::string version = info.version;
std::string dst_url = info.url;
std::string module_name = info.module_type;
json j;
j["upgrade"]["command"] = "start";
j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["upgrade"]["url"] = info.url;
j["upgrade"]["module"] = info.module_type;
j["upgrade"]["version"] = info.version;
j["upgrade"]["src_id"] = 1;
return m_owner->publish_json(j);
}
int DevUpgrade::CtrlUpgradeModule(std::string url, std::string module_type, std::string version)
{
json j;
j["upgrade"]["command"] = "start";
j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["upgrade"]["url"] = url;
j["upgrade"]["module"] = module_type;
j["upgrade"]["version"] = version;
j["upgrade"]["src_id"] = 1;
return m_owner->publish_json(j);
}
} // namespace Slic3r

View File

@@ -44,6 +44,12 @@
#include "DeviceCore/DevManager.h"
#include "DeviceCore/DevUtil.h"
// Orca: adopt DeviceCore split — axis/calib/chamber/status/upgrade modules
#include "DeviceCore/DevAxis.h"
#include "DeviceCore/DevChamber.h"
#include "DeviceCore/DevStatus.h"
#include "DeviceCore/DevUpgrade.h"
#define CALI_DEBUG
#define MINUTE_30 1800000 //ms
@@ -578,6 +584,13 @@ MachineObject::MachineObject(DeviceManager* manager, NetworkAgent* agent, std::s
m_print_options = new DevPrintOptions(this);
m_nozzle_mapping_ptr = std::make_shared<DevNozzleMappingCtrl>(this);
// Orca: adopt DeviceCore split — axis/calib/chamber/status/upgrade modules
m_axis = DevAxis::Create(this);
m_chamber = DevChamber::Create(this);
m_upgrade = DevUpgrade::Create(this);
m_status = new DevStatus(this);
m_calib = new DevCalib(this);
}
}
@@ -630,6 +643,13 @@ MachineObject::~MachineObject()
delete m_print_options;
m_print_options = nullptr;
// Orca: adopt DeviceCore split
delete m_calib;
m_calib = nullptr;
delete m_status;
m_status = nullptr;
}
}
@@ -3003,6 +3023,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
//supported function
m_config->ParseConfig(jj);
m_status->ParseStatus(jj); // Orca: adopt DeviceCore split — populate DevStatus module
if (jj.contains("support_build_plate_marker_detect")) {
if (jj["support_build_plate_marker_detect"].is_boolean()) {
@@ -3427,6 +3448,11 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
if (!key_field_only) {
/* temperature */
// Orca: adopt DeviceCore split — populate DevAxis/DevChamber modules
// alongside the inline handling (side-effect-free; inline stays authoritative)
m_axis->ParseAxis(jj);
m_chamber->ParseChamber(jj);
DevBed::ParseV1_0(jj,m_bed);
if (jj.contains("frame_temper")) {

View File

@@ -22,6 +22,7 @@
#include "DeviceCore/DevDefs.h"
#include "DeviceCore/DevConfigUtil.h"
#include "DeviceCore/DevFirmware.h"
#include "DeviceCore/DevCalib.h" // Orca: adopt DeviceCore split (defines DevCalib, CalibStatus, ManualPaCaliMethod)
#include "DeviceErrorDialog.hpp"
#include <wx/object.h>
@@ -63,11 +64,7 @@ class DeviceErrorDialog; // Previous definitions
}
class NetworkAgent;
enum ManualPaCaliMethod {
PA_LINE = 0,
PA_PATTERN,
};
// Orca: ManualPaCaliMethod now provided by DeviceCore/DevCalib.h (enum class)
#define UpgradeNoError 0
#define UpgradeDownloadFailed -1
@@ -78,7 +75,9 @@ enum ManualPaCaliMethod {
// Previous definitions
class DevAms;
class DevAmsTray;
class DevAxis; // Orca: adopt DeviceCore split
class DevBed;
class DevChamber; // Orca: adopt DeviceCore split
class DevConfig;
class DevCtrl;
class DevExtensionTool;
@@ -92,7 +91,9 @@ class DevLamp;
class DevNozzleSystem;
class DevNozzleMappingCtrl;
class DeviceManager;
class DevStatus; // Orca: adopt DeviceCore split
class DevStorage;
class DevUpgrade; // Orca: adopt DeviceCore split
struct DevPrintTaskRatingInfo;
@@ -124,6 +125,15 @@ private:
DevBed * m_bed;
DevStorage* m_storage;
/* Orca: adopt DeviceCore split — axis/calib/chamber/status/upgrade modules.
Provide the reference-shape surface for later resync clusters; MachineObject's inline
handling of these concerns stays authoritative during the transition (removed in cluster 8). */
std::shared_ptr<DevAxis> m_axis;
std::shared_ptr<DevChamber> m_chamber;
DevCalib* m_calib{ nullptr };
DevStatus* m_status{ nullptr };
std::shared_ptr<DevUpgrade> m_upgrade;
/*Ctrl*/
DevCtrl* m_ctrl;
@@ -146,6 +156,14 @@ public:
~MachineObject();
void set_agent(NetworkAgent* agent) { m_agent = agent; }
NetworkAgent* get_agent() const { return m_agent; } // Orca: needed by DeviceCore modules (DevAxisCtrl)
// Orca: adopt DeviceCore split — reference-shape accessors for the new modules
std::shared_ptr<DevAxis> GetAxis() const { return m_axis; }
std::shared_ptr<DevChamber> GetChamber() const { return m_chamber; }
DevCalib* GetCalib() const { return m_calib; }
DevStatus* GetStatus() const { return m_status; }
std::weak_ptr<DevUpgrade> GetUpgrade() const { return m_upgrade; }
public:
enum ActiveState {