Anatomie eines Kalibrierskripts
Im vorangegangenen Dokument wurde bereits das Skelett für ein neues Kalibrierskript vorgestellt, welches hier als Grundlage dienen soll:
// Zusatzfunktion der Abhängigkeitsauflösung importieren
import { Injectable } from 'injection-js';
// Basisklasse für alle Skripte, jedes Skript muss von `Script` erben.
import { Script } from '@script';
// Klasse als erzeugbar markieren
@Injectable()
export class SkriptName extends Script {
// Im Konstruktor können zusätzliche Parameter angefordert werden
constructor() {
}
// Run enthält das eigentliche Kalibrierskript.
public Run(): void {
}
}
Makroschritte
In KalibriWare sind Skripte immer in Makroschritte unterteilt (analog zu den Parametern in KalibriScript). Verantwortlich für die Verwaltung der Makroschritte ist die Klasse StepsService in der Skriptumgebung. StepsService ist ebenfalls über die Dependency Injection erreichbar.
I.d.R. sieht das Skript dann folgendermaßen aus:
// Zusatzfunktion der Abhängigkeitsauflösung importieren
import { Injectable } from 'injection-js';
// Basisklasse für alle Skripte, jedes Skript muss von `Script` erben.
import { Script, StepsService } from '@script';
// Klasse als erzeugbar markieren
@Injectable()
export class SkriptName extends Script {
// Hier wird der StepsService aus der Dependency Injection angefordert und innerhalb der Klasse abgespeichert.
constructor(private steps: StepsService) {
}
// Run enthält das eigentliche Kalibrierskript.
public Run(): void {
// Makroschritt hinzufügen.
// Im ersten Parameter steht der Name, welcher am Ende auch in der Benutzerschnittstelle angezeigt wird.
// Im zweiten Parameter ist die wirkliche "Ausführungsfunktion", diese führt alle Messungen zu diesem Parameter durch. Diese Funktion kann mehrfach ausgeführt werden, z.B. wenn eine Messung fehlschlägt und der Schritt wiederholt wird.
// Im dritten Parameter sind Optionen enthalten, darüber kann ein Schritt z.B. als überspringbar oder automatisch startend festgelegt werden.
this.steps.Add("Schrittname", async () => {
// TODO Benutzer: Messfunktionen einfügen
}, {});
this.steps.Add("Schritt 2", async () => {
// TODO Benutzer: Messfunktion einfügen
}, { /* TODO Benutzer: Optionen */ });
}
}
Wichtig hierbei ist, dass die Run-Funktion synchron ist, d.h. in dieser Funktion können im Gegensatz zu den Messfunktionen keine Funktionen im Hintergrund ausgeführt werden.
Generell ist festzuhalten, dass Run() ausschließlich die Makroschritte hinzufügen sollte.
Makroschritte können Abhängigkeiten auf vorher ausgeführte Makroschritte über den sog. ContextManager definieren (siehe hier), dabei wird eine Variable in einem vorherigen
Schritt definiert und mit Werten befüllt und später verwendet. Diese Limitierungen ermöglichen es uns, eine Kalibrierung durchzuführen und z.B. bei einem Messfehler den einzelnen Makroschritt (z.B. Pegel bei 1310nm) zu wiederholen.
Ein weiterer Vorteil des Makroschritt-Konzepts ist, dass Makroschritte übersprungen und abgeschaltet werden können, z.B. wenn ein Kalibrierskript für eine Gerätefamilie erstellt wird und bestimmte Optionen nur bei speziellen Baureihen verfügbar sind. Dabei wird ein übersprungener Makroschritt im Protokoll standardmäßig nicht angezeigt.
Abhängigkeiten zwischen Makroschritten
Kalibriware bietet die Möglichkeit, definierte Abhängigkeiten zwischen Schritten zu definieren - dabei kommt der ContextManager zum Einsatz. Abweichend zu anderen Klassen, wird der ContextManager lokal im Skript initialisiert. Beim Initialisieren muss ein Datentyp angegeben werden, welche Kontextinformationen im ContextManager abgelegt und abgefragt werden können.
Beispielhaft kann der ContextManager so initialisiert werden:
import { Injectable } from 'injection-js';
import { Script, StepsService, ContextManager } from '@script';
@Injectable()
export class SkriptName extends Script {
constructor(private steps: StepsService) { }
public Run(): void {
// Erzeugt einen ContextManager mit drei Eigenschaften (keyA, keyB und keyC) und entsprechenden Typen.
const ctx = new ContextManager<{
keyA: string,
keyB: number,
keyC: any,
}>();
// Optional: Standardwerte setzen:
// Wenn außerhalb der Makroschritte ein Wert gesetzt wird, so ist dieser immer verfügbar.
// Damit können Fallbacks für überschringbare Schritte erzeugt werden.
ctx.setKey('keyC', new Date());
this.steps.Add("Schrittname", async () => {
ctx.setKey('keyA', 'value'); // Schreibt 'value' in 'keyA'
}, {
optional: true,
});
this.steps.Add("Schritt 2", async () => {
// liest Wert aus keyA aus - erzeugt eine Fehlermeldung wenn A nie geschrieben wurde.
const a = ctx.getKey('keyA');
});
}
}