Start Simulation for Duet

* PrintHost can now return a set of possible actions to be done after a
  upload is finished
* Added new Button for starting a simulation after upload
* Duet Hosts are now able to start a simulation after upload instead of
  starting a print
* removed now unneeded config key 'printhost_print'
This commit is contained in:
Martin Loidl 2020-10-24 21:36:37 +00:00
parent 2c5ddfefb2
commit ef6f457207
13 changed files with 77 additions and 40 deletions

View File

@ -6124,11 +6124,12 @@ void Plater::send_gcode()
upload_job.printhost->get_groups(groups);
}
PrintHostSendDialog dlg(default_output_file, upload_job.printhost->can_start_print(), groups);
PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups);
if (dlg.ShowModal() == wxID_OK) {
upload_job.upload_data.upload_path = dlg.filename();
upload_job.upload_data.start_print = dlg.start_print();
upload_job.upload_data.post_action = dlg.post_action();
upload_job.upload_data.group = dlg.group();
p->export_gcode(fs::path(), false, std::move(upload_job));
}
}

View File

@ -35,13 +35,13 @@ namespace Slic3r {
namespace GUI {
static const char *CONFIG_KEY_PATH = "printhost_path";
static const char *CONFIG_KEY_PRINT = "printhost_print";
static const char *CONFIG_KEY_GROUP = "printhost_group";
PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print, const wxArrayString &groups)
PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, std::set<PrintHostPostUploadAction> post_actions, const wxArrayString &groups)
: MsgDialog(static_cast<wxWindow*>(wxGetApp().mainframe), _L("Send G-Code to printer host"), _L("Upload to Printer Host with the following filename:"))
, txt_filename(new wxTextCtrl(this, wxID_ANY))
, combo_groups(!groups.IsEmpty() ? new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, groups, wxCB_READONLY) : nullptr)
, post_upload_action(PrintHostPostUploadAction::None)
{
#ifdef __APPLE__
txt_filename->OSXDisableAllSmartSubstitutions();
@ -79,7 +79,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
wxString suffix = recent_path.substr(recent_path.find_last_of('.'));
if (can_start_print) {
if (post_actions.find(PrintHostPostUploadAction::StartPrint) != post_actions.end()) {
auto* btn_print = add_button(wxID_YES, false, _L("Upload and Print"));
btn_print->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
wxString path = txt_filename->GetValue();
@ -90,10 +90,27 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
if (msg_wingow.ShowModal() == wxID_NO)
return;
}
start_print_selected = true;
post_upload_action = PrintHostPostUploadAction::StartPrint;
EndDialog(wxID_OK);
});
}
if (post_actions.find(PrintHostPostUploadAction::StartSimulation) != post_actions.end()) {
auto* btn_print = add_button(wxID_YES, false, _L("Upload and Simulate"));
btn_print->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
wxString path = txt_filename->GetValue();
// .gcode suffix control
if (!path.Lower().EndsWith(suffix.Lower()))
{
MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
if (msg_wingow.ShowModal() == wxID_NO)
return;
}
post_upload_action = PrintHostPostUploadAction::StartSimulation;
EndDialog(wxID_OK);
});
}
add_button(wxID_CANCEL);
if (auto* btn_ok = get_button(wxID_OK); btn_ok != NULL) {
@ -137,9 +154,9 @@ fs::path PrintHostSendDialog::filename() const
return into_path(txt_filename->GetValue());
}
bool PrintHostSendDialog::start_print() const
PrintHostPostUploadAction PrintHostSendDialog::post_action() const
{
return start_print_selected;
return post_upload_action;
}
std::string PrintHostSendDialog::group() const
@ -165,8 +182,7 @@ void PrintHostSendDialog::EndModal(int ret)
AppConfig *app_config = wxGetApp().app_config;
app_config->set("recent", CONFIG_KEY_PATH, into_u8(path));
app_config->set("recent", CONFIG_KEY_PRINT, start_print() ? "1" : "0");
if (combo_groups != nullptr) {
wxString group = combo_groups->GetValue();
app_config->set("recent", CONFIG_KEY_GROUP, into_u8(group));

View File

@ -1,6 +1,7 @@
#ifndef slic3r_PrintHostSendDialog_hpp_
#define slic3r_PrintHostSendDialog_hpp_
#include <set>
#include <string>
#include <boost/filesystem/path.hpp>
@ -13,14 +14,15 @@
class wxButton;
class wxTextCtrl;
class wxChoice;
class wxComboBox;
class wxCheckBox;
class wxDataViewListCtrl;
namespace Slic3r {
struct PrintHostJob;
enum class PrintHostPostUploadAction;
namespace GUI {
@ -28,16 +30,16 @@ namespace GUI {
class PrintHostSendDialog : public GUI::MsgDialog
{
public:
PrintHostSendDialog(const boost::filesystem::path &path, bool can_start_print, const wxArrayString& groups);
PrintHostSendDialog(const boost::filesystem::path &path, std::set<PrintHostPostUploadAction> post_actions, const wxArrayString& groups);
boost::filesystem::path filename() const;
bool start_print() const;
PrintHostPostUploadAction post_action() const;
std::string group() const;
virtual void EndModal(int ret) override;
private:
wxTextCtrl *txt_filename;
wxComboBox *combo_groups;
bool start_print_selected { false };
PrintHostPostUploadAction post_upload_action;
};

View File

@ -115,11 +115,11 @@ bool AstroBox::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error
% url
% upload_filename.string()
% upload_parent_path.string()
% upload_data.start_print;
% (upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false");
auto http = Http::post(std::move(url));
set_auth(http);
http.form_add("print", upload_data.start_print ? "true" : "false")
http.form_add("print", upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false")
.form_add("path", upload_parent_path.string()) // XXX: slashes on windows ???
.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
.on_complete([&](std::string body, unsigned status) {

View File

@ -26,7 +26,7 @@ public:
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
bool has_auto_discovery() const override { return true; }
bool can_test() const override { return true; }
bool can_start_print() const override { return true; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const {return std::set({PrintHostPostUploadAction::StartPrint});}
std::string get_host() const override { return host; }
protected:

View File

@ -67,10 +67,10 @@ bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn e
bool dsf = (connectionType == ConnectionType::dsf);
auto upload_cmd = get_upload_url(upload_data.upload_path.string(), connectionType);
BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filepath: %2%, print: %3%, command: %4%")
BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filepath: %2%, post_action: %3%, command: %4%")
% upload_data.source_path
% upload_data.upload_path
% upload_data.start_print
% int(upload_data.post_action)
% upload_cmd;
auto http = (dsf ? Http::put(std::move(upload_cmd)) : Http::post(std::move(upload_cmd)));
@ -87,9 +87,15 @@ bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn e
BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Request completed but error code was received: %1%") % err_code;
error_fn(format_error(body, L("Unknown error occured"), 0));
res = false;
} else if (upload_data.start_print) {
} else if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
wxString errormsg;
res = start_print(errormsg, upload_data.upload_path.string(), connectionType);
res = start_print(errormsg, upload_data.upload_path.string(), connectionType, false);
if (! res) {
error_fn(std::move(errormsg));
}
} else if (upload_data.post_action == PrintHostPostUploadAction::StartSimulation) {
wxString errormsg;
res = start_print(errormsg, upload_data.upload_path.string(), connectionType, true);
if (! res) {
error_fn(std::move(errormsg));
}
@ -230,7 +236,7 @@ std::string Duet::timestamp_str() const
return std::string(buffer);
}
bool Duet::start_print(wxString &msg, const std::string &filename, ConnectionType connectionType) const
bool Duet::start_print(wxString &msg, const std::string &filename, ConnectionType connectionType, bool simulationMode) const
{
assert(connectionType != ConnectionType::error);
@ -240,14 +246,18 @@ bool Duet::start_print(wxString &msg, const std::string &filename, ConnectionTyp
auto url = dsf
? (boost::format("%1%machine/code")
% get_base_url()).str()
: (boost::format("%1%rr_gcode?gcode=M32%%20\"0:/gcodes/%2%\"")
: (boost::format(simulationMode
? "%1%rr_gcode?gcode=M37%%20P\"0:/gcodes/%2%\""
: "%1%rr_gcode?gcode=M32%%20\"0:/gcodes/%2%\"")
% get_base_url()
% Http::url_encode(filename)).str();
auto http = (dsf ? Http::post(std::move(url)) : Http::get(std::move(url)));
if (dsf) {
http.set_post_body(
(boost::format("M32 \"0:/gcodes/%1%\"")
(boost::format(simulationMode
? "M37 P\"0:/gcodes/%1%\""
: "M32 \"0:/gcodes/%1%\"")
% filename).str()
);
}

View File

@ -25,7 +25,7 @@ public:
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
bool has_auto_discovery() const override { return false; }
bool can_test() const override { return true; }
bool can_start_print() const override { return true; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const {return std::set({PrintHostPostUploadAction::StartPrint, PrintHostPostUploadAction::StartSimulation});}
std::string get_host() const override { return host; }
private:
@ -39,7 +39,7 @@ private:
std::string timestamp_str() const;
ConnectionType connect(wxString &msg) const;
void disconnect(ConnectionType connectionType) const;
bool start_print(wxString &msg, const std::string &filename, ConnectionType connectionType) const;
bool start_print(wxString &msg, const std::string &filename, ConnectionType connectionType, bool simulationMode) const;
int get_err_code_from_body(const std::string &body) const;
};

View File

@ -26,7 +26,7 @@ public:
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
bool has_auto_discovery() const override { return false; }
bool can_test() const override { return true; }
bool can_start_print() const override { return false; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const {return std::set<PrintHostPostUploadAction>();}
std::string get_host() const override { return host; }
private:

View File

@ -137,11 +137,11 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro
% url
% upload_filename.string()
% upload_parent_path.string()
% upload_data.start_print;
% (upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false");
auto http = Http::post(std::move(url));
set_auth(http);
http.form_add("print", upload_data.start_print ? "true" : "false")
http.form_add("print", upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false")
.form_add("path", upload_parent_path.string()) // XXX: slashes on windows ???
.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
.on_complete([&](std::string body, unsigned status) {

View File

@ -28,7 +28,7 @@ public:
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
bool has_auto_discovery() const override { return true; }
bool can_test() const override { return true; }
bool can_start_print() const override { return true; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const {return std::set({PrintHostPostUploadAction::StartPrint});}
std::string get_host() const override { return m_host; }
const std::string& get_apikey() const { return m_apikey; }
const std::string& get_cafile() const { return m_cafile; }
@ -57,7 +57,7 @@ public:
wxString get_test_ok_msg() const override;
wxString get_test_failed_msg(wxString &msg) const override;
bool can_start_print() const override { return false; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const override {return std::set<PrintHostPostUploadAction>();}
protected:
bool validate_version_text(const boost::optional<std::string> &version_text) const override;
@ -82,7 +82,7 @@ public:
wxString get_test_ok_msg() const override;
wxString get_test_failed_msg(wxString& msg) const override;
bool can_start_print() const override { return true; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const {return std::set({PrintHostPostUploadAction::StartPrint});}
protected:
bool validate_version_text(const boost::optional<std::string>& version_text) const override;

View File

@ -2,6 +2,7 @@
#define slic3r_PrintHost_hpp_
#include <memory>
#include <set>
#include <string>
#include <functional>
#include <boost/filesystem/path.hpp>
@ -16,6 +17,11 @@ namespace Slic3r {
class DynamicPrintConfig;
enum class PrintHostPostUploadAction {
None,
StartPrint,
StartSimulation
};
struct PrintHostUpload
{
@ -24,7 +30,7 @@ struct PrintHostUpload
std::string group;
bool start_print = false;
PrintHostPostUploadAction post_action = PrintHostPostUploadAction::None;
};
@ -44,7 +50,7 @@ public:
virtual bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const = 0;
virtual bool has_auto_discovery() const = 0;
virtual bool can_test() const = 0;
virtual bool can_start_print() const = 0;
virtual std::set<PrintHostPostUploadAction> get_post_upload_actions() const = 0;
// A print host usually does not support multiple printers, with the exception of Repetier server.
virtual bool supports_multiple_printers() const { return false; }
virtual std::string get_host() const = 0;

View File

@ -107,7 +107,9 @@ bool Repetier::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error
bool res = true;
auto url = upload_data.start_print?make_url((boost::format("printer/job/%1%") % port).str()):make_url((boost::format("printer/model/%1%") % port).str());
auto url = upload_data.post_action == PrintHostPostUploadAction::StartPrint
? make_url((boost::format("printer/job/%1%") % port).str())
: make_url((boost::format("printer/model/%1%") % port).str());
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%, group: %7%")
% name
@ -115,17 +117,17 @@ bool Repetier::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error
% url
% upload_filename.string()
% upload_parent_path.string()
% upload_data.start_print
% (upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false")
% upload_data.group;
auto http = Http::post(std::move(url));
set_auth(http);
if (! upload_data.group.empty() && upload_data.group != _utf8(L("Default"))) {
http.form_add("group", upload_data.group);
}
if(upload_data.start_print) {
if(upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
http.form_add("name", upload_filename.string());
}

View File

@ -27,7 +27,7 @@ public:
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
bool has_auto_discovery() const override { return false; }
bool can_test() const override { return true; }
bool can_start_print() const override { return true; }
std::set<PrintHostPostUploadAction> get_post_upload_actions() const {return std::set({PrintHostPostUploadAction::StartPrint});}
bool supports_multiple_printers() const override { return true; }
std::string get_host() const override { return host; }