Met OctoPrint kun je via een webbrowser je 3D Printer bedienen en monitoren. Je hoeft dan niet meer handmatig een SD kaartje te gebruiken om GCODE te uploaden naar je printer. Met behulp van Plugins kun je nog allerlei functionaliteit toevoegen aan OctoPrint.

Raspberry Pi

Het wordt aanbevolen om minimaal een Raspberry Pi 3 te gebruiken voor OctoPrint. Ik heb zelf een Raspberry Pi 4 2MB aangeschaft zodat alles lekker snel reageert. Volg de stappen van de site van OctoPrint om deze te installeren. Nadat je een image op de SD kaart hebt gezet moet je de file ‘octopi-wpa-supplicant.txt’ editten met notepad (niet met een andere editor) om je WiFi netwerk in te stellen.

Start nu je Raspberry Pi op en login met putty (user: pi, wachtwoord: raspberry). Run het commando:

sudo raspi-config

Verander vervolgens de settings van:

  1. Change User Password
  2. Localization Options > Timezone
  3. Network Options > Hostname

Reboot hierna de Raspberry Pi. Vervolgens kun je met de webbrowser naar OctoPrint gaan (gebruik IP-adres als URL). Doorloop hier eenmalig de setup wizard. Controleer nu in je OctoPrint Settings of er een software update is (indien je bij de update check een error krijgt dan ligt dit waarschijnlijk aan Pihole, in dat geval zet host ‘codeload.github.com’ in je white-list en restart OctoPrint).

Plugins

De volgende plugins worden over het algemeen aangeraden om te installeren:

  • Octolapse (als je Webcam gebruikt)
  • Floating Nav Bar
  • Tab Order
  • Pushover
  • NavBar Temp
  • Display Layer Progress
  • Dashboard
  • Fan Speed (manueel met deze deze URL)
  • Themify
  • Autoscroll
  • Print Time Genius
  • Octopod
  • Cost Estimation
  • Bed Level Visualizer (als je BL-Touch hebt)
  • BLTouch (als je BL-Touch hebt)

Voor Themify zijn de volgende settings erg handig om zodoende je hele window te gebruiken in je browser.



Aansluiten

Nu wordt het zaak om je Creality Ender 3 Pro printer aan te sluiten op je Raspberry Pi met OctoPrint. Zorg ervoor dat je alleen de Data lijnen van je USB printer aansluit (zie ook deze omschrijving). Hier gaat het bij de meeste mensen namelijk mis.




Je kunt dit simpel met een stukje tape oplossen door de +5V af te plakken. Wil je het echt 100% zeker oplossen dan kun je een USB dongle gebruiken.



Tevens kun je hier de 3D print voor de USB dongle vinden.

Behuizing

Ik heb zelf een behuizing geprint voor de Raspberry Pi 4 zodat ik deze mooi aan de Creality Ender 3 Pro kan bevestigen. Voor de zekerheid heb ik ook een Adjustable Fan gekocht. Om de fan alleen te laten draaien als de temperatuur van de Raspberry Pi te warm wordt heb ik de volgende omschrijving gebruikt.



Webcam

De meeste gebruikte webcam met OctoPrint is de Logitech HD Webcam C270.




Hiervoor zijn tevens erg veel 3D print beschikbaar om deze handig te bevestigen aan je Creality Ender 3 Pro printer. Normaal gesproken kost deze Logitech HD Webcam C270 ongeveer Euro 30,= maar vanwege de Corona crisis is deze erg (tot een factor 4) in prijs gestegen. Ik wacht nu even totdat deze weer een normale prijs heeft voordat ik deze aanschaf.

Auto-connect printer

Aangezien ik mijn Raspberry Pi 4 altijd aan heb staan zal de printer niet auto-connecten naar OctoPrint als je de printer aanzet. Dat kun je met de volgende stappen oplossen.

  1. Login op je Raspberry Pi met Putty en creëer hier het script: ‘/home/pi/connect_octoprint.py’ met inhoud:
    #!/home/pi/oprint/bin/python
    
    OCTOPRINT_URL = 'http://localhost/api/connection'
    API_KEY = '<jouw API-Key (zie OctoPrint Settings > API)>'
    BAUDRATE = 115200
    
    import requests
    import sys
    
    port = sys.argv[1]
    headers = {'X-Api-Key': API_KEY}
    json = {
      "command": "connect",
      "port": port,
      "baudrate": BAUDRATE,
    }
    
    r = requests.post(
            OCTOPRINT_URL,
            json=json,
            headers=headers
    )
    
    if (r.status_code == 204):
        sys.exit(0)
    else:
        print(r)
        sys.exit(1)
    
  2. Voer het volgende commando uit:
    sudo chmod +x /home/pi/connect_octoprint.py
  3. Met root permissie (gebruik ‘sudo’) creëer systemd service met naam ‘/etc/systemd/system/octoprint_connect@.service’ met inhoud:
    [Unit]
    Description=Connect printer to OctoPrint automatically
    BindsTo=dev-%i.device
    After=dev-%i.device
    
    [Service]
    Type=oneshot
    User=pi
    RemainAfterExit=yes
    ExecStart=/home/pi/connect_octoprint.py /dev/%i
  4. Voer het volgende commando uit:
    sudo systemctl daemon-reload
  5. We moeten nu ‘udev’ configureren en daarvoor heb je de ‘idVendor’ en ‘idProduct’ van je printer nodig. Gebruik hiervoor het volgende commando (met printer uit en aan):
    lsusb -v | grep -iE '(^bus|idvendor|idproduct)'
  6. Creëer (als root, dus ‘sudo’) de rule ‘/etc/udev/rules.d/3dprinter.rules’ met de volgende inhoud (verander met jouw printer ids):
    KERNEL=="tty*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", \
        TAG+="systemd", ENV{SYSTEMD_WANTS}="octoprint_connect@%k.service"
  7. Reboot je Raspberry Pi

Domoticz integratie

Aangezien je OctoPrint ook via een API kunt gebruiken, kun je OctoPrint ook eenvoudig in Domoticz integreren. Ik heb hierbij gebruik gemaakt van de informatie die ik hier heb gevonden. In onderstaand script worden 2 dummy-devices (die je zelf in Domoticz moet aanmaken) gevuld met waarden.




Aan het einde van het script kijk ik of device ‘OctoStatus’ de waarde “Operational” heeft met een “Completion” van meer dan 95% en zet dan de printer uit na 5 minuten (zodat deze goed is afgekoeld). Ik heb hiervoor de printer aangesloten op een Sonoff S20 die ik al in Domoticz had geïntegreerd.

--------------------------------------------------------------------------------
-- Octoprint
--------------------------------------------------------------------------------
-- Script to read out certain status values of OctoPrint as defined. To use
-- create two Virtual Dummy devices and define index (IDX) values:
--
-- OctoStatusIDX    = '<number>' -- type: Text
-- OctoCompleteIDX  = '<number>' -- type: Percentage
--
-- Also create user-variable in Domoticz:
--
-- Turn_Printer_Off  -- type: Integer
--------------------------------------------------------------------------------

-- Printer to turn off after completion of job
local device_printer = 'Creality Ender 3 Pro'

-- Variables
local variable_turn_printer_off  = 'Variable:Turn_Printer_Off'
local turn_printer_off           = 'Turn_Printer_Off'

-- IP address of OctPprint 
OctoIP='<IP-adres Raspberry Pi>'

-- Port of Octoprint - Default 80
OctoPort='<Port OctoPrint>'

-- OctoPrint API Key (found in Settings -> API)
OctoAPI='<OctoPrint API-key>'

-- JSON.lua path
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

-- Curl path
curl = '/usr/bin/curl'

-- IDX of your Dummy devices
OctoStatusIDX    ='<number>' -- type: Text
OctoCompleteIDX  ='<number>' -- type: Percentage

OctoPrinter='http://'..OctoIP..':'..OctoPort..'/api/printer'
OctoJob='http://'..OctoIP..':'..OctoPort..'/api/job'

-- Update specific Virtual Dummy Device in Domoticz
local function update(idx, value1)
    local cmd = idx..'|0|'..value1
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

-- Check if Raspberry Pi with ProntoPrint switched on
local function ping (OctoIP)
    ping_success=os.execute('ping -W2 -c1 '..OctoIP)
    return ping_success
end

-- Check if Printer is online?
local function online()
    DataOctoTemp = assert(io.popen(curl..' -s --max-time 8 -H "X-Api-Key: '..OctoAPI..'" "'..OctoPrinter..'"'))
    BlocOctoTemp = DataOctoTemp:read('*all')
    DataOctoTemp:close()
    JsonOctoTemp = json:decode(BlocOctoTemp)
end

-- Round floating value
local function round(num, n)
  local mult = 10^(n or 0)
  return math.floor(num * mult + 0.5) / mult
end

-- Check if value is empty
local function isempty(s)
  return s == nil or s == ''
end

commandArray = {}

-- Check if Printer is Online
local status, retval = pcall(online,10);

-- Check if Raspberry Pi is reachable
if ( ping(OctoIP) ) then

    -- Printer Online?
    if (status) then
        
        -- Obtain status via API of OctoPrint
        DataOctoTemp = assert(io.popen(curl..' -s --max-time 8 -H "X-Api-Key: '..OctoAPI..'" "'..OctoPrinter..'"'))
        BlocOctoTemp = DataOctoTemp:read('*all')
        DataOctoTemp:close()
        JsonOctoTemp = json:decode(BlocOctoTemp)

        -- Obtain current Status of Printer      
        OctoStatus   = JsonOctoTemp.state.text
        update(OctoStatusIDX, OctoStatus)

        -- Obtain status of current job via API of OctoPrint
        DataOctoTime = assert(io.popen(curl..' -s --max-time 8 -H "X-Api-Key: '..OctoAPI..'" "'..OctoJob..'"'))
        BlocOctoTime = DataOctoTime:read('*all')
        DataOctoTime:close()
        JsonOctoTime = json:decode(BlocOctoTime)

        OctoComplete = JsonOctoTime.progress.completion

        -- No Job started yet
        if isempty(OctoComplete) then 
            
            update(OctoCompleteIDX, round(0)) 

            -- Update user-variable indicating that printer should not be turned Off
            commandArray[variable_turn_printer_off] = tostring(0);        
            
        else
            
            update(OctoCompleteIDX, round(OctoComplete)) 
            
        end
            
    else      
    
        -- Printer not connected, initialize status
        update(OctoStatusIDX, "Printer not connected")
        update(OctoCompleteIDX, round(0)) 

        -- Update user-variable indicating that printer should not be turned Off
        commandArray[variable_turn_printer_off] = tostring(0);        
        
    end
else
    update(OctoStatusIDX, "Octoprint offline")
end

-- Loop through all possible changed devices
local is_operational = false
local is_complete_greater_95 = false

for deviceName,deviceValue in pairs(otherdevices) do

    if (deviceName == 'OctoStatus') then

        -- Check if printer is not printing anymore
        if (deviceValue == 'Operational') then
            
            is_operational = true        
            
        end
    
    elseif (deviceName == 'OctoComplete') then

        -- Check if printer completed a print job
        if (tonumber(deviceValue) > 95) then
            
            is_complete_greater_95 = true
            
        end
    end
end    
 
-- If printer is operational and printing percentage > 95, then job must be finished   
if ( (is_operational == true) and (is_complete_greater_95) ) then
        
    if (uservariables[turn_printer_off] == 0) then
        
        if ( otherdevices[device_printer] == 'On') then

            print("Octoprint completed 3D print, turn off printer after 5 minutes")

            -- Yes, then turn off printer after 5 minutes
            commandArray[device_printer] = 'Off AFTER 300';    -- in seconds
        end
        
        -- Update user-variable indicating that printer should be turned Off
        commandArray[variable_turn_printer_off] = tostring(1);        
        
    end
end

return commandArray

SmartPhone Apps

Er zijn ook een aantal Apps voor je SmartPhone waarmee je OctoPrint kunt monitoren/aansturen. Ik zelf zelf voor mijn iPhone de gratis OctoPod software gekozen.



Screenshots

Hieronder zie je een aantal screenshots hoe OctoPrint er bij mij nu uitziet.







Conclusie

OctoPrint is ontzettend handig en maakt het nog gemakkelijker om je 3D prints van je Creality Ender 3 Pro printer te starten en monitoren. De extra plugins en API interface maken het helemaal af. Ik kan iedereen deze software dan ook erg aanraden.