Widget-Registrierung
Jede ui-base, ui-page und ui-group hat eine .register-Funktion. Die Kernregistrierungsfunktion befindet sich in ui-base.
Diese Funktion wird von allen Widgets verwendet, um das Dashboard über ihre Existenz zu informieren, und ermöglicht es dem Widget, zu definieren, zu welcher Gruppe/Seite/UI es gehört, zusammen mit den relevanten Eigenschaften, die das Widget hat, und allen Ereignishandlern (z.B. onInput oder onAction).
Die Funktion wird innerhalb der Node-RED .js-Datei des Knotens aufgerufen, und im Fall eines Widgets, das als Teil einer Gruppe registriert wird (der häufigste Anwendungsfall), würde es ungefähr so aussehen:
module.exports = function (RED) {
function MyNode (config) {
// Knoten in Node-RED erstellen
RED.nodes.createNode(this, config)
// Referenz auf unseren Node-RED-Knoten speichern
const node = this
// in welcher Gruppe rendern wir dieses Widget
const group = RED.nodes.getNode(config.group)
// ein Objekt, das die zu abonnierenden Ereignisse beschreibt
const evts = {}
// das Dashboard-UI informieren, dass wir diesen Knoten hinzufügen
group.register(node, config, evts)
}
RED.nodes.registerType('ui-mywidget', MyNode)
}Argumente
Die Eingaben der Registrierungsfunktion unterscheiden sich leicht, je nachdem, ob sie auf ui-group, ui-page oder ui-base aufgerufen wird:
group.register(node, config, evts)page.register(group, node, config, evts)base.register(page, group, node, config, evts)
Beachten Sie jedoch, dass sie alle 3 gemeinsame Eingaben haben:
node
Dies ist das this des Konstruktors Ihres Knotens und kann direkt aus dem von Node-RED bereitgestellten Wert verwendet werden.
config
Dies wird von Node-RED als Eingabe für den Konstruktor bereitgestellt und kann im Allgemeinen ohne Änderung direkt in die .register-Funktion übergeben werden. Es wird ein Objekt sein, das alle Eigenschaften und Werte abbildet, die in der .html-Definition des Knotens beschrieben wurden.
evts
Wir stellen eine Reihe verschiedener Ereignishandler als Teil der register-Funktion bereit. Alle diese Handler laufen serverseitig (Node-RED).
In einigen Fällen ist es möglich, vollständige Funktionen zu definieren (die zu einem geeigneten Zeitpunkt im Ereignislebenszyklus ausgeführt werden), in anderen Fällen ist es nur möglich, einen true/false-Wert zu definieren, der das Dashboard darüber informiert, dass Sie möchten, dass das Widget dieses Ereignis sendet oder abonniert.
Eine vollständige Übersicht über den Ereignislebenszyklus finden Sie hier.
const evts = {
onAction: // boolean
onChange: // boolean || function
beforeSend: // function
onInput: // function
onError: // function
onSocket // object
}Ereignisse
Alle diese Ereignishandler definieren Verhalten, das serverseitig ausgeführt wird (d.h. innerhalb von Node-RED). Wenn Sie nach clientseitigen Ereignishandlern suchen, sehen Sie hier.
.onAction (boolean)
Wenn auf true gesetzt, löst dieses Flag den Standardhandler aus, wenn die Dashboard-Widgets ein widget-action-Ereignis senden.
- Weist den bereitgestellten Wert
msg.payloadzu - Fügt ein
msg.topichinzu, das in der Knotenkonfiguration definiert ist - Führt
evts.beforeSend()aus (falls bereitgestellt) - Sendet das
msgan alle verbundenen Knoten mitnode.send(msg)
Ein Beispiel dafür ist ui-button, bei dem das UIButton des Widgets eine @click-Funktion enthält, die folgendes enthält:
this.$socket.emit('widget-action', this.id, msg)Dies sendet eine Nachricht über SocketIO an Node-RED, mit dem Thema der Widget-ID. Da ui-button onAction: true in seiner Registrierung hat, wird es folglich den oben beschriebenen Standardhandler ausführen.
.onChange (boolean || function)
Ähnlich wie onAction, löst dieses Flag, wenn es als Boolean verwendet wird, den Standardhandler für ein onChange-Ereignis aus.
Standard onChange Handler
- Weist den bereitgestellten Wert
msg.payloadzu - Fügt ein
msg.topichinzu, das in der Knotenkonfiguration definiert ist - Führt
evts.beforeSend()aus (falls bereitgestellt) - Speichert die letzte Nachricht auf dem Widget unter der
._msg-Eigenschaft, die den neuesten Zustand/Wert des Widgets enthält - Löst ein
widget-sync-Ereignis aus, um die Widgets in allen Clients zu synchronisieren. - Sendet das
msgan alle verbundenen Knoten
Benutzerdefinierter onChange Handler
Alternativ können Sie dieses Standardverhalten überschreiben, indem Sie eine benutzerdefinierte onChange-Funktion bereitstellen. Ein Beispiel dafür ist der ui-switch-Knoten, der node.status-Updates benötigt, damit der Node-RED-Editor seinen neuesten Status widerspiegelt:
/**
* Eingabe vom Widget verarbeiten
* @param {object} msg - die zuletzt bekannte empfangene Nachricht (vor diesem neuen Wert)
* @param {boolean} value - der vom Widget gesendete aktualisierte Wert
* @param {Socket} conn - socket.io-Socket, der mit dem Server verbindet
* @param {String} id - Widget-ID, die die Aktion sendet
*/
onChange: async function (msg, value, conn, id) {
// sicherstellen, dass wir die neueste Instanz des Widget-Knotens haben
const wNode = RED.nodes.getNode(node.id)
node.status({
fill: value ? 'green' : 'red',
shape: 'ring',
text: value ? states[1] : states[0]
})
// den zugewiesenen Ein-/Aus-Wert abrufen
const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, wNode)
const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, wNode)
msg.payload = value ? on : off
// diese Änderung an alle Clients mit demselben Widget synchronisieren
const exclude = [conn.id]
base.emit('widget-sync:' + id, msg, node, exclude)
// simulieren, dass der Node-RED-Knoten eine Eingabe erhält
wNode.send(msg)
}.beforeSend(msg) (function)
Diese Middleware-Funktion wird ausgeführt, bevor der Knoten eine msg an nachfolgende Knoten sendet, die im Editor verbunden sind (z.B. in onInput, onAction und onChange Standardhandler).
Die Funktion muss msg als Eingabe nehmen und auch msg als Ausgabe zurückgeben.
In ui-button verwenden wir beforeSend, um die msg.payload zu bewerten, da wir ein TypedInput (docs) haben. Das TypedInput muss innerhalb von Node-RED bewertet werden, da es auf Variablen außerhalb der Domäne des Button-Knotens verweisen kann (z.B. global oder flow). Der Standard onInput-Handler nimmt dann die Ausgabe von unserem beforeSend und verarbeitet sie entsprechend.
.onInput(msg, send) (function)
Das Definieren dieser Funktion überschreibt den Standard onInput-Handler.
Standard onInput Handler
- Speichert die letzte Nachricht auf dem Widget unter
node._msg - Fügt ein
msg.topichinzu, das in der Knotenkonfiguration definiert ist - Überprüft, ob das Widget eine
passthru-Eigenschaft hat:- Wenn keine
passthru-Eigenschaft gefunden wird, wirdsend(msg)ausgeführt - Wenn die Eigenschaft vorhanden ist, wird
send(msg)nur ausgeführt, wennpassthruauftruegesetzt ist
- Wenn keine
Benutzerdefinierter onInput Handler
Wenn bereitgestellt, überschreibt dies den Standardhandler.
Wir verwenden dies in den Kern-Widgets im Dashboard mit ui-chart, wo wir die Historie der letzten msg-Werte speichern möchten, anstatt nur den neuesten Wert, wie im Standardhandler. Wir verwenden es auch hier, um sicherzustellen, dass wir nicht zu viele Datenpunkte haben (wie in der ui-chart-Konfiguration definiert).
Ein weiterer Anwendungsfall wäre, wenn Sie keine eingehenden msg-Payloads automatisch an verbundene Knoten weitergeben möchten. Zum Beispiel könnten Sie eine Reihe von Befehlstyp-msg-Payloads haben, die Ihren Knoten anweisen, etwas zu tun, die dann für keine vorhergehenden Knoten im Flow relevant sind.
.onError(err) (function)
Diese Funktion wird innerhalb der Handler für onAction, onChange und onInput aufgerufen. Wenn es jemals ein Problem mit diesen Handlern gibt (einschließlich der bereitgestellten benutzerdefinierten Handler), wird die onError-Funktion aufgerufen.
.onSocket (object)
Dies ist ein etwas einzigartiger Ereignishandler, der nur von extern entwickelten Widgets verwendet wird (d.h. nicht Teil der in dieser Dokumentation beschriebenen Kern-Dashboard-Widgets). Es wird bereitgestellt, damit Entwickler benutzerdefinierte SocketIO-Ereignisse emit und folglich abonnieren können, die von ihren benutzerdefinierten Widgets übertragen werden.
Ein detaillierteres Beispiel finden Sie in unserer Dokumentation hier.
Die allgemeine Struktur von onSocket ist wie folgt:
const evts = {
onSocket: {
'my-custom-event': function (id, msg) {
console.log('my-custom-event', id, msg)
}
}
}Beachten Sie, dass diese Ereignisse vom Dashboard gesendet werden, und daher werden diese Handler innerhalb von Node-RED ausgeführt.
