NEWS
Schreiben und Lesen von Dateien
-
Skript wurde nicht angehalten
Dann kannst du in die Asynchronfalle geraten, dass das Skript die Änderung überschreibt, aber...
Bearbeitung der Datei direkt auf dem Raspi.
Das "geht nicht".
Das wird nicht als geänderte Datei markiert.
Dazu muss sie neu mittels writeFile geschrieben, oder manuell über die GUI hochgeladen werden. -
@A250-Fan ja
-
Ich würde das ja versuchen anders aufzuziehen.
Schreib doch von vorneherein nur plausible Werte in die Datei. Dann musste dich auch nicht so umständlich wieder herausklamüsern. -
Vielleicht solltest du zunächst mal genauer definieren, was du als Ziel hast.
Du willst nur die letzten x Messwerte haben?
Oder willst du händisch Einträge löschen? Nach welchen Kriterien? -
Wenn du die Datei doch eh auf ein Netzlaufwerk haben willst, dann kannst du sie auch direkt dorthin schreiben. So mache ich das z.B. mit diversen Listen. Da wird der neue Text immer nur als Zeile darunter gesetzt.
Ich habe das folgende Blockly damals hier im Forum gefunden, weiß nur nicht mehr wo.

Die JS-Funktion enthält:
const fs = require('fs'); switch(mode) { case 'r': return fs.readFileSync(Dateiname, 'utf8'); case 'w': return fs.writeFileSync(Dateiname, Daten); case 'a': return fs.appendFileSync(Dateiname, Daten); default: return 'Parameter mode muss "r", "w" oder "a" sein'; }Oder hier das Blockly als Export:
<xml xmlns="https://developers.google.com/blockly/xml"> <variables> <variable id="[-H^4u[bLNKmNjJW5uP2">Dateiname</variable> <variable id="B@!nDrO;Ag4]/Ns]5`VT">Daten</variable> <variable id="Nw,T]ZGil{Kmm.Tfd=8`">mode</variable> <variable id="@`{2Tshq:9^uF$%i]pMW">Ergebnis</variable> </variables> <block type="schedule" id=",/z9[bkm:Mx.Xz)_WV}C" x="63" y="-12"> <field name="SCHEDULE">0 12 * * *</field> <statement name="STATEMENT"> <block type="variables_set" id="toixTd-7I(w?Pn.u`a?n"> <field name="VAR" id="[-H^4u[bLNKmNjJW5uP2">Dateiname</field> <value name="VALUE"> <block type="text" id="?(6$X5B~AZEV{a([vl[@"> <field name="TEXT">/opt/iobroker/Test.txt</field> </block> </value> <next> <block type="comment" id="E=!qQw-l-tNwXd3eE2{K"> <field name="COMMENT">schreibe Daten</field> <next> <block type="variables_set" id="OOlava!O!gwl*p7jMH{$"> <field name="VAR" id="@`{2Tshq:9^uF$%i]pMW">Ergebnis</field> <value name="VALUE"> <block type="procedures_callcustomreturn" id="#C-F-T.#.ZD80^Pn[:f}" inline="false"> <mutation name="Datei"> <arg name="Dateiname"></arg> <arg name="Daten"></arg> <arg name="mode"></arg> </mutation> <value name="ARG0"> <block type="variables_get" id="#%2(}]P4^Jg4JwKdoO0^"> <field name="VAR" id="[-H^4u[bLNKmNjJW5uP2">Dateiname</field> </block> </value> <value name="ARG1"> <block type="text_join" id="$s-gtsey+o{l3}RQF^uK"> <mutation items="6"></mutation> <value name="ADD0"> <block type="text_newline" id="cDYlllvQ1RZl;+$EdmU1"> <field name="Type">\n</field> </block> </value> <value name="ADD1"> <block type="time_get" id="|^_IZ6r;?Uk`wi{`![?8"> <mutation xmlns="http://www.w3.org/1999/xhtml" format="false" language="false"></mutation> <field name="OPTION">YYYY.MM.DD</field> </block> </value> <value name="ADD2"> <block type="text" id="/yr|qtO+29$HOSt`J$5t"> <field name="TEXT">;</field> </block> </value> <value name="ADD3"> <block type="time_get" id="leJ5uWCm;,j-I2A]Bi`V"> <mutation xmlns="http://www.w3.org/1999/xhtml" format="false" language="false"></mutation> <field name="OPTION">hh:mm:ss</field> </block> </value> <value name="ADD4"> <block type="text" id="=J#lQk)K7uCMaJghmU^;"> <field name="TEXT">;</field> </block> </value> <value name="ADD5"> <block type="get_value" id="f!OZs64Riw}U2PQFJ^Q8"> <field name="ATTR">val</field> <field name="OID">ID auswählen</field> </block> </value> </block> </value> <value name="ARG2"> <block type="text" id="3up}TP81c9Wp-96*F,5@"> <field name="TEXT">a</field> </block> </value> </block> </value> </block> </next> </block> </next> </block> </statement> </block> <block type="procedures_defcustomreturn" id="y8r,:{{HHSZ8(K/J*Z%." x="588" y="13"> <mutation statements="false"> <arg name="Dateiname" varid="[-H^4u[bLNKmNjJW5uP2"></arg> <arg name="Daten" varid="B@!nDrO;Ag4]/Ns]5`VT"></arg> <arg name="mode" varid="Nw,T]ZGil{Kmm.Tfd=8`"></arg> </mutation> <field name="NAME">Datei</field> <field name="SCRIPT">Y29uc3QgZnMgPSByZXF1aXJlKCdmcycpOw0Kc3dpdGNoKG1vZGUpIHsNCiAgICBjYXNlICdyJzogcmV0dXJuIGZzLnJlYWRGaWxlU3luYyhEYXRlaW5hbWUsICd1dGY4Jyk7DQogICAgY2FzZSAndyc6IHJldHVybiBmcy53cml0ZUZpbGVTeW5jKERhdGVpbmFtZSwgRGF0ZW4pOw0KICAgIGNhc2UgJ2EnOiByZXR1cm4gZnMuYXBwZW5kRmlsZVN5bmMoRGF0ZWluYW1lLCBEYXRlbik7DQogICAgZGVmYXVsdDogcmV0dXJuICdQYXJhbWV0ZXIgbW9kZSBtdXNzICJyIiwgInciIG9kZXIgImEiIHNlaW4nOw0KfQ==</field> <comment pinned="false" h="80" w="160">Beschreibe diese Funktion …</comment> </block> </xml>Gruß, Johannes
-
@homoran
Habe heute weiter getestet.
Test 1: Skript angehalten, Datei geändert, Skript wieder gestartet. Ergebnis: Die gelöschten Zeilen erscheinen nach dem nächsten Schreibzugriff von Blockly wieder.
Test 2: Skript angehalten, Datei in anderes Verzeichnis verschoben, geändert und wieder im ursprünglichen Verzeichnis gespeichert. Ergebnis: Die gelöschten Zeilen erscheinen nach dem nächsten Schreibzugriff von Blockly wieder. -
@jojo58
Hallo jojo58, auch deinen Vorschlag habe ich getestet. Das funktioniert auch wie ich mir das vorgestellt habe. Das ursprünglich ausgessuchte Verzeichnis für die Datei mochte dein Skript allerdings nicht (da gibt es wohl nicht die passenden Rechte). Das macht aber nichts, letztendlich ist es mir nicht wichtig in welchem Verzeichnis die Datei liegt. Mein Problem ist damit gelöst. Herzlichen Dank! -
@jojo58
Hallo jojo58, auch deinen Vorschlag habe ich getestet. Das funktioniert auch wie ich mir das vorgestellt habe. Das ursprünglich ausgessuchte Verzeichnis für die Datei mochte dein Skript allerdings nicht (da gibt es wohl nicht die passenden Rechte). Das macht aber nichts, letztendlich ist es mir nicht wichtig in welchem Verzeichnis die Datei liegt. Mein Problem ist damit gelöst. Herzlichen Dank!Das kann sein, bei der Version ins Dateisystem schreiben, muss der Ordner und die Datei schon vorhanden sein und die Gruppe iobroker muss darauf Schreibrechte haben.
Wenn du es noch einfacher haben willst und anstatt manuell Zeilen zu löschen, kannst du den folgenden Code in der Funktion nutzen. Darin die let maxLines = 100 an deine Bedürfnisse anpassen und dann wird die Liste immer nur so lang, wie du gesetzt hast. Die ältesten Zeilen werden dann gelöscht.
Den folgenden Code in der Funktion setzen und bei "mode" nicht a sondern "aL" (append Limit) eintragen.const fs = require('fs'); switch (mode) { case 'r': return fs.readFileSync(Dateiname, 'utf8'); case 'w': return fs.writeFileSync(Dateiname, Daten); case 'a': return fs.appendFileSync(Dateiname, Daten); case 'aL': let maxLines = 100; let content = ''; if (fs.existsSync(Dateiname)) { content = fs.readFileSync(Dateiname, 'utf8'); } let lines = content === '' ? [] : content.split(/\r?\n/); // Technischen leeren letzten Eintrag entfernen, // wenn die Datei mit Zeilenumbruch endet if (lines.length > 0 && lines[lines.length - 1] === '') { lines.pop(); } // Führende Zeilenumbrüche aus neuen Daten entfernen, // damit keine Leerzeilen zwischen den Einträgen entstehen let neuerEintrag = String(Daten).replace(/^\r?\n+/, ''); // Neuen Eintrag unten anhängen lines.push(neuerEintrag); // Maximal 100 Zeilen behalten if (lines.length > maxLines) { lines = lines.slice(-maxLines); } fs.writeFileSync(Dateiname, lines.join('\n') + '\n'); return `OK (${lines.length}/${maxLines})`; default: return 'Parameter mode muss "r", "w", "a" oder "aL" sein'; }Die Änderungen habe ich mit Hilfe von KI gemacht.
Gruß, Johannes
-
@jojo58
Interessante Idee. Die KI zu befragen ist mir bisher noch nicht in den Sinn gekommen, obwohl ich schon mal davon gehört habe, daß KI auch Quellcode generieren kann. In meiner Datei ist allerdings in den ersten beiden Zeilen eine Beschreibung die ich natürlich nicht löschen möchte. Ich werde mal versuchen, ob ich der KI meine Wünsche verständlich machen kann.
Nochmals herzlichen Dank, schöne Feiertage und Grüße aus Ratingen -
@jojo58
Interessante Idee. Die KI zu befragen ist mir bisher noch nicht in den Sinn gekommen, obwohl ich schon mal davon gehört habe, daß KI auch Quellcode generieren kann. In meiner Datei ist allerdings in den ersten beiden Zeilen eine Beschreibung die ich natürlich nicht löschen möchte. Ich werde mal versuchen, ob ich der KI meine Wünsche verständlich machen kann.
Nochmals herzlichen Dank, schöne Feiertage und Grüße aus RatingenFalls du es deiner KI nicht beibringen kannst
, hier die Version mit den Headerzeilen. Kannst dann einstellen wieviel Zeilen immer stehen bleiben sollen:const fs = require('fs'); switch (mode) { case 'r': return fs.readFileSync(Dateiname, 'utf8'); case 'w': return fs.writeFileSync(Dateiname, Daten); case 'a': return fs.appendFileSync(Dateiname, Daten); case 'aL': let maxLines = 100; // Anzahl Datenzeilen (ohne Header) let headerLines = 2; // Anzahl geschützter Zeilen oben let content = ''; if (fs.existsSync(Dateiname)) { content = fs.readFileSync(Dateiname, 'utf8'); } let lines = content === '' ? [] : content.split(/\r?\n/); // technischen letzten Leer-Eintrag entfernen if (lines.length > 0 && lines[lines.length - 1] === '') { lines.pop(); } // Header und Daten trennen let header = lines.slice(0, headerLines); let data = lines.slice(headerLines); // führende \n aus neuen Daten entfernen let neuerEintrag = String(Daten).replace(/^\r?\n+/, ''); // neuen Eintrag anhängen (nur Datenbereich!) data.push(neuerEintrag); // Datenbereich begrenzen if (data.length > maxLines) { data = data.slice(-maxLines); } // wieder zusammensetzen let result = header.concat(data); fs.writeFileSync(Dateiname, result.join('\n') + '\n'); return `OK (Header: ${header.length}, Daten: ${data.length}/${maxLines})`; default: return 'Parameter mode muss "r", "w", "a" oder "aL" sein'; }Schöne Ostertage.
Gruß, Johannes
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden