Neu: Die KI-Firewall überwacht jedes Modul und erklärt jeden Vorfall in einfachen Worten. So funktioniert es

Der Script-Block

Führen Sie eigenes JavaScript in einem Flow aus – was der Code sieht und zurückgibt, Kontext, Hilfsfunktionen, Grenzwerte, Fehler, Tests und Beispiele.

Der Block Script (JavaScript) führt Ihren Code für jede Nachricht aus. Verwenden Sie ihn, wenn die übrigen Blöcke nicht ausdrücken können, was Sie brauchen: Decodieren eines ungewöhnlichen Binärformats, Durchlaufen einer Liste, Erstellen eines komplexen Objekts. Bevorzugen Sie die fertigen Blöcke, wenn sie passen: Sie sind leichter zu lesen, benötigen kein Script-Kontingent und laufen schneller.

Einstellungen

EinstellungBedeutungStandardWerte
codeDas Scriptein Beispielerforderlich; bis zu 64 KiB
AusgängeAnzahl der Ausgänge11 bis 4 (o0 bis o3)
labelsAusgabenamen, durch Kommas getrenntleerBuchstaben, Ziffern, _, Leerzeichen und -; einer pro Ausgang, alle verschieden

Jeder Script-Block in einem bereitgestellten Flow zählt auf das Kontingent Ihres Tarifs für Script-Blöcke (3, 6 oder 29 je nach IoT-Stufe). Eine Bereitstellung, die ein Script enthält, ist eine Bereitstellung mit Code-Risiko: Sie verlangt, dass der Name des Flows eingetippt wird, und wird protokolliert („Script changed“).

Was der Code sieht

Der Editor zeigt die Signatur über dem Codefeld: msg, node, context, flow, global, env → return msg | [a, b] | [[a, b]] | "label" | nothing.

NameWas es ist
msgDie Nachricht, eine Kopie, die Sie ändern dürfen. msg.metadata ist beschreibbar, außer den Systemfeldern; msg.msgType und msg.originator sind schreibgeschützt.
node.send(msg)Sendet eine Nachricht sofort auf Ausgang 1 (node.send([a, b]) wählt Ausgänge wie eine Rückgabe)
node.status({ fill, shape, text })Der Status, der unter dem Block angezeigt wird
node.warn(value), node.error(text)Schreibt in das Protokoll des Blocks
context.get("key"), context.set("key", value)Ein Speicher dieses Blocks
flow.get(…), flow.set(…)Die Variablen des Flows, geteilt mit den Pfaden flow.* in anderen Blöcken
global.get(…), global.set(…)Die Variablen der Organisation (global.*)
env.get(name)Ein Umgebungswert
console.log(value)Dasselbe Protokoll wie node.warn

Verwenden Sie den Schlüssel persist:name für den persistenten Speicher, zum Beispiel flow.set("persist:total", 12). Wird ein Schlüssel auf undefined gesetzt, wird er gelöscht.

Kontext-Schreibvorgänge werden angewendet, nachdem das Script gelaufen ist. Der erste Schreibvorgang über dem Limit eines Speichers stoppt die übrigen, und die Nachricht verlässt den Block über error mit limit; frühere Schreibvorgänge bleiben erhalten.

Was zurückgegeben werden darf

RückgabeWirkung
return msgSendet die Nachricht auf Ausgang 1
return [a, b]a auf Ausgang 1, b auf Ausgang 2 (bis zu 4); null sendet auf diesem Ausgang nichts
return [[a, b]]Beide auf Ausgang 1
return "alarm"Die eingehende Nachricht auf dem Ausgang mit dem Label alarm
Nichts (undefined, null, [])Es wird nichts gesendet; die Nachricht endet hier

Höchstens 64 Nachrichten pro Lauf. Ein neues Objekt wie return { payload: 1 } wird aus der Eingabe ergänzt; setzt es ein Engine-Feld auf einen anderen Wert, schlägt es mit readonly_field fehl.

Hilfsfunktionen

NamensraumFunktionen
bytesfromHex, toHex, fromBase64, toBase64, sha256, toText, fromText, readUint, readInt, readFloat, writeUint, writeInt, writeFloat; außerdem TextEncoder, TextDecoder
numround(value, digits), toHex(value, { bytes, bigEndian, prefix })
bitsfromBytes, fromInt, toInt, get
objflatten(value, { separator, exclude, pathInKey })
timeparse, format, add, fields, mit Mustern wie yyyy-MM-dd HH:mm:ss und IANA-Zonen

Nicht verfügbar: require, import(), eval, Function, fetch, Timer (verwenden Sie einen Block Delay), process, Buffer, WebAssembly. Das Script hat keinen Netzwerkzugriff, keine Dateien und keine Zugangsdaten. Date ist die echte Uhr.

Grenzwerte

GrenzwertWert
CPU-Zeit pro Nachricht50 ms (Ihr Tarif erlaubt eventuell bis zu 200 ms)
Speicher32 MiB
Code64 KiB
Zurückgegebene Nachrichten64
Nachrichtengröße, ein- und ausgehend256 KiB
übergebener Kontext64 KiB

Drei Abbrüche in Folge (timeout oder memory) sperren das Script für 60 Sekunden: Nachrichten schlagen dann mit blocked fehl, ohne zu laufen. Die CPU-Zeit jedes Laufs zählt auf die monatliche Script-CPU auf der Nutzungskarte.

Fehler

Der Ausgang error enthält msg.error.code:

CodeBedeutung
scriptDer Code hat einen Fehler ausgelöst; line und col zeigen, wo
timeout, memoryÜber der CPU-Zeit oder dem Speicher
limitMehr als 64 zurückgegebene Nachrichten oder ein Kontext-Schreibvorgang über seinem Limit
msg_too_bigEine Nachricht über 256 KiB
unknown_labelEin Label zurückgegeben, das kein Ausgang hat
bad_returnEtwas zurückgegeben, das keine Nachricht, keine Liste und kein Label ist (oder ein Promise)
readonly_fieldmsgType, originator oder ein Systemfeld geändert
blockedNach drei Abbrüchen pausiert
host_busyDie Sandbox war nach einigen Versuchen weiterhin belegt
script_unavailableDer Script-Dienst ist nicht verfügbar

Das Script testen

Script testen im Block-Panel führt den Code einmal in der echten Sandbox aus: „Nichts wird bereitgestellt; Speichern übernimmt den Code in den Block.“ Füllen Sie Payload (JSON), Metadata (JSON object), Message type, Originator type und Originator id aus, optional Context (optional JSON) als { "node": {…}, "flow": {…}, "global": {…} }, und wählen Sie Run. Das Ergebnis zeigt jeden Ausgang, das Protokoll, den geschriebenen Kontext und die CPU-Zeit. In den Block speichern behält den Code.

Beispiele

Ein 4-Byte-Float aus einer rohen Hex-Payload decodieren:

const data = bytes.fromHex(msg.payload.raw_hex);
msg.payload = { level_m: num.round(bytes.readFloat(data, 0, 4, { bigEndian: true }), 3) };
return msg;

Eine Nachricht mit einer Liste von Sensoren in je einen Messwert pro Sensorschlüssel aufteilen:

// in: { "sensors": [ { "id": "t1", "v": 21.5 }, { "id": "t2", "v": 19.0 } ] }
const out = {};
for (const s of msg.payload.sensors || []) out[`temp_${s.id}`] = s.v;
msg.payload = out; // { temp_t1: 21.5, temp_t2: 19 }
return msg;

Nach einer berechneten Klasse auf beschriftete Ausgänge leiten (Labels ok,warn,crit):

const t = msg.payload.temperature;
if (typeof t !== 'number') return null;
return t > 8 ? 'crit' : t > 6 ? 'warn' : 'ok';

Eine laufende Summe über Nachrichten hinweg führen:

const total = (flow.get('persist:litres_total') || 0) + (msg.payload.litres || 0);
flow.set('persist:litres_total', total);
msg.payload.litres_total = total;
return msg;

Wann man kein Script verwenden sollte

BedarfStattdessen verwenden
Eine FormelCalculate
Schlüssel umbenennen, kopieren oder löschenChange
Binäre FelderBytes
Verzweigung anhand eines WertsSwitch oder If / else
Verbrauch aus einem ZählerDelta
WartenDelay, Trigger, Timer

Siehe Datentransformations-Blöcke und Flow-Limits.