# Die Werkzeuge, Bereich für Bereich

> Was jedes Werkzeug tut, das ein Agent aufrufen kann, gruppiert nach dem Berechtigungsschalter, der es anbietet, und die Hilfewerkzeuge, die keinen brauchen.

Namen von Werkzeugen sind stabile Bezeichner in snake_case. Fehler sind strukturiert und
verwertbar: Ein fehlgeschlagener Aufruf liefert zurück, was schiefging, dazu einen Hinweis,
der das Werkzeug oder den Schritt nennt, der es behebt, sodass ein Agent sich selbst
korrigiert, statt zu raten. Der Server weist jeden Agenten an, die Hilfe mit `help_search`
und `help_read` zu lesen, bevor er eine Frage dazu beantwortet, wie die Anwendung
funktioniert, und, wenn der Bereich Sicherungen (Verwalten) ein ist, vor Änderungen an der
Konfiguration eine Sicherung anzulegen. Welche dieser Listen ein Agent tatsächlich sieht,
steht in [Was jeder Bereich öffnet](agent-areas); dazu kommen die Hilfewerkzeuge, die
keinen Bereich brauchen.

## Hilfe {#help}

Die beiden Hilfewerkzeuge lesen diese Dokumentation so, wie die Installation sie mitbringt:
dieselben Artikel, die der [Hilfebereich](app-window#contextual-help) öffnet, geschrieben
für die Version, die auf der Station installiert ist. Sie kommen mit dem Endpunkt, sobald
der Hauptschalter ein ist, unabhängig davon, was die Schalter der Bereiche sagen, denn der
Text ist die öffentliche Dokumentation und zeigt nichts von der Station. Beide arbeiten
auch bei gestoppter Runtime weiter.

| Werkzeug | Wirkung |
| --- | --- |
| `help_search` | Findet Artikel anhand der Wörter einer Frage und liefert zu jedem den Slug, den Titel, die Zusammenfassung und die Abschnitte, die die Wörter berühren, den besten Treffer zuerst (standardmäßig 10, bis zu 50). Groß- und Kleinschreibung und Akzente werden ignoriert. Ohne Suchbegriff listet es alle Artikel auf. |
| `help_read` | Liest einen ganzen Artikel anhand seines Slugs als reinen Text: den Titel, die Zusammenfassung, die Liste der Abschnitte und den Text, jeden Abschnitt auf einer eigenen Überschriftenzeile und Tabellen mit einer Zeile pro Tabellenzeile, dazu die Slugs der Artikel, auf die er verweist. |

Beide lesen standardmäßig in der Sprache der Oberfläche der Station, damit die Seiten,
Tasten und Felder, die eine Antwort nennt, die auf dem Bildschirm sind. Jedes nimmt eine
`culture` an, die eine andere Sprache nennt, die die installierte Hilfe mitbringt; eine
Sprache, die sie nicht mitbringt, wird mit der Liste der vorhandenen abgelehnt, und keine
andere Sprache antwortet an ihrer Stelle. Eine Installation, deren Hilfe fehlt oder nicht
gelesen werden kann, beantwortet jeden Aufruf mit dem Grund statt mit Artikeln.

## Connector: Lesen {#connector--read}

| Werkzeug | Wirkung |
| --- | --- |
| `connector_browse` | Listet den Baum, den die Seite Connector zeichnet, mit dem aktuellen Zustand auf: jeden Treiber, der der Station hinzugefügt ist, auch einen ohne etwas darunter, und ein Treiber mit einem Gerät, einer seriellen Leitung oder einem Broker ist immer hinzugefügt; Modbus RTU als Treiber, serielle Leitung, Gerät, Tag; MQTT als Treiber, Broker (mit dem Zustand seiner Sitzung), Gerät, Tag; jeden anderen Treiber als Treiber, Gerät, Tag, mit dem Ordner jedes Geräts daneben. Generic serial and TCP listet seine seriellen Leitungen wie Modbus RTU und seine Netzwerkgeräte wie jeder andere Treiber auf, mit dem Übertragungsweg jedes Geräts. SCPI instruments listet seine seriellen Leitungen und seine übrigen Geräte genauso auf. Ein File-Gerät trägt seinen Ordner, seinen Dateinamen, wie es liest (eine Datei oder ein Eingangsordner) und sein Format. Ein Database-Gerät trägt seinen Datenbanktyp (`databaseKind`). Jedes Gerät trägt `error`, den einen Satz, den seine Seite zeigt, in der Sprache der Station: einen Satz, der auf seine serielle Leitung oder seinen Broker verweist, wenn der Fehler dort liegt, sonst den eigenen Fehler des Geräts (es verbindet sich nicht, die Verbindung wird abgelehnt, der Treiber warnt), sonst die Zusammenfassung seiner Tags, deren Lesevorgang abgelehnt wird, wobei der Grund jedes Tags das `readFailure` von `tag_read` ist. Er ist `null`, wenn das Gerät keinen hat; der Satz, den `tag_read` für ein Tag nennt, dessen Gerät nicht verbunden ist, führt hierher. Zeigt die Alias-Namen der Tags (`Driver.Folders….Device.Tag`), die `tag_read`, `tag_write` und die Ausdrücke von Logic verwenden. Solange der Connector gestoppt ist, sind die Aliasse null. |
| `tag_read` | Liest die aktuellen Werte eines Tags über seinen Alias: `valueRaw`, den Wert des Geräts selbst vor jeder Stufe, `value`, den technischen Wert nach allen Stufen der Wertkette, die Stufe Dezimalstellen eingeschlossen (ein Double, das das Gerät als 2,718281828459 meldet, liest sich mit Dezimalstellen auf 2 als 2,72), die Qualität, beide Zeitstempel und `substitution`, das sagt, ob der Wert ein eingestellter Ersatzwert ist statt dessen, was das Gerät gemeldet hat: `None` (eine Messung oder gar kein Wert), `NaNReplaced` (der Messwert war NaN und die erklärte Zahl ist an seine Stelle getreten), `LastGoodHeld` (der Lesevorgang ist fehlgeschlagen und der letzte Messwert, der angekommen ist, wird gehalten, mit seinem Rohwert und seinen Zeitstempeln) oder `ReadFailureReplaced` (der Lesevorgang ist fehlgeschlagen und die erklärte Zahl wird dargestellt). Ein Ersatzwert zählt als Wert, die Qualität bleibt also gut, solange keine Grenzverletzung vorliegt, aber er ist nie eine Messung. `communicating` sagt, ob das Gerät noch antwortet: falsch, wenn der letzte Lesevorgang fehlgeschlagen ist oder noch nichts gelesen wurde. Ein Messwert, auf den während des Abfrageintervalls des Tags, plus einem kleinen Spielraum, kein neuer folgt, zählt als fehlgeschlagener Lesevorgang: Wert, Qualität und `substitution` antworten wie bei einem solchen (standardmäßig kein Wert und schlechte Qualität, der gehaltene Messwert oder die festgelegte Zahl, wo das Tag es verlangt), `communicating` ist falsch, und die Zeitstempel datieren den letzten eingetroffenen Messwert. Ein Wert außerhalb der Grenzen des Tags ist keine Verbindungsstörung: Die Qualität wird schlecht, während `communicating` wahr bleibt. `readFailure` sagt, warum ein Lesevorgang nicht angekommen ist, in dem einen Satz, den der Bereich des Tags zeigt, in der Sprache der Station: der Grund, den das Gerät oder der Treiber nannte, als der Lesevorgang des Tags selbst abgelehnt wurde, oder ein Satz, der auf das Gerät des Tags verweist, wenn dieses nicht verbunden ist. Er ist `null`, solange das Tag liest, und wenn für einen nicht angekommenen Lesevorgang noch kein Grund vorliegt. |
| `modbus_server_status` | Meldet den eigenen [Modbus-Server](connector-modbus-server) der Station: ob er eingeschaltet ist (`enabled`), seinen `port`, seinen `status` (Off, Listening, PortInUse, Failed mit den Worten des Systems in `failure`, oder RuntimeStopped), die gerade verbundenen Clients (höchstens `maximumClients` gleichzeitig) und jede Zeile der Registertabelle: ihre `registerClass`, das ab 0 gezählte `register` und `lastRegister`, ihren Typ und ihre Anordnung, ihren `access` (ReadOnly oder ReadAndWrite), ihre Quelle (ein Tag oder eine Variable, mit Adresse und ID) und was ein Client dort gerade liest, `value` und `good`, oder die `gap` (NoSource, SourceRemoved, NoGoodValue, NotRepresentable), für die ein Client die Ausnahme 04 erhält. Funktioniert weiter, während die Runtime gestoppt ist. |
| `station_broker_status` | Meldet den eigenen [MQTT-Broker](connector-mqtt-broker) der Station, an den Geräte veröffentlichen, nie einen der Broker, die die Station liest: ob er an ist (`enabled`), seinen `port`, seinen `status` (Off, Listening, PortInUse, Failed mit den Worten des Systems in `failure`, oder RuntimeStopped), seine `authentication` (Anonymous oder UsernamePassword, mit `username` und `hasPassword`, nie das Passwort), die jetzt verbundenen Geräte (höchstens `maximumClients` gleichzeitig) und `thisStationEntry`, den Broker Diese Station des MQTT-Treibers, über den die Station ihn liest. Es funktioniert auch bei gestoppter Runtime. |
| `mqtt_publish_list` | Listet auf, was die Station auf jedem MQTT-Broker veröffentlicht, den sie liest, die [Karte Veröffentlichen](driver-mqtt#the-publish-card) jedes Brokers: sein `publishTopicPrefix` und ob er veröffentlicht, und jede Zeile mit ihrer Quelle (über die Adresse, `removed`, wenn die Quelle gelöscht wurde), ihrem `topic` und ihrer Nachricht (`value` oder `alarm`), beide Nachrichten in `payloads` beschrieben. Funktioniert weiter, während die Runtime gestoppt ist. Eine Zeile, deren `access` `ReadAndWrite` ist, nimmt Werte unter ihrem `writeTopic` an (ihrem Topic gefolgt von `/set`), die in ihre Quelle geschrieben und im Journal als `MQTT <Name des Brokers>` festgehalten werden; `payloads.write` sagt, was dieses Topic annimmt. Jeder Broker nennt sein `publishFormat`; ein Broker in Sparkplug B ergänzt `sparkplug` (seine Gruppe, die Edge-Node-ID der Station und seine Geräte), jede seiner Zeilen nennt Gerät und Metrik, als die sie veröffentlicht wird, und `payloads.sparkplug` sagt, wie Sparkplug B hinausgeht ([Veröffentlichen in Sparkplug B](driver-mqtt#publishing-in-sparkplug-b)). |
| `remote_access_devices` | Meldet, wer die Bilder der Station über das Netzwerk öffnet: die Browser, die gerade von einem anderen Computer oder Tablet aus verbunden sind (Adresse, Browser und System, Seite, Benutzer, seit wann und welches konfigurierte Gerät jeder ist), und die konfigurierten Geräte damit, wie jedes öffnet (Startbild, Sperre, als wer es sich anmeldet, die Minuten, nach denen es zurückkehrt, Nur ansehen und warum es anders öffnet, wenn sich sein fester Benutzer oder sein Startbild geändert hat). Es trägt nie einen Schlüssel oder dessen Hash. Es funktioniert weiter, während die Laufzeit angehalten ist. |
| `server_status` | Meldet den Zustand des eingebetteten [OPC UA-Servers](connector-opcua-server): ob er eingeschaltet ist (`enabled`), ob er läuft, seine Laufzeit, die URL des Endpunkts und die verbundenen Client-Sitzungen sowie die Größe des konfigurierten Adressraums; `available` sagt, ob die Runtime des Connectors liest, was sie auch tut, während der Server ausgeschaltet oder gestoppt ist, und `serverError`, warum der letzte Start des Servers fehlschlug. `list` ist das, was der Server bereitstellt, und alles, was er bereitstellt: eine Zeile je Tag, Logic-Variable, Alarm oder Gerätebefehl, jede mit ihrem `access` und dem `node`, mit dem ein Client eingerichtet wird; solange sie leer ist, ist `servesNothing` wahr. |

## Connector: Konfigurieren {#connector--configure}

| Werkzeug | Wirkung |
| --- | --- |
| `driver_capabilities` | Listet jeden Treiber auf, den die Anwendung bedienen kann, mit den Verbindungsfeldern, die ein Gerät braucht, dem Adressierungsmodell der Tags (Freitextadresse und/oder typisierte Felder), der Unterstützung und den Parametern der Gerätesuche, den Zeitbereichen und den unterstützten Werttypen, dazu `defaultPort`, den Port, über den ein Gerät ohne eigenen Port angewählt wird. `added` sagt, ob der Treiber der Station hinzugefügt ist, was ihn im Baum des Connectors zeichnet; ein Gerät, eine serielle Leitung oder einen Broker mit `device_upsert`, `serial_line_upsert` oder `mqtt_broker_upsert` anzulegen fügt seinen Treiber hinzu. AVEVA PI und HTTP wählen den Port des Übertragungswegs, den das Gerät spricht, und nennen deshalb außerdem `defaultPortByTransport`: 443 über HTTPS, ihr Standard, und 80 im Klartext. Generic serial and TCP ergänzt `genericSerialTcp`: seine Übertragungswege, wie Bytes eingegeben werden, wie Nachrichten enden, die Prüfsummen, die Lesemodi, Filter und Entnahmen der Tags, wie Werte gelesen und geschrieben werden, und zwei durchgerechnete Beispiele. Omron ergänzt `omron`: seine beiden Protokolle mit den Gerätefeldern, Adressformen und Datentypen jedes Protokolls, die FINS-Transporte und -Bereiche, das Schreiben und die Gerätesuche. SCPI instruments ergänzt `scpi`: seine Übertragungswege, ob dieser Rechner VISA hat (`visa.installed`), die Endezeichen, die Schreibbestätigungen, die Einrichtungsbefehle, wie Abfragen und Schreibbefehle geschrieben und Antworten gelesen werden, die Gerätesuche und zwei durchgerechnete Beispiele. NI-DAQmx ergänzt `niDaqmx`: für jede Messgröße einen Beispielkanal, die Einheit, ihre Felder sowie die Datentypen und Zugriffe, die sie erlaubt. Ein Treiber, dessen Geräte etwas brauchen, das das Produkt nicht mitliefern kann, ergänzt `prerequisite` (Fluke NetDAQ: die Laufzeitumgebung Visual C++ 2005; OPC DA: die OPC Core Components, OpcEnum und Proxy und Stub von OPC DA; NI-DAQmx: NI-DAQmx von National Instruments; SCPI: ein 64-Bit-VISA, NI-VISA oder die Keysight IO Libraries Suite, nur für seine VISA-Geräte, mit beiden Seiten; Database: ein 64-Bit-ODBC-Treiber oder eine Datenquelle für ein ODBC-Gerät, je Gerät beurteilt (`perDevice` true), daher bleibt `installed` null und der eigene Fehler des Geräts sagt, was fehlt): ob dieser Rechner sie hat (`installed`, für einen der Station hinzugefügten Treiber), die offizielle Downloadseite, die Datei, wie sie installiert wird, den bekannten Stolperstein und was danach geschieht. SNMP ergänzt `snmp`: seine Versionen und die Anmeldeangaben, die jede nimmt, die SNMPv3-Sicherheitsstufen und -Protokolle, die Typen je Art von Wert, jedes Standardobjekt, das der Treiber beim Namen kennt, mit seiner OID, wie sich Lesen und Schreiben verhalten, die Gerätesuche und zwei durchgerechnete Beispiele. File fügt `file` hinzu: den einfachen Weg, den Ordner und die Beschränkung auf ihn, die Formen des Dateinamens, eine Datei oder einen Eingangsordner, die Formate mit ihrer Adressgrammatik, was ein Tag liest und seine Typen, die Texteinstellungen, wie sich Lesen und Schreiben verhalten, die Gerätesuche und drei vollständige Beispiele. Database fügt `database` hinzu: jede Datenbank mit ihren Feldern und ihrem eigenen Port, die Verschlüsselung, die zwei Arten, wie ein Tag liest, und die zwei, wie es schreibt, die Regel, dass ein Wert nur als `@value` oder `@now` in eine Anweisung kommt, die Wartezeiten, den Rat zum Datenbankbenutzer, die Gerätesuche und vier vollständige Beispiele. Die Karte, die ein Agent vor `device_upsert` oder `tag_upsert` liest. |
| `serial_line_list` | Listet jede gespeicherte serielle Leitung auf, auch deaktivierte und leere, mit ihrer stabilen ID und ihrem Treiber; eine Modbus RTU-Leitung auch mit ihrem Modus und den eingestellten, den automatischen und den wirksamen Zeitwerten. |
| `serial_line_upsert` | Erzeugt eine serielle Leitung oder ändert eine über ihre stabile ID. `driver` nennt den Treiber, zu dem sie gehört, `ModbusRtu` (der Standard), `GenericSerialTcp`, `Scpi` oder `Omron`, beim Anlegen festgelegt; eine Leitung des generischen, des SCPI- oder des Omron-Treibers lehnt `mode`, `responseTimeoutMs` und `minimumTransactionIntervalMs` ab. Name und Aktivierung lassen sich jederzeit ändern, das minimale Transaktionsintervall auch im aktivierten Zustand; serieller Anschluss, Baudrate, serielles Format, Übertragungsmodus und Antwort-Zeitlimit nur, solange die gespeicherte Leitung deaktiviert ist. |
| `serial_line_delete` | Löscht eine Leitung über ihre stabile ID. Eine Leitung, die noch Geräte enthält, wird abgelehnt, sofern der Aufruf nicht ausdrücklich erlaubt, jedes untergeordnete Gerät und jedes Tag mit zu löschen. |
| `mqtt_broker_list` | Listet jeden gespeicherten MQTT-Broker auf, deaktivierte und leere eingeschlossen, mit seiner stabilen ID, wo er antwortet, seinem Übertragungsweg, Benutzernamen, seiner Client-ID, seinem Keep-Alive, seinem Topic-Präfix und der Anzahl seiner Geräte. Sagt, ob ein Passwort hinterlegt ist, und gibt es nie zurück. Zeigt auch das Format der Veröffentlichung (`publishFormat`) und die Sparkplug B-Gruppe (`sparkplugGroupId`). |
| `mqtt_broker_upsert` | Legt einen MQTT-Broker an oder aktualisiert einen über seine stabile ID: Name, Aktivierung, Host (eine ganze `mqtt://`- oder `mqtts://`-Adresse wird zerlegt), Port, TLS, Benutzername, Passwort, Client-ID, Keep-Alive und das Präfix, unter dem seine Karte Veröffentlichen Topics vorschlägt (`publishTopicPrefix`, eine leere Zeichenkette führt zum Standard zurück). Nur übergebene Parameter ändern sich; ein Broker wird nur mit Host aktiviert, und eine Client-ID, die ein anderer Broker nutzt, wird abgelehnt. Eine gespeicherte Änderung der Verbindung verbindet die Sitzung neu, die sich alle Geräte unter dem Broker teilen. `publishFormat` (`Json` oder `SparkplugB`) wählt, wie die Karte Veröffentlichen hinausgeht, und `sparkplugGroupId` die Sparkplug B-Gruppe des Edge-Nodes der Station (eine leere Zeichenfolge führt zu `GanterLab` zurück; eine Gruppe mit `/`, `+` oder `#` wird abgelehnt). |
| `mqtt_broker_delete` | Löscht einen Broker über seine stabile ID. Ein Broker, der noch Geräte enthält, wird abgelehnt, sofern der Aufruf nicht ausdrücklich erlaubt, jedes untergeordnete Gerät und jedes Tag mit zu löschen. |
| `mqtt_publish_upsert` | Legt eine Zeile der [Karte Veröffentlichen](driver-mqtt#the-publish-card) eines Brokers an (`brokerId` und `source`: ein Tag, `Connector.` und sein Alias, eine Variable, `Variables.` und ihr Pfad, oder ein Alarm, `Alarms.` und sein Pfad) oder bearbeitet eine über `id`. `topic` ist optional: Fehlt es, erhält die Zeile das aus dem Namen der Quelle unter dem Präfix des Brokers vorgeschlagene, und eine leere Zeichenkette holt es erneut. Ein Broker veröffentlicht eine Quelle einmal und ein Topic einmal; ein Topic enthält weder + noch # und beginnt nicht mit $. Eine Zeile wechselt nie den Broker. `access` ist `ReadOnly`, der Standard, oder `ReadAndWrite`, das nur ein Tag mit Schreibzugriff auf einem Treiber, der schreibt, oder eine Merker-Variable annimmt: Die Station schreibt dann, was unter dem Topic der Zeile gefolgt von `/set` veröffentlicht wird ([Zurückschreiben](driver-mqtt#writing-back)). Das Topic einer Zeile darf nicht das Topic einer anderen gefolgt von `/set` sein. Auf einem Broker in Sparkplug B wird die Zeile als Metrik veröffentlicht (`row.sparkplug`), und `ReadAndWrite` nimmt die Werte an, die Sparkplug B-Befehle an sie senden. |
| `mqtt_publish_delete` | Löscht eine Zeile einer Karte Veröffentlichen über `id`. Die Station veröffentlicht sie nicht mehr; das Tag, die Variable oder der Alarm bleibt unberührt. |
| `device_upsert` | Erzeugt oder ändert ein Gerät über Treiber und Name (der Treiber ist nach dem Anlegen unveränderlich). Nur übergebene Parameter ändern sich; die Verbindungsfelder hängen vom Treiber ab; ein Gerät in einen Ordner zu verschieben schreibt jeden Verweis auf seine alten Tag-Adressen um. Ein Gerät von Generic serial and TCP nimmt `transport` und die Felder seiner Karten Nachrichten und Prüfsumme, und `serialLineId` nur für eine Leitung seines eigenen Treibers; ein Gerät auf einer Leitung lehnt Host, Port und Ordner ab. Ein Omron-Gerät nimmt `omronProtocol` (`Fins` oder `NjNx`) und über FINS die Felder `fins*` seiner Karte FINS; ein über Tag-Namen gelesenes Gerät lehnt einen Port ab. Ein SCPI-Gerät nimmt `transport` (`Tcp`, `Visa` oder `SerialLine` mit der `serialLineId` einer Leitung seines eigenen Treibers), `visaResource`, `terminator`, `responseTimeoutMs`, `writeCheck` und `setupCommands`. Ein NI-DAQmx-Gerät nimmt `daqmxDevice`, den Namen, den NI MAX ihm gibt. Ein SNMP-Gerät nimmt `snmpVersion`, `snmpCommunity` (SNMPv1, SNMPv2c), `username`, `password`, `snmpSecurityLevel`, `snmpAuthProtocol`, `snmpPrivacyProtocol` und `snmpPrivacyPassword` (SNMPv3), `responseTimeoutMs` und `snmpRetries`; es liefert, ob jedes Geheimnis gesetzt ist, nie das Geheimnis. Ein File-Gerät nimmt `fileFolder`, `fileName`, `fileMode` (`SingleFile` oder `Inbox`), `fileFormat`, `fileEncoding`, `fileSeparator`, `fileDecimal`, `fileHeaderRow` und `fileWrites`, bei eingeschaltetem Schreiben dazu `fileHeaderText` und `fileLineEnd`; es liefert `file.fileStatus`, die Datei, die der laufende Treiber liest, und was er aus ihr gelesen hat. Ein Database-Gerät nimmt `databaseKind`, und für einen Server `host`, `port` und `databaseName` (bei SQL Server auch `databaseInstance`, `databaseWindowsSignIn` und `databaseEncryption`), `databaseFile` für SQLite oder `databaseOdbc` für ODBC, mit `username` und `password`; es liefert `database`, die Adresse und ob das Gerät noch auf seinen Benutzer wartet, nie das Passwort. Ein Port außerhalb von 0 bis 65535 wird abgelehnt; 0 steht für den Port, den der Treiber verwendet. Die Änderung wird sofort in den laufenden Server übernommen. |
| `device_delete` | Löscht ein Gerät und alle seine Tags; wird sofort in den laufenden Server übernommen. |
| `tag_upsert` | Erzeugt oder ändert ein Tag an einem Gerät. Die Adressierung hängt vom Treiber ab (Freitextadresse und/oder typisierte Felder; bei Generic serial and TCP Lesemodus, Anfrage, Filter, Entnahme und die Schreibfelder; bei SCPI instruments die Abfrage als `address`, `valueField` und `writeTemplate`; bei NI-DAQmx den physischen Kanal als `address` und die Felder `daqmx*` seiner Messgröße; bei SNMP die OID als `address`, in Zahlen oder mit Standardnamen; bei File die Spalte oder den Pfad als `address`, `fileSource`, `fileRow` und seine Felder, `fileWriteMode` und `fileLineTemplate`, ein Wert aus freiem Text mit den `value*`-Feldern des generischen Treibers, und ein neues Tag entsteht mit Nur lesen; bei Database die Wertspalte als `address`, `databaseSource`, `databaseTable`, `databaseRow` und seine Felder oder `databaseQuery`, und sobald das Tag schreibt `databaseWriteMode` und `databaseCommand`, wobei ein neues Tag ebenfalls mit Nur lesen entsteht); die Antwort gibt die zusammengesetzte Busadresse und den Alias für `tag_read` zurück. Enthält die Stufen für ungültige Messwerte: die NaN-Aktion für numerische Tags und die Darstellung bei Lesefehler für jedes Tag, das die Station liest, wobei nur `Replace` auf numerische Tags und Boolean beschränkt ist. Ein bereits gespeichertes `Replace`, das der neue Typ des Tags nicht annimmt, wird als Vorgabe gespeichert: Die NaN-Aktion wird zu `PassThrough`, sobald der Typ nicht mehr numerisch ist, und die Darstellung bei Lesefehler wird zu `ShowError`, sobald der Typ String, DateTime, Guid oder ByteString ist. |
| `tag_delete` | Löscht ein Tag; wird sofort übernommen. |
| `server_start` | Schaltet den eingebetteten OPC UA-Server ein und startet ihn, wie Aktivieren auf seiner Zeile: er stellt seine Liste bereit, und bleibt über Neustarts hinweg eingeschaltet bis `server_stop`. Ohne Wirkung, wenn er bereits läuft; läuft der Connector selbst nicht, wird er zuerst gestartet und baut die aktuelle Konfiguration auf. |
| `server_stop` | Schaltet den Server aus und stoppt ihn geordnet, wie Deaktivieren: Die OPC UA-Clients werden getrennt, und bis `server_start` ihn wieder einschaltet, wird nichts veröffentlicht. Der Connector liest weiter, und das Lesen der Tags, Logic und die Aufzeichnungen laufen weiter. |
| `server_restart` | Stoppen und wieder starten, nur der Server, solange er eingeschaltet ist; der Connector liest die ganze Zeit. Ein ausgeschalteter Server wird abgelehnt, denn eingeschaltet wird er mit `server_start`. Änderungen an Geräten und Tags werden mit `connector_refresh` übernommen. |
| `server_list_upsert` | Legt eine Zeile der [Liste](connector-opcua-served-nodes) des OPC UA-Servers an oder ändert eine über ihre `id`. `source` nennt ein Tag (`Connector.` und sein Alias), eine Variable (`Variables.` und ihr Pfad), einen Alarm (`Alarms.` und sein Pfad) oder einen Gerätebefehl (die Adresse des Geräts, ein Punkt, der Name des Befehls und `()`); eine Quelle steht nur einmal in der Liste. `access` ist ReadOnly, die Vorgabe jeder neuen Zeile, oder ReadAndWrite, das nur ein Tag mit Schreibzugriff oder eine Merker-Variable annimmt; ein Schreibzugriff eines Clients geht dann durch den Schreibtrichter der Logic und wird mit der Sitzung des Clients im Journal festgehalten. Die Antwort enthält die Zeile mit ihrem `node`. |
| `server_list_delete` | Löscht eine Zeile der Liste über ihre `id`. Ein Client findet ihren Knoten nicht mehr; die Quelle, die sie bereitstellte, wird nicht berührt. |
| `modbus_server_configure` | Schaltet den Modbus-Server ein oder aus (`enabled`) oder verschiebt ihn auf einen anderen `port`, 1 bis 65535, wie es seine Seite tut. Ein Port, auf den der Webserver, der Agentenzugriff oder der OPC UA-Server eingestellt ist, und ein Port, den ein anderes Programm hält, werden abgelehnt; die Windows-Firewall wird nie verändert. Eingeschaltet lässt er jeden Rechner, der den Port erreicht, lesen, was die Tabelle bereitstellt. Antwortet mit dem ganzen Server, wie `modbus_server_status`. |
| `station_broker_configure` | Schaltet den eigenen MQTT-Broker der Station ein oder aus (`enabled`), verschiebt ihn auf einen anderen `port` und ändert seine `authentication`, `username` und `password`, wie seine Seite es tut, in dieser Reihenfolge: Port, Authentifizierung, dann ein oder aus. Ein Port, auf den der Webserver, der Agentenzugriff, der OPC UA-Server oder der Modbus-Server eingestellt ist, und ein Port, den ein anderes Programm belegt, werden abgewiesen; die Windows-Firewall wird nie geändert. Eingeschaltet fügt er dem MQTT-Treiber den Broker Diese Station hinzu. Antwortet mit dem ganzen Broker, wie `station_broker_status`. |
| `modbus_map_upsert` | Legt eine Zeile der Registertabelle des Modbus-Servers an oder ändert eine über ihre `id`. `source` nennt ein Tag über seine Adresse (`Connector.` und sein Alias, wie `connector_browse` es auflistet) eine Variable (`Variables.` und ihr Pfad) oder einen Alarm (`Alarms.` und sein Pfad, immer ReadOnly, der den Zustand liefert, den `alarmValue` nennt: Active, Acked oder State); `registerClass` (standardmäßig HoldingRegister), `register` (ab 0), `type` (standardmäßig Float, Boolean in einer Coil oder einem diskreten Eingang), `length` für einen String, `mostSignificantByte` und `mostSignificantWord` übernehmen die Felder und die Regeln eines Modbus-Tags. `access` ist ReadOnly, die Vorgabe jeder neuen Zeile, oder ReadAndWrite, das nur ein Holding-Register oder eine Coil annimmt, von einer Quelle, die Schreibzugriffe annimmt (ein Tag mit Schreibzugriff, eine Merker-Variable). Eine neue Zeile braucht ihr `register` und ihre `source`; eine Zeile, die die Tabelle ablehnt, wird mit dem Grund und einem Hinweis beantwortet. |
| `modbus_map_delete` | Löscht eine Zeile der Registertabelle über ihre `id`. Ein Client, der ihre Register liest, erhält von da an die Ausnahme 02; das Tag oder die Variable, die sie bereitstellte, bleibt unberührt. |
| `remote_access_device_update` | Ändert die Bezeichnung eines konfigurierten Geräts, sein Startbild (ein Dashboard nach ID oder Name, oder leer, um es zu entfernen, was auch die Sperre aufhebt), die Sperre, die Minuten ohne Berührung (0 für nie) und Nur ansehen, so wie seine Zeile auf der Seite Fernzugriff. Als wer sich das Gerät anmeldet, wird hier nicht geändert: Das verlangt eine Person mit Lokale Benutzer verwalten. Ein Gerät wird auf dem Bildschirm der Station konfiguriert und vergessen, nie über ein Werkzeug. Antwortet mit dem Gerät, wie `remote_access_devices` es aufführt. |

## Connector: Bedienen {#connector--operate}

| Werkzeug | Wirkung |
| --- | --- |
| `connector_refresh` | Gleicht den laufenden Server schrittweise mit den konfigurierten Geräten ab (hinzufügen, entfernen, neu anlegen), ohne vollständigen Neustart; der leichtere Weg, Änderungen anzuwenden. |
| `device_discover` | Führt den Suchlauf der Gerätesuche eines Treibers aus und liefert Kandidaten mit ihren Tags zurück, ohne etwas zu speichern. Nur Treiber, deren Protokoll einen echten Suchlauf unterstützt, nehmen teil; bereits vorhandene Kandidaten werden als solche gekennzeichnet. Ein SNMP-Suchlauf durchläuft entweder `target` mit `snmpCommunity` oder `snmpDevice`, ein konfiguriertes Gerät, und nur so wird ein SNMPv3-Agent durchsucht. Ein File-Suchlauf liest entweder `fileDevice`, ein konfiguriertes Gerät, oder `fileFolder`, `fileName`, `fileMode` und `fileFormat`, für den Suchlauf eingegeben. Ein Database-Suchlauf liest `databaseDevice`, ein konfiguriertes Gerät, und optional `databaseTables`, einen Tabellennamen oder ein Muster mit `*`. Ein `target`, das die Karte Suchbereich des Treibers ablehnen würde, oder keines, wo der Suchlauf eines braucht, wird mit dem abgelehnt, was es sein muss. Ein Database-, File- oder SNMP-Suchlauf, der an seiner Grenze an Werten, Tabellen oder Objekten angehalten hat, sagt es in `cut`, mit dem, was zu übergeben ist, um den Rest zu sehen; eine vollständige Liste hat kein `cut`. |

## Logic: Lesen {#logic--read}

| Werkzeug | Wirkung |
| --- | --- |
| `logic_browse` | Durchsucht den verwurzelten Adressraum von Logic, denselben Punktbaum, den jeder Ausdruck liest: System, Server, Connector, Variables, Alarms, Process und Assets. Ordner des Bedieners sind echte Adressebenen; untergeordnete Punkte enthalten ihren aktuellen Wert und ihre Qualität, und ein Punkt eines Tags aus dem Connector trägt zusätzlich `substitution` und `communicating`, so wie `logic_read` sie meldet. |
| `logic_read` | Liest einen Punkt über seine Punktadresse (zum Beispiel `Variables.Setpoint`) und liefert den aktuellen Wert und die Qualität. Ein Punkt eines Tags aus dem Connector trägt zusätzlich `substitution` und `communicating`, so wie `tag_read` sie meldet, und das ist es, was einen Ersatzwert oder den Messwert eines Geräts, das nicht mehr antwortet, von einer laufenden Messung unterscheidet; andere Punkte tragen keines von beiden. Ein verstummter Messwert liest sich dort wie ein fehlgeschlagener Lesevorgang. |

## Logic: Konfigurieren {#logic--configure}

Ein Upsert ist teilweise (weggelassene Parameter behalten ihren Wert), und jeder
zusammengeführte Entwurf durchläuft dieselbe Prüfung wie in den Editoren von
[Logic](logic); ein ungültiger Entwurf wird abgelehnt, und nichts bleibt halb angewendet.

| Werkzeug | Wirkung |
| --- | --- |
| `variable_upsert` | Erzeugt oder ändert eine Variable: Expression (ein einzelner, nur lesender JavaScript-Ausdruck über dem Adressraum) oder Memory (ein schreibbarer, wahlweise remanenter Wert). Der Name ist der Schlüssel und, bereinigt, die Adresse; der Parameter für den Ordner legt sie ab und schreibt dabei jeden Verweis auf die alte Adresse um. |
| `variable_delete` | Löscht eine Variable über ihren Pfad, samt ihres remanent gehaltenen Werts. Kanäle, die daran gebunden sind, verlieren ihre Quelle. |
| `action_upsert` | Erzeugt oder ändert eine Aktion: ein JavaScript-Anweisungsblock mit genau zwei Schreibbefehlen, der Zuweisung an eine Variable vom Typ Memory und dem Schreiben auf einen technischen Tag-Wert. Statisch geprüft, beim Speichern nie ausgeführt. |
| `action_delete` | Löscht eine Aktion über ihren Namen. Auslöser, die daran gebunden sind, laufen leer. |
| `trigger_upsert` | Erzeugt oder ändert einen Auslöser mit festem Intervall: Alle `intervalMs` (mindestens 100) läuft die gebundene Aktion auf der Aktionsspur; ein Takt während einer noch laufenden Ausführung wird übersprungen. Die Bindung an die Aktion ist lose und erfolgt über den Namen. |
| `trigger_delete` | Löscht einen Auslöser; die gebundene Aktion bleibt unberührt. |
| `alarm_upsert` | Erzeugt oder ändert einen Alarm: einen Bedingungsausdruck vom Typ Wahrheitswert, die Priorität (Critical/High/Medium/Low), die Verzögerungen beim Kommen und Gehen, ob eine Quittierung nötig ist, und die Art der Meldung. Das Speichern einer geänderten Bedingung oder Zeit setzt den laufenden Zustandsautomaten zurück. |
| `alarm_delete` | Löscht einen Alarm über seinen Pfad; eine aktive Meldung wird zuvor gelöscht. |
| `logic_folder_upsert` | Erzeugt, benennt um oder verschiebt einen Ordner zur Gliederung eines Abschnitts (Variables, Alarms, Actions, Triggers; höchstens drei Ebenen). Bei Variables und Alarms gehört der Ordnerpfad zur Adresse, deshalb schreiben Umbenennen und Verschieben jeden Ausdruck, jedes Skript, jede Bedingung und jede Verknüpfung im Dashboard darunter um. |
| `logic_folder_delete` | Löscht einen Ordner. Nichts, was er enthielt, geht verloren: Einträge und Unterordner rücken eine Ebene nach oben, und Verweise werden umgeschrieben; ein Namenskonflikt am Ziel verhindert das Löschen. |

## Logic: Bedienen {#logic--operate}

Alle diese Werkzeuge laufen über denselben Schreibtrichter der Logik wie die Seiten und werden mit dem
Ursprung **MCP** protokolliert. Ein Schreibvorgang verlässt die Logic in Richtung der eigenen Auslieferungswarteschlange des Geräts, und es ist der Werkzeugaufruf, der auf die Antwort wartet: Zurück kommt also, was aus dem Wert geworden ist, und nicht bloß, dass er gesendet wurde.

| Werkzeug | Wirkung |
| --- | --- |
| `variable_write` | Schreibt einen Wert in eine Variable vom Typ Memory (auf ihren Ausgabetyp gewandelt, bei Remanenz gespeichert). Variablen vom Typ Expression werden berechnet und lehnen Schreibzugriffe ab. |
| `tag_write` | Schreibt einen technischen Wert auf ein schreibbares Tag: rückwärts durch die Wertkette des Tags geführt, auf den Typ des Geräts gewandelt, auf das Gerät geschrieben. Die Antwort trägt, was das Tag zeigt, sobald der Schreibvorgang durch ist: den Wert, die Qualität, `substitution` und `communicating`, so wie `tag_read` sie meldet, sodass ein Gerät, das den Schreibvorgang angenommen hat, auf Lesevorgänge aber nicht mehr antwortet, nicht mit einem verwechselt wird, das noch antwortet. Schreibgeschützte Tags und schreibgeschützte Treiber werden mit der Begründung abgelehnt. |
| `action_run` | Führt eine Aktion auf der Aktionsspur aus und liefert ihr Ergebnis und ihre Dauer. Eine deaktivierte Aktion schlägt fehl, ohne zu laufen. |
| `alarm_ack` | Quittiert einen Alarm, die Antwort des Bedieners; ohne Wirkung, wenn nichts ansteht. |
| `alarm_ack_all` | Quittiert jeden Alarm, der auf eine Quittierung wartet, als einen Eintrag in der Warteschlange der Logik, wobei jeder Übergang protokolliert wird. |

## Logs: Lesen {#logs--read}

| Werkzeug | Wirkung |
| --- | --- |
| `logs_read` | Liest den programmweiten Live-Strom des Journals (denselben, den die Konsole von [Ereignisse](events) zeigt), gefiltert nach Mindeststufe (Debug/Information/Warning/Error, Standard Information), Bereich (App/Server/Connector/Logic/Process/Dashboard/Agent/Licensing), Komponente und einer Teilzeichenfolge aus dem Kontext; liefert die neuesten Treffer (Standard 100, höchstens 500). Handlungen eines Agenten werden im Bereich Agent protokolliert. |
| `event_history_read` | Liest die dauerhafte Zeitleiste der Betriebsereignisse, die Neustarts übersteht: Übergänge von Alarmen, von Ereigniseinträgen und von Verriegelungen. Filtern nach Art (Alarm/Occurrence/Interlock), einem einschließenden UTC-Zeitraum und einer Stufe (Priorität des Alarms, Schwere des Ereigniseintrags oder Übergang der Verriegelung); neueste zuerst, Standard 100, höchstens 500. Streng nur lesend: Einträge des Journals lassen sich weder leeren noch löschen. |

## Process: Lesen {#process--read}

| Werkzeug | Wirkung |
| --- | --- |
| `process_models` | Listet die Modelle von [Process](process) vollständig auf: Kanäle, gemeinsame Gruppen, Einheiten mit aufgelöster Verdrahtung und Betriebszustand, Abläufe, Bereiche, Rezepte, Bewertungen, Ereigniseinträge sowie die globale Bibliothek der Berichtsvorlagen. Die Karte, die ein Agent liest, bevor er etwas startet. |
| `process_runs` | Listet Läufe auf, die jüngsten zuerst: ID, Name, Zustand, Prüfergebnis, was gelaufen ist, wer ihn gestartet hat (Station/User/Automation/Agent), Zeiten und Fortschritt im Zyklus. Lässt sich auf aktive Läufe einschränken, nach einem Teil des Namens oder eines beliebigen Metadatenwerts (einer Seriennummer, einer Charge) durchsuchen und in der Anzahl begrenzen (Standard 50). |
| `process_run` | Liest die vollständige, eingefrorene Aufzeichnung eines Laufs über seine ID: Momentaufnahme, Metadaten, bewertete Kriterien mit Anzahl der Abtastwerte, Episoden und Ereignisse von Ereigniseinträgen, tatsächlich ausgeführte Schreibzugriffe des Rezepts, Kommentare sowie die eingefrorenen Dateien von Bericht und Etikett mit ihren Druckversuchen. Berechnet auf Wunsch die Zeilenzahl und den Zeitbereich des Datalogs. |
| `process_samples` | Liest die Abtastwerte, die ein Lauf aufgezeichnet hat, während er aufzeichnet oder nachdem er geendet hat. Ein Zeitraum mit bis zu 500 Abtastwerten kommt so, wie er aufgezeichnet wurde: ein Punkt je Abtastwert, mit einem Wert je Kanal. Ein längerer kommt zusammengefasst: Seine Dauer wird in 500 gleich lange Teilstücke geteilt, und jedes trägt für jeden Kanal Minimum, Maximum und Mittelwert, sodass eine Spitze im Maximum erhalten bleibt. Die Antwort sagt, welcher der beiden Fälle vorliegt, und bei einer Zusammenfassung, wie lange jedes Teilstück dauert und wie viele Abtastwerte es zusammenfasst. `fromUtc` und `toUtc` grenzen den Zeitraum ein, und ein ausreichend enger kommt so, wie er aufgezeichnet wurde; `channels` liest nur die genannten Kanäle. |
| `unit_status` | Meldet den aktuellen Zustand einer Einheit: ob sie läuft (mit dem aktiven Lauf) und den aktuellen technischen Wert hinter jedem Kanal, gelesen ohne aufzuzeichnen. |

## Process: Konfigurieren {#process--configure}

| Werkzeug | Wirkung |
| --- | --- |
| `process_view_configure` | Konfiguriert genau einen Bereich eines Modells: das Icon daneben und ob er auf der Seite View steht. Sonst ist nichts am Aggregat von Process über MCP beschreibbar; der Rest wird auf der Seite Process bearbeitet. |

## Process: Bedienen {#process--operate}

Läufe, die ein Agent startet, beendet oder kommentiert, tragen **Agent über MCP** als
handelnde Instanz ein, nie den Bediener, der gerade am Prüfstand angemeldet ist.

| Werkzeug | Wirkung |
| --- | --- |
| `process_snapshot` | Nimmt eine Datalog-Zeile an einer Einheit außerhalb eines Ablaufs auf. Jeder Aufruf erzeugt in [Historien](histories) einen neuen, bereits abgeschlossenen Lauf der Art Direkt ohne Bewertung (Prüfergebnis None). |
| `process_evaluate` | Nimmt eine Datalog-Zeile auf und beurteilt sie mit einer Bewertung; erzeugt einen abgeschlossenen Lauf der Art Direkt und liefert dessen Prüfergebnis. |
| `process_recipe_apply` | Wendet ein Rezept der Art Direkt einmal auf eine Einheit an, über den Schreibkanal und die Quellsperren von Process. Steuert die Anlage an; erzeugt keinen Lauf (die Schreibzugriffe werden protokolliert). Rezepte der Art Zeitgeführt werden abgelehnt. |
| `process_start` | Startet den Lauf eines Ablaufs auf einer Einheit, mit einem JSON-Objekt für die Metadatenfelder, die der Ablauf abfragt. Jeder übergebene Wert wird aufgezeichnet, oder nichts startet: Ein Feld, das der Ablauf nicht abfragt, ein Wert für ein fortlaufendes Feld (die Anwendung setzt es beim Start zusammen) oder ein zweimal genanntes Feld verhindern den Start, ebenso fehlende oder ungültige Pflichtangaben, eine bereits laufende Einheit oder ein Sperrkonflikt an einem gemeinsam genutzten Kanal. Liefert die ID des neuen Laufs. |
| `process_stop` | Stoppt einen laufenden Lauf: Abschlussblock, eingefrorene Momentaufnahme für die Historie, berechnetes Prüfergebnis. |
| `process_hold` | Hält das zeitliche Profil eines Laufs beim letzten Sollwert an; das Datalog zeichnet weiter auf. |
| `process_resume` | Setzt das zeitliche Profil eines angehaltenen Laufs fort. |
| `process_abort` | Bricht einen Lauf aus Running oder Held ab: der Abschluss läuft, die Momentaufnahme wird geschrieben, der Zustand wird Aborted und das Prüfergebnis NOK. |
| `process_comment` | Fügt der Datei eines Laufs einen Kommentar mit Zeitstempel hinzu: während des Laufs eine Notiz in der Zeitleiste, danach eine Notiz nach dem Lauf. |
| `process_report` | Erzeugt den PDF-Bericht eines abgeschlossenen Laufs oder erzeugt ihn neu und liefert seinen Dateipfad. Eine benannte Vorlage aus der globalen Bibliothek hat Vorrang vor der im Ablauf eingestellten; ohne beides gilt das Standardlayout mit allen Abschnitten. Wird abgelehnt, solange der Lauf aktiv ist. |
| `process_run_delete` | Löscht einen aufgezeichneten Lauf endgültig: seinen Verweis im Index der Historie und die Datenbankdatei des Laufs. Wird abgelehnt, solange er aktiv ist; die Konfiguration bleibt unberührt. |

## Dashboard: Konfigurieren {#dashboard--configure}

Die Rollennamen, die diese Werkzeuge lesen und melden, sind auf jeder Station englisch:
`Not signed in`, `Viewer`, `Operator`, `Maintainer` und `Developer`, gleich welche Wörter
der Bediener auf dem Bildschirm liest. `Admin` steht nicht in der Liste: diese Rolle sieht
immer jedes Dashboard. Eine vom Administrator umbenannte Rolle trägt den Namen, den er
eingetippt hat.

| Werkzeug | Wirkung |
| --- | --- |
| `dashboard_list` | Listet Dashboards auf (oder, wenn ein Modell genannt wird, dessen Bilder): Rastergröße, Ordner, Icon, Kennzeichen für den Start, Sichtbarkeit je Rolle und jede Komponente mit ihrer Position, ihrer Ebene und ihrem Eigenschaften-JSON, dazu jedes gespeicherte Verbindungsnetz. Liefert außerdem den Katalog der Komponentenarten mit der Standardgröße und den Standardeigenschaften jeder Art. |
| `dashboard_upsert` | Erzeugt oder ändert ein Dashboard über seinen Namen: Rastergröße (eine Verkleinerung, die eine Komponente heimatlos machen würde, wird abgelehnt), Ordner und Icon in der Spalte Visualisierung der Seite View, Kennzeichen für den Start, Sichtbarkeit der Statusleiste im Vollbild und Sichtbarkeit je Rolle. Wird ein Modell genannt, spricht der Aufruf stattdessen die Bilder dieses Modells an. Geöffnete Dashboard-Seiten übernehmen die Änderung sofort. |
| `dashboard_delete` | Löscht ein Dashboard und seine Komponenten über den Namen; wird ein Modell genannt, wird stattdessen dessen Bild gelöscht. |
| `component_upsert` | Fügt eine Komponente einer Art hinzu (ohne andere Angabe in der ersten freien Zelle mit der Standardgröße dieser Art platziert) oder ändert eine über ihre ID. Die Platzierung muss innerhalb des Rasters liegen; Überlappen ist erlaubt, wobei die z-Ebene die Zeichenreihenfolge bestimmt; das Eigenschaften-JSON ist der typisierte Satz dieser Art. Wird ein Modell genannt, spricht der Aufruf stattdessen die Bilder dieses Modells an, sodass ein dort angelegtes Bild hier eingerichtet werden kann. |
| `component_delete` | Entfernt eine Komponente über ihre ID; wird ein Modell genannt, spricht der Aufruf stattdessen die Bilder dieses Modells an. |
| `connection_upsert` | Verbindet zwei Anschlusspunkte von Symbolen mit einem typisierten Verbindungsnetz und löst Typ, Rolle und Richtung genau so aus dem Symbolkatalog auf wie der Editor der Zeichenfläche. Enden, die zu verschiedenen Typen aufgelöst werden, schlagen fehl, sofern eine unbestimmte Verbindung nicht ausdrücklich erlaubt ist; ein Ankerpunkt, der bereits eine Verbindung trägt, wird abgelehnt. Wird ein Modell genannt, spricht der Aufruf stattdessen die Bilder dieses Modells an. |
| `connection_delete` | Entfernt ein Verbindungsnetz über ID und erwartete Revision, sodass ein veralteter Löschbefehl abgelehnt wird, statt eine neuere Änderung zu überschreiben; wird ein Modell genannt, spricht der Aufruf stattdessen die Bilder dieses Modells an. |

## Oberfläche: Automatisieren {#ui--automate}

Diese Werkzeuge bedienen das echte Anwendungsfenster; es gibt sie, damit ein Agent die
Oberfläche prüfen kann, die der Bediener sieht, und keine Nachbildung davon. Die Eingaben
gehen an die laufende Oberfläche, deshalb ist es vorgesehen, auf jede Geste ein
`ui_screenshot` folgen zu lassen und die Wirkung anzusehen; mehrdeutige Treffer kommen als
Liste von Kandidaten zurück statt als geratener Klick.

| Werkzeug | Wirkung |
| --- | --- |
| `ui_state` | Meldet den Zustand der Oberfläche: aktive Seite, verfügbare Seiten, Design, Fenstergröße und Sichtbarkeit sowie die Loopback-Adresse, unter der diese Instanz ihre Oberfläche ausliefert. Der Aufruf zur Orientierung vor allem anderen. |
| `ui_navigate` | Aktiviert eine Seite der Oberfläche über ihren stabilen Namen, der auf jeder Station englisch ist: `View`, `Process`, `Logic`, `Connector`, `Users`, `Validation`, `Events`, `Agent`, `Settings`, `Account`. Die Beschriftung, die die Navigationsleiste in der Sprache der Station zeigt, wird ebenfalls angenommen. |
| `ui_screenshot` | Nimmt das Fenster so auf, wie es auf dem Bildschirm steht, speichert es als PNG-Datei und liefert deren absoluten Pfad; ist das Fenster in den Infobereich ausgeblendet, wird es zuvor wiederhergestellt. Kann statt des ganzen Fensters einen benannten Bildbereich aufnehmen (einen eindeutigen, sichtbaren Bereich mit `data-doc-region`); ein fehlender, verdeckter oder mehrdeutiger Bereich schlägt fehl und listet die sichtbaren Bereiche auf, statt stillschweigend das ganze Fenster aufzunehmen. |
| `ui_scroll` | Rollt den Hauptbereich der aktiven Seite an den Anfang, an das Ende oder um ganze Sichtfenster und liefert die Offsets zurück, sodass eine lange Seite abgefahren werden kann. |
| `ui_set_theme` | Wendet das Design der Station an (System, Light oder Dark): das Design, in dem das Fenster der Station zeichnet und dem jeder Browser folgt, der kein eigenes gewählt hat; ein Browser, der ein eigenes gewählt hat, behält es. Es wird genauso dauerhaft gespeichert wie eine Wahl mit den Tasten für das Design im Fenster der Station, ein wohlerzogener Agent stellt den ursprünglichen Wert danach also wieder her. |
| `ui_resize` | Ändert die Größe des wiederhergestellten Fensters in geräteunabhängigen Einheiten, begrenzt auf die Mindestgröße des Fensters; nützlich, um enge Layouts zu prüfen. |
| `ui_click` | Klickt die sichtbare Schaltfläche, den Link, das Kontrollkästchen oder den Schalter, dessen Text passt; Kontrollkästchen und Schalter werden über ihre Feldbeschriftung gefunden, und das Ergebnis meldet den erreichten Zustand. Bei Mehrdeutigkeit kommen die Kandidaten zurück, statt dass einer geraten wird. |
| `ui_set_text` | Schreibt einen Wert in ein Textfeld, das über seine Feldbeschriftung gefunden wird, und übernimmt die Bindung so, wie es das Tippen täte. |
| `ui_select` | Wählt einen Eintrag über seinen sichtbaren Text: Ein durch Schrägstriche getrennter Pfad läuft durch einen Baum und klappt ihn dabei auf; ein einzelnes Segment trifft auch Einträge in Listen, Registerkarten und Auswahlfeldern sowie Zeilen einer Tabelle auf der aktuellen Seite. |

## Sicherungen: Verwalten {#backups--manage}

| Werkzeug | Wirkung |
| --- | --- |
| `backup_create` | Erzeugt im laufenden Betrieb eine Momentaufnahme der Konfigurationsdatenbank im Ordner der Sicherungen, mit einer optionalen Notiz. Aufgezeichnete Läufe liegen außerhalb der Konfiguration und werden von Sicherung und Wiederherstellung nie berührt. |
| `backup_list` | Listet die Sicherungen der Konfiguration auf (Dateiname, Zeitpunkt der Erstellung, Größe, Notiz) sowie eine bereits eingeplante Wiederherstellung. |

Es gibt bewusst **kein Werkzeug zum Löschen von Sicherungen**: Die Aufbewahrung liegt allein
beim Bediener, auf der Seite [Sicherungen](settings-backups).

## Sicherungen: Wiederherstellen {#backups--restore}

| Werkzeug | Wirkung |
| --- | --- |
| `backup_restore` | Plant ein, dass eine Sicherung die aktuelle Konfiguration beim **nächsten** Start der Anwendung ersetzt. In der laufenden Anwendung ändert sich nichts, und das Werkzeug startet sie nie neu; von der Konfiguration, die ersetzt wird, wird zuvor automatisch eine Momentaufnahme angelegt, und der Bediener kann die eingeplante Wiederherstellung bis zum Neustart in den Einstellungen abbrechen. Wird abgelehnt, solange eine Aufzeichnung läuft. |

## Einstellungen: Verwalten {#settings--manage}

| Werkzeug | Wirkung |
| --- | --- |
| `settings_read` | Liest die Einstellungen der Station für Anzeige und Verhalten: Formate für Datum, Uhrzeit und Zahlen, Nachkommastellen, Design sowie die Kennzeichen für Schließen in den Infobereich und für Absturzberichte. |
| `localization_set` | Ändert die Einstellungen für die Anzeige (teilweise: weggelassene Parameter bleiben). Nur die Anzeige: Speicherung, Ein- und Ausgabe der Treiber und Aufzeichnungen verwenden immer das invariante Format. |
| `asset_list` | Listet die eigenen Ressourcen auf (Bilder, Icons, Farben), mit IDs, Werten und Pfaden. |
| `asset_import` | Importiert eine PNG- oder JPG-Datei von einem lokalen Pfad in die Ressourcenbibliothek der Anwendung und liefert die ID der neuen Ressource. Die Bytes werden kopiert, die Quelldatei darf danach also verschoben werden. |
| `symbol_validate` | Prüft übergebenen Symbolinhalt (reines SVG oder ein Paket der Version 2), ohne etwas zu speichern: ein Trockenlauf genau desselben Imports, der Fehler, Warnungen der Bereinigung und eine Zusammenfassung des Erkannten liefert. Die Beschreibung des Werkzeugs enthält den vollständigen [Vertrag für portable Symbole](ganter-symbols). |
| `symbol_import` | Importiert übergebenen Symbolinhalt als neue eigene Symbolressource und liefert deren ID und den Verweis `user:<guid>`. Erzeugt immer eine neue Ressource; ein bereits vergebener Name erhält automatisch einen Zusatz. |

## Meldungen: Entwerfen {#reports--draft}

| Werkzeug | Wirkung |
| --- | --- |
| `report_draft` | Öffnet das [Meldeformular](account-feedback#a-report-drafted-by-an-agent) im Fenster der Station, schon ausgefüllt mit dem, was der Agent geschrieben hat: `kind` (`DriverRequest`, `Bug` oder `Suggestion`), `summary` (eine Zeile mit höchstens 120 Zeichen; eine längere wird abgelehnt, nicht gekürzt) und `details` (optional). Wie die Schaltfläche Melden in der Titelleiste nimmt es zuerst ein Bildschirmfoto des Fensters auf und bietet es mit der Meldung an, mit gesetztem Häkchen. Es antwortet sofort, dass das Formular offen ist und nichts gesendet wurde. |

Das Werkzeug sendet nie. Die Person an der Station liest die Meldung, korrigiert sie, wenn sie will, und drückt Senden; das Ergebnis erscheint in der Statusleiste der Station und wird dem Agenten nicht zurückgemeldet. Solange dieser Bereich ein ist, bittet der Server jeden Agenten, eine Meldung anzubieten, wenn die Person einen Treiber braucht, den Ganter Lab nicht hat, wenn ein Aufruf so fehlschlägt, dass es nach einem Fehler des Programms aussieht, oder wenn die Person sich eine Verbesserung wünscht; die Beschreibungen von `driver_capabilities`, `device_upsert` und `device_discover` sagen dasselbe.

Es lehnt mit einem `reason` ab und öffnet dann nichts und nimmt nichts auf:

| `reason` | Wann |
| --- | --- |
| `not_permitted` | Die an der Station angemeldete Rolle hat Meldungen an Ganter senden nicht. |
| `no_station_window` | Die Station hat kein eigenes Fenster, in dem sich das Formular öffnen ließe: ein Host, der seine Seiten nur Browsern ausliefert. |
| `no_credential` | Die Sitzung kann nicht senden: das Profil der Vorführung, angemeldet oder nicht, oder eine Anmeldung am Ganter-Konto der Station, die keine Anmeldedaten hält. |
| `form_busy` | Das Meldeformular ist an der Station offen, oder eine Meldung wird gerade aufgenommen oder gesendet. |
| `draft_in_progress` | Das Formular enthält eine Meldung, die eine Person gerade schreibt. Ein früherer Entwurf des Agenten, den niemand geändert hat, wird dagegen ersetzt. |

Eine Station, die an keinem Ganter-Konto angemeldet ist, wird nicht abgewiesen: das Formular öffnet
sich und sagt, dass die Meldung ohne Konto hinausgeht und Ganter deshalb nicht darauf antworten kann.

Wie jedes Werkzeug, das etwas ändert, antwortet es `Runtime stopped`, solange die Runtime gestoppt ist.
