Forum: PC-Programmierung JavaScript - Variablen aus JSON-Datei laden


von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Hallo Community,
ich möchte Variablen aus einer JSON-Datei sekündlich laden.
Dazu hab ich ein kleines Script geschrieben:
JSON-Datei:
1
{
2
"temp_1": 10,
3
"pumpe_1": 1
4
}
JavaScript-Datei:
1
/** URL zur Variablendefinierung - JSON-Format */
2
var urlVariables = "./variables/variables.html";
3
function nameVariables(jd){
4
/** Variablen deklarieren */
5
temp_1 = (jd.temp_1);
6
pumpe_1 = (jd.pumpe_1);
7
}
8
function updateVariables(){
9
$.getJSON(urlVariables, nameVariables);
10
}
11
/** Alle 1000ms werden die Variablen aktualisiert */
12
updateVariables();
13
setInterval(updateVariables, 1000);
Die Variablen sollen dann Global verfügbar sein, weil Anzeigen, 
Graphen,... davon abhängig sind und dynamisch aktualisiert werden.

Das Script funktioniert, wenn ich nur eine Variable verwende wie z.B. 
temp_1.
Aber eine 2te oder mehr Variablen funktionier nicht.
Ich suche jetzt schon ein paar Stunden an dem Fehler, aber ich komme 
nicht darauf.

Kann mir da vll. jemand einen Tipp geben/helfen?
Danke und Mfg,
Tropaion

von Jan H. (j_hansen)


Lesenswert?

Funktioniert bei mir problemlos. Der Fehler muss woanders liegen.

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Ich habe ein 2te Script wo ich die Variable so verwende, was aber nicht 
funktioniert. Kann es daran liegen das die Variable nicht übergeben 
wird?
Weil wenn ich sie im selben Script vor der Funktion defniere 
funktioniert es.
1
function funcMode()
2
{
3
  if(kreiselpumpe_1_mode){
4
    document.getElementById("modeOpen").innerHTML = "Automatisch";
5
  }
6
  else{
7
    document.getElementById("modeOpen").innerHTML = "Manuell";
8
  }
9
}
10
funcMode();
11
setInterval(funcMode, 1000);

von Jan H. (j_hansen)


Lesenswert?

Aus deinem 1. Posting:
1
/** Variablen deklarieren */
2
temp_1 = (jd.temp_1);
3
pumpe_1 = (jd.pumpe_1);

Fabian P. schrieb:
> Ich habe ein 2te Script wo ich die Variable so verwende, was aber nicht
> funktioniert.

Und in deinem 2. Script kommt weder "temp_1" noch "pumpe_1" vor. Kann 
sein, dass es sich hier um ein Verständnisproblem meinerseits handelt. 
Aber das könnte man ganz einfach umgehen indem du einfach deinen 
gesamten Code posten würdest und auch erwähnen würdest, wie du den 
ausführst. JScript, Firefox, NodeJS, Rhino,...?

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Angehängte Dateien:

Lesenswert?

Als Anhang jetzt alle Dateien.
Ausführen tu ich es mit Firefox aktuellste Version.

von Jan H. (j_hansen)


Lesenswert?

Firefox-Fehlermeldungen schon gelesen? Das kann manchmal durchaus 
hilfreich sein (ironisch gemeint; es ist fast immer sinnvoll).
> ReferenceError: pump_1 is not defined" in "functions.js" (Zeile 3).
Das sollte wohl "pumpe_1" heißen, oder?

von Dirk D. (dicky_d)


Lesenswert?

du hat da nen type, an manchen stellen nutzt du pump_1 an anderen 
pumpe_1.
in der Heizkreis2.html klappt das dann. in der heizkessel1.html nicht, 
da fehlt glaub ich der Aufruf zur functions.js.

Du solltest dein json file auch .json nennen, je nach einstellung mag 
dein browser es nicht wenn json mit falschem content-type ausgeliefert 
wird.

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Ich habe es bist jetzt immer nur mit Heizkreis 1 probiert.
Die anderen Seiten sind filler.
Ob es mit dem Format JSON geht muss ich schauen, ich weis nemlich nicht 
ob die SPS auf der ich das Lade kann.

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Angehängte Dateien:

Lesenswert?

Bin die Variablen jetzt noch mal in Ruhe durchgegangen und ich bin der 
Meinung es sollte passen. .json hab ich jetzt auch reingetan.

Die Temperaturanzeige funktioniert auch (dynamisch).
Habe das script functions ganz unten eingebunden, weil es ja erst laden 
soll wenn das DOM-Model vollständig ist sonst kann es ja nicht 
funktionieren.

Nach rumprobiern bin ich der Meinung das die Variable das script nicht 
"erreicht". Denn beide funktionen selbst funktionieren ja.

Im Anhang geänderte Dateien.

Ich muss mich entschuldigen wenn der Code nicht besonders schön ist, ich 
arbeite erst seit ein paar Tagen intensiv mit JS.

: Bearbeitet durch User
von Bastler (Gast)


Lesenswert?

> weil es ja erst laden soll wenn das DOM-Model vollständig ist

Dafür hat das Fenster das Event "onload".
Und dafür, daß das nach geldverdienen klingt, seid ihr sehr unbeleckt.

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Also erstens mal bin ich berufsuntätig, ich bin Schüler an einer 
technischen Schule.
Dieses Projekt mache ich in meiner Freizeit um mein Wissen und Können zu 
erweitern. Es wird wahrscheinlich nie verwendet werden geschweige denn 
verkauft. Höchstens auf meiner Webseite als OpenSource-Projekt 
veröffentlicht. (OpenSource-Befürworter ;) )

Wenn es Geld verdienen wäre wäre es nicht verkaufbar da stimme ich dir 
zu.
Aber was erwartet man von jemanden der seit 4 Tagen mit JavaScript 
arbeitet ;)

Von "onload" hab ich schon gehört, aber ich versuche es am Anfang 
einfacher zu halten und immer mehr zu erweitern.

Ich denke nicht das "onload" der Grund ist das es nicht funktioniert 
oder liege ich da falsch?

Mfg,
Tropaion

: Bearbeitet durch User
von Jan H. (j_hansen)


Lesenswert?

Fabian P. schrieb:
> Ich denke nicht das "onload" der Grund ist das es nicht funktioniert

Der Grund ist, dass JS hochgradig asynchron arbeitet. Wenn du JS sagst, 
es soll dir deine "variables.json" holen, dann macht es das. Irgendwann.
Währenddessen läuft das Programm weiter ab, denn so ein Datenabruf kann 
im Internet ja einige Zeit dauern. Wäre ja blöd, wenn währenddessen 
alles blockiert wäre. Es läuft also weiter in deine functions.js, will 
die "pumpe_1_mode" lesen und peng - nicht gefunden, weil die kommt erst 
irgendwann in der Zukunft asynchron daher. Also dort einen check 
einbauen, ob es die schon gibt, ansonsten "return". Beim Durchlauf eine 
Sekunde später ist sie dann schon da.

von Dirk D. (dicky_d)


Lesenswert?

Oder du kannst deine variable anfangs global initialisieren, dann 
klappts auch.

von Bastler (Gast)


Lesenswert?

In
$.getJSON(urlVariables, nameVariables);
ist nameVariables ein "Funktionsobjekt", d.h. ein Objekt, das den 
()-Operator kennt, mit dem man das im Objekt versteckte Script ausführen 
kann. $.getJSON ruft dieses dann irgendwann später auf, um die 
empfangenen Daten zurückzuliegen.

PS.: seh's als Kompliment, daß ich den Schüler nicht gleich entdeckt 
hab. Ich bin dir eben 35 Jahre voraus. Damals haben wir am TG noch 
deutlich einfachere Dinge gemacht ;-)

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Danke Basterl ;)

Das es ein Obejekt ist, ist mir glar was was meinst du mit aufrufen?


@Dirk
Global initialisiert sind sie doch eh oder?
Laut definition in W3C ist eine Variable ohne "var" in einem 
Unterprogramm automatisch global

@Jan Hansen
Auch wenn das so ist, die Funktion wird ja jede Sekunde ausgeführt, das 
heißt es müsste spätestens eine Sekunde nach dem Laden gehen oder nicht?

EDIT:
Ok, um ehrlich zu sein, ich bin jetzt etwas verwirrt. Hab denn Tipp von 
Hansen mal ausprobiert und er funktioniert, jedoch warum ist mir 
unerklärlich.
1
/** URL zur Variablendefinierung - JSON-Format */
2
var urlVariables = "./variables/variables.json";
3
var pumpe_1_mode;
4
  
5
function nameVariables(jd){
6
/** Variablen deklarieren */
7
  temp_1 = (jd.temp_1);
8
  pumpe_1_mode = (jd.pumpe_1_mode);
9
}
10
  
11
function updateVariables(){
12
  $.getJSON(urlVariables, nameVariables);
13
}
14
/** Alle 1000ms werden die Variablen aktualisiert */
15
updateVariables();
16
setInterval(updateVariables, 1000);

Die Variable "temp_1" kann ich ja auch mit einer anderen Funktion 
(Global) aufrufen, laut W3C (http://www.w3schools.com/js/js_scope.asp) 
definiert man eine Variable ja auch so innerhalb einer Funktion als 
Global. Warum muss ich dann pumpe_1_mode noch mal außerhalb der Funktion 
deklarieren
1
 var pumpe_1_mode;
 damit sie global ist?

: Bearbeitet durch User
von Bastler (Gast)


Lesenswert?

Schau dir mal selfhtml.org an. Da kann man sich über viel Beispiele an 
das Thema rantasten. Jeder vernüftige Browser erlaubt heute per F12 zu 
debuggen. Viel zu tun für die Ferien ;-)

von Jan H. (j_hansen)


Lesenswert?

Fabian P. schrieb:
> @Jan Hansen
> Auch wenn das so ist, die Funktion wird ja jede Sekunde ausgeführt, das
> heißt es müsste spätestens eine Sekunde nach dem Laden gehen oder nicht?

Habe den Code nicht mehr vor mir, aber wenn ich mich richtig erinnere 
rufst du die Funktion initial einmal auf (Skriptfehler => Abbruch), erst 
danach setzt du das Intervall (wird in diesem Fall nicht gemacht, weil 
vorher der Fehler war).
Also prinzipiell hast du recht: hättest du das Intervall vor dem Fehler 
gesetzt, dann hätte der nächste Durchlauf geklappt. So gibt es aber 
keine weiteren Durchläufe.

von Jan H. (j_hansen)


Lesenswert?

Fabian P. schrieb:
> @Dirk
> Global initialisiert sind sie doch eh oder?
> Laut definition in W3C ist eine Variable ohne "var" in einem
> Unterprogramm automatisch global

Ja, aber das machst du erst später asynchron. So versucht er die globale 
Variable zu lesen, die es nicht gibt. Wenn du zu Beginn "pumpe_1_mode = 
null;" schreibst, dann gibt es sie und alles ist paletti.

> var pumpe_1_mode;
> damit sie global ist?

Musst du eh nicht, ohne "var" passt damit sie global ist.

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Habe jetzt window.onload eingebaut in das Script:
1
function funcMode(varHeizkreis)
2
{
3
  if(eval("pumpe_" + varHeizkreis + "_mode")){
4
    document.getElementById("modeOpen").innerHTML = "Automatisch";
5
  }
6
  else{
7
    document.getElementById("modeOpen").innerHTML = "Manuell";
8
  }
9
}
10
window.onload = function() {
11
  funcMode(1);
12
  setInterval(function(){funcMode(1);}, 1000);
13
}
Jetzt funktioniert es auch ohne das die Variablen extra definiert 
werden.

Kann ich das Script varUpdate.js so priorisieren, das es das erste 
Script ist welches ausgeführt werden soll?

von Dirk D. (dicky_d)


Lesenswert?

Um da mal weniger an den symptomen rumzudoktern und das alles ein 
bisschen grade zu rücken:
warum rufst du nicht aus deinem update-interval (ggf. wenn du 
festgestellt hast das sich etwas geändert hat) ein update des dom auf? 
dann hast du das Problem gar nicht das die Daten noch nicht da sind wenn 
du den dom updaten willst, und du hast deine Daten im schnitt 500ms 
schneller auf dem schirm :)

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Sehr interessanter Ansatz, mir kam das auch schon mal in den Sinn, aber 
ich wusste nicht das das geht.
Wie heißt der Befehl mit dem das geht, bzw. nach was muss ich suchen?
Unter "Javascript dom update" finde ich nichts dazu.
Und wie kommst du darauf das es im Schnitt 500ms sind?

Danke und Mfg,
Tropaion

: Bearbeitet durch User
von Dirk D. (dicky_d)


Lesenswert?

Na momentan hast du ja 2 Intervale die alle 1000ms dinge tun, der eine 
läd Daten irgendwo her und speichert sie zwischen, der andere nimmt 
diese Daten und zeigt sie an (in dem es den dom updated).
Die Zeit die vergeht zwischen dem Updaten der zwischengespeicherten 
Daten und dem Anzeigen dieser ist liegt zwischen 0 und 1000ms. Wo genau 
kannst du nur im Einzelfall bestimmen, und es gibt da einen Drift.
Der Mittelwert ist also ( 100 - 0 ) / 2.
Was du jetzt tun kannst: du kannst in dem interval der die Daten 
einsammelt sie auch rausschreiben, am besten mit einer Prüfung ob sich 
diese überhaupt geändert haben.
Grüße, Dirk

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Achso, sozusagen ein Intervall mit einer anonymen Funktion wo alle 
Funktionen zum Updaten einfach ausgeführt wird so unser Art:
Intervall {
varUpdate;
valueUpdate1;
valueUpdate2;
.....
}

Von der Rechnung her meinst du wahr. (1000 - 0)/2 = 500ms oder?

Danke und Mfg,
Tropaion

von Dirk D. (dicky_d)


Lesenswert?

Ja genau, nur ein interval.
und genau so komm ich an die 500ms, jetzt hast du im schlimmsten fall 
2000ms Verzögerung wenn sich ein wert ändert, beide Intervalle addieren 
sich im schlimmsten fall. so hast du maximal 1000ms

von Fabian P. (Firma: wiki.flowerhouse.at) (tropaion)


Lesenswert?

Jetzt weiß ich auch was du meinst.
Wir haben mal so was ähnliches in der Schule gemacht.
Prozessor -> zyklisches Abarbeiten von Befehlen.

Meine Lösung ist jetzt:
1
<script>
2
<!--
3
/** Alle 1000ms werden die Werte aktualisiert */
4
window.onload = function() {
5
  setInterval(function() {
6
/** Die zu aktualisierenden Funktionen hier eintragen */
7
    updateVariables();
8
    funcMode(pumpe_1_mode);
9
    g1.refresh(temp_1);
10
    g2.refresh(pumpe_1_temp);
11
    g3.refresh(pumpe_1);
12
    funcOverheated(pumpe_1_temp, pumpe_1_max_temp);
13
  }
14
/** Aktualisierungszyklus in ms  */  
15
  ,1000);
16
};
17
//-->
18
</script>

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.