Anleitung - Aktualisierung des TEMPO-Tarifs (Aktualisierung via PDF im Auto)

Hallo zusammen,

Wie versprochen im Tutorial von @mutmut: (Danke für das Tutorial)

Und nach meinem Tutorial, das es ermöglicht, die Tarife außerhalb von Tempo abzurufen:

Wollte ich sehen, wie man die verschiedenen Kosten automatisch abrufen kann.

Ich bin dann auf dieses Jeedom-Tutorial gestoßen (Danke an den Autor), von dem ich mich stark inspirieren ließ, mit der Kopie des Node-Red-Codes:

Das Ziel hier ist es, die PDF-Datei des Tempo-Tariftarifs direkt von der EDF-Website abzurufen, um die Werte direkt in Gladys zu aktualisieren und den tatsächlichen Kosten pro kWh bereit zu haben, um sie in anderen Szenen zu verwenden :slight_smile:

Die Datei ist hier zu finden:
https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf

Man muss nur hoffen, dass die Struktur/Zusammensetzung der Datei nicht von EDF geändert wird :grin:

Das Endergebnis:

image

Hier ist der Node-Red-Fluss:
(Ein Catch-All ist vorhanden, um Fehler abzufangen und per E-Mail zu senden)

[
    {
        "id": "670838a9edef0758",
        "type": "catch",
        "z": "d6333988d9cfb817",
        "name": "Fehler",
        "scope": null,
        "uncaught": false,
        "x": 110,
        "y": 60,
        "wires": [
            [
                "c097dad994334b5e"
            ]
        ]
    },
    {
        "id": "c097dad994334b5e",
        "type": "e-mail",
        "z": "d6333988d9cfb817",
        "server": "monserveuremail",
        "port": "465",
        "authtype": "BASIC",
        "saslformat": false,
        "token": "oauth2Response.access_token",
        "secure": true,
        "tls": true,
        "name": "monadresse@email.fr",
        "dname": "Mail",
        "x": 250,
        "y": 60,
        "wires": []
    },
    {
        "id": "bf708d78a507d9c3",
        "type": "http request",
        "z": "d6333988d9cfb817",
        "name": "",
        "method": "GET",
        "ret": "bin",
        "paytoqs": "ignore",
        "url": "https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 430,
        "y": 140,
        "wires": [
            [
                "c6602cec6bea28ca"
            ]
        ]
    },
    {
        "id": "c6602cec6bea28ca",
        "type": "file",
        "z": "d6333988d9cfb817",
        "name": "",
        "filename": "/tmp/Grille_prix_Tarif_Bleu.pdf",
        "filenameType": "str",
        "appendNewline": true,
        "createDir": false,
        "overwriteFile": "true",
        "encoding": "none",
        "x": 290,
        "y": 200,
        "wires": [
            [
                "866bd16b214c1d1d"
            ]
        ]
    },
    {
        "id": "a0349e7017779b4a",
        "type": "change",
        "z": "d6333988d9cfb817",
        "name": "Text",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.text",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 670,
        "y": 200,
        "wires": [
            [
                "d23eb75a79c8996d"
            ]
        ]
    },
    {
        "id": "d23eb75a79c8996d",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Nach \"Option Tempo\"",
        "func": "const regex = /Option Tempo((.|\\n)*)/gm;\nconst found = msg.payload.match(regex);\nmsg.payload = found[0];\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 480,
        "y": 280,
        "wires": [
            [
                "09faecd167fed230"
            ]
        ]
    },
    {
        "id": "09faecd167fed230",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "6 kVA",
        "func": "const regex = /^12\b.*$/gm; // Leistung\nconst found = msg.payload.match(regex);\nconst searchRegExp = /,/g; // ersetzt Kommas durch Punkte\nconst replaceWith = '.';\nmsg.payload = found[0];\nmsg.payload = msg.payload.replace(searchRegExp, replaceWith);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 670,
        "y": 280,
        "wires": [
            [
                "e7ca8ee4d891c581"
            ]
        ]
    },
    {
        "id": "e7ca8ee4d891c581",
        "type": "split",
        "z": "d6333988d9cfb817",
        "name": "",
        "splt": " ",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 510,
        "y": 360,
        "wires": [
            [
                "9f3df8ae0bd5d4bf"
            ]
        ]
    },
    {
        "id": "9f3df8ae0bd5d4bf",
        "type": "join",
        "z": "d6333988d9cfb817",
        "name": "",
        "mode": "custom",
        "build": "array",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "num",
        "reduceFixup": "",
        "x": 650,
        "y": 360,
        "wires": [
            [
                "88eaf52f02be48c8"
            ]
        ]
    },
    {
        "id": "88eaf52f02be48c8",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "JSON",
        "func": "msg.payload = {\n    \"puissance\": msg.payload[0],\n    \"prix_abonnement\": Number((Number(msg.payload[1]) * 12).toFixed(2)),\n    \"prix_HCJB\": Number(Number(msg.payload[2] / 100).toFixed(4)),\n    \"prix_HPJB\": Number(Number(msg.payload[3] / 100).toFixed(4)),\n    \"prix_HCJW\": Number(Number(msg.payload[4] / 100).toFixed(4)),\n    \"prix_HPJW\": Number(Number(msg.payload[5] / 100).toFixed(4)),\n    \"prix_HCJR\": Number(Number(msg.payload[6] / 100).toFixed(4)),\n    \"prix_HPJR\": Number(Number(msg.payload[7] / 100).toFixed(4)),\n}\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 790,
        "y": 360,
        "wires": [
            [
                "6e2b78e27c34c026",
                "4d19e36f157bd2c0",
                "50608e9e9bdecdc6",
                "d9fe4a5ac7c52d90",
                "b4a2b0d2177a9058",
                "c5f9959555f3e7b9"
            ]
        ]
    },
    {
        "id": "1316dbce795332d5",
        "type": "inject",
        "z": "d6333988d9cfb817",
        "name": "Jeden Tag um 9:30 Uhr",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "30 09 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 140,
        "wires": [
            [
                "bf708d78a507d9c3"
            ]
        ]
    },
    {
        "id": "866bd16b214c1d1d",
        "type": "pdfparse",
        "z": "d6333988d9cfb817",
        "name": "",
        "path": "/tmp/Grille_prix_Tarif_Bleu.pdf",
        "x": 520,
        "y": 200,
        "wires": [
            [
                "a0349e7017779b4a"
            ]
        ]
    },
    {
        "id": "6e2b78e27c34c026",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Blauer Tag HC",
        "func": "msg.payload = msg.payload.prix_HCJB;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 960,
        "y": 300,
        "wires": [
            [
                "0a6e473635b8b423"
            ]
        ]
    },
    {
        "id": "4d19e36f157bd2c0",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Blauer Tag HP",
        "func": "msg.payload = msg.payload.prix_HPJB;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 960,
        "y": 340,
        "wires": [
            [
                "69c1fb09c3ede0e0"
            ]
        ]
    },
    {
        "id": "50608e9e9bdecdc6",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Weißer Tag HC",
        "func": "msg.payload = msg.payload.prix_HCJW;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 970,
        "y": 380,
        "wires": [
            [
                "467f6ce03f7ed6c0"
            ]
        ]
    },
    {
        "id": "d9fe4a5ac7c52d90",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Weißer Tag HP",
        "func": "msg.payload = msg.payload.prix_HPJW;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 970,
        "y": 420,
        "wires": [
            [
                "ed628e4d71dbbc38"
            ]
        ]
    },
    {
        "id": "b4a2b0d2177a9058",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Roter Tag HC",
        "func": "msg.payload = msg.payload.prix_HCJR;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 970,
        "y": 460,
        "wires": [
            [
                "f2b3869570196614"
            ]
        ]
    },
    {
        "id": "c5f9959555f3e7b9",
        "type": "function",
        "z": "d6333988d9cfb817",
        "name": "Roter Tag HP",
        "func": "msg.payload = msg.payload.prix_HPJR;\nmsg.payload = parseFloat(msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 970,
        "y": 500,
        "wires": [
            [
                "ae1d548f6cb679aa"
            ]
        ]
    },
    {
        "id": "0a6e473635b8b423",
        "type": "mqtt out",
        "z": "d6333988d9cfb817",
        "name": "",
        "topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-bleu-hc/state",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "0ee77e0f90aa9681",
        "x": 1370,
        "y": 300,
        "wires": []
    },
    {
        "id": "69c1fb09c3ede0e0",
        "type": "mqtt out",
        "z": "d6333988d9cfb817",
        "name": "",
        "topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-bleu-hp/state",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "0ee77e0f90aa9681",
        "x": 1370,
        "y": 340,
        "wires": []
    },
    {
        "id": "467f6ce03f7ed6c0",
        "type": "mqtt out",
        "z": "d6333988d9cfb817",
        "name": "",
        "topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-blanc-hc/state",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "0ee77e0f90aa9681",
        "x": 1370,
        "y": 380,
        "wires": []
    },
    {
        "id": "ed628e4d71dbbc38",
        "type": "mqtt out",
        "z": "d6333988d9cfb817",
        "name": "",
        "topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-blanc-hp/state",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "0ee77e0f90aa9681",
        "x": 1370,
        "y": 420,
        "wires": []
    },
    {
        "id": "f2b3869570196614",
        "type": "mqtt out",
        "z": "d6333988d9cfb817",
        "name": "",
        "topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-rouge-hc/state",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "0ee77e0f90aa9681",
        "x": 1370,
        "y": 460,
        "wires": []
    },
    {
        "id": "ae1d548f6cb679aa",
        "type": "mqtt out",
        "z": "d6333988d9cfb817",
        "name": "",
        "topic": "gladys/master/device/mqtt:edf/feature/mqtt:cout-abonnement-jour-rouge-hp/state",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "0ee77e0f90aa9681",
        "x": 1370,
        "y": 500,
        "wires": []
    },
    {
        "id": "0ee77e0f90aa9681",
        "type": "mqtt-broker",
        "name": "GLADYS-MQTT",
        "broker": "mqtt://192.168.0.248",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

Denken Sie daran, die abonnierte Leistung zu ändern :slight_smile:

Voraussetzungen:

Installieren Sie das Modul node-red-contrib-pdfparse:

Hier ist das MQTT-Gerät mit den Funktionen:





Hier sind die Szenen:

Weißer Tag - HC:





Weißer Tag - HP:





Blauer Tag - HC:





Blauer Tag - HP:





Roter Tag - HC:





Roter Tag - HP:





Wenn Sie Fragen oder Anmerkungen haben, zögern Sie nicht, mir Bescheid zu sagen :slight_smile:

Changelog in Kürze:

  • Keine (Ihre Kommentare :slight_smile: )

Super Tutorial! Danke @prohand!

Bravo @prohand, ich hatte nicht den Mut, alle meine Screenshots für alle HCHP- und „Guter-Tag“-Fälle einzufügen :wink:
Kleine Frage zu den Triggern, warum hast du einen um 00:01 Uhr gesetzt? Verfolgt Gladys nicht den Übergang von einem Tag zum anderen?

EDIT: Es gibt einen « Download CSV »-Absatz, der am Ende deines Flusses herumliegt (ich habe ihn entfernt, weil ich ihn nicht verstanden habe) und für diejenigen, die einen etwas unberührten Node-Red wie meinen haben, werde ich hinzufügen, dass man pdfparse installieren muss:


Natürlich nicht vergessen, deinen MQTT-Server (mit Login/Passwort) zu konfigurieren.

EDIT 2: @prohand, welches Modul hast du für die E-Mail verwendet?
Ich habe Installationsprobleme :frowning:

2024-12-13T18:18:42.602Z Installer : node-red-node-email 3.0.2

2024-12-13T18:18:42.699Z npm install --no-audit --no-update-notifier --no-fund --save --save-prefix=~ --production --engine-strict node-red-node-email@3.0.2
2024-12-13T18:18:43.732Z [err] npm
2024-12-13T18:18:43.733Z [err]  WARN
2024-12-13T18:18:43.734Z [err]  config production Verwende `--omit=dev` stattdessen.
2024-12-13T18:18:45.070Z [err] npm
2024-12-13T18:18:45.071Z [err]  ERR! code EBADENGINE
2024-12-13T18:18:45.075Z [err] npm
2024-12-13T18:18:45.076Z [err]  ERR!
2024-12-13T18:18:45.076Z [err]  engine Nicht kompatibel mit deiner Node/npm-Version: node-red-node-email@3.0.2
2024-12-13T18:18:45.077Z [err] npm 
2024-12-13T18:18:45.077Z [err] ERR! notsup Nicht kompatibel mit deiner Node/npm-Version: node-red-node-email@3.0.2
2024-12-13T18:18:45.077Z [err] npm ERR! notsup
2024-12-13T18:18:45.077Z [err]  Required: {"node":">=18.0.0"}
2024-12-13T18:18:45.077Z [err] npm 
2024-12-13T18:18:45.077Z [err] ERR! notsup Actual:   {"npm":"8.19.4","node":"v16.20.2"}
2024-12-13T18:18:45.082Z [err] 
2024-12-13T18:18:45.082Z [err] npm ERR!
2024-12-13T18:18:45.083Z [err]  Ein vollständiger Log dieser Ausführung kann gefunden werden in:
2024-12-13T18:18:45.083Z [err] npm ERR!     /data/.npm/_logs/2024-12-13T18_18_43_653Z-debug-0.log
2024-12-13T18:18:45.094Z rc=1

Tatsächlich ist es ein Fehler, dass es um 00:01 Uhr passiert, denn ich dachte, um 00:00 Uhr würde der Tag wechseln…
Aber hier ist der Beweis, dass dem nicht so ist :grin:
image

Daher ist es tatsächlich nicht nötig :slight_smile:
Ich korrigiere die Screenshots direkt nach dieser Nachricht

Ich korrigiere auch den Node-Red-Fluss, das war ein Copy-Paste-Fehler

Ich füge hinzu, dass das Modul pdfparse installiert werden muss

Für die E-Mail habe ich diese hier genommen:

image

Danke für all diese Rückmeldungen :wink:

Hallo,
ich habe gerade gesehen, dass ich dasselbe Node-RED-Modul node-red-node-email wie du installiert habe, aber ich habe nur die Version 3.0.2, während du die 2.2.1 hast. Das Problem ist, dass für dieses Modul in der Version 3.x.x NodeJS >18 benötigt wird :frowning:
Wie hast du es geschafft, diese spezifische Version zu bekommen?
Ich bin für ein Upgrade von NodeJS, wenn es möglich ist, natürlich dabei :wink:

Hallo,

Ich habe es sicherlich heruntergeladen, als es die letzte Version war, ganz einfach ^^
Falls du herausfindest, wie man eine ältere Version installiert, bin ich interessiert :slight_smile:

ich kämpfe : ich habe in einer Docker-Konsole versucht, npm i node-red-node-email@2.2.1 auszuführen
Es heißt, ein neues Modul wurde installiert, andere müssten aktualisiert werden, aber nichts erscheint in node-red, selbst nach einem Neuladen der Webseite.

Dann wollte ich die node-red-Integration von GLadys deaktivieren und sie erneut aktivieren.
Ergebnis: Ich habe alles verloren (Flüsse und installierte Module) :cry:
Die Deaktivierung löscht den Container, aber auch alle Daten, die auf dem gemounteten Volume gespeichert sind (/volume1/docker/gladysassistant/node-red in meinem Fall auf einem Syno). Der totale Verlust :grimacing:

Ich weiß nicht, ob das ein normales Verhalten ist, aber es ist sehr ärgerlich, besonders wenn du dieses Verzeichnis nicht gesichert hast, @pierre-gilles, könntest du uns das sagen?

Aie, ja das übersteigt meine Fähigkeiten ^^
Deshalb sichere ich jeden Abend die gesamte VM auf meiner Seite :slight_smile:
Ich habe auch ein Backup meiner Flüsse an meine E-Mail-Adresse, falls etwas passiert.
Viel Glück dir :neutral_face:

Ich bin nicht der Entwickler dieser Integration, aber ja, das ist das erwartete Verhalten :slight_smile:

Aber eine Warnmeldung wäre trotzdem willkommen!

Ich habe ein Issue erstellt:

@prohand morgen (1. Februar) sollten wir normalerweise wissen, ob die Datei denselben Namen behält und im schlimmsten Fall müssen wir den Link in Node-RED ändern :wink:

Hallo,

Ich sag dir, ich bin gerade nicht mehr im Takt :wink:

EDIT: Alles, was folgt, ist ein großes Missverständnis meinerseits, aber ich lasse es für die Nachverfolgung des Beitrags stehen.

Zusammenfassung

Die URL hat sich leider geändert, hier ist die neue: https://particuliers.es.fr/sites/default/files/documents/2025.02.01_PART_TRV_Bleu_(INF456).pdf
Und auch das Tabellenformat hat sich geändert :frowning:
VORHER:


JETZT:

Und da ich in Node-RED eine Niete bin, ist der Flow auch hinüber…
@prohand, hättest du kurz Zeit, den Flow zu ändern? Vielen Dank im Voraus

Ach Mist :frowning:

Leider werde ich in den nächsten Tagen keine Zeit haben.

Aber es ist nichts wirklich Kompliziertes, du kannst den aktuellen Code an ChatGPT geben und ihn bitten, ihn an den neuen anzupassen.

Für den aktuellen Node-RED-Flow habe ich das schon gemacht :wink:

ich habe mich vertan, weil ich bei ES und nicht bei EDF bin, ich habe die ES-Datei genommen … ich analysiere gerade und suche die EDF-Datei.

Oyé Oyé, ich bin ein Trottel!

Abgesehen davon hat die Datei von EDF seit dem 1. Februar 2025 mit den neuen Tarifen immer noch denselben Namen und dieselbe URL, und alles funktioniert perfekt, ohne etwas zu ändern!

Danke @prohand für den ursprünglichen Flow :wink: und ich werde nicht mehr mehrmals auf meiner Tastatur tippen, bevor ich fünfmal überprüfe :sweat_smile:

EDIT: und zur Info gibt es jetzt die TEMPO-Tarife als Open Data seit dem 30.01.25: Jeu de données - Historique des tarifs réglementés de vente d'électricité pour les consommateurs résidentiels | data.gouv.fr

Hallo,

ich bringe eine kleine Änderung am Regex für die vereinbarte Leistung ein.
Tatsächlich sucht der Regex dieses Jahr bei mir, der einen 12-kVA-Abonnement hat, nach der Zahl 12 im PDF und landet bei einem Verbrauchspreis, nämlich 16,12, und extrahiert nur das, was in der Zeile folgt:


Um sicherzustellen, dass nur die Zeile mit 12 am Anfang genommen wird, muss man Folgendes verwenden:

const regex = /^12\b.*$/gm; // vereinbarte Leistung

^12\b : Die Zeile beginnt mit 12 als Ganzzahl (nicht 112 oder 120).
@prohand, falls du den regex = /6 .*/gm; in der Node-RED-Flusszeile in deinem ersten Beitrag ändern kannst:

"func": "const regex = /6 .*/gm; // vereinbarte Leistung\nconst found = msg.payload.match(regex);\nconst searchRegExp = /,/g; // ersetzt Kommas durch Punkte\nconst replaceWith = '.';\nmsg.payload = found[0];\nmsg.payload = msg.payload.replace(searchRegExp, replaceWith);\nreturn msg;",

das wäre super :slight_smile:

Danke @mutmut
Ich habe im ersten Beitrag geändert :slight_smile: