From 1c74067da09a9a23ce66227b55146af6182d747d Mon Sep 17 00:00:00 2001 From: eMAKER Date: Fri, 16 Jun 2017 02:54:27 +0100 Subject: [PATCH] =?UTF-8?q?Octoprint=20settings=20functionality=20expanded?= =?UTF-8?q?=20to=20allow=20upload=20to=20RepRapFi=E2=80=A6=20(#4028)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Octoprint settings functionality expanded to allow upload to RepRapFirmware on a Duet controller. * octoprint_host renamed to print_host to enhance code readability. Fixes #4022 --- lib/Slic3r/GUI/Plater.pm | 84 ++++++++++++++++++++++---------- lib/Slic3r/GUI/PresetEditor.pm | 33 ++++++++----- xs/src/libslic3r/PrintConfig.cpp | 19 ++++++-- xs/src/libslic3r/PrintConfig.hpp | 17 ++++++- 4 files changed, 108 insertions(+), 45 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 21078818d..1139251c4 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -49,7 +49,7 @@ sub new { my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $self->{config} = Slic3r::Config->new_from_defaults(qw( bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width - serial_port serial_speed octoprint_host octoprint_apikey shortcuts filament_colour + serial_port serial_speed host_type print_host octoprint_apikey shortcuts filament_colour )); $self->{model} = Slic3r::Model->new; $self->{print} = Slic3r::Print->new; @@ -1410,8 +1410,8 @@ sub config_changed { $self->{btn_print}->Hide; } $self->Layout; - } elsif ($opt_key eq 'octoprint_host') { - if ($config->get('octoprint_host')) { + } elsif ($opt_key eq 'print_host') { + if ($config->get('print_host')) { $self->{btn_send_gcode}->Show; } else { $self->{btn_send_gcode}->Hide; @@ -1731,7 +1731,7 @@ sub on_export_completed { $message = "File added to print queue"; $do_print = 1; } elsif ($self->{send_gcode_file}) { - $message = "Sending G-code file to the OctoPrint server..."; + $message = "Sending G-code file to the " . $self->{config}->host_type . " server..."; $send_gcode = 1; } else { $message = "G-code file exported to " . $self->{export_gcode_output_file}; @@ -1804,23 +1804,33 @@ sub prepare_send { my $ua = LWP::UserAgent->new; $ua->timeout(5); - my $res = $ua->get( - "http://" . $self->{config}->octoprint_host . "/api/files/local", - 'X-Api-Key' => $self->{config}->octoprint_apikey, - ); + my $res; + if ($self->{config}->print_host) { + if($self->{config}->host_type eq 'octoprint'){ + $res = $ua->get( + "http://" . $self->{config}->print_host . "/api/files/local", + 'X-Api-Key' => $self->{config}->octoprint_apikey, + ); + }else { + $res = $ua->get( + "http://" . $self->{config}->print_host . "/rr_files", + ); + } + } $progress->Destroy; if ($res->is_success) { - if ($res->decoded_content =~ /"name":\s*"\Q$filename\E"/) { + my $searchterm = ($self->{config}->host_type eq 'octoprint') ? '/"name":\s*"\Q$filename\E"/' : '"'.$filename.'"'; + if ($res->decoded_content =~ $searchterm) { my $dialog = Wx::MessageDialog->new($self, "It looks like a file with the same name already exists in the server. " . "Shall I overwrite it?", - 'OctoPrint', wxICON_WARNING | wxYES | wxNO); + $self->{config}->host_type, wxICON_WARNING | wxYES | wxNO); if ($dialog->ShowModal() == wxID_NO) { return; } } } else { - my $message = "Error while connecting to the OctoPrint server: " . $res->status_line; + my $message = "Error while connecting to the " . $self->{config}->host_type . " server: " . $res->status_line; Slic3r::GUI::show_error($self, $message); return; } @@ -1839,24 +1849,44 @@ sub send_gcode { $ua->timeout(180); my $path = Slic3r::encode_path($self->{send_gcode_file}); - my $res = $ua->post( - "http://" . $self->{config}->octoprint_host . "/api/files/local", - Content_Type => 'form-data', - 'X-Api-Key' => $self->{config}->octoprint_apikey, - Content => [ - # OctoPrint doesn't like Windows paths so we use basename() - # Also, since we need to read from filesystem we process it through encode_path() - file => [ $path, basename($path) ], - print => $self->{send_gcode_file_print} ? 1 : 0, - ], - ); - + my $filename = basename($self->{print}->output_filepath($main::opt{output} // '')); + my $res; + if($self->{config}->print_host){ + if($self->{config}->host_type eq 'Octoprint'){ + $res = $ua->post( + "http://" . $self->{config}->print_host . "/api/files/local", + Content_Type => 'form-data', + 'X-Api-Key' => $self->{config}->octoprint_apikey, + Content => [ + # OctoPrint doesn't like Windows paths so we use basename() + # Also, since we need to read from filesystem we process it through encode_path() + file => [ $path, basename($path) ], + print => $self->{send_gcode_file_print} ? 1 : 0, + ], + ); + }else{ + $res = $ua->post( + "http://" . $self->{config}->print_host . "/rr_upload?name=0:/gcodes/" . basename($path) . "&time=1234567890123", + Content_Type => 'form-data', + Content => [ + # OctoPrint doesn't like Windows paths so we use basename() + # Also, since we need to read from filesystem we process it through encode_path() + file => [ $path, basename($path) ], + ], + ); + if ($self->{send_gcode_file_print}) { + $res = $ua->get( + "http://" . $self->{config}->print_host . "/rr_gcode?gcode=M32%20" . basename($path), + ); + } + } + } $self->statusbar->StopBusy; if ($res->is_success) { - $self->statusbar->SetStatusText("G-code file successfully uploaded to the OctoPrint server"); + $self->statusbar->SetStatusText("G-code file successfully uploaded to the " . $self->{config}->host_type . " server"); } else { - my $message = "Error while uploading to the OctoPrint server: " . $res->status_line; + my $message = "Error while uploading to the " . $self->{config}->host_type . " server: " . $res->status_line; Slic3r::GUI::show_error($self, $message); $self->statusbar->SetStatusText($message); } @@ -2605,7 +2635,7 @@ use base 'Wx::Dialog'; sub new { my $class = shift; my ($parent, $filename) = @_; - my $self = $class->SUPER::new($parent, -1, "Send to OctoPrint", wxDefaultPosition, + my $self = $class->SUPER::new($parent, -1, "Send to Server", wxDefaultPosition, [400, -1]); $self->{filename} = $filename; @@ -2614,7 +2644,7 @@ sub new { my $optgroup; $optgroup = Slic3r::GUI::OptionsGroup->new( parent => $self, - title => 'Send to OctoPrint', + title => 'Send to Server', on_change => sub { my ($opt_id) = @_; diff --git a/lib/Slic3r/GUI/PresetEditor.pm b/lib/Slic3r/GUI/PresetEditor.pm index 74c64420e..d00deb4bd 100644 --- a/lib/Slic3r/GUI/PresetEditor.pm +++ b/lib/Slic3r/GUI/PresetEditor.pm @@ -1194,7 +1194,7 @@ sub options { bed_shape z_offset z_steps_per_mm has_heatbed gcode_flavor use_relative_e_distances serial_port serial_speed - octoprint_host octoprint_apikey + host_type print_host octoprint_apikey use_firmware_retraction pressure_advance vibration_limit use_volumetric_e start_gcode end_gcode before_layer_gcode layer_gcode toolchange_gcode between_objects_gcode @@ -1296,9 +1296,11 @@ sub build { $optgroup->append_line($line); } { - my $optgroup = $page->new_optgroup('OctoPrint upload'); + my $optgroup = $page->new_optgroup('Print server upload'); + + $optgroup->append_single_option_line('host_type'); - my $host_line = $optgroup->create_single_option_line('octoprint_host'); + my $host_line = $optgroup->create_single_option_line('print_host'); $host_line->append_button("Browse…", "zoom.png", sub { # look for devices my $entries; @@ -1311,19 +1313,19 @@ sub build { my $dlg = Slic3r::GUI::BonjourBrowser->new($self, $entries); if ($dlg->ShowModal == wxID_OK) { my $value = $dlg->GetValue . ":" . $dlg->GetPort; - $self->config->set('octoprint_host', $value); - $self->_on_value_change('octoprint_host'); + $self->config->set('print_host', $value); + $self->_on_value_change('print_host'); } } else { Wx::MessageDialog->new($self, 'No Bonjour device found', 'Device Browser', wxOK | wxICON_INFORMATION)->ShowModal; } - }, undef, !eval "use Net::Bonjour; 1"); + }, \$self->{print_host_browse_btn}, !eval "use Net::Bonjour; 1"); $host_line->append_button("Test", "wrench.png", sub { my $ua = LWP::UserAgent->new; $ua->timeout(10); my $res = $ua->get( - "http://" . $self->config->octoprint_host . "/api/version", + "http://" . $self->config->print_host . "/api/version", 'X-Api-Key' => $self->config->octoprint_apikey, ); if ($res->is_success) { @@ -1333,7 +1335,7 @@ sub build { "I wasn't able to connect to OctoPrint (" . $res->status_line . "). " . "Check hostname and OctoPrint version (at least 1.1.0 is required)."); } - }, \$self->{octoprint_host_test_btn}); + }, \$self->{print_host_test_btn}); $optgroup->append_line($host_line); $optgroup->append_single_option_line('octoprint_apikey'); } @@ -1534,12 +1536,17 @@ sub _update { $self->{serial_test_btn}->Disable; } } - if ($config->get('octoprint_host') && eval "use LWP::UserAgent; 1") { - $self->{octoprint_host_test_btn}->Enable; - } else { - $self->{octoprint_host_test_btn}->Disable; + if (($config->get('host_type') eq 'octoprint')) { + $self->{print_host_browse_btn}->Enable; + }else{ + $self->{print_host_browse_btn}->Disable; } - $self->get_field('octoprint_apikey')->toggle($config->get('octoprint_host')); + if (($config->get('host_type') eq 'octoprint') && eval "use LWP::UserAgent; 1") { + $self->{print_host_test_btn}->Enable; + } else { + $self->{print_host_test_btn}->Disable; + } + $self->get_field('octoprint_apikey')->toggle($config->get('print_host')); my $have_multiple_extruders = $self->{extruders_count} > 1; $self->get_field('toolchange_gcode')->toggle($have_multiple_extruders); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index d9449f1a9..cc95d38b6 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -629,6 +629,17 @@ PrintConfigDef::PrintConfigDef() def->enum_labels.push_back("No extrusion"); def->default_value = new ConfigOptionEnum(gcfRepRap); + def = this->add("host_type", coEnum); + def->label = "Host type"; + def->tooltip = "Select Octoprint or Duet to connect to your machine via LAN"; + def->cli = "host-type=s"; + def->enum_keys_map = ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("octoprint"); + def->enum_values.push_back("duet"); + def->enum_labels.push_back("Octoprint"); + def->enum_labels.push_back("Duet"); + def->default_value = new ConfigOptionEnum(htOctoprint); + def = this->add("infill_acceleration", coFloat); def->label = "Infill"; def->category = "Speed > Acceleration"; @@ -818,9 +829,9 @@ PrintConfigDef::PrintConfigDef() def->cli = "octoprint-apikey=s"; def->default_value = new ConfigOptionString(""); - def = this->add("octoprint_host", coString); + def = this->add("print_host", coString); def->label = "Host or IP"; - def->tooltip = "Slic3r can upload G-code files to OctoPrint. This field should contain the hostname or IP address of the OctoPrint instance."; + def->tooltip = "Slic3r can upload G-code files to an Octoprint/Duet server. This field should contain the hostname or IP address of the server instance."; def->cli = "octoprint-host=s"; def->default_value = new ConfigOptionString(""); @@ -1694,6 +1705,8 @@ PrintConfigBase::_handle_legacy(t_config_option_key &opt_key, std::string &value std::ostringstream oss; oss << "0x0," << p.value.x << "x0," << p.value.x << "x" << p.value.y << ",0x" << p.value.y; value = oss.str(); + } else if (opt_key == "octoprint_host" && !value.empty()) { + opt_key = "print_host"; } else if ((opt_key == "perimeter_acceleration" && value == "25") || (opt_key == "infill_acceleration" && value == "50")) { /* For historical reasons, the world's full of configs having these very low values; @@ -1716,7 +1729,7 @@ PrintConfigBase::_handle_legacy(t_config_option_key &opt_key, std::string &value || opt_key == "scale" || opt_key == "duplicate_grid" || opt_key == "start_perimeters_at_concave_points" || opt_key == "start_perimeters_at_non_overhang" || opt_key == "randomize_start" - || opt_key == "seal_position" || opt_key == "bed_size" + || opt_key == "seal_position" || opt_key == "bed_size" || opt_key == "octoprint_host" || opt_key == "print_center" || opt_key == "g0" || opt_key == "threads") { opt_key = ""; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index ae4a46fbf..91e463f3a 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -29,6 +29,10 @@ enum GCodeFlavor { gcfRepRap, gcfTeacup, gcfMakerWare, gcfSailfish, gcfMach3, gcfMachinekit, gcfNoExtrusion, gcfSmoothie, gcfRepetier, }; +enum HostType { + htOctoprint, htDuet, +}; + enum InfillPattern { ipRectilinear, ipGrid, ipAlignedRectilinear, ipTriangles, ipStars, ipCubic, @@ -58,6 +62,13 @@ template<> inline t_config_enum_values ConfigOptionEnum::get_enum_v return keys_map; } +template<> inline t_config_enum_values ConfigOptionEnum::get_enum_values() { + t_config_enum_values keys_map; + keys_map["octoprint"] = htOctoprint; + keys_map["duet"] = htDuet; + return keys_map; +} + template<> inline t_config_enum_values ConfigOptionEnum::get_enum_values() { t_config_enum_values keys_map; keys_map["rectilinear"] = ipRectilinear; @@ -511,7 +522,8 @@ class PrintConfig : public GCodeConfig class HostConfig : public virtual StaticPrintConfig { public: - ConfigOptionString octoprint_host; + ConfigOptionEnum host_type; + ConfigOptionString print_host; ConfigOptionString octoprint_apikey; ConfigOptionString serial_port; ConfigOptionInt serial_speed; @@ -522,7 +534,8 @@ class HostConfig : public virtual StaticPrintConfig } virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { - OPT_PTR(octoprint_host); + OPT_PTR(host_type); + OPT_PTR(print_host); OPT_PTR(octoprint_apikey); OPT_PTR(serial_port); OPT_PTR(serial_speed);