Um meinen 3D-Drucker aus der Ferne zu steuern benutze ich OctoPrint. Damit ist es möglich den Druck zu starten und zu überwachen. Dafür muss aber der angeschlossene Drucker die ganze eingeschaltet sein. Auch das Licht welches ich nachgerüstet habe würde dann die gesamte Zeit unnütz leuchten. Da das OctoPrint auf einem Raspberry Pi läuft und ich noch ein PiFace V1 Board in der Grabbelkiste liegen hatte, lag es nahe dieses zu benutzen. Auf dem Board sind zwei Relais verbaut mit denen ich den Drucker und das Licht schalten kann.

Dafür habe ich einen kleines Python Script geschrieben das die Ausgänge des PiFace steuert. Anfänglich hatte ich versucht das mit einem einzigen Script zu lösen. Das hat aber nicht funktioniert, da die im Script befindliche Initialisierungsfunktion die Ports des PiFace bei jedem Aufruf immer wieder zurückgesetzt hat. Deshalb habe ich die Funktionen aufgeteilt. Auf der einen Seite ein Server der die Textbefehle entgegennimmt, diese prüft und das PiFace ansteuert. Als zweites einen Client der die Befehle sendet. Dadurch entfällt die erneute Initialisierung der Ports.


Der Server und der Client

Der Server besteht aus nur wenigen Zeilen. Er empfängt die Daten vom Client die auf Port 50000/UDP gesendet werden und trennt diese nach PiFace Port und State auf. Danach wir überprüft ob die übergebenen Daten numerisch sind. Ist das der Fall wir nochmals auf Plausibilität geprüft und die Daten in das PiFace geschrieben.

Der Server (gpiosrv.py)

#!/usr/bin/python
# UDP Server
# Schaltet die Ausgaenge des PiFace
# Dateiname:
# Server: gpiosrv.py
# Client: gpiocli.py
#
# gpiocli.py <port>:<state>
# <port> 0-7
# <state> 0/1

import socket
import sys
import pifacedigitalio

UDP_PORT = 50000

pfd = pifacedigitalio.PiFaceDigital()
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
value = 0

try:
sock.bind(("", UDP_PORT))
while True:
try:
daten, addr = sock.recvfrom(1024)
output = daten.split(":")
port = int(output[0])
state = int(output[1])
except (ValueError, TypeError):
#Nicht Numerisch
error = 1
if (port >= 0 and port <=7 and ((state == 0) or (state == 1))):
pfd.output_pins[port].value = state
finally:
s.close()

Der Client (gpiocli.py)

#!/usr/bin/python
# UDP Client
# Dateiname: gpiocli.py
# Benutzung gpiocli.py <piface_port>:<state>

import socket
import sys

UDP_IP = "127.0.0.1"
UDP_PORT = 50000

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
nachricht = sys.argv[1]

sock.sendto(nachricht,(UDP_IP, UDP_PORT))
sock.close()

Ich habe beide Dateien unter /opt auf dem Raspberry Pi gespeichert.

Als nächstes muss man den Server starten. Zum testen ist es immer ganz gut das "&" am Ende wegzulassen. Damit läuft das Script nicht im Hintergrund und man kann sehen, ob es sich nicht mit einer Fehlermeldung verabschiedet. Wenn alles läuft sollte man es immer mit dem & am Ende starten.

python /opt/gpiosrv.py &

Um jetzt das Relais K0 auf dem PiFace einzuschalten ruft man über ein zweites Konsolenfenster die gpiocli.py wie folgt auf.

python /opt/gpiocli.py 0:1

Läuft alles zufriedenstellend kann man jetzt den Server bei jedem Systemstart automatisch mit starten lassen. Dazu trägt man den Serveraufruf "python /opt/gpiosrv.py &" in die /etc/rc.local Datei am Ende, jedoch noch vor dem "exit 0" ein.

sudo nano /etc/rc.local


Die Steuerung aus OctoPrint heraus

Um das Ganze jetzt aus OctoPrint heraus zu steuern benutze ich einmal ein Plugin und als zweites die Events die OctoPrint erzeugt. Dazu weiter unten.

Als Plugin habe ich System Command Editor aus dem Pluginmanager von OctoPrint installiert. Damit kann man sich ganz einfach zusätzliche Befehle auf unterschiedliche Button legen. Diese werden dann im der Kopf von OctoPrint unter "System herunterfahren" etc. angezeigt.

Die Schaltflächen sind wie folgt einzurichten. 

Ist alles eingerichtet, kann man über die beiden Button "Licht an" und "Licht aus" das Licht am Extruder ein oder ausschalten. ;-)


Automatische Steuerung von OctoPrint

Bei der weiteren Durchsicht des Funktionsumfangs von OctoPrint bin ich auf die Event-Steuerung gestoßen. Damit ist es möglich auf alle möglichen Events von OctoPrint zu reagieren. Das heißt in meinem Beispiel, dass das Licht bei Druckbeginn automatisch eingeschaltet und bei Druckende automatisch ausgeschaltet wird. Leider gibt es für die Administration der Events keine grafische Oberfläche. Die entsprechenden Befehle muss man in die OctoPrint Config Datei händisch auf der Linix Konsole eintragen.

Nach dem verbinden auf die Console sollte man als erstes den OctoPrint server herunterfahren und die Config-Datei ~/.octoprint/config.yaml sichern.

sudo service octoprint stop
sudo cp ~/.octoprint/config.yaml ~/

Nachdem wir nun also eine Sicherung angelegt haben können wir die Datei bearbeiten

sudo nano ~/.octoprint/config.yaml

Für mein Licht an/Licht aus Beispiel von oben habe ich folgende Zeilen der config.yaml unten angehangen. Falls der Bereich Event schon vorhanden ist, dann dort mit einfügen. Ein kompletter Befehl besteht immer aus den drei Zeilen ab "- command: "

events:
 enabled: true
 subscriptions:
 - command: python /opt/gpiocli.py 1:1
 event: PrintStarted
 type: system
 - command: python /opt/gpiocli.py 1:0
 event: PrintDone
 type: system

Ist alles gespeichert kann man den OctoPrint Server neu starten. Beim nächsten Druck sollte dann das Licht automatisch an und auch wieder ausgehen.

sudo service octoprint start

Links:

OctoPrint Homepage

OctoPrint Docs

pifacedigitalio

PiFace

Python WiKi Udp Communication

Kommentare powered by CComment