Slic3r PE 'Send to printer'?



  • Hi
    Has anybody manged to 'send to printer' from Slic3r Prusa Edition?



  • No, sadly. I don't think it's supported at the moment. There is a plugin for Cura to send directly to the Duet though.



  • I use the development version from GitHub, but if you're handy with perl, they're not too far diverged and you don't need to support OctoPrint you can probably just hardcode the changes. This part is all perl so there is no compiling, just hack it and see if it works 🙂

    The file is Plater.pm, on the Mac this is in Contents/MacOS/local-lib/lib/perl5/Slic3r/GUI/Plater.pm in the Application bundle.
    The routine is send_gcode(), find the parts that match under 'if($self->{config}->host_type eq 'octoprint')' and replace them with the parts under 'else'.

    [[Perl]]
    sub send_gcode {
        my ($self) = @_;
    
        $self->statusbar->StartBusy;
    
        my $ua = LWP::UserAgent->new;
        $ua->timeout(180);
    
        my $path = Slic3r::encode_path($self->{send_gcode_file});
        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{
                # slurp the file we would send into a string - should be someplace to reference this but could not find it?
                local $/=undef;
                open (my $gch,$path);
                my $gcode=<$gch>;
                close($gch);
    
                # get the time string            
                my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
                my $t = sprintf("%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec);
    
                my $req = HTTP::Request->new(POST => "http://" . $self->{config}->print_host . "/rr_upload?name=0:/gcodes/" . basename($path) . "&time=$t",);
                $req->content( $gcode );
                $res = $ua->request($req);
    
                if ($res->is_success) {
                    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 " . $self->{config}->host_type . " server");
        } else {
            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);
        }
    }
    
    

    There may be something to disable 'send to printer' unless the OctoPrint API test has worked, sorry you're on your own to find and disable that.



  • Thanks for that as a start… Should be able look at it soon.... I read a thread here that slic3r supported duet again but that is maybe not in the PE branch. If I get the Perl script to work I'll post it....



  • Slic3r has it, Slic3rPE does not (yet?).
    What are the main differences between the two anyway? Apart from PE being developed towards the Prusa machines.



  • I doubt that this feature will be integrated into the prusa edition - the main audience of the software are users of prusa printers, which don't use Duet boards. 😕



  • the PE version has a lot of improvements and has a higher development rate…so I would like to stick with that...but as said the perl script is an option i will investigate



  • I thought so aswell, but Slic3r is actually updated regularly. Last update is from 26th feb.



  • OK I found a solution. It is a bit of a hack where I use the ip address /url to determine whether to send it to an octopi or a duet
    my octopi has address octopi.local
    my duet has address hevo.local
    I needed to do this since the PE version doesn't have the member variables that the orginal slic3r has compiled in c++. And there is no host_type as in the code above. And I have no urge to compile it all ..
    it is a hack an I will need to change it for every new releae..however I'm so use with my octopi just to hit 'send to printer', that it is worth it for me.
    for windows you will need to change the file (1.39 as example)
    C:\Slic3r-1.39.1-beta1-prusa3d-win64-full-201802221543\Slic3r-1.39.1-beta1-prusa3d-win64-full-201802221543\lib\Slic3r\GUI\Plater.pm
    sub send_gcode at line 1459 to

    [[perl]]
    sub send_gcode {
        my ($self) = @_;
    
        $self->statusbar->StartBusy;
    
        my $ua = LWP::UserAgent->new;
        $ua->timeout(180);
        my $res;
         if($self->{config}->octoprint_host eq 'octopi.local'){
    		$res = $ua->post(
            "http://" . $self->{config}->octoprint_host . "/api/files/local",
            Content_Type => 'form-data',
            'X-Api-Key' => $self->{config}->octoprint_apikey,
            Content => [
                file => [ 
                    # On Windows, the path has to be encoded in local code page for perl to be able to open it.
                    Slic3r::encode_path($self->{send_gcode_file}),
                    # Remove the UTF-8 flag from the perl string, so the LWP::UserAgent can insert 
                    # the UTF-8 encoded string into the request as a byte stream.
                    Slic3r::path_to_filename_raw($self->{send_gcode_file})
                ],
                print => $self->{send_gcode_file_print} ? 1 : 0,
            ],
        );
        }
    	else{
             # slurp the file we would send into a string - should be someplace to reference this but could not find it?
             local $/=undef;
             open (my $gch,Slic3r::encode_path($self->{send_gcode_file}));
             my $gcode=<$gch>;
             close($gch);
    #
             # get the time string            
             my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
             my $t = sprintf("%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec);
    
             my $req = HTTP::Request->new(POST => "http://" . $self->{config}->octoprint_host . "/rr_upload?name=0:/gcodes/" . basename(Slic3r::encode_path($self->{send_gcode_file})) . "&time=$t",);
             $req->content( $gcode );
             $res = $ua->request($req);
    
             if ($res->is_success) {
                 if ($self->{send_gcode_file_print}) {
                     $res = $ua->get(
                         "http://" . $self->{config}->octoprint_host . "/rr_gcode?gcode=M32%20" . basename(Slic3r::encode_path($self->{send_gcode_file})),
                     );
                 }
             }
         }
        $self->statusbar->StopBusy;
    
        if ($res->is_success) {
            $self->statusbar->SetStatusText("G-code file successfully uploaded to the OctoPrint server");
        } else {
            my $message = "Error while uploading to the OctoPrint server: " . $res->status_line;
            Slic3r::GUI::show_error($self, $message);
            $self->statusbar->SetStatusText($message);
        }
    }
    
    


  • I wonder if it would be possible to just do a pull request for Slic3r PE to take the Duet connectivity from the main Slic3r dev branch that already has it working.



  • It seems prusa hasn't merged that code from slic3r. I checked the source code of 1.39 and didn't find the changes in PE



  • @AlexLin:

    OK I found a solution. It is a bit of a hack where I use the ip address /url to determine whether to send it to an octopi or a duet
    my octopi has address octopi.local
    my duet has address hevo.local
    I needed to do this since the PE version doesn't have the member variables that the orginal slic3r has compiled in c++. And there is no host_type as in the code above. And I have no urge to compile it all ..
    it is a hack an I will need to change it for every new releae..however I'm so use with my octopi just to hit 'send to printer', that it is worth it for me.
    for windows you will need to change the file (1.39 as example)
    C:\Slic3r-1.39.1-beta1-prusa3d-win64-full-201802221543\Slic3r-1.39.1-beta1-prusa3d-win64-full-201802221543\lib\Slic3r\GUI\Plater.pm
    sub send_gcode at line 1459 to

    [[perl]]
    sub send_gcode {
        my ($self) = @_;
        
        $self->statusbar->StartBusy;
        
        my $ua = LWP::UserAgent->new;
        $ua->timeout(180);
        my $res;
         if($self->{config}->octoprint_host eq 'octopi.local'){
    		$res = $ua->post(
            "http://" . $self->{config}->octoprint_host . "/api/files/local",
            Content_Type => 'form-data',
            'X-Api-Key' => $self->{config}->octoprint_apikey,
            Content => [
                file => [ 
                    # On Windows, the path has to be encoded in local code page for perl to be able to open it.
                    Slic3r::encode_path($self->{send_gcode_file}),
                    # Remove the UTF-8 flag from the perl string, so the LWP::UserAgent can insert 
                    # the UTF-8 encoded string into the request as a byte stream.
                    Slic3r::path_to_filename_raw($self->{send_gcode_file})
                ],
                print => $self->{send_gcode_file_print} ? 1 : 0,
            ],
        );
        }
    	else{
             # slurp the file we would send into a string - should be someplace to reference this but could not find it?
             local $/=undef;
             open (my $gch,Slic3r::encode_path($self->{send_gcode_file}));
             my $gcode=<$gch>;
             close($gch);
    #
             # get the time string            
             my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
             my $t = sprintf("%4d-%02d-%02dT%02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec);
    
             my $req = HTTP::Request->new(POST => "http://" . $self->{config}->octoprint_host . "/rr_upload?name=0:/gcodes/" . basename(Slic3r::encode_path($self->{send_gcode_file})) . "&time=$t",);
             $req->content( $gcode );
             $res = $ua->request($req);
    
             if ($res->is_success) {
                 if ($self->{send_gcode_file_print}) {
                     $res = $ua->get(
                         "http://" . $self->{config}->octoprint_host . "/rr_gcode?gcode=M32%20" . basename(Slic3r::encode_path($self->{send_gcode_file})),
                     );
                 }
             }
         }
        $self->statusbar->StopBusy;
        
        if ($res->is_success) {
            $self->statusbar->SetStatusText("G-code file successfully uploaded to the OctoPrint server");
        } else {
            my $message = "Error while uploading to the OctoPrint server: " . $res->status_line;
            Slic3r::GUI::show_error($self, $message);
            $self->statusbar->SetStatusText($message);
        }
    }
    
    

    Thanks, that worked for me on 1.38.5.



  • nice , somebody else can use it;-)



  • @Phaedrux:

    I wonder if it would be possible to just do a pull request for Slic3r PE to take the Duet connectivity from the main Slic3r dev branch that already has it working.

    It looks like it is this commit https://github.com/alexrj/Slic3r/commit/1c74067da09a9a23ce66227b55146af6182d747d, it should be possible to pull it in and build your 'own' slic3r version, but I guess that these are not the only changes needed. 5fbb245b9790193b6924735fd985dc3cd2350ee6 and 13f121e3d952cca33b1ee5fdd73c12d85bf54d0e also mention the duet.

    Edit: As I said before, I doubt that this would get accepted 😕



  • @AlexLin:

    OK I found a solution. It is a bit of a hack where I use the ip address /url to determine whether to send it to an octopi or a duet

    Nice work, well done. (in lieu of a 'like' button for an individual post) 🙂



  • I don't think prusa will accept a pull request for this issue at the moment.
    On github i found the following open issue https://github.com/prusa3d/Slic3r/issues/695, seems they will do some refactoring.

    Today they committed a change which seems to be part of the refactoring.
    https://github.com/prusa3d/Slic3r/commit/4a90ab1f6a1390df4ce332b342536ee61db6ebfd


 

Looks like your connection to Duet3D was lost, please wait while we try to reconnect.