NEWS
[gelöst] Adapter Scope-Problem mit scheduleJob getState (ReferenceError)
-
Ich bin dabei, meinen ersten Adapter (Husqvarna Automower) zu schreiben. Es läuft schon ganz gut, allerdings hänge ich jetzt an einem Problem, wo ich nicht weiterkomme.
Als Vorlage habe ich einen Landroid-Adapter genommen. Die Kernfunktionen laufen. Nun möchte ich um Mitternacht Tageswerte akkumulieren und habe einen entsprechenden Schedule erstellt:
mScheduleDailyAccumulation = husqSchedule.scheduleJob({hour: 0, minute: 0}, function () { dailyAccumulation(); });
Zum Testen rufe ich die Funktion via setTimeout auf:
setTimeout(dailyAccumulation, 4000);
Die dailyAccumulation-Funktion:
function dailyAccumulation() { var fctName = 'dailyAccumulation'; adapter.log.debug(fctName + ' started'); adapter.log.debug(fctName + '; stop status timer'); // stop status timer if(mScheduleStatus !== null) { //clearSchedule(mScheduleStatus); //mScheduleStatus.cancel; clearInterval(mScheduleStatus); mScheduleStatus = null; } adapter.log.debug(fctName + '; add current covered distance to overall distance ...'); // add current covered distance to overall distance in km adapter.getState(idnCurrentCoveredDistance, function (errCCD, stateCCD) { if (!errCCD && stateCCD) { adapter.getState(idnOverallCoveredDistance, function (errOCD, stateOCD) { if (!errOCD && stateOCD) { adapter.setState(idnOverallCoveredDistance, (stateOCD.val + (stateCCD.val / 1000)), true); // distance in km adapter.log.debug(fctName + '; overall distance: ' + stateOCD.val + ': current covered distance: ' + stateCCD.val / 1000); // move current covered distance to last distance and reset current adapter.setState(idnLastCoveredDistance, Math.round(stateCCD.va), true); adapter.setState(idnCurrentCoveredDistance, 0, true); } }); } }); adapter.log.debug(fctName + '; move lastlocations to lastday locations'); // move lastlocations to lastday locations adapter.getState(idnLastLocations, function (errLC, stateLC) { if (!errLC && stateLC) { adapter.setState(idnLastdayLocations, stateLC.val, true); adapter.setState(idnLastLocations, '[]', true); } }); adapter.log.debug(fctName + '; add current mowing time to overall working time ...'); // add current mowing time to overall working time adapter.getState(idnMowingTime, function (errWT, stateWT) { if (!errWT && stateWT) { adapter.getState(idnOverallMowingTime, function (errOWT, stateOWT) { if (!errOWT && stateOCD) { adapter.setState(idnOverallMowingTime, (stateOWT.val + (stateWT.val / 60))); adapter.log.debug(fctName + '; overall mowing time: ' + stateOWT.val + ': current mowing time: ' + stateWT.val / 60); // move current working time to last working time and reset current adapter.setState(idnLastMowingTime, stateWT.val, true); adapter.setState(idnMowingTime, 0, true); } }); } }); // reset daily values adapter.setState(idnMowingStartTime, 0, true); // start status scheduler, use last timer value createStatusScheduler(); adapter.log.debug(fctName + ' finished'); } // dailyAccumulation()
Außer "fctName" sind alle Variablen globale Variablen, die am Anfang des Codes deklariert und initialisiert werden.
Bei der Ausführung läuft der Code dann auf einen ReferenceError, weil die Variable idnLastdayLocations nicht definiert wäre.
Ich hätte jetzt erwartet, dass alle globalen Variablen am gezeigten BreakPoint bekannt wären.
Habe ich einen prinzipiellen Fehler, liegt es in der Art des Aufrufes, so dass die Umgebung nicht mitgegeben wird oder habe ich einfach nur etwas übersehen.
Der Adapter ist kurz vor der Fertigstellung und Testfreigabe. Wer den Code einsehen möchte, findet ihn unter https://github.com/truegreyhound/ioBrok … -automower, muss ihn heute aber noch aktualisieren.
Hoffe ihr habt dazu ein paar Hinweise.
-
Hi,
wie genau lautet denn der ReferenceError? Grundsätzlich strange und sollte nicht passieren.
Ansonsten hier noch ein paar Anmerkungen:
-
Die ganzen States (scheint ja recht viel und immer gleich zu sein) kannst Du auch in der io-package unter instanceObjects definieren. Dann werden die automatisch von ioBroker angelegt wenn der Adapter installiert wird. Dann sparst Du dir den Code dafür im Skript.
-
die beiden "setTimeouts" am Ende kommen mir auch etwas optimierbar vor. Falls es darum geht zu warten bis andere Dinge fertig sind am besten mit callbacks arbeiten
-
-
Die Fehlermeldung
"C:\Program Files\JetBrains\WebStorm 2018.1\bin\runnerw.exe" "C:\Program Files\nodejs\node.exe" --debug-brk=23504 --expose_debug_as=v8debug C:\ioBroker\node_modules\iobroker.husq-automower\main.js --force --log Debugger listening on [::]:23504 ReferenceError: idnLastdayLocations is not defined at Socket. <anonymous>(C:\ioBroker\node_modules\iobroker.husq-automower\main.js:859:30) at Socket.onack (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\socket.js:316:9) at Socket.onpacket (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\socket.js:241:12) at Manager. <anonymous>(C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-bind\index.js:21:15) at Manager.Emitter.emit (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-emitter\index.js:133:20) at Manager.ondecoded (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\manager.js:345:8) at Decoder. <anonymous>(C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-bind\index.js:21:15) at Decoder.Emitter.emit (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-emitter\index.js:133:20) at Decoder.add (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-parser\index.js:251:12) at Manager.ondata (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\manager.js:335:16) Process finished with exit code 6</anonymous></anonymous></anonymous>
Das mit dem setTimeout kann wahrscheinlich direkt erfolgen, ansonsten baue ich das noch um.
Ja, die States hatte ich erst in der io-package, aber die Lösung im Skript finde ich besser pflegbar und außerdem kann ich da gleich meine Initialen Werte setzen, was letztendlich den Ausschlag gab. Denke per io-package geht das nicht.
-
Die Fehlermeldung
"C:\Program Files\JetBrains\WebStorm 2018.1\bin\runnerw.exe" "C:\Program Files\nodejs\node.exe" --debug-brk=23504 --expose_debug_as=v8debug C:\ioBroker\node_modules\iobroker.husq-automower\main.js --force --log Debugger listening on [::]:23504 ReferenceError: idnLastdayLocations is not defined at Socket. <anonymous>(C:\ioBroker\node_modules\iobroker.husq-automower\main.js:859:30) at Socket.onack (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\socket.js:316:9) at Socket.onpacket (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\socket.js:241:12) at Manager. <anonymous>(C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-bind\index.js:21:15) at Manager.Emitter.emit (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-emitter\index.js:133:20) at Manager.ondecoded (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\manager.js:345:8) at Decoder. <anonymous>(C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-bind\index.js:21:15) at Decoder.Emitter.emit (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-emitter\index.js:133:20) at Decoder.add (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-parser\index.js:251:12) at Manager.ondata (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\manager.js:335:16) Process finished with exit code 6</anonymous></anonymous></anonymous> ```` `
Kannst Du bitte Code auf Github updaten … Da ist die zeile was ganz anderes.
Strange ist in jedem Fall der Stacktrace hier ... Wie genau löst Du das aus? WO setzt du den Timer dafür?
Ja, die States hatte ich erst in der io-package, aber die Lösung im Skript finde ich besser pflegbar und außerdem kann ich da gleich meine Initialen Werte setzen, was letztendlich den Ausschlag gab. Denke per io-package geht das nicht. `
Doch ab js-controller 1.5.0 wird es gehen "common.def" kann man dann leere States auf initialwerte setzen. -
Die Fehlermeldung
"C:\Program Files\JetBrains\WebStorm 2018.1\bin\runnerw.exe" "C:\Program Files\nodejs\node.exe" --debug-brk=23504 --expose_debug_as=v8debug C:\ioBroker\node_modules\iobroker.husq-automower\main.js --force --log Debugger listening on [::]:23504 ReferenceError: idnLastdayLocations is not defined at Socket. <anonymous>(C:\ioBroker\node_modules\iobroker.husq-automower\main.js:859:30) at Socket.onack (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\socket.js:316:9) at Socket.onpacket (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\socket.js:241:12) at Manager. <anonymous>(C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-bind\index.js:21:15) at Manager.Emitter.emit (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-emitter\index.js:133:20) at Manager.ondecoded (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\manager.js:345:8) at Decoder. <anonymous>(C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-bind\index.js:21:15) at Decoder.Emitter.emit (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\component-emitter\index.js:133:20) at Decoder.add (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-parser\index.js:251:12) at Manager.ondata (C:\ioBroker\node_modules\iobroker.js-controller\node_modules\socket.io-client\lib\manager.js:335:16) Process finished with exit code 6</anonymous></anonymous></anonymous>
Das mit dem setTimeout kann wahrscheinlich direkt erfolgen, ansonsten baue ich das noch um.
Ja, die States hatte ich erst in der io-package, aber die Lösung im Skript finde ich besser pflegbar und außerdem kann ich da gleich meine Initialen Werte setzen, was letztendlich den Ausschlag gab. Denke per io-package geht das nicht. `
Day hast du einmal gross und einmal klein geschrieben
-
Der Code ist aktualisiert, für den Test mache ich das mit setTimeout als letzte Anweisung in Main.
Den Fehler bekomme ich per WebStorm oder auch beim Start als ioBroker-Adapter, dann erst um Mitternacht (ohne den Testtimer). Da war mir der Fehler im Log aufgefallen.
Ist ein eigener Schedule in einem Adapter erlaubt? Habe sonst keine andere Möglichkeit gefunden, um Mitternacht jeweils etwas laufen zu lassen.
Wahrscheinlich wichtig auch die Umgebung:
-
Windows10
-
node v6.14.2
-
ioBroker aktuell aus latest
-
-
Day hast du einmal gross und einmal klein geschrieben `
Ich wundere mich manchmal wirklich über die eigene Code-Blindheit.Ich danke euch ganz dolle :ugeek:
-
Ich hätte da noch eine Anmerkung zur Verwendung von 'var'. Das ist eigentlich veraltet und wurde in ES6 durch 'let' und 'const' ersetzt. Der Grund ist das var nicht klar abgrenzt wo die Variable dann abgegriffen werden kann.
let und const sind immer nur innerhalb eines Blocks verfügbar. So kann man auch den selben variablen Namen öfter definieren ohne das man gleich ein Problem hat.
Generell empfehle ich sich mit ES6 auseinander zu setzen das es viele Änderungen gebracht hat.
ES = Ecma Script was der Name für den Standard von JavaScript ist.
Gesendet von meinem m8 mit Tapatalk
-
Day hast du einmal gross und einmal klein geschrieben `
Ich wundere mich manchmal wirklich über die eigene Code-Blindheit.Ich danke euch ganz dolle :ugeek: `
Mit der Blindheit schliesse ich mich an … und verfluche die Firefox websuche das die im Standard Not-Case-Sensitive sucht
-
Und noch mal eine andere Frage, gab es hier nicht mal einen Danke-Button zu den einzelnen Beiträgen?
-
Doch gab es, das Plugin ist nicht mehr Kompatibel mit der Foren Software.
Gesendet von meinem m8 mit Tapatalk