@derdom
Servus, das klingt gut
Nur zur Info, falls du es noch nicht kennst, so eine konstante Abweichung kannst du, wenn gewünscht, in den Einstellungen des BM kompensieren - bei mir im BM1 ist es der Parameter A15, den ich von -5 bis +5 Grad einstellen kann.
Sieh’ dir dazu nur auch die Montageanleitung zu deinem BM an, da sollte es genau beschrieben sein.
NEWS
Best posts made by ofri2607
-
RE: Wolf Therme CGB-2k-24, ioBroker, Außentemperatur-Fühler
-
RE: inventwo Multi Widget Auswertungslogik für Rollladen
@lxffm
Ich habe eine inventwo Multi Widget für meinen Rolladen in Kombination mit Fenster/Terassentür offen mit insgesamt 4 Zustände im Einsatz. Dazu habe ich mir aber mit Javascript einen Datenpunkt Rolladen in Bewegung gebaut.
Im Widget frage ich
im Zustand [0] 100 als Rolladen geschlossen,
im Zustand [1] true als in Bewegung,
im Zustand [2] true als Fenster/Terrassentür geöffnet und
im Zustand [3] 0 als Rolladen geöffnet ab
und zeige mir dazu jeweils ein entsprechendes Symbol an. Das funktioniert für mich so, wie es soll.Ich denke in deinem Fall musst du
im Zustand [0] die greaterequal 95, dann
im Zustand [1] die lower 5 und
im Zustand [2] dann die lower 95
abfragen.
Ich probiere hier auch immer wieder herum, denke aber, dass der erste „wahre“ Zustand greift. -
RE: (Erledigt) http post request für CodeProject.AI calls
im Skript das @2 weglassen (das ist nur für den Installer, dass er die v2 installiert und nicht die v3), d.h.
const fetch2 = require('node-fetch');
-
RE: Test Adapter LG ThinQ
@lucky_esa sagte in Test Adapter LG ThinQ v0.0.1:
Kannst du bitte noch mal testen.
Hallo Lucky,
Installation war jetzt problemlos und die thinq2 Geräte funktionieren wie gewohnt.Und das thinq1 Gerät lässt sich einwandfrei, sowie wie von dir beschrieben einschalten und auch im snapshot wird der DP Operation sauber aktualisiert.
Zurück Ausschalten - mit xxx.remote.settings.Operation = AUS(0) und danach xxx.remote.SetOperation = true hat leider nicht funktioniert. (habe dann auch probiert auf false und dann wieder auf true - leider auch ohne Ergebnis)Nach dem Ausschalten über die Fernbedienung hat dann erneutes Einschalten mit xxx.remote.settings.Operation = Rechts an(1) und danach xxx.remote.SetOperation = true wieder einwandfrei funktioniert.
Zurück Ausschalten leider wieder nicht, es kommt aber auch da irgendwas bei der Klima an, denn sie gibt ein Signal von sich wenn ich xxx.remote.SetOperation = true setze, aber sie schaltet nicht aus. Der snapshot wird nach dem Ausschalten mit der Fernbedienung leicht zeitverzögert entsprechend auf AUS(0) aktualisiert.Habe dann auch noch direkt xxx.snapshot.Operation = AUS(0) versucht, da kommt dann im Log:
lg-thinq.0 2023-06-25 13:59:43.566 error AxiosError: Request failed with status code 400 lg-thinq.0 2023-06-25 13:59:43.566 error Send failed
Wie auch von @Merlin123 beschrieben ist bei mir auch in der App das Gerät mit "Wohnzimmer ist in Verwendung. Versuchen Sie es später noch einmal." gesperrt.
-
RE: Interaktion aus HTML Tabelle möglich?
Ich habe das in vis in einem basic-html Widget für einen View-Wechsel so gelöst:
<table width=100% height=100% style="border-collapse:collapse; cursor: pointer;" onclick="changeView(10)"> ...
Im Reiter Skripte ist dann folgendes js enthalten:
//Wechseln der View bei Click --- Aufrufbsp: changeView(8) function changeView(view = 0) { servConn.setState('linkeddevices.0.VIS.LINK', view); }
-
RE: [gelöst] setState String erzeugt Fehlermeldung
@pingo sagte in setState String erzeugt Fehlermeldung:
setState('vw-connect.0.WV2ZZZEB4RH004449.status.chargingSettings.maxChargeCurrentAC'/maxChargeCurrentAC/,reduced);
Ich würde tippen, dass reduced jetzt keine Variable ist, oder?
Dann musst du das in Anführungszeichen setzen.setState('vw-connect.0.WV2ZZZEB4RH004449.status.chargingSettings.maxChargeCurrentAC'/*maxChargeCurrentAC*/,"reduced");
-
RE: Ecovacs Deebot Adapter: Status und Feedback
@chris76e sagte in Ecovacs Deebot Adapter: Status und Feedback:
Einfach auf change beim ...status.device ist ja auch nicht richtig, bevor charging kommt, kommt ja noch returing.....
Ja klar, da müsstest du dann auch in dem "on.." die Auswertung der .ts und auch den Status getState('ecovacs-deebot.0.status.device').val == 'charging' mit einbauen.
Kann dir leider, wie gesagt, aktuell kein Codebeispiel im Detail zusammenstellen, da ich es nicht testen könnte.
Aber als Idee so ungefähr in der Richtung dann z.B.:on({id: ['ecovacs-deebot.0.status.device', 'ecovacs-deebot.0.cleaninglog.lastCleaningTimestamp'] , change: "gt"}, function(obj){ if (getState('ecovacs-deebot.0.status.device').val == 'cleaning' && getState('ecovacs-deebot.0.status.device').ts < getSate('ecovacs-deebot.0.cleaninglog.lastCleaningTimestamp').ts) { }; });
Ev. brauchst dann noch eine zusätzliche Prüfung, wenn die Aktualisierung von "lastCleaningTimestamp" doch schon vor der Statusänderung zu "cleaning" erfolgt.
Wollte dir damit nur ein paar Gedankenanregungen lieferen. -
RE: [gelöst] Script läuft nicht mehr.... DOMParser
@homoran
Letztes OT:
Eigentlich schräg, aber hin und wieder hat der Apfel so seine Eigenheiten … dann war‘s in dem Fall ja doch ein Problem hinter und nicht vor der Tastatur
Latest posts made by ofri2607
-
RE: sendTo & InfluxDB -> ??? [gelöst]
@legro
Gerne, sieht gut aus.
Das await ohne Einbindung in eine async function auch geht, hätte ich nicht gedacht.Ja, das ist einer der wichtigen Punkte beim Arbeiten mit den Promises - für mich aber auch immer bei Programmieren - das man sich auch die Gedanken um die saubere Fehlerbehandlung macht. Lässt sich aber, in deinem Beispiel leicht mit try-catch ergänzen.
-
RE: sendTo & InfluxDB -> ??? [gelöst]
Vorweg einmal für alle ggf. mitlesenden Profis. Für mich ist Javascript nur Hobby und Spaß und bin da sehr weit weg ein Profi zu sein. Daher verzeiht mir bitte ggf. unsaubere oder laienhafte Beschreibungen
@legro
Wir nähern uns. Du vermischt jedoch noch zwei Dinge - das eine sind Callbacks und das andere sind Promises.
Im Ergebnis liefern sie für dich dann das selbe, sind aber zwei unterschiedliche Techniken. Soweit ich es weiß, ist Promise die neuere und modernen Technik um "Abfragen" bzw. "Zeitlichkeiten" in eine gesteuerte, serielle Reihenfolge zu bekommen. Ohne der Verwendung des Callback bzw. Promise laufen die Dinge sinngemäß ungesteuert und tlw. parallel ab.Ein Beispiel: Du möchtest Gerätedaten über ein API abfragen: Oft musst du da als erstes einen Sicherheitsschlüssel abholen, mit dem so erhaltenen Sicherheitsschlüssel holst du dir ein Token, mit dem Token die Geräteliste, aus der Geräteliste ein spezielles Gerät und dann die Gerätedaten.
Da hast du dann plötzlich fünf Abfragen, die seriell laufen müssen, weil immer das Ergebnis der vorhergehenden Abfrage für die nächste benötigt wird. Du weißt aber nicht (hast keinen Einfluss darauf), wie lange es dauert bis nach der Abfrage die Rückmeldung eingetroffen ist; daher musst du auf diese warten.Lösung mit Callbacks:
Machst du das jetzt mit Callbacks, bist du hier ganz schnell in den Untiefen der sog. Callback-Hell verschwunden. Das ist die Bezeichnung dafür, das ein Callback in einen anderen Callback, usw. verschachtelt ist. Es funktioniert an sich, aber der Code ist da tlw. fast nicht mehr lesbar bzw. nachvollziehbar.Lösung mit Promise:
Mit Promises hast du da die Möglichkeit es in der sog. Promise-Chain aufzubauen; d.h. du verschachtelst den Code nicht sondern du hast es auf "einer Ebene" untereinander (sinngemäß in der Darstellung im Code keine Einrücken).
Bei den Promises hast du hier zwei Möglichkeiten der Schreibweise:- Entweder mit
.then() (hier können mehrere nacheinander erfolgen => das ist dann die Promise-Chain) und dann mit
.catch() (dient der Fehlerbehandlung wenn in einem der .then() ein Fehler auftritt und bei Bedarf ganz zum Schluss mit
.finally() (hier kannst du definieren was immer - auf nach einem Fehler der im catch behandelt wurde - im Code weiter erfolgen soll. - oder mit async / await
async dient hier "nur" zum Definieren bei einer Funktion das im folgenden Ablauf ein await erfolgt.
Du kannst dann z.B. auch mehrere awaits untereinander schreiben - sprich sinngemäß eine Chain, wie o.a. mit den .then().
Bei await hast du aber keine direkte Fehlerbehandlung, daher musst du das dann in ein try - catch packen um Fehlerrückmeldungen vom Promise (= reject) sauber abzufangen. Sinngemäß ist es das gleiche wie o.a. das .catch()
Das heißt async/await und .then(), .catch, .finally() sind beides sinngemäß das Selbe (= Promise) nur in einer anderen Schreibweise.
Dementsprechend nutze ich in meinem Beispiel im obigen Post nur Promise (und kein Callback). Kurz zur Erklärung dazu:
Mit demreturn new Promise(async (resolve, reject) => {
wird der Rückgabewert der Funktion queryInfluxDB(tag) als Promise "erzeugt". Das async darinnen ist erforderlich, da im nachfolgenden Code mit
const result = await sendToAsync('influxdb.0', 'query', query);
ein "anderes/eigenes" Promise von sendToAsync verwendet wird.
Bei Aufruf der Funktion im for-Loop dann, wird das oben in der Funktion queryInfluxDB(tag) erzeugte Promise mit
const success = await queryInfluxDB(('0' + i).slice(-2));
aufgerufen, daher ist die Kennzeichnung der Funktion callLoop mit async erforderlich.
Einen Fehler habe ich meinem Code im obigen Post:
In der Funktion queryInfluxDB(tag) im catch-Block ist einreject(false);
Das ist ohne Fehlerbehandlung mit try-catch im Aufruf beim loop "falsch" bzw. unsauber programmiert, da würde der Code dann mit einem unbehandelten Fehler stoppen.
Das zu lösen gibt es zwei Möglichkeiten: entweder in der Funktion callLoop() auch ein try-catch einbauen, oder anstelle von reject hier auch resolve verwenden. Ich habe das im obigen Post auf resolve geändert - inkl. Editanmerkung.
Probiere es einfach mal aus, damit du siehst was da jeweils passiert.
Ich hatte dir im Beispiel im obigen Post bewusst ein paar Logausgaben eingebaut, damit du die zeitliche Abfolge siehst. Wenn du es ausprobierts, lasse dann z.B. mal das await bei Aufruf von queryInfluxDB im for-Loop weg und sieh die dann die Log-Ausgabe an, dann solltest du den Unterschied gut erkennen können, bzw. denke ich, verstehen was das await bewirkt. - Entweder mit
-
RE: sendTo & InfluxDB -> ??? [gelöst]
Ich würde es so machen (wie ich in meinem obigen Post schon geschrieben) - mit Promise in der Funktion und for in einer async function mit await im loop::
let minMaxObj = {}; function queryInfluxDB(tag) { return new Promise(async (resolve, reject) => { //let d = tag für was hast du das eingebaut? try { const query = `from(bucket: "db_iobroker") |> range(start: 2025-01-${tag}T00:00:00.000Z, stop: 2025-01-${tag}T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")`; const result = await sendToAsync('influxdb.0', 'query', query); let qry = result.result let werte = [] let min = qry[0][0]._value let max = qry[0][0]._value for (let i=0; i<qry[0].length; i++) { werte.push(qry[0][i]._value) if (werte[i] < min) {min=werte[i]} if (max < werte[i]) {max=werte[i]} } log({tag, min,max}) minMaxObj[tag] = { min: min, max: max }; //getResults(abfrage.substring(44,54),{min,max}) //der 1. Parameter liefert das Tagesatum String resolve(true); } catch (error) { log("Fehler bei der Abfrage Tag " + tag + ":" + error.message, "error"); //reject(false); EDIT: => liefert ohne Behandlung mit try-catch im Aufruf einen unbehandelten Fehler, daher resolve(false); } }) } async function callLoop() { for (let i=1; i<32; i++) { const success = await queryInfluxDB(('0' + i).slice(-2)); log(i + " = " + (success ? „erfolgreich“ : „NICHT erfolgreich“), „info“); } log("Datensätze: " + JSON.stringify(minMaxObj), "info"); } callLoop();
Das durcheinander gewürfelte ist klar, denn bei deiner Lösung "feuert" der for-Loop eines nach dem anderen sofort ab und wartet nicht bis die aufgerufene Funktion fertig abgearbeitet wurde. Welche aufgerufene Funktion queryInfluxDB dann schneller ist, hat gewonnen.
Daher die Lösung mit dem await im for-Loop, damit wird, vereinfacht gesagt, gewartet bis das Promise aus der Funktion zurückgemeldet hat.Die Frage die sich mir nur auch stellt ist, warum ist dir die Reihenfolge überhaupt so wichtig?
Wenn du ein Object ausserhalb der Funktion queryInfluxDB definierst, dass du mit der Funktion befüllst, ist die Reihenfolge an sich irrelevant, habe es dir oben als Beispiel dazu eingebaut.EDIT: reject(false) im obigen Code-Beispiel durch resolve(false) ausgetauscht => siehe auch mein unten folgendes Post
-
RE: sendTo & InfluxDB -> ??? [gelöst]
Gerne.
Sieh dir dazu nochmal das Beispiel zu sentToAsync an:const res = await sendToAsync('sql.0', 'getEnabledDPs', {}); log(JSON.stringify(res));
Du wirst etwas vom Promis der sentToAsync Abfrage zurückbekommen.
In den Beispielen zu Promise wird meist das timeout verwendet, da es bei dem Thema um den zeitlichen Ablauf („Zeitverzögerung“) im Code geht. Sinngemäß ist das auch so bei dem sentToAsync; das hat seine „Bearbeitungszeit“ mit der Anfrage und Auswertung an die influxDB. Das ist das was du, vereinfacht gesagt, mit dem await im for-loop machst, du wartest damit bis die Rückmeldung vom Promise kommt und erst dann erfolgt der nächste Schleifendurchlauf. Ohne dem wird nicht gewartet, sonder es geht sofort in den nächsten Schleifendurchlauf.
Ich würde es in etwa so lösen:
Baue die Funktion getMinMax(abfrage) auf ein Promise um:function getMinMax(abfrage) return new Promise(async (resolve, reject) => { try { const query = await sentToAsync('influxdb.0', 'query', abfrage); log(query) //nur zum Testen let qry = JSON.parse(JSON.stringify(query.result)); //… usw. mit deinem Code resolve(true); } catch(err) { log(err.message, „warn“); reject(false); } }) }
Und in deiner for-Schleife, die in einer async function eingebettet ist, rufst du dann
const success = await getMinMax(tag); log((success ? „erfolgreich“ : „NICHT erfolgreich“), „info“);
auf.
-
RE: sendTo & InfluxDB -> ??? [gelöst]
… asynchronen Verhalten von sendTo
Sieh‘ dir dazu sendToAsync an - https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#sendtoasync
Und für die Lösung im for-Loop findet sich unter dem Suchbegriff „javascript promise for loop“ zahlreiche Informationen, z.B. hier - https://stackoverflow.com/questions/40328932/javascript-es6-promise-for-loop
Pkt. 4 aus der ersten Antwort ist mE das was du benötigst. -
RE: Sonos Album Cover Bildwechsel
Ich bin mir jetzt nicht ganz sicher, ob es mit deinem Problem zusammenhängt, aber es gibt da ein offenes Issue beim sonos-Adapter - siehe https://github.com/ioBroker/ioBroker.sonos/issues/204
-
RE: schedules löschen bei Script Neustart
Servus,
ich hatte auch immer wieder mal eigenartige Effekte in der Richtung (nutze auch mehrere Javascript-Instanzen).
Daher baue ich es mir in all meinen Skripten so auf (Besipielauszug aus einem Skript von mir):let electricConsumtionTimer = schedule({hour: 23, minute: 59, second: 59}, setMeterReadings) onStop(() => { clearSchedule(electricConsumtionTimer); electricConsumtionTimer = null; }, 1000)
Das "electricConsumtionTimer = null" im onStop ist nicht unbedingt erforderlich, ist eher der Hosenträger zum Gürtel;
Das funktioniert bei mir einwandfrei und seitdem habe ich keine parallel laufenden Schedules mehr erkennen können.
Im selben Prinzip mache ich das auch mit setInterval und setTimeout.onStop siehe ioBroker.javascript Doku
-
RE: json Object wird unter Objekte nicht richtig angezeigt
würde ich so lösen:
const l_tibberlink = "tibberlink.0.Homes.cf930f37-ceea-4c0c-a941-b395fb865fc3.PricesToday."; const l_pvforecast = "pvforecast.0.summary.energy.hoursToday."; const l_Strompreise = "0_userdata.0.Strompreise"; let arr = {}; for (let i = 0; i < 24; i++) { arr[i] = { level: getState(l_tibberlink + i + ".level").val, price: getState(l_tibberlink + i + ".total").val, pvSolcast: (i < 5 || i > 21) ? 0 : getState(l_pvforecast + (i < 10 ? ("0" + i) : i) + ":00:00").val }; } setState(l_Strompreise, JSON.stringify(arr), true); log(JSON.parse(getState(l_Strompreise).val)[18]); //z.b. für Stunde 18