NEWS
Schreiben in Datenpunkt schießt JS Instanz ab
-
So, jetzt mal ein harter Brocken:
Ich habe mir eine Art "Pipeline" für die Ansagen gebastellt, da ich verhindern möchte, dass beim Eintreten von zwei Events, die eine Sprachausgabe auslösen, alles durcheinander gesabbelt wird. Dabei habe ich festgestellt, dass sowieso nur Texte bis maximal 70 Zeichen gesprochen werden können, weshalb ich dann halt die Texte in Stücke zerlegt habe. Das ganze wird in einem Array abgespeichert im Format Text, Verzögerung, Text, Verzögerung,...
Wenn dieser Datenpunkt sich verändert, springt die "Abspielroutine" per Trigger an und soll dann Jobs kreiren, die nach der Verzögerung x den nächsten Text aufsagen. Das ganze ist noch nicht hundertprozent fertig, aber zum Testen bis hierhin reicht es.Solange die Texte kurz sind, klappt alles wunderbar.
Sind die Texte aber länger als 70 Zeichen, dann bringt mir der Schreibbefehl des Arrays in den Datenpunkt, in dem ich die Pipe abspeichern will die komplette Javascript Instanz zum resetten...Eine Fehlermeldung gibt es nicht.
Wie kann ich nun rausfinden woran das liegt?
var targetDatapoint, Delay_ms, cronMessage, text, ID_DP_Pipe, ID_DP_Pipe_Trigger, ID_DP_Sprache_Ausgangspuffer, Text_in_ms, ID_Fully_ScreenOn, ID_DP_Sprachausgabe, Pipe, ID_DP_Lautst_C3_A4rke, ID_DP_Sprachlog, Pipe_running, ID_DP_Alarmausl_C3_B6sung, Textstring, Textteil, Trunc_pos, myjsonArray; // Beschreibe diese Funktion … async function createObj(text) { return {zeit: formatDate(new Date(), 'hh:mm:ss'), text: text}; } createState('0_userdata.0.Visualisierung.Pipe', [], { type: 'array', read: true, write: true }, async () => { ID_DP_Pipe = '0_userdata.0.Visualisierung.Pipe'; ID_DP_Pipe_Trigger = '0_userdata.0.Visualisierung.Pipe_Trigger'; ID_DP_Sprache_Ausgangspuffer = '0_userdata.0.Visualisierung.Sprache_Ausgangspuffer'; ID_Fully_ScreenOn = 'fullybrowser.0.Samsung_A7_Eingang.Commands.screenOn'; ID_DP_Sprachausgabe = '0_userdata.0.Visualisierung.Sprachausgabe'; ID_DP_Sprachlog = '0_userdata.0.Visualisierung.Sprachlog'; ID_DP_Lautst_C3_A4rke = '0_userdata.0.Visualisierung.Lautstärke'; ID_DP_Alarmausl_C3_B6sung = '0_userdata.0.Sicherheit.Alarm_Auslösung'; Text_in_ms = 0; setStateDelayed(ID_DP_Pipe, { val: [], ack: false }, parseInt(((0) || '').toString(), 10), false); on({ id: [].concat(ID_DP_Sprachausgabe), change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; Pipe = getState(ID_DP_Pipe).val; Textstring = getState(ID_DP_Sprachausgabe).val; Text_in_ms = Textstring.length * 200; if (Textstring.length > 70) { while (!(Textstring.length < 71)) { Textteil = Textstring.slice(0, 70); Trunc_pos = Textteil.lastIndexOf(' ') + 1; Textteil = Textstring.slice(0, Trunc_pos - 1); Textstring = Textstring.slice((Trunc_pos - 1), Textstring.length); console.info((['Text geteilt in: ',Textteil,'\n','- und in - ',Textstring,'- mit Zeichenanzahl: ',Textstring.length].join(''))); Text_in_ms = Textteil.length * 200; Pipe.push(Textteil); Pipe.push(Text_in_ms); } Text_in_ms = Textstring.length * 200; } Pipe.push(Textstring); Pipe.push(Text_in_ms); console.info((['Pipe: ',Pipe,'- Pipelänge: ',Pipe.length].join(''))); setStateDelayed(ID_DP_Pipe, { val: Pipe, ack: true }, parseInt(((0) || '').toString(), 10), false); setStateDelayed(ID_DP_Pipe_Trigger, { val: true, ack: false }, parseInt(((1000) || '').toString(), 10), false); }); }); on({ id: [].concat(['0_userdata.0.Visualisierung.Pipe_Trigger']), change: 'any' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; Text_in_ms = 100; if (!Pipe_running) { Pipe = getState(ID_DP_Pipe).val; console.info('Pipe not running...'); console.info(('Länge der Pipe bei bis: ' + String(Pipe.length))); while (!(Pipe.length < 2)) { console.info('test'); Pipe_running = true; Pipe = getState(ID_DP_Pipe).val; Textstring = Pipe[0]; console.info((['Cronjob erstellen mit ',ID_DP_Sprache_Ausgangspuffer,' - ',Text_in_ms,' - ',Textstring].join(''))); console.info(('Länge der Pipe: ' + String(Pipe.length))); Text_in_ms = Pipe[1]; if (Pipe.length > 2) { Pipe = Pipe.slice(0, Pipe.length - 2); console.info(('Pipe nach Durchlauf: ' + String(Pipe))); } else { Pipe = []; Text_in_ms = 100; } console.info(('Länge der Pipe danach: ' + String(Pipe.length))); } Pipe_running = false; if (getState(ID_DP_Pipe).val.length > 0) { console.info('Lösche Pipe'); setStateDelayed(ID_DP_Pipe, { val: [], ack: true }, parseInt(((0) || '').toString(), 10), false); } } }); on({ id: [].concat(ID_DP_Sprache_Ausgangspuffer), change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; sendTo("sayit", "say", { text: getState(ID_DP_Sprache_Ausgangspuffer).val, volume: getState(ID_DP_Lautst_C3_A4rke).val });});
-
Hier sind auch noch die Blocklys dazu, die allerdings so lang sind, dass ich sie splitten musste:
MOD-EDIT: Das hier gezeigte Blockly wurde nachträglich ausgetauscht! Die folgenden 4 Antworten beziehen sich auf das inzwischen gelöschte Blockly!
-
Warum das A schmiert weiß ich nicht.
In dem Blockly ist aber einiges komisch....Warum sind die Blöcke zum DP generieren alle verschachtelt?
Warum überhaupt noch die Blöcke, DPs sind ja jetzt angekegt.
Warum kommen da drinnen irgendwann relevante Aktionen wie den Zähler aber das alles hat keinen Trigger?Warum hast du innerhalb einer Funktion einen Trigger?
Warum die ganzen Cronejobs anlegen?
Ich finde das alles sehr komplihiert aufgebaut.
-
@joergh Du solltest schon mal deiner Funktion
Element
als Parameter übergeben und sich nicht darauf verlassen das der Wert noch stimmt während in deinem Startskript in der Schleife schon der nächste Wert in Element geschrieben wird.Und du hast diese große Hammerroutine die dann für jedes Fenster/Tür etc. einmal komplett hinterlegt wird. Und es letztendlich doch nur darum geht das ganze einmal neu anzustoßen wenn sich der Zustand eines Datenpunktes ändert.
Pack das ganze doch in eine Funktion. So oder so:
Dann lässt du dein Startskript eine(!) Liste erstellen in der alle Datenpunkte sind die überwacht werden sollen.
Und dann packst du ganz unten unter dein Startskript, nicht in einer Funktion, einen(!) Trigger dem du diese Liste übergibst als Parameter und der den Aufruf der Funktion enthält. Von mir aus mit dem ganzen Inhalt deiner bisherigen Funktion.
Das Verschachteln mit "Datenpunkt erzeugen" würde ich auch dringen aufheben.
Im Schlimmsten Fall musst du beim allerersten mal dein Skript 2x Starten damit die Datenpunkte da sind und auch gleich genutzt werden können.Und was genau beabsichtigst du mit den ganzen Cronjobs pro Fenster/Tür etc? Was machen dieses zeitlich gesteuerten Jobs?
-
@david-g sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
Warum das A schmiert weiß ich nicht.
In dem Blockly ist aber einiges komisch....@david-g
Danke, dass Du Dich damit beschäftigt hast.Warum sind die Blöcke zum DP generieren alle verschachtelt?
Ich habe zu Datenpunkt anlegen nirgends eine Beschreibung gefunden und bin mir nicht im Klaren wofür die Klammer da sein soll, habe es dann mal so umgesetzt, damit er nicht auf die Idee kommt außerhalb der Klammer vielleicht nicht auf die Datenpunkte zugreifen zu können. Ansonsten verkürzt es das Script oben etwas. Vielleicht kannst Du mir ja sagen, wofür das sein?
Er legt jedenfalls die Datenpunkte an.
Warum überhaupt noch die Blöcke, DPs sind ja jetzt angekegt.
Weil beim nächsten Umzug auf ein neues System die Datenpunkte nicht mehr das sind...weil das Skript so für jedermann leichter anpassbar wäre und er sich um die nötigen Datenpunkte weniger Gedanken machen müsste. Weil ich so leicht die Datenpunkte irgendwo anders anlegen lassen kann ohne alle manuell zu löschen und neu einzurichten...hat Vorteile.
Warum kommen da drinnen irgendwann relevante Aktionen wie den Zähler aber das alles hat keinen Trigger?
Der Zähler wird benötigt um die Listen mit Fenstern und Türen zu erstellen beim Initialisieren des Programms. Links ist reine Initialisierung zu sehen. Er startet und erstellt die nötigen DP, soweit nicht vorhanden und die liest welche Fenster und Türen vorhanden sind und in welchen Räumen und erstellt entsprechende Listen. Dabei vergleicht er mit der alten Liste, die er zuvor erstellt hat und ergänzt neue Komponenten. So wird verhindert, dass wenn mal wieder die HomematicIP Datenpunkte ihre Eigenschaften (Fenster, Tür, Raum) verloren haben, das Skript nicht mehr funktioniert. Das wird alles nur einmal durchlaufen.
Am Ende wird dann die Funktion Trigger starten gestartet mit der neu erstellten Liste und es werden cronjobs zur Überwachung der Fenster und Türen eingerichtet. Bei jeder Veränderung werden die entsprechenden cronjobs dann die zählung der offenen Fenster / Türen neu anstoßen.
Warum hast du innerhalb einer Funktion einen Trigger?
Warum die ganzen Cronejobs anlegen?
Ich finde das alles sehr komplihiert aufgebaut.
Es ist eine komplizierte Materie ...bin aber immer offen für Vorschläge, wie man das alles einfacher lösen kann....
-
Sorry!!! Mir fällt gerade auf, dass ich die falschen Blocklys gepostet habe! Das ist ein funktionierendes Skript und nicht das zu dem Problem....das korrekte kommt gleich.
[Edit] : Jetzt passt es.
-
Ich vermute Mal es liegt an den while schleifen
Da kommt es oft zu solchen Fehlern - Javascript Neustart ohne Fehler Meldung
-
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
[Edit] : Jetzt passt es.
jetzt passen aber die Antworten nicht mehr
-
@homoran Stimmt. Die Antwort passt auf den Post der Amnmerkungen zu dem falschen Blockly. Ich beantworte auch gerne Fragen zu dem nun zum Script passenden Blockly.
-
@liv-in-sky Das habe ich auch schon befürchtet und mal von "solange" auf "bis" umgestellt, hat aber keine Änderung gebracht...Hast Du eine Idee, wie ich denn anders eine Schleife darstellen kann, als mit dem entsprechenden Blockly?
-
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
@homoran Stimmt. Die Antwort passt auf den Post der Amnmerkungen zu dem falschen Blockly. Ich beantworte auch gerne Fragen zu dem nun zum Script passenden Blockly.
Deswegen niemals nachträglich ohne Kennzeichnung (und belassen des falschen) Änderungen durchführen
Das gehört zu den Grundlagen eines Forums!https://forum.iobroker.net/topic/51555/hinweise-für-gute-forenbeiträge/1
-
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
Sorry!!! Mir fällt gerade auf, dass ich die falschen Blocklys gepostet habe! Das ist ein funktionierendes Skript und nicht das zu dem Problem....das korrekte kommt gleich.
[Edit] : Jetzt passt es.
-
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
Sorry!!! Mir fällt gerade auf, dass ich die falschen Blocklys gepostet habe! Das ist ein funktionierendes Skript und nicht das zu dem Problem....das korrekte kommt gleich.
[Edit] : Jetzt passt es.
???
was willst du mir damit sagen?Hast du den verlinkten Thread überhaupt (vollständig) gelesen?
EDIT:
Habe einen entsprechenden Kommentar im betreffenden Post eingefügt! -
habe dein script nicht wirklich analisiert - aber du willst doch texte, die kleiner 70 zeichen sind
zum testen
bringt sowas:
avascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 68 : Dies ist ein sehr sehr langer sehr langer Beispieltext, der mehr als javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 69 : siebzig Zeichen hat. Wir möchten sicherstellen, dass der Text korrekt javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 65 : an Leerzeichen getrennt wird. Das ganze soll ein Script mit einer javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 65 : FOR-Schleife sein und somit sicherer als mit einer WHILE-Schleife javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 60 : sein. Jetzt weiß ich nicht mehr, was ich noch schreiben soll
-
@homoran Es hatte außer zwei Personen noch keiner geantwortet, die Blocklys austauschen dürfte da wohl eher wenig für Verwirrung sorgen, zumal ich direkt danach darauf hingewiesen habe und dies kenntlich gemacht habe. Geht es jetzt ums Prinzipenreiten oder gibt es ein echtes Problem?
-
@liv-in-sky sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
habe dein script nicht wirklich analisiert - aber du willst doch texte, die kleiner 70 zeichen sind
zum testen
bringt sowas:
avascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 68 : Dies ist ein sehr sehr langer sehr langer Beispieltext, der mehr als javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 69 : siebzig Zeichen hat. Wir möchten sicherstellen, dass der Text korrekt javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 65 : an Leerzeichen getrennt wird. Das ganze soll ein Script mit einer javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 65 : FOR-Schleife sein und somit sicherer als mit einer WHILE-Schleife javascript.0 11:06:17.939 info script.js.common.AA-Versuche.Skript_1: 60 : sein. Jetzt weiß ich nicht mehr, was ich noch schreiben soll
Richtig, ich will die Texte splitten und dann in ein array schreiben. Das funktioniert auch genauso so weit, bis er zum Schreiben des Datenpunktes kommt, dann schmiert er ab.
Du meinst ich sollte die Split Funktion in dem JS-Script auslagern, da ich damit auch die Schleife "verzichten" kann, sprich sie im JS-Script läuft...?
Wäre eine Möglichkeit...probiere ich mal aus. Danke für die Anregung!
-
die andere while schleife solltest du auch dann noch ersetzen - leider muss ich wieder los - zur not hilft dir auch chatgpt, falls sich kein anderer findet
-
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
Geht es jetzt ums Prinzipenreiten oder gibt es ein echtes Problem?
Ich will mich hier nicht weiter reinhängen, aber genau um den ersten Teil der Frage geht es ganz und gar nicht, aber der zweite Teil ist durchaus für einen unbedarften Leser möglich. Deswegen auch das Mod-Edit bzw., die Ergänzung unter dem im 2. Beitrag ausgetauschten Blockly.
Wer das als Neuleser von Anfang an ohne Vorahnung (ggf. auch später) liest und eben nicht weiß, dass es eine schon korrigierte Austauschfassung ist, sucht wg. der Folgekommentare einen möglichen Fehler darin der gar nicht mehr enthalten ist. Bis dieser über den kleine unscheinbaren Edit-Hinweis im 6. Post gestolpert ist, ist u.U. nen Haufen Lebenszeit sinnlos verbraten.
Um nichts anderes ging es @Homoran bei seinen Ausführungen. Genau das ist der Grund warum nachträgliche Edits in Beiträgen ohne dortige direkte und deutliche Kenntlichmachung in echtes Foren-NoGo sind.
-
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
Weil beim nächsten Umzug auf ein neues System die Datenpunkte nicht mehr das sind.
Dann macht es evtl Sinn sich ein Alias für die Geräte anzulegen.
Ich zähle meine Kontakte indem ich den DPs eine Funktion gebe. Das kann man schön schnell anpassen.
Das Script sucht die Funktion der DPs und fertig.EDIT
Ich prüfe nur auf geschlossen und offen. Aber lässt sich ja leicht anpassen.
Du Funktion habe ich von meiner Alarmanlage übernommen. Dort werden alle Fenster geprüft. Dann muss ich es nicht doppelt vergeben.
Die Variable Durchlauf habe ich um das "und" richtig zu setzen für die Sprachansage. -
@david-g sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
@joergh sagte in Schreiben in Datenpunkt schießt JS Instanz ab:
Weil beim nächsten Umzug auf ein neues System die Datenpunkte nicht mehr das sind.
Dann macht es evtl Sinn sich ein Alias für die Geräte anzulegen.
Ja, kann man machen. Ist eine Alternative. Ich lege die Datenpunkte lieber selber an, so wie jeder Adapter das schließlich auch macht. Ich denke genau dafür wurde die Blöcke doch auch eingerichtet.
Ich zahle meine Kontakte indem ich den DPs eine Funktion gebe. Das kann man schon schnell anpassen.
Das ist eben das Problem, welches ich schon öfter hatte: Beim bisher verwendeten Skript durfte man NICHT die Channels mit der Funktion ausstatten, MUSSTE aber die STATEs ausstatten. Leider liefert die Homematic_CCU es aber anders nach Neueinlesen. Beim mehr als 30 Fenster ging es mir gegen den Strich jedesmal die ganzen Eigenschaften wieder neu setzen zu müssen und vor allem habe ich nicht einmal mitbekommen, dass sie aus irgendwelchen Gründen mal wieder verschwunden sind und mich dann irgendwann gewundert, warum keine Warnungen mehr erschienen sind.
Das Script sucht die Funktion der DPs und fertig.
EDIT
Ich prüfe nur auf geschlossen und offen. Aber lässt sich ja leicht anpassen.
Mein Skript für die Fenster läuft nun auch wunderbar und vermeidet die oben genannte Problematik, da es die Eigenschaften so nutzt, wie sie von Homematic_CCU angeliefert werden, ohne irgendwas im iobroker setzen zu müssen (in der HM-CCU müssen sie natürlich zugeordnet sein!). Ich kann dann noch einstellen nach wie vielen Minuten er eine Warnung in einen Datenpunkt schreiben soll und damit weiterarbeiten.
Das war aber leider das falsche Skript, ich habe die Instanz-Absturz in einem anderen. Der JS-Code der Blockly-Blöcke war schon korrekt, nur die Screenshots nicht.