mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-09 21:42:56 +00:00
CrealityPrint: add multi-color print protocol for K2 Plus
For supported models, start_print() sends colorMatch (filament-to-slot mapping) followed by multiColorPrint (with optional calibration via enableSelfTest) instead of the legacy opGcodeFile command. The dialog passes color mapping and calibration settings through extended_info. Signed-off-by: Igor Mammedov <niallain@gmail.com> --- v4: - Skip "path" form field in multipart upload for multi-color printers (extra field breaks K2 Plus firmware parser) - Use fire-and-forget ws.write() for colorMatch and multiColorPrint instead of ws_send_and_read() (printer sends response asynchronously)
This commit is contained in:
@@ -140,15 +140,16 @@ bool CrealityPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn,
|
||||
|
||||
auto http = Http::post(url); // std::move(url));
|
||||
set_auth(http);
|
||||
http.form_add("path", upload_parent_path.string())
|
||||
.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
|
||||
if (!supports_multi_color_print())
|
||||
http.form_add("path", upload_parent_path.string());
|
||||
http.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
|
||||
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
|
||||
|
||||
if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||
wxString errormsg;
|
||||
if (!start_print(errormsg, safe_filename(upload_filename.string()))) {
|
||||
if (!start_print(errormsg, safe_filename(upload_filename.string()), upload_data.extended_info)) {
|
||||
error_fn(std::move(errormsg));
|
||||
res = false;
|
||||
}
|
||||
@@ -278,28 +279,81 @@ std::string CrealityPrint::query_boxes_info() const
|
||||
}
|
||||
}
|
||||
|
||||
bool CrealityPrint::start_print(wxString &msg, const std::string &filename) const
|
||||
bool CrealityPrint::start_print(wxString &msg, const std::string &filename, const std::map<std::string, std::string>& extended_info) const
|
||||
{
|
||||
try {
|
||||
const std::string gcode_path = "/mnt/UDISK/printer_data/gcodes/" + filename;
|
||||
|
||||
net::io_context ioc;
|
||||
websocket::stream<beast::tcp_stream> ws{ioc};
|
||||
ws_connect(ioc, ws, m_host, "9999");
|
||||
|
||||
json j2 = {
|
||||
{ "method", "set" },
|
||||
{
|
||||
"params", {
|
||||
{ "opGcodeFile", "printprt:/usr/data/printer_data/gcodes/" + filename }
|
||||
if (supports_multi_color_print()) {
|
||||
// Build colorMatch list from the mapping provided by the dialog
|
||||
json color_list = json::array();
|
||||
for (int i = 0; ; i++) {
|
||||
auto it = extended_info.find("colorMatch_" + std::to_string(i));
|
||||
if (it == extended_info.end())
|
||||
break;
|
||||
// Value format: "toolId\ttype\tcolor\tboxId\tmaterialId"
|
||||
auto val = it->second;
|
||||
std::vector<std::string> parts;
|
||||
std::istringstream iss(val);
|
||||
std::string part;
|
||||
while (std::getline(iss, part, '\t'))
|
||||
parts.push_back(part);
|
||||
if (parts.size() >= 5) {
|
||||
color_list.push_back({
|
||||
{"id", parts[0]},
|
||||
{"type", parts[1]},
|
||||
{"color", parts[2]},
|
||||
{"boxId", std::stoi(parts[3])},
|
||||
{"materialId", std::stoi(parts[4])}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ws.write(net::buffer(to_string(j2)));
|
||||
json color_match = {
|
||||
{"method", "set"},
|
||||
{"params", {
|
||||
{"colorMatch", {
|
||||
{"path", gcode_path},
|
||||
{"list", color_list}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
ws.write(net::buffer(to_string(color_match)));
|
||||
|
||||
beast::flat_buffer buffer;
|
||||
// Read enableSelfTest from extended_info, default to 0 (calibration off)
|
||||
int enable_self_test = 0;
|
||||
auto it = extended_info.find("enableSelfTest");
|
||||
if (it != extended_info.end())
|
||||
enable_self_test = std::stoi(it->second);
|
||||
|
||||
ws.read(buffer);
|
||||
json multi_color_print = {
|
||||
{"method", "set"},
|
||||
{"params", {
|
||||
{"multiColorPrint", {
|
||||
{"gcode", gcode_path},
|
||||
{"enableSelfTest", enable_self_test}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
ws.write(net::buffer(to_string(multi_color_print)));
|
||||
} else {
|
||||
json cmd = {
|
||||
{"method", "set"},
|
||||
{"params", {
|
||||
{"opGcodeFile", "printprt:/usr/data/printer_data/gcodes/" + filename}
|
||||
}}
|
||||
};
|
||||
ws.write(net::buffer(to_string(cmd)));
|
||||
|
||||
beast::flat_buffer buffer;
|
||||
ws.read(buffer);
|
||||
}
|
||||
|
||||
ws.close(websocket::close_code::normal);
|
||||
return true;
|
||||
} catch(std::exception const& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "CrealityPrint: Error starting print: " << e.what();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef slic3r_CrealityPrint_hpp_
|
||||
#define slic3r_CrealityPrint_hpp_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <wx/string.h>
|
||||
#include <boost/optional.hpp>
|
||||
@@ -44,7 +45,7 @@ private:
|
||||
mutable std::string m_model;
|
||||
|
||||
std::string make_url(const std::string& path) const;
|
||||
bool start_print(wxString& msg, const std::string& path) const;
|
||||
bool start_print(wxString& msg, const std::string& filename, const std::map<std::string, std::string>& extended_info) const;
|
||||
std::string safe_filename(const std::string& filename) const;
|
||||
void query_model() const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user