Dialog-Tutorial

Wenn du eine druckergesteuerte Anzeige ersetzen möchtest, möchtest du vielleicht einige Dialoge anzeigen, die durch bestimmte Aktionen oder Druckerreaktionen ausgelöst werden. Zu diesem Zweck unterstützt der Server einige Serverbefehle, die einen Dialog auf dem Touchscreen, der normalen Benutzeroberfläche und dem Repetier-Server Monitor anzeigen, wenn der Drucker aktiv ist.

Die gleichen Dialoge werden auch verwendet, wenn die Firmware die Host-Eingabeaufforderungen unterstützt. In diesem Fall werden die von der Firmware generierten Dialoge auf die gleiche Weise angezeigt. Dies geschieht jedoch automatisch, so dass wir dies in diesem Tutorial ignorieren und uns auf die Dialoge konzentrieren, die durch eine spezielle Druckerkonfiguration erzeugt werden.

Grundlegende Dialoge

Der Server unterstützt 3 Standarddialoge, die lediglich eine Meldung anzeigen – Info-, Warn- und Fehlerdialoge. Um sie zu erstellen, füge einfach den Befehl wie folgt hinzu:

@info Text einer Nachricht
@warning Einige Warnhinweise
@error Einige Fehlertexte

Da du nun weißt, wie du diese anzeigen kannst, stellt sich die Frage, wo du sie einfügen kannst. Du kannst sie zwar überall einfügen, aber sie sollten natürlich nur erscheinen, wenn es einen Grund dafür gibt. Im generierten G-Code kannst du an bestimmten Stellen eine Info einfügen, z. B. eine Warnung, dass du bald xy ausführen musst, oder vor einem @pause-Befehl, um den Benutzer darüber zu informieren, warum pausiert wird.

Wahrscheinlicher ist, dass du willst, dass eine Druckeraktion eine Meldung auslöst. Daher ist es nun an der Zeit, die erweiterten Einstellungen auf der Registerkarte Druckereinstellungen- G-Codes kennenzulernen. Es gibt eine Unterregisterkarte namens Antwort auf Ereignis, die du benötigst. Nehmen wir an, du hast einen Auslöser zu deinem Drucker hinzugefügt, der erkennt, wenn die Spule nur noch 10 % Kapazität hat. Wenn dieser Wert erreicht wird, schreibt die Firmware einmal „filament_low“. Wir wollen eine Warnung erhalten, wenn dies geschieht, ohne ständig die Konsole zu beobachten.

Du fügst also ein Ereignis hinzu – der Ereignisname darf keine Leerzeichen enthalten! Es handelt sich um eine Nachricht, die an alle angeschlossenen Schnittstellen gesendet wird, so dass du damit auch andere Funktionen auslösen kannst. In diesem Fall ist es nicht relevant.

Als nächstes folgt der reguläre Ausdruck, der mit der Ausgabe übereinstimmen soll. In unserem Fall ist der Ausdruck „^filament_low$“. Das ^ bedeutet, dass die Zeile mit diesem Ausdruck beginnen muss. Das $ kennzeichnet das Ende der Zeile. Es werden also nur Zeilen gefunden, die genau diesen Begriff enthalten. Wenn du diese Zeichen weglässt, würde jede Zeile, die irgendwo den Text „filament_low“ enthält, passen. Wenn du dich nicht sicher bist, empfehle ich dir, deinen Ausdruck vorab mit einem Online-Tool wie https://regex101.com/ zu testen. Wenn du mit regulären Ausdrücken nicht vertraut sind, gibt es viele Tutorials oder frage einfach Wikipedia.

Der letzte Block ist Auszuführender G-Code. Hier geben wir unsere Warnung ein:

@warning Wenig Filament. Stelle sicher, dass du Ersatz hast

Speichere nun die neuen Einstellungen und versuche, sie auszulösen. Du solltest dann die Warnung sehen.

Dialoge

Wenn du etwas Interaktivität benötigst, musst du Server-Dialoge verwenden. Diese funktionieren genauso wie die Host-Eingabeaufforderung-Unterstützung, die einige Firmwares anbieten, nur dass sie vollständig vom Server verwaltet werden. Zuerst erstelle den Dialog. Hier ein einfaches Beispiel zum Homen, bei der du auswählen kannst, welche Achse du homen willst:

@dialogStart "Wähle die Achse zum Homen" "Home"
@dialogButton All "G28"
@dialogButton X "G28 X0"
@dialogButton Y "G28 Y0"
@dialogButton Z "G28 Z0"
@dialogButton Abbrechen
@dialogShow

Wie funktioniert das also? Mit @dialogStart leitest du die Erstellung eines Dialogfeldes ein. Der erste Parameter ist die Meldung im Dialog und der zweite der Headertext. Wenn der Text Leerzeichen enthält, setze ihn in doppelte Anführungszeichen, wie im Beispiel gezeigt.

Der nächste Schritt ist die Definition der Schaltflächen. Es gibt keine Begrenzung, aber zu viele sehen vielleicht nicht so schön aus. Sie benötigen wiederum zwei Befehle. Der erste ist der Text der Schaltfläche und der zweite ist der auszuführende G-Code. Setze ihn in Anführungszeichen und trenne die Befehle mit \n.

Der letzte Schritt ist der Aufruf von @dialogShow, der das Dialogfeld schließlich allen Benutzern zeigt, die sich auf der Druckerschnittstelle befinden. Wenn du dich in einem globalen Fenster befindest, wirst du den Dialog erst sehen, wenn du zum Drucker wechselst. Im Repetier-Server Monitor Dashboard siehst du ein Warnsymbol, wenn Dialoge von Druckern verfügbar sind.

Der Benutzer kann nun den Dialog verschieben, indem er ihn an der Kopfzeile zieht (außer auf der Touch-Oberfläche), und eine der Schaltflächen auswählen. Jede Auswahl einer Schaltfläche schließt den Dialog für alle Benutzer und führt den mit dieser Schaltfläche verbundenen G-Code aus. Wenn eine Schaltfläche keinen G-Code hat, wie die Schaltfläche „Abbrechen“ in diesem Beispiel, wird nur der Dialog geschlossen.

Die beiden typischen Orte sind in Druckereinstellungen G-Codes  Schnellbefehle oder Assistenten. Hier kannst du sie verwenden, um komplexere G-Code-Sequenzen zu definieren.

Im folgenden Beispiel wird das Skript für die manuelle Bettnivellierung erläutert:

Der Ablauf dieses Skripts ist in 4 Schritte unterteilt:

  • Eröffnung eines Dialogs
  • Identifizieren des Druckertyps
  • Berechnen der Position
  • Anfahren der berechneten Position

Um diese Schritte besser strukturieren zu können, erstellen wir Funktionen. Mit Funktionen kannst du bestimmte Befehle bündeln und mit einem Befehl verfügbar machen.

Zunächst solltest du prüfen, ob das Druckbett frei von Gegenständen ist, denn der Drucker muss homen.

Zu diesem Zweck wird ein Dialog eingerichtet:

@dialogStart "Dieser Assistent ist für die manuelle Bettnivellierung gedacht. Er bietet Tasten, um schnell zu den Rändern und zur Mitte zu fahren. Am Anfang wird es homen, so stelle bitte sicher, dass das Bett frei von Hindernissen ist." "Manuelle Bettnivellierung"
@dialogIcon '<svg version="1.1" viewBox="-10 0 1011 1000"> <path fill="currentColor" d="M494.27 425.45c41.6104 33.8623 68.2715 54.5059 88.3301 102.375c24.0908 57.4873 18.9805 92.1377 18.25 155.138l-116.069 -0. 788086c0.729492 -44.0996 8.93066 -57.5654 -6.57031 -96.8623c-14.5996 -37.0127 -32.8496 -49.6123 -60.5898 -77. 9629zM2.91016 800.85l713.939 -787.5l81.7607 85.0508l-534.36 581.175h726.05v121.274h-987.39z"></path></svg>'
@dialogButton "Druckbett ist frei - Start" "@call MBLStart"
@dialogButton "Abbrechen"
@dialogShow

In diesem Abschnitt wird ein Dialog mit den Serverbefehlen @dialogStart und @dialogShow erstellt. Zwischen diesen Befehlen können Elemente gesetzt werden. In diesem Fall wird eine Schaltfläche hinzugefügt, die den Serverbefehl @call MBLStart ausführt, der die benannte Funktion MBLStart. ausführt.

Die Funktion MBLStart prüft dann, welches Druckermodell verwendet wird, da Deltadrucker anders nivelliert werden als karthesische Drucker. Dies kann leicht überprüft werden, da wir wissen, welche Druckbettform jedes Gerät hat. Wir machen diese Unterscheidung mit einer Bedingung.

@func MBLStart
G28
@if {{config.bed_shape == "circle"}}
@call MBLDelta
@else
@call MBLCartesian
@endif
@endfunc

Innerhalb von doppelten geschweiften Klammern kannst du Ausdrücke mit Variablen und mathematischen Operatoren schreiben. Schau in der Anleitung unter Computed expressions für weitere Details. Der Serverbefehl wird mit dem ausgewerteten Ausdruck ausgeführt. Hier in der if-Bedingung vergleichen wir die Variable bed_shape mit dem Wort circle. Das Ergebnis ist 1 oder 0. Diese Variable kann als Werte „circle“, „rectangle“ und „belt“ haben. Für „circle“ wird die Funktion MBLDelta aufgerufen, ansonsten (else) die Funktion MBLCartesian.

In diesem Beispiel gehen wir davon aus, dass die Maschine ein kartesischer Drucker ist. Die folgende Funktion MBLCartesian sieht wie folgt aus:

@func MBLCartesian
@set local.middleX {{(config.bed_x_min + config.bed_x_max) / 2}}
@set local.middleY {{(config.bed_y_min + config.bed_y_max) / 2}}
@dialogStart "Offset X und Y sind die Abstände der Punkte zur Bettkante. Wenn du mit einem Blatt Papier misst, solltest du für Z Höhe 0 nivellieren. Wenn du einen Block mit bekannter Höhe hast, den du zwischen Bett und Düse schiebst, gib stattdessen die Objekthöhe ein. Bei Z-Hop hebt der Drucker den Kopf an, wenn er sich zwischen den Punkten bewegt." "Manuelle Bettnivellierung"
@dialogIcon '<svg version="1.1" viewBox="-10 0 1011 1000"> <path fill="currentColor" d="M494.27 425.45c41.6104 33.8623 68.2715 54.5059 88.3301 102.375c24.0908 57.4873 18.9805 92.1377 18.25 155.138l-116.069 -0.788086c0.729492 -44.0996 8.93066 -57.5654 -6.57031 -96.8623c-14.5996 -37.0127 -32.8496 -49.6123 -60.5898 -77.9629zM2.91016 800.85l713.939 -787.5l81.7607 85.0508l-534.36 581.175h726.05v121.274h-987.39z"></path></svg>'
@dialogInputDouble "Offset X [mm]" perm.manBedLevXoffset default({{get("perm","manBedLevXoffset","20")}}) min(0) max({{local.middleX}})
@dialogInputDouble "Offset Y [mm]" perm.manBedLevYoffset default({{get("perm","manBedLevYoffset","20")}}) min(0) max({{local.middleY}})
@dialogInputDouble "Messe Z bei [mm]" perm.manBedLevZoffset default({{get("perm","manBedLevZoffset","0")}}) min(0) max({{config.move_z_max}})
@dialogInputDouble "Z-Hop [mm]" perm.manBedLevZhop default({{get("perm","manBedLevZhop","5")}}) min(0) max({{config.move_z_max}})
@dialogButton "Oben-Links" "@call MBLDriveTo {{config.bed_x_min + perm.manBedLevXoffset}} {{config.bed_y_max - perm.manBedLevYoffset}}"
@dialogButton "Oben-Rechts" "@call MBLDriveTo {{config.bed_x_max - perm.manBedLevXoffset}} {{config.bed_y_max - perm.manBedLevYoffset}}"
@dialogButton "Mitte" "@call MBLDriveTo {{(config.bed_x_min + config.bed_x_max) / 2}} {{(config.bed_y_min + config.bed_y_max) / 2}}"
@dialogButton "Unten-Links" "@call MBLDriveTo {{config.bed_x_min + perm.manBedLevXoffset}} {{config.bed_y_min + perm.manBedLevYoffset}}"
@dialogButton "Unten-Rechts" "@call MBLDriveTo {{config.bed_x_max - perm.manBedLevXoffset}} {{config.bed_y_min + perm.manBedLevYoffset}}"
@dialogButton "Fertig"
@dialogShow
@endfunc

Hier werden 2 neue Variablen erstellt: local.middleX und local.middleY. Der local Bereich definiert Variablen, auf die nur innerhalb der definierenden Funktion zugegriffen werden kann und die abgerufen werden können.

Hier wurden die folgenden Eingabefelder definiert:

  • Offset X [mm] – speichert den Wert in der Variable perm.manBedLevXoffset
  • Offset Y [mm] – speichert den Wert in der Variable perm.manBedLevYoffset
  • Messe Z bei [mm] -speichert den Wert in der Variable perm.manBedLevZoffset
  • Z-Hop [mm] – speichert den Wert in der Variable perm.manBedLevZhop

Der perm-Bereich ist ein Bereich, in dem Variablen dauerhaft gespeichert werden können, sie existieren sogar noch nach einem Server-Neustart. Wir machen das, weil wir versuchen, die Variablen in den einzelnen Eingabefeldern als Standardwerte abzurufen, damit die zuletzt eingegebenen Werte wieder vorgeschlagen werden. Der angezeigte Standardwert wird mit dem Parameter default für die einzelnen Eingaben gesetzt. Nun gibt es den Fall, dass diese Variablen noch nicht definiert sind, weil sie erst nach dem ersten Schließen des Dialogs angelegt werden. Für diesen Fall verwenden wir die Inline-Funktion get, die als Parameter den Scope, den Variablennamen und einen Default-Wert liefert, für den Fall, dass die Variable noch nicht existiert. Diese Funktion gibt den Wert der Variable oder den eingestellten Standardwert zurück.

Wenn eine Schaltfläche gedrückt wird, werden die Werte in der in den Eingabefeldern genannten Variablen gespeichert. Bei @dialogInputDouble ist dies der zweite Parameter. Wie du siehst, sind dies die oben beschriebenen perm.*.

Weitere Parameter der einzelnen Eingabefelder sind min und max. Diese definieren die minimalen und maximalen Werte, die eingegeben werden können.

Zusätzlich zu den Eingabefeldern gibt es die folgenden Schaltflächen, die die Funktion MBLDriveTo mit berechneten X- und Y-Parametern aufrufen:

  • Oben-Links
  • Oben-Rechts
  • Mitte
  • Unten-Links
  • Unten-Rechts

Wenn eine Schaltfläche gedrückt wird, führt der Server den Befehl im letzten Parameter aus. Für die Positionierungsschaltflächen wird die Funktion MBLDriveTo aufgerufen, wobei die X- und Y-Positionen anhand der Druckerkonfiguration und der eingegebenen Werte berechnet werden.

Schließlich gibt es noch die Schaltfläche Fertig, die nichts aufruft. Wir werden später darauf zurückkommen.

Wenn du nun eine Positionstaste drückst und damit MBLDriveTo mit den entsprechenden Positionen aufgerufen hast, werden die Koordinaten nun in den G-Code eingefügt:

@func MBLDriveTo x y
G1 Z{{fixed(min(perm.manBedLevZhop + perm.manBedLevZoffset, config.move_z_max),3)}} F{fixed(config.speed_z_per_minute,0)}}
G1 X{{fixed(local.x,2)}} Y{{fixed(local.y,2)}} F{{fixed(config.speed_xy_per_minute,0)}}
G1 Z{{fixed(local.manBedLevZoffset,3)}} F{{fixed(config.speed_z_per_minute,0)}}
@call MBLCartesian
@endfunc

Du siehst in der Zeile @func, dass diese Funktion die beiden Parameter X und Y erwartet. Funktionsparameter werden im lokalen Bereich gespeichert, so dass du mit local.x und local.y darauf zugreifen kannst.

Hier wird ein Z-Hop in der angegebenen Höhe gemacht, solange der eingestellte Z-Offset und der Z-Hop zusammen nicht höher als die eingestellte Gesamt-Z-Höhe sind. Hier wird die Funktion min verwendet. Die Funktion min gibt den kleineren der beiden definierten Werte zurück. Dann werden X und Y an die Position mit der höchstmöglichen Geschwindigkeit bewegt. Schließlich wird Z auf die definierte Z-Position zurückgebracht. Die Inline-Funktion fixed rundet die Werte auf die angegebene Dezimalgenauigkeit.

Nach dem Verschieben wird die Funktion MBLCartesian erneut aufgerufen. Dadurch wird der Dialog wieder geöffnet und es kann eine neue Position ausgewählt werden. Das geht so lange, bis der Button Fertig gedrückt wird, der nichts ausführt und die Funktion auslaufen lässt. Danach ist das Skript beendet.