NEWS
Adapter Architektur von ioBroker?
-
.
Danke für die Antworten, auch für die nicht mehr gestellten :mrgreen:
Die Webseite lädt schon einmal
Mit net hatte ich gar nicht so auf dem Schirm. Jetzt ist es klarer (auch in Verbindung mit der node.js Doku).
Die anderen Fragen drehten sich um die package.json und die io-package.json. Das hat keine Prio. Darum kümmere ich mich, wenn schon was brauchbares läuft.
Dann:
@Bluefox:In deinem Fall solltest du doch keine Werte vom System bekommen. D.h du muss nur in das System schreiben.
Das ist auch auch einfach. Wenn du die Werte zusammen gebaut hast, z.B. "fritzbox.0.calling", dann schreibst du einfach
adapter.setState('calling', true, true);
Erste "true", das ist das Wert (Anruf läuft). Zweite "true" sagt, dass es um Zustand (und nicht um Befehl) geht. `
Muss ich das Objekt/den Datenpunkt erst noch anlegen, bevor ich ihn beschreiben kann?
D.h. ein adapter.createState() oder so?
So sehe ich die Werte unter Ereignisse und Zustände.
Unter Objekte taucht der Wert nicht auf (das Objekt wird nicht erzeugt).
Soweit kämpfe ich mich durch. Man kann sich ja einiges abschauen (andere Adapter, Fritzbox-Adapter der ccu.io).
Ab und an ein Schubser… und es geht schneller
Erst einmal bin ich jetzt froh, dass Webstorm läuft, die Webseite lädt, Debugging funktioniert und Daten aus der Fritzbox im Log ausgegeben werden.
Nun aber meine größte Hürde.
Javascript in Node-red schön und gut. So ein Flow ist schön zu verfolgen. Im Adapter sieht es ganz anders aus. Hier fehlt mir jegliche Erfahrung.
Wie baut man denn so etwas auf (gerne auch Pseudocode)? Die Funktion main() ist in den ganzen Adaptern ja erfrischend klein.
Was gehört in main()?
Wo reagiere ich auf die Daten aus der Fritzbox?
Wann brauche ich adapter.on('message', function (obj) {?
Und wann adapter.on('stateChange', function (id, state) {?
Brauche ich das überhaupt?
Mein Dilemma wird man an diesem Stück Code sehen:
function connectToFritzbox() { var socketBox = net.connect({port: 1012, host: '172.16.130.254'}, function() { // IP muss noch von der html admin Seite kommen adapter.log.info("adapter fritzBox connected to fritz: "); // + ip (todo) socketBox.on('data', function(data) { //hat gefühlt nichts in der Funktion und in main() zu suchen adapter.log.info("Daten empfangen:" + data); }); }); } function main() { adapter.log.debug('main: Hallo, ich bin es. Der Fritzbox-Adapter'); connectToFritzbox(); }
Die Funktion connectToFritzbox() halte ich so für Blödsinn (damit meine ich nicht, dass sie noch nichts zurückgibt). Denn Connect und das "Warten auf Daten" sollte man doch wahrscheinlich trennen. Auch der Aufruf aus main() heraus.
In Node-red gab es nur ein paar lokale Funktionen und kein main(). Es wurde nur an wenigen Stellen auf etwas reagiert. Ansonsten gab es einen schönen linearen Verlauf. Alles kein Thema. Brauche nur den Einstieg. Ansonsten kämpfe ich mich da schon durch.
-
` > Muss ich das Objekt/den Datenpunkt erst noch anlegen, bevor ich ihn beschreiben kann?
D.h. ein adapter.createState() oder so?
So sehe ich die Werte unter Ereignisse und Zustände.
Unter Objekte taucht der Wert nicht auf (das Objekt wird nicht erzeugt). `
Wie du richtig bemerkt hast, kannst du schon das Wert schreiben, nun wird es dafür kein Objekt erzeugt.Weil alle deine Datenpunkte (DP) nicht dynamisch sind (es wird nicht meht und nicht weniger Datenpunkte und die Namen sind konstant), dann kannst du alle Datenpunkte schon in io-package.json definieren und die werden automatisch (bei INSTALLL) angelegt.
Schaue, z.b https://github.com/ioBroker/ioBroker.yr … ckage.json
... "objects": [ ], "instanceObjects": [ { "_id": "forecast.day0", "type": "channel", "common": { "name": "actual weather or forecast for today", "role": "weather.forecast" }, "native": {} }, { "_id": "forecast.day0.date", "type": "state", "common": { "name": "Actual date", "type": "string", "role": "date", "read": true, "write": false, "desc": "Actual date as string" }, "native": {} } ... }
Beim INSTALL werden dann automatisch yr.X.forecast.day0 und yr.X.forecast.day0.date angelegt. Du musst genauso machen.
Die DP kann man auch als CHANNELS zusammengruppieren oder flach lassen. Hängt davon ab, wie viel und welche Variablen du hast. Ich kann jetzt schon folgende Kanäle sehen: actualcall (oder call), history, control…
Und dann kansst du so aufbauen:
fritzbox.X.call.incoming (oder
fritzbox.X.call.duration ...
fritzbox.X.history.HTMLtable
fritzbox.X.history.JSONtable
...
> Wie baut man denn so etwas auf (gerne auch Pseudocode)? Die Funktion main() ist in den ganzen Adaptern ja erfrischend klein.
"main" das ist nur ein Namen, der sagt, hier startet das Programm. Es muss aber nicht unbedingt "main" heißen.Einstiegs-punkt ist
adapter.on("ready", function () {....});
> Was gehört in main()?
Wie gesagt, nichts. Du kannst aus "ready" direct "connectToFritzbox" aufrufen.> Wo reagiere ich auf die Daten aus der Fritzbox?
Hier:socketBox.on('data', function (data) { //Analyse the data });
Wie du es machst, ist dir überlassen. Du kannst direkt da analysieren wie in https://github.com/hobbyquaker/ccu.io/b … ritzBox.js (Zeile 307) oder als Funktion ...
` > Wann brauche ich adapter.on('message', function (obj) {?
Und wann adapter.on('stateChange', function (id, state) {?
Brauche ich das überhaupt? `
Reicht es momentan, wenn ich sage: Nein. Du brauchst die nicht.` > Mein Dilemma wird man an diesem Stück Code sehen:
function connectToFritzbox() { var socketBox = net.connect({port: 1012, host: '172.16.130.254'}, function() { // IP muss noch von der html admin Seite kommen adapter.log.info("adapter fritzBox connected to fritz: "); // + ip (todo) socketBox.on('data', function(data) { //hat gefühlt nichts in der Funktion und in main() zu suchen adapter.log.info("Daten empfangen:" + data); }); }); } function main() { adapter.log.debug('main: Hallo, ich bin es. Der Fritzbox-Adapter'); connectToFritzbox(); }
Die Funktion connectToFritzbox() halte ich so für Blödsinn (damit meine ich nicht, dass sie noch nichts zurückgibt). Denn Connect und das "Warten auf Daten" sollte man doch wahrscheinlich trennen. Auch der Aufruf aus main() heraus. `
"main" ist nur ein Zeichen, dass hier Anfang ist. Nichts weiteres.im ccu.io/fritzbox werden noch die Ereignisse: close, end und error behandelt und einfach Reconnection gestartet.
> In Node-red gab es nur ein paar lokale Funktionen und kein main().
Vergiss "main" :lol:> Es wurde nur an wenigen Stellen auf etwas reagiert. Ansonsten gab es einen schönen linearen Verlauf. Alles kein Thema. Brauche nur den Einstieg. Ansonsten kämpfe ich mich da schon durch. ;-)
Hier ist auch alles linear. Und hier wird dein Startpunkt on("data") sein. Da startet dein node-red flow.
-
wow… das nenne ich mal eine ausführliche Antwort.
sorry Bluefox, wenn ich an der Stelle etwas nachhake. Ich möchte nur vermeiden, dass ich am Anfang an der falschen Stelle anfange. So komme ich gut zurecht. Deine Antworten waren extrem hilfreich.
Die Punkte sind für mich nun klar und ich gehe mal davon aus, dass ich das hinbekomme:
-
Datenpunkte anlegen, z.B. über io-package.json
-
main() ja, habe ich begriffen
-
socketBox.on() ist klar. da empfange ich auch schon Daten und habe angefangen das zu zerpflücken
(da habe ich aber noch eine Frage)
- close, end und error. Damit meinst Du wahrscheinlich die tcp Verbindung. Werde ich auch mit klar kommen.
(geht ja auch noch nachträglich)
Jetzt trotzdem noch einmal grundlegend:
a)
In dem Beispielcode wird in einer Funktion die Verbindung hergestellt und dann auf Daten gewartet.
Ist das prinzipiell OK? D.h. bei Daten wird ja quasi mitten in die Funktion gesprungen...
Funktion
--tcp Verbindung herstellen
--warte auf Daten <---- on()
--verarbeite Daten
Funtkion Ende
b)
Alternativ muss ich das on() aus der Funktion rausnehmen und SocketBox muss global definiert werden.
oder c)
ohne Funktion die tcp Verbindung herstellen und dann Daten empfangen und verarbeiten
Was ist schicker, bzw. der richtige Weg? a), b) oder c)
Oder ist das gänzlich egal?
Wenn ich raten müsste, dann ist es kein Problem, mitten in eine Funktion zu springen. Wäre ja in adapter.on("ready", function () {....}); genauso.
Und eine, hoffentlich erst einmal, letzte Frage zu Objekten/Variablen.
Ich habe einmal die Datenpunkte in den Objekten. Die sind restartsicher.
Dann habe ich die Variablen im Programm, die nicht restartsicher sind.
Ich brauche wahrscheinlich einige Infos restartsicher, die ich aber nicht als Datenpunkte benötige. Ich muss noch überlegen, ob das wirklich nötig ist. Gibt es da einen Weg oder besteht nur die Wahl aus den Datenpunkten oder Variablen zur Laufzeit?
Ich gehe mal davon aus, dass ich dann erst einmal genug Infos habe, um zu starten und erst später wieder die eine oder andere Frage haben werde
-
-
OK, ich werfe gerade einen Blick auf den Code…
...und glaube, die Frage, ob man innerhalb einer Funktion auf ein Ereignis reagieren kann/soll war blöd...
-
Jetzt trotzdem noch einmal grundlegend:
a)
In dem Beispielcode wird in einer Funktion die Verbindung hergestellt und dann auf Daten gewartet.
Ist das prinzipiell OK? D.h. bei Daten wird ja quasi mitten in die Funktion gesprungen…
Funktion
--tcp Verbindung herstellen
--warte auf Daten <---- on()
--verarbeite Daten
Funtkion Ende `
b)
Alternativ muss ich das on() aus der Funktion rausnehmen und SocketBox muss global definiert werden.
oder c)
ohne Funktion die tcp Verbindung herstellen und dann Daten empfangen und verarbeiten
Was ist schicker, bzw. der richtige Weg? a), b) oder c)
Oder ist das gänzlich egal?
Du hast es begriffen.
Es gibt folgendes, falls die Funktion groß ist, dann ist besser das als Funktion zu gestallten.
function parseData(data) { //200 Zeilen } socketBox.on('data', parseData);
Falls Funktion an mehreren stellen verwendet wird, dann auch als named Funktion:
var connecting = false; function restartConnection() { if (socketBox) { socketBox.end(); socketBox = null; } if (!connecting){ connecting = setTimeout(function () { connectToFritzBox(); }, 10000); } } socketBox.on('error', restartConnection); socketBox.on('close', restartConnection); socketBox.on('end', restartConnection);
Wenn ich raten müsste, dann ist es kein Problem, mitten in eine Funktion zu springen. Wäre ja in adapter.on("ready", function () {….}); genauso. `
"Viele Wege führen nach Rom"Ich habe einmal die Datenpunkte in den Objekten. Die sind restartsicher.
Dann habe ich die Variablen im Programm, die nicht restartsicher sind.
Ich brauche wahrscheinlich einige Infos restartsicher, die ich aber nicht als Datenpunkte benötige. Ich muss noch überlegen, ob das wirklich nötig ist. Gibt es da einen Weg oder besteht nur die Wahl aus den Datenpunkten oder Variablen zur Laufzeit? `
Eigentlich ja. Nur states und objects. Du kannst noch natürlich einfach in einer Datei speichern… Aber dann wird es später nicht mit redundantem Ausbau funktionieren.Kannst du Beispiel nennen?
-
Ein Beispiel sind die Callids mit Ihren langsam aufbauenden Zuständen.
Wenn ich das beim Überfliegen des ccu.io fritzbox-Adapters richtig gesehen habe, geht der davon aus, dass es immer max einen Anruf parallel gibt. Ich bin der Meinung, dass ich mit den Callids besser auch parallel Anrufe verarbeiten kann.
Wenn man im bestehenden Gespräch den Adapter neu startet, dann sollen die aktuellen Zustände erhalten bleiben.
mmh… das mit den Zuständen wird wahrscheinlich nicht funktionieren, da dann eine identische ID unter Umständen schon ein anderer Anruf ist. Ich denk das noch einmal durch, ob das persistent sein muss oder nicht.
Die Antwort ist (?):
-
persistent über Objekte/Datenpunkte in ioBroker
-
flüchtig mit Variablen im Script
Damit kann ich arbeiten.
Danke für die Info mit den Funktionen!
-
-
> Wenn man im bestehenden Gespräch den Adapter neu startet, dann sollen die aktuellen Zustände erhalten bleiben.
Ich denke das kann man Opfern. -
ja, kann man
Muss doch noch einmal stören. :mrgreen:
Wie kann ich denn ein Objekt/Datenpunkt aus ioBroker lesen?
Ich möchte einen DP aus Node-red lesen, und bei Änderung reagieren.
Hintergrund. Für das Testen möchte ich den fertigen Callgenerator aus dem Node-red Flow nutzen. Dieser simuliert dann die Calls und schreibt die simulierte Fritzboxmeldung in ein Node-red Datenpunkt. Diesen möchte ich dann alternativ mit der parseData() Funktion verwenden.
-
Grummel…
wahrscheinlich mit:
var callgenMessage = adapter.getState("node-red.0.fritzbox.meldungAusDerFritzBox");
Wundere mich, warum ich immer undefined zurückbekomme…
In der Entwicklungsumgebung für ioBroker habe ich kein Node-red installiert, kein Flow, keine DP
Allerdings bekomme ich Node-red auch nicht auf dem Mac installiert. Überlege mir was anderes.
EDIT: mit einem tcp output in Node-red hat es funktioniert.
-
Grummel…
wahrscheinlich mit:
var callgenMessage = adapter.getState("node-red.0.fritzbox.meldungAusDerFritzBox");
Wundere mich, warum ich immer undefined zurückbekomme…
In der Entwicklungsumgebung für ioBroker habe ich kein Node-red installiert, kein Flow, keine DP
Allerdings bekomme ich Node-red auch nicht auf dem Mac installiert. Überlege mir was anderes. `
Richtig ist:
adapter.getState("node-red.0.fritzbox.meldungAusDerFritzBox", function (err, val) { // Asynchron!! var callgenMessage = val.val; });
Aber vermutlich du willst darauf reagieren , wenn das Wert gesetzt ist?
Dann:
- erst einmalig "Subscriben", z.B in "ready":
adapter.subscribeForeignStates("node-red.0.fritzbox.*);
Dann auf die Änderungen reagieren:
adapter.on("stateChange", function (id, state) { if (state && id == "node-red.0.fritzbox.meldungAusDerFritzBox") { // New value of adapter.log.info(state .val); } });
-
Hi Bluefox,
ich habe einen Punkt, an dem ich gerade hänge.
Bist auf den history Channel habe ich alle Datenpunkte in der io-package.json definiert.
Wenn ich den Fritzboxadapter in ioBroker installiere werden auch die Channels und die Objekte angelegt.
In ioBroker sehe ich unter "Zustände" die Werte. In den ioBroker/Objekten bleiben die Werte leer
Den Datenpunkt schreibe ich mit:
adapter.setState('call.counterActualCalls.ringCount', ringCount , true);
Die io-package.json sieht so aus:
{ "common": { "name": "fritzbox", "version": "0.0.1", "title": "fritzbox Adapter", "desc": { "en": "Adapter verarbeitet die Anrufinformation der Fritzbox über tcp, Port 1012 (Callmonitor in der Fritzbox mit #96*5* aktivieren)", "de": "Adapter verarbeitet die Anrufinformation der Fritzbox über tcp, Port 1012 (Callmonitor in der Fritzbox mit #96*5* aktivieren)", "ru": "Adapter verarbeitet die Anrufinformation der Fritzbox über tcp, Port 1012 (Callmonitor in der Fritzbox mit #96*5* aktivieren)" }, "authors": [ "ruhr <ruhr@digheim.de>" ], "license": "MIT", "platform": "Javascript/Node.js", "mode": "daemon", "availableModes": [ "daemon" ], "readme": "https://github.com/ioBroker/.../README.md", "loglevel": "debug", "icon": "fritzbox.png", "keywords": [ "fritzbox", "cdr", "callmonitor" ], "extIcon": "", "type": "communication" }, "native": { "devices": [], "interval": 60000 }, "objects": [], "instanceObjects": [ { "_id": "message", "type": "state", "common": { "name": "Last fritzbox message", "type": "string", "role": "message", "read": true, "write": false, "desc": "last message from fritzbox as string" }, "native": {} }, { "_id": "calls", "type": "channel", "common": { "name": "calls", "role": "call info" }, "native": {} }, { "_id": "calls.ring", "type": "state", "common": { "name": "ring activ?", "type": "boolean", "role": "call info", "read": true, "write": false, "desc": "ring activ?" }, "native": {} }, { "_id": "calls.missedCount", "type": "state", "common": { "name": "Counter: rings missed", "type": "string", "role": "call info", "read": true, "write": true, "desc": "Counter: rings missed" }, "native": {} }, { "_id": "calls.ringActualNumber", "type": "state", "common": { "name": "actual last ringing number", "type": "string", "role": "call info", "read": true, "write": false, "desc": "actual last ringing number" }, "native": {} }, { "_id": "calls.ringActualNumbers", "type": "state", "common": { "name": "actual ringing numbers", "type": "string", "role": "call info", "read": true, "write": false, "desc": "actual ringing numbers" }, "native": {} }, { "_id": "calls.ringLastNumber", "type": "state", "common": { "name": "ring last number", "type": "string", "role": "call info", "read": true, "write": false, "desc": "ring last number" }, "native": {} }, { "_id": "calls.ringLastMissedNumber", "type": "state", "common": { "name": "ring last missed number", "type": "string", "role": "call info", "read": true, "write": false, "desc": "ring last missed number" }, "native": {} }, { "_id": "calls.callLastNumber", "type": "state", "common": { "name": "call last number", "type": "string", "role": "call info", "read": true, "write": false, "desc": "call last number" }, "native": {} }, { "_id": "calls.connectNumber", "type": "state", "common": { "name": "actual last connected number", "type": "string", "role": "call info", "read": true, "write": false, "desc": "actual last connected number" }, "native": {} }, { "_id": "calls.connectNumbers", "type": "state", "common": { "name": "actual last connected numbers", "type": "string", "role": "call info", "read": true, "write": false, "desc": "actual last connected numbers" }, "native": {} }, { "_id": "calls.counterActualCalls", "type": "channel", "common": { "name": "calls", "role": "call info" }, "native": {} }, { "_id": "calls.counterActualCalls.allActiveCount", "type": "state", "common": { "name": "Counter: all active Calls", "type": "string", "role": "call info", "read": true, "write": false, "desc": "Counter: all active Calls" }, "native": {} }, { "_id": "calls.counterActualCalls.connectCount", "type": "state", "common": { "name": "actual activ onnects", "type": "string", "role": "call info", "read": true, "write": false, "desc": "Counter: actual activ connected calls" }, "native": {} }, { "_id": "calls.counterActualCalls.ringCount", "type": "state", "common": { "name": "actual ring count", "type": "string", "role": "call info", "read": true, "write": false, "desc": "Counter: actual ring" }, "native": {} }, { "_id": "calls.counterActualCalls.callCount", "type": "state", "common": { "name": "actual activ calls", "type": "string", "role": "call info", "read": true, "write": false, "desc": "Counter: actual activ calls" }, "native": {} }, { "_id": "calls.telLinks", "type": "channel", "common": { "name": "calls", "role": "call info" }, "native": {} }, { "_id": "calls.telLinks.ringLastNumberTel", "type": "state", "common": { "name": "ring last number tel:link", "type": "string", "role": "call info", "read": true, "write": false, "desc": "ring last number tel:link" }, "native": {} }, { "_id": "calls.telLinks.callLastNumberTel", "type": "state", "common": { "name": "call last number tel:link", "type": "string", "role": "call info", "read": true, "write": false, "desc": "call last number tel:link" }, "native": {} }, { "_id": "calls.telLinks.ringLastMissedNumberTel", "type": "state", "common": { "name": "ring last missed number tel:link", "type": "string", "role": "call info", "read": true, "write": false, "desc": "ring last missed number tel:link" }, "native": {} }, { "_id": "history", "type": "channel", "common": { "name": "history calls", "role": "history calls" }, "native": {} }, { "_id": "history.allTableHTML", "type": "state", "common": { "name": "history of calls as HTML", "type": "string", "role": "history", "read": true, "write": false, "desc": "history of calls as HTML" }, "native": {} }, { "_id": "history.allTableJSON", "type": "state", "common": { "name": "history of calls as JSON", "type": "string", "role": "history", "read": true, "write": false, "desc": "history of calls as JSON" }, "native": {} } ] }</ruhr@digheim.de>
Ich hoffe, es ist nur eine Kleinigkeit
Viele Grüße und danke schon einmal
Michael
-
Dein Namens-Model ist durcheinander:
States Objects --------------------------------------------- fritzbox.0.system.deltaTime ??? call calls
-
Guten Morgen Bluefox,
sorry, ich verstehe es noch nicht…
Vielleicht habe ich noch ein generelles Verständnisproblem von den Channels und Objekten.
Der Channel (type:channel):
fritzbox.0.system
Und das Objekt (type:state):
fritzbox.0.system.deltaTime
fehlten in der Tat in meiner io-packages.json Datei.
Ich habe dies in der JSON ergänzt:
{ "_id": "system", "type": "channel", "common": { "name": "history calls", "role": "history calls" }, "native": {} }, { "_id": "system.deltaTime", "type": "state", "common": { "name": "delta time in seconds between fritzbox and ioBroker", "type": "string", "role": "seconds", "read": true, "write": false, "desc": "delta time in seconds between fritzbox and ioBroker" }, "native": {} },
Und schon wird das Objekt angelegt und über den Adapter gefüllt.
Aber warum funktioniert das im Channel Calls nicht?
Da habe ich Tomaten auf den Augen.
Da ist in der JSON folgendes angelegt:
Der Channel (type:channel):
fritzbox.0.calls
Und das Objekt (type:state):
fritzbox.0.system.ring
{ "_id": "calls", "type": "channel", "common": { "name": "calls", "role": "call info" }, "native": {} }, { "_id": "calls.ring", "type": "state", "common": { "name": "ring activ?", "type": "boolean", "role": "call info", "read": true, "write": false, "desc": "ring activ?" }, "native": {} },
Hier wird das Objekt nicht gefüllt.
Der einzige Unterschied, der mit auffällt, ist dass ich in dem Channel Calls noch weitere Channels angelegt habe.
Der Channel (type:channel):
fritzbox.0.calls
enthält z.B. noch einen Channel:
fritzbox.0.calls.telLinks
sorry. ich habe es versucht, bin aber mit Deiner Antwort nicht weiter gekommen :?
VG,
Michael
-
Dein Objekt heißt "calls" und dein Zustand heißt "call"
-
oh Gott…
Das nenne ich blind... :shock:
Danke Dir Bluefox! Da hatte ich wirklich Tomaten auf den Augen. Zigmal drüber geschaut...
-
Hi Bluefox,
ich habe leider noch einen Punkt, an dem ich nicht weiter komme
Ich möchte Dein Tabellen Widget nutzen und dafür ein JSON schreiben. Leider komt dies nie in den ioBroker Objekten an. Ich hoffe, es ist nicht wieder ein einfacher Schreibfehler. :?
Zum Test wird ein Array mit einem einfachen Objekt befüllt:
var lineHistoryAllJson = { "Uhrzeit" : call[id].date, "Anrufer" : call[id].externalNumber }; historyListAllJson.unshift(lineHistoryAllJson); if (historyListAllJson > configHistoryAllLines) { historyListAllJson.length = configHistoryAllLines; }
So will ich es in Richtung ioBroker schreiben:
adapter.setState('history.allTableJSON', historyListAllJson, true);
Und zum Test lass ich mir jeweils das erste Objekt im Log ausgeben:
adapter.log.info("historyListAllJson[0] " + historyListAllJson[0].Uhrzeit + " " + historyListAllJson[0].Anrufer);
Als Ergebnis erhalte ich im Log:
2015-06-21 22:55:24.126 - info: fritzbox.0 historyListAllJson[0] 21.06.15 22:55:24 040207714031
So ist das Objekt in der io-package.json definiert:
{ "_id": "history.allTableJSON", "type": "state", "common": { "name": "history of calls as JSON", "type": "object", "role": "table", "read": true, "write": false, "desc": "history of calls as JSON" }, "native": {} },
In ioBroker bekomme ich meine Tabellen als html und txt im selben Channel. Nur das Objekt history.allTableJSON will einfach nicht funktionieren.
Nach dem call/calls traue ich mich schon fast gar nicht mehr zu fragen… momentan hänge ich aber leider an der Stelle.
VG,
Michael
-
Versuch mal:
adapter.setState('history.allTableJSON', JSON.stringify(historyListAllJson), true);
-
Hi Bluefox,
die tägliche Frage… :mrgreen: :?
Ich habe jetzt soweit den Node-Red Flow komplett für den Adapter umgesetzt und um einige Ausgaben ergänzt.
Jetzt stehe ich mangels Wissen wieder vor einer kleinen Hürde...
Im Node-red Flow hatte ich im Callmonitor die Gesprächssekunden der bestehenden Verbindungen hochgezählt. Dies würde ich noch gerne realisieren, bevor ich mich an der Config-Webseite versuche. Mir fehlt aber jede Idee.
D.h., wenn ein Connect aktiv ist, möchte ich einen Wert jede Sekunde hochzählen. Das Programm muss in der Zeit aber ganz normal weiter ausgeführt werden (parallele Calls).
Ein kleiner Tipp... ...für einen Einsteiger...
Wenn das gelöst ist, wären die nächsten Schritte:
(1)
-
Config über die Webseite
-
Dokumentation der einzelnen Objekte/Datenpunkte
-
(mal drüber sehen, ob die Objekte so Sinn machen)
-
veröffentlichen?
(2)
Dann als nächstes folgende Erweiterungen für eine Version 2:
-
Telefonbuchimport und Verarbeitung
-
Verfeinerung der Config für den Anwender
-
(möglichst keine Änderungen an den Objekten/Datenpunkten)
-
-
Hi Bluefox,
die tägliche Frage… :mrgreen: :?
Ich habe jetzt soweit den Node-Red Flow komplett für den Adapter umgesetzt und um einige Ausgaben ergänzt.
Jetzt stehe ich mangels Wissen wieder vor einer kleinen Hürde...
Im Node-red Flow hatte ich im Callmonitor die Gesprächssekunden der bestehenden Verbindungen hochgezählt. Dies würde ich noch gerne realisieren, bevor ich mich an der Config-Webseite versuche. Mir fehlt aber jede Idee.
D.h., wenn ein Connect aktiv ist, möchte ich einen Wert jede Sekunde hochzählen. Das Programm muss in der Zeit aber ganz normal weiter ausgeführt werden (parallele Calls).
Ein kleiner Tipp... ...für einen Einsteiger...
Wenn das gelöst ist, wären die nächsten Schritte:
(1)
-
Config über die Webseite
-
Dokumentation der einzelnen Objekte/Datenpunkte
-
(mal drüber sehen, ob die Objekte so Sinn machen)
-
veröffentlichen?
(2)
Dann als nächstes folgende Erweiterungen für eine Version 2:
-
Telefonbuchimport und Verarbeitung
-
Verfeinerung der Config für den Anwender
-
(möglichst keine Änderungen an den Objekten/Datenpunkten)
filename="2016-06-22 Adapter Ist-Stand.png" index="0">~~ `
var intervalRunningCall = null; if (callStarted && !intervalRunningCall) { // Do it every second intervalRunningCall = setInterval(function () { adapter.getState('call.time', function(err, state) { adapter.setState('call.time', state.val + 1); }); }, 1000); } else if (!callStarted && intervalRunningCall) { // Stop interval clearInterval(intervalRunningCall); intervalRunningCall = null; }
-