Le bloc Script (JavaScript) exécute votre code sur chaque message. Utilisez-le lorsque les autres blocs ne peuvent pas exprimer ce dont vous avez besoin : décoder un format binaire inhabituel, parcourir une liste, construire un objet complexe. Privilégiez les blocs prêts à l’emploi lorsqu’ils conviennent : ils sont plus faciles à lire, ne nécessitent aucune allocation de script et s’exécutent plus rapidement.
Paramètres
| Paramètre | Signification | Par défaut | Valeurs |
|---|---|---|---|
| code | Le script | un exemple | obligatoire ; jusqu’à 64 KiB |
| sorties | Nombre de sorties | 1 | De 1 à 4 (o0 à o3) |
| libellés | Noms des sorties, séparés par des virgules | vide | lettres, chiffres, _, espace et - ; un par sortie, tous différents |
Chaque bloc script d’un flux déployé compte dans les blocs Script de votre forfait (3, 6 ou 29 selon le palier IoT). Un déploiement qui contient un script est un déploiement à risque Code : il demande de saisir le nom du flux et est audité (« Script changed »).
Ce que voit le code
L’éditeur affiche la signature au-dessus du champ de code : msg, node, context, flow, global, env → return msg | [a, b] | [[a, b]] | "label" | nothing.
| Nom | Ce que c’est |
|---|---|
msg | Le message, une copie que vous pouvez modifier. msg.metadata est modifiable, sauf les champs système ; msg.msgType et msg.originator sont en lecture seule. |
node.send(msg) | Envoie un message sur la sortie 1 immédiatement (node.send([a, b]) choisit les sorties comme le fait un return) |
node.status({ fill, shape, text }) | Le statut affiché sous le bloc |
node.warn(value), node.error(text) | Écrit dans le journal du bloc |
context.get("key"), context.set("key", value) | Un stockage propre à ce bloc |
flow.get(…), flow.set(…) | Les variables du flux, partagées avec les chemins flow.* des autres blocs |
global.get(…), global.set(…) | Les variables de l’organisation (global.*) |
env.get(name) | Une valeur d’environnement |
console.log(value) | Le même journal que node.warn |
Utilisez la clé persist:name pour le stockage persistant, par exemple flow.set("persist:total", 12). Affecter undefined à une clé la supprime.
Les écritures de contexte sont appliquées après l’exécution du script. La première écriture au-delà de la limite d’un stockage interrompt les suivantes, et le message sort par la sortie error avec limit ; les écritures précédentes restent.
Ce qu’il peut renvoyer
| Retour | Effet |
|---|---|
return msg | Envoie le message sur la sortie 1 |
return [a, b] | a sur la sortie 1, b sur la sortie 2 (jusqu’à 4) ; null n’envoie rien sur cette sortie |
return [[a, b]] | Les deux sur la sortie 1 |
return "alarm" | Le message entrant sur la sortie libellée alarm |
Rien (undefined, null, []) | Rien n’est envoyé ; le message s’arrête ici |
64 messages au maximum par exécution. Un nouvel objet tel que return { payload: 1 } est complété à partir de l’entrée ; un objet qui définit un champ du moteur avec une autre valeur échoue avec readonly_field.
Utilitaires
| Espace de noms | Fonctions |
|---|---|
bytes | fromHex, toHex, fromBase64, toBase64, sha256, toText, fromText, readUint, readInt, readFloat, writeUint, writeInt, writeFloat ; aussi TextEncoder, TextDecoder |
num | round(value, digits), toHex(value, { bytes, bigEndian, prefix }) |
bits | fromBytes, fromInt, toInt, get |
obj | flatten(value, { separator, exclude, pathInKey }) |
time | parse, format, add, fields, avec des motifs tels que yyyy-MM-dd HH:mm:ss et des fuseaux IANA |
Non disponibles : require, import(), eval, Function, fetch, les minuteurs (utilisez un bloc Delay), process, Buffer, WebAssembly. Le script n’a accès ni au réseau, ni aux fichiers, ni aux identifiants. Date est l’horloge réelle.
Limites
| Limite | Valeur |
|---|---|
| Temps CPU par message | 50 ms (votre forfait peut autoriser jusqu’à 200 ms) |
| Mémoire | 32 MiB |
| Code | 64 KiB |
| Messages renvoyés | 64 |
| Taille des messages, en entrée ou en sortie | 256 KiB |
| Contexte transmis en entrée | 64 KiB |
Trois arrêts forcés d’affilée (timeout ou memory) bloquent le script pendant 60 secondes : les messages échouent alors avec blocked sans être exécutés. Le temps CPU de chaque exécution compte dans le total mensuel Script CPU de la carte d’utilisation.
Erreurs
La sortie error transporte msg.error.code :
| Code | Signification |
|---|---|
script | Le code a levé une exception ; line et col indiquent où |
timeout, memory | Dépassement du temps CPU ou de la mémoire |
limit | Plus de 64 messages renvoyés, ou une écriture de contexte au-delà de sa limite |
msg_too_big | Un message de plus de 256 KiB |
unknown_label | Un libellé renvoyé qu’aucune sortie ne possède |
bad_return | Une valeur renvoyée qui n’est ni un message, ni une liste, ni un libellé (ni une promesse) |
readonly_field | Modification de msgType, de originator ou d’un champ système |
blocked | Mis en pause après trois arrêts forcés |
host_busy | Le bac à sable est resté occupé après plusieurs tentatives |
script_unavailable | Le service de script n’est pas disponible |
Tester le script
Tester le script dans le panneau du bloc exécute le code une fois sur le bac à sable réel : « Rien n’est déployé ; Enregistrer place le code dans le bloc. » Renseignez Payload (JSON), Metadata (JSON object), Message type, Originator type et Originator id, éventuellement Context (optional JSON) sous la forme { "node": {…}, "flow": {…}, "global": {…} }, puis sélectionnez Run. Le résultat affiche chaque sortie, le journal, le contexte écrit et le temps CPU. Save into the block conserve le code.
Exemples
Décoder un flottant sur 4 octets à partir d’une charge utile hexadécimale brute :
const data = bytes.fromHex(msg.payload.raw_hex);
msg.payload = { level_m: num.round(bytes.readFloat(data, 0, 4, { bigEndian: true }), 3) };
return msg;
Découper un message contenant une liste de capteurs en une lecture par clé de capteur :
// 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;
Router selon une classe calculée vers des sorties libellées (libellés ok,warn,crit) :
const t = msg.payload.temperature;
if (typeof t !== 'number') return null;
return t > 8 ? 'crit' : t > 6 ? 'warn' : 'ok';
Conserver un total cumulé d’un message à l’autre :
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;
Quand ne pas utiliser de script
| Besoin | Utiliser à la place |
|---|---|
| Une formule | Calculate |
| Renommer, copier ou supprimer des clés | Change |
| Champs binaires | Bytes |
| Aiguillage selon une valeur | Switch ou If / else |
| Consommation à partir d’un compteur | Delta |
| Temporisation | Delay, Trigger, Timer |
Voir Blocs de transformation de données et Limites des flux.

