NEWS
Schreiben und danach lesen von Datenpunkten ist fehlerhaft
-
Ich Schreibe einen Datenpunkt und lese diesen danach sofort wieder aus.
Der ausgelesene Wert ist nicht der vorher geschriebene !
Was ist falsch?
Hinweis: „Aktualisiere“ durch „Steuere“ ersetzte hilft nicht. -
@automatisierer-0 möglicherweise geht das zu schnell, bau doch zum testen mal ne kleine pause ein vorm debug output ein
den datenpunkt selbst mal geprüft ob er sich wie gewünscht ändert?
-
@automatisierer-0 sagte: Der ausgelesene Wert ist nicht der vorher geschriebene !
setState() (steuere, aktualisiere) arbeitet asynchron, ist also noch nicht fertig, wenn der Datenpunkt eingelesen wird. Deshalb arbeitet man mit Variablen.
-
@paul53 Kann ich machen.
Dazu 2 Fragen:- Wie lege ich in Blockly eine globale Variable an?
Als globale Variable meine ich eine Variable, auf die in jedem Script geschieben/gelesen werden kann - Was passiert, wenn in einem Script eine Variable angelegt wurde, welche den gleichen Namen wie ein globale Variable hat? Wird dann die lokale Variable angesprochen? Funktioniert dies dann?
- Wie lege ich in Blockly eine globale Variable an?
-
@automatisierer-0 sagte: Als globale Variable meine ich eine Variable, auf die in jedem Script geschieben/gelesen werden kann
Der Datenaustausch zwischen verschiedenen Scripts erfolgt in ioBroker über Datenpunkte. Die Reihenfolge der Abarbeitung von Scripts (gleiche Trigger) kann ohnehin nicht vorgeben werden.
@automatisierer-0 sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
eine Variable angelegt wurde, welche den gleichen Namen
Der Gültigkeitsbereich von Variablen ist auf das Script begrenzt. Es können also immer wieder gleiche Variablenbezeichner verwendet werden.
Oder meinst Du Variablen in Scripts unter der Gruppe "global", die in jedes andere Script kopiert werden? Scripts unter "global" sollten nur für häufig verwendete eigene Funktionen verwendet werden - wenn überhaupt (ist mit Blockly schwierig).
-
@paul53 Jetzt drehen wir uns langsam im Kreis.
Auf meine ursprüngliche Anfrage schreibst du:
setState() (steuere, aktualisiere) arbeitet asynchron, ist also noch nicht fertig, wenn der Datenpunkt eingelesen wird. Deshalb arbeitet man mit Variablen.
OK, Jetzt will ich globale Variablen verwenden, da schreibst du:
Der Datenaustausch zwischen verschiedenen Scripts erfolgt in ioBroker über Datenpunkte.Ich möchte:
So wie in Programmiersprachen generell möglich, möchte ich in Blockly eine globale Variable anlegen.
Auf diese globale Variable möchte ich von verschiedenen Blockly-Scripts lesen bzw schreiben.
Wie mache ich das?Ursprünglich wollte ich das mit Datenpunkten realisieren, nur wie du eben geschrieben hast, funktioniert dies wegen der Asynchronität scheinbar nicht.
-
@automatisierer-0 sagte: Ursprünglich wollte ich das mit Datenpunkten realisieren, nur wie du eben geschrieben hast, funktioniert dies wegen der Asynchronität scheinbar nicht.
Das funktioniert über Datenpunkte. Nur innerhalb eines Scripts sollte man Variablen verwenden anstelle von Datenpunkt schreiben mit anschließendem Einlesen.
@automatisierer-0 sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
möchte ich in Blockly eine globale Variable anlegen.
Auf diese globale Variable möchte ich von verschiedenen Blockly-Scripts lesen bzw schreiben.Wozu? Javascript arbeitet nicht zyklisch, sondern Ereignis gesteuert (Trigger).
-
@automatisierer-0 sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
Ich möchte:
So wie in Programmiersprachen generell möglich, möchte ich in Blockly eine globale Variable anlegen.
Auf diese globale Variable möchte ich von verschiedenen Blockly-Scripts lesen bzw schreiben.
Wie mache ich das?
Ursprünglich wollte ich das mit Datenpunkten realisieren, nur wie du eben geschrieben hast, funktioniert dies wegen der Asynchronität scheinbar nicht.- Eine Globale Variable kannst du in Blockly meines Wissens nicht anlegen.
- Der Datenaustausch zwischen Skripten über Datenpunkte ist der richtige.
- Die Annahme, das verschiedene Skripte "synchron" laufen, sprich das die Reihenfolge in der Skripte abgearbeitet werden in irgend einer Weise stabil vorgegeben kann ist falsch.
daraus folgt:
- Ein Datenpunkt den das Skript A schreibt darf das Skript B lesen.
- Ob es den Wert bekommt bevor Skript A geschrieben hat oder nachdem Skript A geschrieben hat hängt vom Zeitverhalten der Skripte ab.
- Skripte bei denen dieses Zeitverhalten kritisch sind sind prinzipiell instabil (Thema "race condition"). Wenn du sicher gehen willst das Datenpunkte sich geändert haben dann solltest du in dem Skript in dem du den lesend nutzen willst einen Trigger auf den Datenpunkt anlegen - im Trigger speicherst du dann den geänderten Wert in einer lokalen Variable. Damit bekommst Du die Änderungen sauber mit und weisst ob du einen "alten" oder "neuen" Wert hast.
- Innerhalb eines einzelnen Skriptes gilt die Regel Erst lesen, dann Rechnen, dann Schreiben
ich hoffe inständig das du deine Skripte nicht versuchst via "Heartbeat" synchron laufen zu lassen - das geht immer in die Hose.
Anders als bei "normalen" Programmiersprachen laufen einzelne Skripte eben gerade nicht synchron ab. Der passende Vergleich zu klassischen Sprachen wäre ein Programm welches mit vielen unterschiedlichen Threads arbeitet. Bei Multithreading ist der Datenaustausch zwischen verschiedenen Threads über globale Variablen von race-conditions bedroht und es wird davon abgeraten.
A.
Nachtrag: SetState ist asynchron - der Zeitversatz beim Schreiben liegt üblicherweise bei wenigen 10 ms. Nur in ausnahmefällen kann das mal länger werden. Dein Test "schreiben dann lesen im gleichen Skript" ist daher zwar korrekt, aber für den Einsatzfall Datenaustausch zwischen Skripten nur bedingt aussagekräftig.
-
@asgothian Super präziese Antwort.
Vielen Dank, jetzt kenne ich mich aus!!!! -
@automatisierer-0 sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
So wie in Programmiersprachen generell möglich
Javascript ist auch eine Programmiersprache!
@automatisierer-0 sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
Ursprünglich wollte ich das mit Datenpunkten realisieren, nur wie du eben geschrieben hast, funktioniert dies wegen der Asynchronität scheinbar nicht.
wenn die anderen Scripte auf die Änderung in dem Datenpunkt triggern klappt das sehr wohl, aber um ein paar Millisekunden verzögert
-
@homoran sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
Javascript ist auch eine Programmiersprache!
Stimmt. Und in JS kannst du auch (wenn ich das alles richtig erinnere) global definierte Strukturen erzeugen (skripte im global Verzeichnis). Allerdings geht das meines Wissens nach bei Blockly nicht.
Und Blockly würde ich nicht als Programmiersprache bezeichnen, sondern als Entwicklungsumgebung für Javascript. Da kann es dann auch Einschränkungen geben was effektiv unterstützt wird.
-
@asgothian sagte: (skripte im global Verzeichnis). Allerdings geht das meines Wissens nach bei Blockly nicht.
Man kann auch Blocklys unter der Gruppe "global" erstellen. Allerdings würde ich dringend davon abraten.
Der Zugriff auf globale Funktionen kann in Blockly nur über den Umweg "JS-Funktion mit Ergebnis" erfolgen. -
@asgothian sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
Blockly würde ich nicht als Programmiersprache bezeichnen, sondern als Entwicklungsumgebung für Javascript.
Sehe ich genau so.
@asgothian sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
in JS kannst du auch (wenn ich das alles richtig erinnere) global definierte Strukturen erzeugen (skripte im global Verzeichnis). Allerdings geht das meines Wissens nach bei Blockly nicht.
hier geht mein Wissen fast genau so weit, nur bin ich mir nicht sicher ob "der Inhalt" von Variablen bei globalen Skripten ebenfalls mit übergeben wird.
Wenn ja, darf man natürlich nicht in den Skripten noch e7nmal den selben Bezeichner für eine andere Aufgabe verwenden.
So wie hier gefragt:@automatisierer-0 sagte in Schreiben und danach lesen von Datenpunkten ist fehlerhaft:
Was passiert, wenn in einem Script eine Variable angelegt wurde, welche den gleichen Namen wie ein globale Variable hat
-
@homoran sagte: nur bin ich mir nicht sicher ob "der Inhalt" von Variablen bei globalen Skripten ebenfalls mit übergeben wird.
Nein, wie sollte das funktionieren? Jedes Skript verwendet die Variable mit dem gleichen Bezeichner im eigenen Scope (die Deklaration wird kopiert). Global machen nur häufig verwendete Funktionen und Konstanten Sinn.
-
@paul53 sagte:
Nein, wie sollte das funktionieren?
das hatte mich ja gerade irritiert.
Ich hatte allerdings @Automatisierer-0 so verstanden, als ob er dies wolle, u d daran gezweifelt, dass das geht.