Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Duet Class Reference

#include <src/slic3r/Utils/Duet.hpp>

+ Inheritance diagram for Slic3r::Duet:
+ Collaboration diagram for Slic3r::Duet:

Public Types

typedef Http::ProgressFn ProgressFn
 
typedef std::function< void(wxString)> ErrorFn
 
typedef std::function< void(wxString, wxString)> InfoFn
 

Public Member Functions

 Duet (DynamicPrintConfig *config)
 
 ~Duet () override=default
 
const char * get_name () const override
 
bool test (wxString &curl_msg) const override
 
wxString get_test_ok_msg () const override
 
wxString get_test_failed_msg (wxString &msg) const override
 
bool upload (PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const override
 
bool has_auto_discovery () const override
 
bool can_test () const override
 
PrintHostPostUploadActions get_post_upload_actions () const override
 
std::string get_host () const override
 
virtual bool supports_multiple_printers () const
 
virtual bool get_groups (wxArrayString &) const
 
virtual bool get_printers (wxArrayString &) const
 
virtual bool get_storage (wxArrayString &, wxArrayString &) const
 

Static Public Member Functions

static PrintHostget_print_host (DynamicPrintConfig *config)
 

Protected Member Functions

virtual wxString format_error (const std::string &body, const std::string &error, unsigned status) const
 

Private Types

enum class  ConnectionType { rrf , dsf , error }
 

Private Member Functions

std::string get_upload_url (const std::string &filename, ConnectionType connectionType) const
 
std::string get_connect_url (const bool dsfUrl) const
 
std::string get_base_url () const
 
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, bool simulationMode) const
 
int get_err_code_from_body (const std::string &body) const
 

Private Attributes

std::string host
 
std::string password
 

Detailed Description

Member Typedef Documentation

◆ ErrorFn

typedef std::function<void(wxString )> Slic3r::PrintHost::ErrorFn
inherited

◆ InfoFn

typedef std::function<void(wxString , wxString )> Slic3r::PrintHost::InfoFn
inherited

◆ ProgressFn

Member Enumeration Documentation

◆ ConnectionType

Constructor & Destructor Documentation

◆ Duet()

Slic3r::Duet::Duet ( DynamicPrintConfig config)
explicit
31 :
32 host(config->opt_string("print_host")),
33 password(config->opt_string("printhost_apikey"))
34{}
std::string host
Definition Duet.hpp:33
std::string password
Definition Duet.hpp:34

◆ ~Duet()

Slic3r::Duet::~Duet ( )
overridedefault

Member Function Documentation

◆ can_test()

bool Slic3r::Duet::can_test ( ) const
inlineoverridevirtual

Implements Slic3r::PrintHost.

27{ return true; }

◆ connect()

Duet::ConnectionType Slic3r::Duet::connect ( wxString &  msg) const
private
124{
125 auto res = ConnectionType::error;
126 auto url = get_connect_url(false);
127
128 auto http = Http::get(std::move(url));
129 http.on_error([&](std::string body, std::string error, unsigned status) {
130 auto dsfUrl = get_connect_url(true);
131 auto dsfHttp = Http::get(std::move(dsfUrl));
132 dsfHttp.on_error([&](std::string body, std::string error, unsigned status) {
133 BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error connecting: %1%, HTTP %2%, body: `%3%`") % error % status % body;
134 msg = format_error(body, error, status);
135 })
136 .on_complete([&](std::string body, unsigned) {
138 })
139 .perform_sync();
140 })
141 .on_complete([&](std::string body, unsigned) {
142 BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: Got: %1%") % body;
143
144 int err_code = get_err_code_from_body(body);
145 switch (err_code) {
146 case 0:
148 break;
149 case 1:
150 msg = format_error(body, L("Wrong password"), 0);
151 break;
152 case 2:
153 msg = format_error(body, L("Could not get resources to create a new connection"), 0);
154 break;
155 default:
156 msg = format_error(body, L("Unknown error occured"), 0);
157 break;
158 }
159
160 })
161 .perform_sync();
162
163 return res;
164}
int get_err_code_from_body(const std::string &body) const
Definition Duet.cpp:276
std::string get_connect_url(const bool dsfUrl) const
Definition Duet.cpp:199
static Http get(std::string url)
Definition Http.cpp:607
virtual wxString format_error(const std::string &body, const std::string &error, unsigned status) const
Definition PrintHost.cpp:66
#define L(s)
Definition I18N.hpp:18

References dsf, error, Slic3r::PrintHost::format_error(), Slic3r::Http::get(), get_connect_url(), get_err_code_from_body(), L, and rrf.

Referenced by test(), and upload().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ disconnect()

void Slic3r::Duet::disconnect ( ConnectionType  connectionType) const
private
167{
168 // we don't need to disconnect from DSF or if it failed anyway
169 if (connectionType != ConnectionType::rrf) {
170 return;
171 }
172 auto url = (boost::format("%1%rr_disconnect")
173 % get_base_url()).str();
174
175 auto http = Http::get(std::move(url));
176 http.on_error([&](std::string body, std::string error, unsigned status) {
177 // we don't care about it, if disconnect is not working Duet will disconnect automatically after some time
178 BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error disconnecting: %1%, HTTP %2%, body: `%3%`") % error % status % body;
179 })
180 .perform_sync();
181}
std::string get_base_url() const
Definition Duet.cpp:212

References error, Slic3r::Http::get(), get_base_url(), and rrf.

Referenced by test(), and upload().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ format_error()

wxString Slic3r::PrintHost::format_error ( const std::string &  body,
const std::string &  error,
unsigned  status 
) const
protectedvirtualinherited
67{
68 if (status != 0) {
69 auto wxbody = wxString::FromUTF8(body.data());
70 return wxString::Format("HTTP %u: %s", status, wxbody);
71 } else {
72 return wxString::FromUTF8(error.data());
73 }
74}
static char error[256]
Definition tga.cpp:50

References error.

Referenced by connect(), Slic3r::PrusaLink::post_inner(), Slic3r::PrusaLink::put_inner(), start_print(), Slic3r::AstroBox::test(), Slic3r::FlashAir::test(), Slic3r::Moonraker::test(), Slic3r::OctoPrint::test(), Slic3r::PrusaLink::test(), Slic3r::Repetier::test(), Slic3r::PrusaLink::test_with_method_check(), Slic3r::AstroBox::upload(), upload(), Slic3r::FlashAir::upload(), Slic3r::MKS::upload(), Slic3r::Moonraker::upload(), Slic3r::Repetier::upload(), and Slic3r::OctoPrint::upload_inner_with_host().

+ Here is the caller graph for this function:

◆ get_base_url()

std::string Slic3r::Duet::get_base_url ( ) const
private
213{
214 if (host.find("http://") == 0 || host.find("https://") == 0) {
215 if (host.back() == '/') {
216 return host;
217 } else {
218 return (boost::format("%1%/") % host).str();
219 }
220 } else {
221 return (boost::format("http://%1%/") % host).str();
222 }
223}

References host.

Referenced by disconnect(), get_connect_url(), get_upload_url(), and start_print().

+ Here is the caller graph for this function:

◆ get_connect_url()

std::string Slic3r::Duet::get_connect_url ( const bool  dsfUrl) const
private
200{
201 if (dsfUrl) {
202 return (boost::format("%1%machine/status")
203 % get_base_url()).str();
204 } else {
205 return (boost::format("%1%rr_connect?password=%2%&%3%")
206 % get_base_url()
207 % (password.empty() ? "reprap" : password)
208 % timestamp_str()).str();
209 }
210}
std::string timestamp_str() const
Definition Duet.cpp:225

References get_base_url(), password, and timestamp_str().

Referenced by connect().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_err_code_from_body()

int Slic3r::Duet::get_err_code_from_body ( const std::string &  body) const
private
277{
278 pt::ptree root;
279 std::istringstream iss (body); // wrap returned json to istringstream
280 pt::read_json(iss, root);
281
282 return root.get<int>("err", 0);
283}

Referenced by connect(), and upload().

+ Here is the caller graph for this function:

◆ get_groups()

virtual bool Slic3r::PrintHost::get_groups ( wxArrayString &  ) const
inlinevirtualinherited

Reimplemented in Slic3r::Repetier.

65{ return false; }

◆ get_host()

std::string Slic3r::Duet::get_host ( ) const
inlineoverridevirtual

Implements Slic3r::PrintHost.

29{ return host; }

References host.

◆ get_name()

const char * Slic3r::Duet::get_name ( ) const
overridevirtual

Implements Slic3r::PrintHost.

36{ return "Duet"; }

◆ get_post_upload_actions()

◆ get_print_host()

PrintHost * Slic3r::PrintHost::get_print_host ( DynamicPrintConfig config)
staticinherited
35{
37
38 {
39 const auto opt = config->option<ConfigOptionEnum<PrinterTechnology>>("printer_technology");
40 if (opt != nullptr) {
41 tech = opt->value;
42 }
43 }
44
45 if (tech == ptFFF) {
46 const auto opt = config->option<ConfigOptionEnum<PrintHostType>>("host_type");
47 const auto host_type = opt != nullptr ? opt->value : htOctoPrint;
48
49 switch (host_type) {
50 case htOctoPrint: return new OctoPrint(config);
51 case htDuet: return new Duet(config);
52 case htFlashAir: return new FlashAir(config);
53 case htAstroBox: return new AstroBox(config);
54 case htRepetier: return new Repetier(config);
55 case htPrusaLink: return new PrusaLink(config);
56 case htPrusaConnect: return new PrusaConnect(config);
57 case htMKS: return new MKS(config);
58 case htMoonraker: return new Moonraker(config);
59 default: return nullptr;
60 }
61 } else {
62 return new SL1Host(config);
63 }
64}
PrinterTechnology
Definition Config.hpp:205
@ ptFFF
Definition Config.hpp:207
@ htMoonraker
Definition PrintConfig.hpp:47
@ htPrusaLink
Definition PrintConfig.hpp:47
@ htRepetier
Definition PrintConfig.hpp:47
@ htMKS
Definition PrintConfig.hpp:47
@ htPrusaConnect
Definition PrintConfig.hpp:47
@ htDuet
Definition PrintConfig.hpp:47
@ htOctoPrint
Definition PrintConfig.hpp:47
@ htFlashAir
Definition PrintConfig.hpp:47
@ htAstroBox
Definition PrintConfig.hpp:47
ConfigOptionEnum< PrinterTechnology >
Definition PrintConfig.hpp:1079

References Slic3r::htAstroBox, Slic3r::htDuet, Slic3r::htFlashAir, Slic3r::htMKS, Slic3r::htMoonraker, Slic3r::htOctoPrint, Slic3r::htPrusaConnect, Slic3r::htPrusaLink, Slic3r::htRepetier, Slic3r::ConfigBase::option(), Slic3r::ptFFF, and Slic3r::ConfigOptionSingle< T >::value.

Referenced by Slic3r::GUI::PhysicalPrinterDialog::build_printhost_settings(), Slic3r::GUI::PhysicalPrinterDialog::update_printers(), and Slic3r::GUI::PhysicalPrinterDialog::update_printhost_buttons().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_printers()

virtual bool Slic3r::PrintHost::get_printers ( wxArrayString &  ) const
inlinevirtualinherited

Reimplemented in Slic3r::Repetier.

66{ return false; }

◆ get_storage()

virtual bool Slic3r::PrintHost::get_storage ( wxArrayString &  ,
wxArrayString &   
) const
inlinevirtualinherited

Reimplemented in Slic3r::PrusaLink, and Slic3r::PrusaConnect.

69{ return false; }

◆ get_test_failed_msg()

wxString Slic3r::Duet::get_test_failed_msg ( wxString &  msg) const
overridevirtual

Implements Slic3r::PrintHost.

52{
53 return GUI::format_wxstr("%s: %s", _L("Could not connect to Duet"), msg);
54}
wxString format_wxstr(const char *fmt, TArgs &&... args)
Definition format.hpp:42
#define _L(s)
Definition I18N.hpp:3

References _L, and Slic3r::GUI::format_wxstr().

+ Here is the call graph for this function:

◆ get_test_ok_msg()

wxString Slic3r::Duet::get_test_ok_msg ( ) const
overridevirtual

Implements Slic3r::PrintHost.

47{
48 return _(L("Connection to Duet works correctly."));
49}
#define _(msgid)
Definition getopt.c:87

References _, and L.

◆ get_upload_url()

std::string Slic3r::Duet::get_upload_url ( const std::string &  filename,
ConnectionType  connectionType 
) const
private
184{
185 assert(connectionType != ConnectionType::error);
186
187 if (connectionType == ConnectionType::dsf) {
188 return (boost::format("%1%machine/file/gcodes/%2%")
189 % get_base_url()
190 % Http::url_encode(filename)).str();
191 } else {
192 return (boost::format("%1%rr_upload?name=0:/gcodes/%2%&%3%")
193 % get_base_url()
194 % Http::url_encode(filename)
195 % timestamp_str()).str();
196 }
197}
static std::string url_encode(const std::string &str)
Definition Http.cpp:653

References dsf, error, get_base_url(), timestamp_str(), and Slic3r::Http::url_encode().

Referenced by upload().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ has_auto_discovery()

bool Slic3r::Duet::has_auto_discovery ( ) const
inlineoverridevirtual

Implements Slic3r::PrintHost.

26{ return false; }

◆ start_print()

bool Slic3r::Duet::start_print ( wxString &  msg,
const std::string &  filename,
ConnectionType  connectionType,
bool  simulationMode 
) const
private
239{
240 assert(connectionType != ConnectionType::error);
241
242 bool res = false;
243 bool dsf = (connectionType == ConnectionType::dsf);
244
245 auto url = dsf
246 ? (boost::format("%1%machine/code")
247 % get_base_url()).str()
248 : (boost::format(simulationMode
249 ? "%1%rr_gcode?gcode=M37%%20P\"0:/gcodes/%2%\""
250 : "%1%rr_gcode?gcode=M32%%20\"0:/gcodes/%2%\"")
251 % get_base_url()
252 % Http::url_encode(filename)).str();
253
254 auto http = (dsf ? Http::post(std::move(url)) : Http::get(std::move(url)));
255 if (dsf) {
256 http.set_post_body(
257 (boost::format(simulationMode
258 ? "M37 P\"0:/gcodes/%1%\""
259 : "M32 \"0:/gcodes/%1%\"")
260 % filename).str()
261 );
262 }
263 http.on_error([&](std::string body, std::string error, unsigned status) {
264 BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error starting print: %1%, HTTP %2%, body: `%3%`") % error % status % body;
265 msg = format_error(body, error, status);
266 })
267 .on_complete([&](std::string body, unsigned) {
268 BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: Got: %1%") % body;
269 res = true;
270 })
271 .perform_sync();
272
273 return res;
274}
static Http post(std::string url)
Definition Http.cpp:612
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:44
constexpr auto get(span< E, S > s) -> decltype(s[N])
Definition span.hpp:590
Definition args.hpp:18
STL namespace.

References dsf, error, Slic3r::PrintHost::format_error(), Slic3r::Http::get(), get_base_url(), Slic3r::Http::post(), and Slic3r::Http::url_encode().

Referenced by upload().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ supports_multiple_printers()

virtual bool Slic3r::PrintHost::supports_multiple_printers ( ) const
inlinevirtualinherited

Reimplemented in Slic3r::Repetier.

60{ return false; }

◆ test()

bool Slic3r::Duet::test ( wxString &  curl_msg) const
overridevirtual

Implements Slic3r::PrintHost.

39{
40 auto connectionType = connect(msg);
41 disconnect(connectionType);
42
43 return connectionType != ConnectionType::error;
44}
void disconnect(ConnectionType connectionType) const
Definition Duet.cpp:166
ConnectionType connect(wxString &msg) const
Definition Duet.cpp:123

References connect(), disconnect(), and error.

+ Here is the call graph for this function:

◆ timestamp_str()

std::string Slic3r::Duet::timestamp_str ( ) const
private
226{
227 enum { BUFFER_SIZE = 32 };
228
229 auto t = std::time(nullptr);
230 auto tm = *std::localtime(&t);
231
232 char buffer[BUFFER_SIZE];
233 std::strftime(buffer, BUFFER_SIZE, "time=%Y-%m-%dT%H:%M:%S", &tm);
234
235 return std::string(buffer);
236}

Referenced by get_connect_url(), and get_upload_url().

+ Here is the caller graph for this function:

◆ upload()

bool Slic3r::Duet::upload ( PrintHostUpload  upload_data,
ProgressFn  prorgess_fn,
ErrorFn  error_fn,
InfoFn  info_fn 
) const
overridevirtual

Implements Slic3r::PrintHost.

57{
58 wxString connect_msg;
59 auto connectionType = connect(connect_msg);
60 if (connectionType == ConnectionType::error) {
61 error_fn(std::move(connect_msg));
62 return false;
63 }
64
65 bool res = true;
66 bool dsf = (connectionType == ConnectionType::dsf);
67
68 auto upload_cmd = get_upload_url(upload_data.upload_path.string(), connectionType);
69 BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filepath: %2%, post_action: %3%, command: %4%")
70 % upload_data.source_path
71 % upload_data.upload_path
72 % int(upload_data.post_action)
73 % upload_cmd;
74
75 auto http = (dsf ? Http::put(std::move(upload_cmd)) : Http::post(std::move(upload_cmd)));
76 if (dsf) {
77 http.set_put_body(upload_data.source_path);
78 } else {
79 http.set_post_body(upload_data.source_path);
80 }
81 http.on_complete([&](std::string body, unsigned status) {
82 BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body;
83
84 int err_code = dsf ? (status == 201 ? 0 : 1) : get_err_code_from_body(body);
85 if (err_code != 0) {
86 BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Request completed but error code was received: %1%") % err_code;
87 error_fn(format_error(body, L("Unknown error occured"), 0));
88 res = false;
89 } else if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
90 wxString errormsg;
91 res = start_print(errormsg, upload_data.upload_path.string(), connectionType, false);
92 if (! res) {
93 error_fn(std::move(errormsg));
94 }
95 } else if (upload_data.post_action == PrintHostPostUploadAction::StartSimulation) {
96 wxString errormsg;
97 res = start_print(errormsg, upload_data.upload_path.string(), connectionType, true);
98 if (! res) {
99 error_fn(std::move(errormsg));
100 }
101 }
102 })
103 .on_error([&](std::string body, std::string error, unsigned status) {
104 BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
105 error_fn(format_error(body, error, status));
106 res = false;
107 })
108 .on_progress([&](Http::Progress progress, bool &cancel) {
109 prorgess_fn(std::move(progress), cancel);
110 if (cancel) {
111 // Upload was canceled
112 BOOST_LOG_TRIVIAL(info) << "Duet: Upload canceled";
113 res = false;
114 }
115 })
116 .perform_sync();
117
118 disconnect(connectionType);
119
120 return res;
121}
std::string get_upload_url(const std::string &filename, ConnectionType connectionType) const
Definition Duet.cpp:183
bool start_print(wxString &msg, const std::string &filename, ConnectionType connectionType, bool simulationMode) const
Definition Duet.cpp:238
static Http put(std::string url)
Definition Http.cpp:619

References connect(), disconnect(), dsf, error, Slic3r::PrintHost::format_error(), get_err_code_from_body(), get_upload_url(), L, Slic3r::Http::post(), Slic3r::PrintHostUpload::post_action, Slic3r::Http::put(), Slic3r::PrintHostUpload::source_path, start_print(), Slic3r::StartPrint, Slic3r::StartSimulation, and Slic3r::PrintHostUpload::upload_path.

+ Here is the call graph for this function:

Member Data Documentation

◆ host

std::string Slic3r::Duet::host
private

Referenced by get_base_url(), and get_host().

◆ password

std::string Slic3r::Duet::password
private

Referenced by get_connect_url().


The documentation for this class was generated from the following files: