mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-29 13:52:07 +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));
|
auto http = Http::post(url); // std::move(url));
|
||||||
set_auth(http);
|
set_auth(http);
|
||||||
http.form_add("path", upload_parent_path.string())
|
if (!supports_multi_color_print())
|
||||||
.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
|
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) {
|
.on_complete([&](std::string body, unsigned status) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
|
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
|
||||||
|
|
||||||
if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||||
wxString errormsg;
|
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));
|
error_fn(std::move(errormsg));
|
||||||
res = false;
|
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 {
|
try {
|
||||||
|
const std::string gcode_path = "/mnt/UDISK/printer_data/gcodes/" + filename;
|
||||||
|
|
||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
websocket::stream<beast::tcp_stream> ws{ioc};
|
websocket::stream<beast::tcp_stream> ws{ioc};
|
||||||
ws_connect(ioc, ws, m_host, "9999");
|
ws_connect(ioc, ws, m_host, "9999");
|
||||||
|
|
||||||
json j2 = {
|
if (supports_multi_color_print()) {
|
||||||
{ "method", "set" },
|
// Build colorMatch list from the mapping provided by the dialog
|
||||||
{
|
json color_list = json::array();
|
||||||
"params", {
|
for (int i = 0; ; i++) {
|
||||||
{ "opGcodeFile", "printprt:/usr/data/printer_data/gcodes/" + filename }
|
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;
|
return true;
|
||||||
} catch(std::exception const& e) {
|
} catch(std::exception const& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "CrealityPrint: Error starting print: " << e.what();
|
BOOST_LOG_TRIVIAL(error) << "CrealityPrint: Error starting print: " << e.what();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef slic3r_CrealityPrint_hpp_
|
#ifndef slic3r_CrealityPrint_hpp_
|
||||||
#define slic3r_CrealityPrint_hpp_
|
#define slic3r_CrealityPrint_hpp_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
@@ -44,7 +45,7 @@ private:
|
|||||||
mutable std::string m_model;
|
mutable std::string m_model;
|
||||||
|
|
||||||
std::string make_url(const std::string& path) const;
|
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;
|
std::string safe_filename(const std::string& filename) const;
|
||||||
void query_model() const;
|
void query_model() const;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user