Übersicht aus json generieren.

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

chromo23

Neues Mitglied
14 Oktober 2021
11
1
3
40
Nachdem mir hier beim letzten Mal so gut geholfen wurde und ich gerade bei einem ähnlichen Thema am Verzweifeln bin, wende ich mich mal wieder an das Forum.

Ich frage json werte ab:
Code:
<script onload="setInterval()">
    setInterval(
        async function sensors() {
            response = await fetch("json");
            myJson = await response.json();
            kwRem = myJson.Sensors[2].TaskValues[0].Value;
            document.getElementById("kwRId").innerHTML = kwRem;

        }, 1000);
</script>
Das funktioniert sehr gut.
Nun möchte ich eine Übersicht der vorhandenen Sensoren erstellen:
Hier die Json-Ausgabe:
Code:
{
    "Sensors":[
    {
    "TaskName":"Display",
    "TaskNumber":1
    },

    {
    "TaskValues": [
    {"ValueNumber":1,
    "Name":"Counter",
    "Value":0
    }],
    "TaskName":"Rotary",
    "TaskNumber":2
    },

    {
    "TaskValues": [
    {"ValueNumber":1,
    "Name":"Temperature",
    "Value":20.7
    },
    {"ValueNumber":2,
    "Name":"Humidity",
    "Value":55
    },
    {"ValueNumber":3,
    "Name":"Pressure",
    "Value":1001.98
    }],
    "TaskName":"sensor",
    "TaskNumber":3
    },
],
}

Uns so sollte es dann aussehen:

Display
RotaryCounter:1
sensorTemperature: 20.7
Humidity: 55
Pressure: 1001.98

Ich habe zwei Wege probiert, scheitere aber immer daran, dass es Werte in mehr als eine Ebene gibt (TaskValues is ein Array mit x Unterpunkten) und daran, dass es "Sensoren" gibt, die keine TaskValues Eintrag besitzen.

Einer der Versuche bisher:
Code:
<script onload="setInterval()">
    setInterval(
        async function () {
        response = await fetch("json");
        myJson = await response.json();
        let htmlS = '';
        myJson.Sensors.forEach(sensor => {
            Object.entries(sensor).forEach(([key, value]) => {
                console.log(`${key} ${value}`);
  
            htmlS += `<a id="${key}">${value}</a>`;
        });
        document.getElementById('sensorsMenu').innerHTML = htmlS;
    });

          
        }, 1000);
</script>

Da zeigt der natürlich alles an was es gibt.. :rolleyes:
Alles was es an Beispielen zu diesem Thema gibt behandelt leider nicht das Problem eines Arrays bei der Abfrage.

Kann mir jemand helfen? Wichtig ist, dass wenn TaskValues (siehe z.B. Display) nicht vorhanden, dieser Wert leer bleibt
Und wie kann ich auf einfache Weise bestimmte Sensoren nach Namen dabei ausklammern. z.B
pseudocode:
Code:
exclude: "Rotary","Display"
Ergebnis:
sensorTemperature: 20.7
Humidity: 55
Pressure: 1001.98
 
Zuletzt bearbeitet:

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
scheitere aber immer daran, ... dass es "Sensoren" gibt, die keine TaskValues Eintrag besitzen.
Ob es solch einen Eintrag gibt, kannst Du sehr einfach überprüfen:
Code:
                myJson.Sensors.forEach(sensor => {
                    // Hat der aktuelle Eintrag TaskValues?
                    if (sensor.TaskValues) {

                    }
                });
Und wie kann ich auf einfache Weise bestimmte Sensoren nach Namen dabei ausklammern
Eine Liste anlegen und danach ausfiltern:
Code:
                const blackList = ["Rotary", "Display"];
                myJson.Sensors.forEach(sensor => {
                    // Hat der aktuelle Eintrag TaskValues
                    // und ist er nicht in der Blacklist?
                    if (sensor.TaskValues && !blackList.includes(sensor.TaskName)) {

                    }
                });
Wenn ich mir dein Ergebnis ansehe, willst Du offenbar gezielt Temperature, Humidity und Pressure ausgeben. Für den Zugriff sind die TaskValues ein wenig unglücklich gestaltet. Um einen direkten Zugriff zu ermöglichen, schlage ich vor, das Ganze in ein Objekt umzuwandeln:
Code:
                myJson.Sensors.forEach(sensor => {
                    // Hat der aktuelle Eintrag TaskValues
                    // und ist er nicht in der Blacklist?
                    if (sensor.TaskValues && !blackList.includes(sensor.TaskName)) {
                        const values = {};
                        // TaskValues in ein Objekt umwandeln, das direkten Zugriff ermöglicht:
                        sensor.TaskValues.forEach(item => {
                            values[item.Name] = item.Value;
                        });
                        // Jetzt können wir sehr einfach auf die Werte zugreifen:
                        console.log('Temperature=' + values.Temperature);
                        console.log('Humidity=' + values.Humidity);
                        console.log('Pressure=' + values.Pressure);
                    }
                });
 

chromo23

Neues Mitglied
14 Oktober 2021
11
1
3
40
Vielen Dank schonmal.
Ich hätte vielleicht erwähnen sollen, dass die json liste sehr dynamisch sein kann.
So kann die Art und Anzahl der Sensoren wechseln und die Werte dementsprechend anders sein.
So kann es z.b. einen sensor geben, der co2 heißt und ppm als valuenamen hat.
Ich will im Prinzip alle Sensoren in der Liste erfassen und das übersichtlich ausgeben.
Nur bei Bedarf soll ein Sensor geblacklistet werden. Ich verstehe noch nicht so richtig, wie ich das mit deinem Beispielcode umgesetzt bekomme. Aber ich lese, lerne und probiere...
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
Prüfe, ob dies besser ist:
Code:
        const blackList = ["Rotary", "Display"];
        setInterval(
            async function () {
                response = await fetch("thread760.json");
                myJson = await response.json();
                let htmlS = '';
                myJson.Sensors.forEach(sensor => {
                    // Hat der aktuelle Eintrag TaskValues
                    // und ist er nicht in der Blacklist?
                    if (sensor.TaskValues && !blackList.includes(sensor.TaskName)) {
                        // Über alle Werte des Sonsors:
                        sensor.TaskValues.forEach(item => {
                            console.log(item.Name + '=' + item.Value);
                        });
                    }
                });
            }, 1000);
 

chromo23

Neues Mitglied
14 Oktober 2021
11
1
3
40
Das funktioniert zum großen Teil schon.
Zwei Probleme habe ich noch.

Erstens:
Ich habe erstmal im log den Sensornamen hinzugefügt.
Code:
console.log(sensor.TaskName + ':' + item.Name + '=' + item.Value);

das sieht dann so aus:
Code:
sensor:Temperature=21.3
sensor:Humidity=51
sensor:Pressure=1008.42
Clock:Output=0
Rotary:Counter=0

Was muss ich tun, dass es dann auf der Webseite so angezeigt wird:

Code:
sensor: Temperature=21.3
        Humidity=51
        Pressure=1008.42
Clock:  Output=0
Rotary: Counter=0

Zweitens:
Die Blacklist funktioniert für Sensoren mit Werten.
Da Display (ist ja eigentlich kein Sensor) keinen Wert hat, wird es, auch wenn ich es aus der Blacklist entferne, nicht angezeigt. Ich nehme an, es liegt daran, dass, so wie ich sensor.TaskName hinzugefügt habe, jeder Sensor mit einem Wert verknüpft werden möchte?
 
Zuletzt bearbeitet:

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
Was muss ich tun, dass es dann auf der Webseite so angezeigt wird:

Code:
sensor: Temperature=21.3
        Humidity=51
        Pressure=1008.42
Clock:  Output=0
Rotary: Counter=0
Solch eine Anforderung gibt es häufig. Führe einen Merker, der angibt ob es die erste Zeile für einen Sensor ist und gib abhängig davon entweder den Sensornamen oder ein Leerelement aus:
Code:
                myJson.Sensors.forEach(sensor => {
                    // Hat der aktuelle Eintrag TaskValues
                    // und ist er nicht in der Blacklist?
                    if (sensor.TaskValues && !blackList.includes(sensor.TaskName)) {
                        // Über alle Werte des Sonsors:
                        let html = '', firstItem = true;
                        sensor.TaskValues.forEach(item => {
                            // Handelt es sich um den ersten Wert des Sensors?
                            if (firstItem) {
                                firstItem = false;
                                // Container mit Name zum HTML hinzu fügen:
                                html += '<div>' + sensor.TaskName + '</div>';
                            } else {
                                // Leeren Container zum HTML hinzu fügen:
                                html += '<div></div>';
                            }
                            // Container mit Name und Wert zum HTML hinzu fügen:
                            html += '<div>' + item.Name + ' =' + item.Value + '</div>';
                            console.log(sensor.TaskName + ':' + item.Name + '=' + item.Value);
                        });
                        console.log(html);
                    }
                });
Die Container dann mit Gridlayout in einem Raster anordnen.
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
PS: Wie ich sehe, habe ich da noch einen Fehler gemacht: Die Variable html muss vor der äußeren Schleife auf einen Leerstring gesetzt werden statt vor der inneren.
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
Da Display (ist ja eigentlich kein Sensor) keinen Wert hat, wird es, auch wenn ich es aus der Blacklist entferne, nicht angezeigt. Ich nehme an, es liegt daran, dass, so wie ich sensor.TaskName hinzugefügt habe, jeder Sensor mit einem Wert verknüpft werden möchte?
Ja genau. Hiermit:
Code:
if (sensor.TaskValues
wird geprüft ob ein Array mit Werten vorhanden ist.
Was möchtest Du denn bei einem Sensor ohne Werte anzeigen? Nur den Namen? Das kannst Du dann im else-Zweig tun.
 

chromo23

Neues Mitglied
14 Oktober 2021
11
1
3
40
Yesssssss! Es funktioniert
Was möchtest Du denn bei einem Sensor ohne Werte anzeigen? Nur den Namen? Das kannst Du dann im else-Zweig tun.
Code:
else if (!blackList.includes(sensor.TaskName)) {html += '<div>' + sensor.TaskName + '</div>';}

Ausgabe ist immer noch so:
Code:
<div>Display</div>
<div>Rotary</div>
<div>Counter =0</div>
<div>sensor</div>
<div>Temperature =20.9</div>
<div></div>
<div>Humidity =54</div>
<div></div>
<div>Pressure =1009.42</div>
Deshalb meine (hoffentlich) letzte Frage: Wie bekomme ich das sortiert?
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
Wie bekomme ich das sortiert?
Meinst Du damit "Wie bekomme ich das in einem Raster angeordnet"? Wenn ja, sind es zwei CSS-Anweisungen:
Code:
        /* Ein Raster mit zwei Spalten einrichten: */
        #grid-container {
            display: inline-grid;
            grid-template-columns: auto auto;
        }

        /* Dies nur damit es ansprechender aussieht: */
        #grid-container div {
            padding: 0 0.5em 0 0.5em;
        }
 

chromo23

Neues Mitglied
14 Oktober 2021
11
1
3
40
Sorry. :oops: Es ist schon spät. Der Grund warum ich das nicht sortiert bekommen habe war:

Code:
else if (!blackList.includes(sensor.TaskName)) {html += '<div>' + sensor.TaskName + '</div>' + '<div></div>';}

Ohne Wert kommt da auch nichts mehr, deshalb muss man manuell noch
Code:
'<div></div>'
hinten ran hängen.

Danke dir vielmals!!! Gute Nacht....
 

chromo23

Neues Mitglied
14 Oktober 2021
11
1
3
40
Und auch hier wieder ein visuelles Feedback.
Bildschirmfoto 2021-10-22 um 19.43.45.png
Bildschirmfoto 2021-10-22 um 19.44.16.png Bildschirmfoto 2021-10-22 um 19.45.34.png
So langsam, ganz, ganz langsam komme ich da rein
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.512
478
83
68
Sieht ja super aus, danke für das Feedback!
Wie ich sehe, brauchst Du gar keine Ratschläge was das Layouting betrifft :smile: Hast Du das mit Grid gemacht?
 
Zuletzt bearbeitet:
Werbung:

Neueste Beiträge