JSON Liste in UI darstellen

GUI Relevanten, PaperUI, BasicUI, HabPanel ...

Moderatoren: seppy, udo1toni

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: JSON Liste in UI darstellen

Beitrag von peter-pan »

scotty hat geschrieben: 27. Nov 2022 16:20 Ich denke, dass deshalb meine Aufgabenstellung etwas einfacher ist.
Sorry, aber ich hatte eigentlich mehr die Fragestellung von @penguin im Fokus.

Und dafür könnte ich auch ein erstes Provisorium (Widget) liefern. Das Widget liefert bei der Eingabe des gesamten JSON-Strings eine Liste. Allerdings müsste man da noch etwas Hand anlegen um das ganze etwas "aufzuhübschen". Und natürlich müsste der String, dann auch noch aus dem Item gelesen werden.Das sollte aber dann nicht allzu schwer sein.

Yaml-Code:

Code: Alles auswählen

uid: z_test_anrufliste
tags:
  - Anruferliste aus JSON-String
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: Background of the card e.g. linear-gradient(to top left,#B0E0E6 20%,#1E90FF 30%,#FFC0CB 60%) or green, etc, also hex and rgb
      label: Background
      name: background1
      required: false
      type: TEXT
    - description: JSON-Array
      label: JSON-String
      name: datearray
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Nov 27, 2022, 4:29:34 PM
component: f7-card
config:
  style:
    background: '=(props.background1) ? props.background1 : "linear-gradient(to top left,#B0E0E6 20%,#1E90FF 30%,#FFC0CB 60%)"'
    background-position: down
    background-repeat: no-repeat
    background-size: cover
    border-radius: var(--f7-card-expandable-border-radius)
    font-size: medium
    height: auto
    margin: 5px
    noShadow: true
    padding: 0px
  title: =props.title
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-list
            config:
              mediaList: true
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: listitem
                    fragment: true
                    in: '=props.datearray.split("\},")'
                  slots:
                    default:
                      - component: oh-list-item
                        config:
                          title: =loop.listitem
Das Ergebnis des Widgets sieht dann etwa so aus:
liste.jpg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Benutzeravatar
scotty
Beiträge: 676
Registriert: 28. Apr 2020 04:44

Re: JSON Liste in UI darstellen

Beitrag von scotty »

Vielen Dank Peter, für deine Antwort. Dieses Ergebnis liefert mir das Item 'CallList7' schon ohne Widget. Ich benötige aktuell lediglich den Wert aus 'duration' . Dazu müsste meine Zeile mit eurer Hilfe zerlegt werden.
OH 3.4.5 im Docker auf Synology DS918+ mit USV, Reolink-RLC-511WA, Philips Hue, AVM Fritz!Box 6591C, Alexa, Logitech Harmony und diversen Shelly's

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: JSON Liste in UI darstellen

Beitrag von peter-pan »

Ich habe jetzt mal ein kleines Widget gebastelt, das diesen JSON-String zeilen-/spaltenweise in Textform aufbereitet. Zwischen den Spalten ist jeweils ein Pipe-Symbol als Feldtrenner eingebaut. Damit wird es auch möglich eine (Excel)-Tabelle zu erzeugen.

Eine Darstellung in einer OH3-Page ist natürlich auch möglich :lol: .

Code: Alles auswählen

uid: z_test_json_parse_v0
tags:
  - TR064 Anrufer-Liste
  - peter-pan
props:
  parameters:
    - description: Überschrift - Headline
      label: Title/Titel
      name: title
      required: false
      type: TEXT
    - context: item
      description: JSON String aus TR064
      label: JSON String
      name: js_string
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Nov 29, 2022, 10:20:04 PM
component: f7-card
config:
  style:
    background: '=(props.background1) ? props.background1 : "linear-gradient(to top left,#B0E0E6 20%,#1E90FF 30%,#FFC0CB 60%)"'
    background-position: down
    background-repeat: no-repeat
    background-size: cover
    border-radius: var(--f7-card-expandable-border-radius)
    --jslength: JSON.parse(items[props.js_string].state).length
    font-size: medium
    height: auto
    margin: 5px
    padding: 0px
  title: ='> ' + props.title +' <'
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-list
            config:
              mediaList: true
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: i
                    sourceType: array
                    fragment: true
                    in: '=props.js_string ? JSON.parse(items[props.js_string].state) : ""'
                  slots:
                    default:
                      - component: oh-list-item
                        config:
                          title: '= "Eigene Nr.: |" + loop.i.localNumber + "| Anrufer: |" + loop.i.remoteNumber + "| Datum: |" + loop.i.date.substring(0,10) + "| Uhrzeit: |" + loop.i.date.substring(11,19)  + "| Anruftyp: |" + ((loop.i.type == 1 ) ? "eingehend" : (loop.i.type == 2 ) ? "verpasst" : (loop.i.type == 3 ) ? "ausgehend" : "abgewiesen") + "| Dauer: |" + loop.i.duration '

Das Ganze sieht dann so aus:
anrufer.jpg

Hier noch eine weitere Version mit der du auch noch etwas spielen kannst.

Code: Alles auswählen

uid: z_test_anrufliste_v2
tags:
  - Anruferliste aus JSON-String
  - peter-pan
  - zwei Varianten 1. einfache Liste aus JSON | 2. formatierte Liste
  - die jeweils nicht benötigte Komponente kann ausgeblendet werden
props:
  parameters:
    - description: Title of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: Background of the card e.g. linear-gradient(to top left,#B0E0E6 20%,#1E90FF 30%,#FFC0CB 60%) or green, etc, also hex and rgb
      label: Background
      name: background1
      required: false
      type: TEXT
    - description: Auswahl der gewünschten Liste = 1 Typ 1 (einfach) = 2 Typ 2 (formatiert) - ohne = beide Listen
      label: ListTyp
      name: list
      required: false
      type: TEXT
    - context: item
      description: JSON-String der als Liste umgewandelt werden soll aus AVM Fritz TR064
      label: JSON-String
      name: json_string
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Nov 29, 2022, 6:58:46 PM
component: f7-card
config:
  style:
    background: '=(props.background1) ? props.background1 : "linear-gradient(to top left,#B0E0E6 20%,#1E90FF 30%,#FFC0CB 60%)"'
    background-position: down
    background-repeat: no-repeat
    background-size: cover
    border-radius: var(--f7-card-expandable-border-radius)
    font-size: medium
    height: auto
    margin: 5px
    noShadow: true
    padding: 0px
  title: =props.title
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-list
            config:
              mediaList: true
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: listitem
                    fragment: true
                    in: '=props.json_string ? items[props.json_string].state.replace("[","").replace("}]","").replace("{","").split("\},{") : "" '
                  slots:
                    default:
                      - component: oh-list-item
                        config:
                          title: =loop.listitem
                          visible: "=props.list == 1 ? true : props.list == 2 ? false : true"
                      - component: oh-list-item
                        config:
                          title: ="Eigene Nummer:\ " + loop.listitem.split("\"")[3] + " entfernte Nummer:\ " + loop.listitem.split("\"")[7] + " Anrufdatum:\ " + loop.listitem.split("\"")[11].substring(0,10) + " Type:\ " + loop.listitem.split("\"")[14].replace(":1,","eingehend").replace(":2,","verpasst").replace(":3,","ausgehend").replace(":10,","abgewiesen") + " Dauer:\ " + loop.listitem.split("\"")[16].replace(":","") + " Min."
                          visible: "=props.list == 2 ? true : props.list == 1 ? false : true"
Der String wird hier etwas anders zerlegt. Du kannst hier auch zwei Versionen der Liste erzeugen. Feldtrenner müsstest du da evtl. noch selber einbauen.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Benutzeravatar
scotty
Beiträge: 676
Registriert: 28. Apr 2020 04:44

Re: JSON Liste in UI darstellen

Beitrag von scotty »

Hallo Peter,

da hast du dir aber viel Arbeit gemacht, danke noch einmal. Allerdings hatte ich bereits geschrieben, dass ich lediglich den Wert Duration des letzten Gespräches benötige. Inzwischen hat sich jedoch herausgestellt, dass auch der Wert "type" ganz sinnvoll wäre. Dafür müsste die erste Zeile des Items 'Calllist' ausgewertet (zerlegt) werden. Damit sie von den anderen Zeilen zu unterscheiden ist, habe ich sie durch eine Function etwas verändert:

Code: Alles auswählen

2022-11-30 13:03:35.513 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'FritzBox_CallList1' changed from [{"Eigene Nummer ":"108118","Anrufer ":"043563569806","Datum / Zeit":"30.11.2022 10:59","type":3,"Dauer":45},
Die Bezeichnungen (wie z. B. Anrufer, Datum u. Dauer) sind in deutsch verfasst, bei allen folgenden Verbindungen ist die Schreibweise englisch. Das könnte helfen, die richtigen Werte an Variablen zu übergeben. Exakt dafür benötige ich Hilfe. Ich möchte die Werte aus dem Beispiel von "type" = 3 und "Dauer" = 45 extrahieren um sie anschließend via postupdate an vorhandene Items übergeben zu können.

Noch einmal zum besseren Verständnis: ich verwende bereits zur Anzeige der letzten 7 Ausgangs- und Eingangsgespräche ein Widget. Das ganze sieht so aus, wobei die Angelegenheit jederzeit erweiterbar ist:
telefonliste.png
Dazu habe ich mit tatkräftiger Unterstützung von Udo eine tolle Regel, die ich hier schon einmal öffentlich gemacht habe: viewtopic.php?t=7442&start=20

Leider hat sich im Nachhinein ein Fehler herausgestellt: kommt während eines Ausgangsgespräches ein Gespräch an, wird die Messung für die Ausgangsverbindung zerstört, obwohl die Gegenstelle das Besetztzeichen hört. Es kommt nicht oft vor, aber es passiert.

Aus diesem Grund habe ich eine ungenauere Alternative in Betracht gezogen, nämlich die gerundeten Zeiten aus der Fritzbox. Inzwischen habe ich aber auch festgestellt, das es offensichtlich schwierig ist die Werte aus "type" und "Dauer" zu übernehmen. Es war schon ein ziemlicher Aufwand bis hierhin...
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
OH 3.4.5 im Docker auf Synology DS918+ mit USV, Reolink-RLC-511WA, Philips Hue, AVM Fritz!Box 6591C, Alexa, Logitech Harmony und diversen Shelly's

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: JSON Liste in UI darstellen

Beitrag von peter-pan »

scotty hat geschrieben: 30. Nov 2022 15:23 Ich möchte die Werte aus dem Beispiel von "type" = 3 und "Dauer" = 45 extrahieren um sie anschließend via postupdate an vorhandene Items übergeben zu können.
...ich verstehe die Regeln die dir Udo geschrieben hat nicht so ganz, das ist schon richtig schwieriger Code mit den Lambdas, etc.. Dazu kommt noch, dass ich das TR064-Binding auch gar nicht im Einsatz habe und deshalb auch nichts von den Items weiss die da generiert werden.

Das einzige was ich in diesem Beitrag verstanden habe, ist, dass es einen JSON-String gibt der "ungefiltert" in ein Item geschrieben wird. Dieser String besteht aus "Einzel-Arrays"(die Anrufe), die dan zeilenweise in einem Widget ausgegeben werden sollen. Das habe ich versucht einfach darzustellen. Das sieht natürlich nicht so toll aus wie dein Widget.

Aber grundsästzlich ist es so, wie Udo das bereits beschrieben hat. Du musst die Anzahl der "Einzel-Arrays" des Strings ermitteln.

Code: Alles auswählen

$.length
Das Ergebnis, z.B. "5" kannst du verwenden (-1) um dein JSON-Feld zu extrahieren:

Code: Alles auswählen

$.[4].duration
So ähnlich habe ich das auch mit dem OH-Repeater in dem Muster-Widget gemacht. In dieser Weise, denke ich, muss man auch in einem DSL-Script vorgehen.

Bei dir kommt dann halt noch ein Item-Update dazu. Und da bin ich leider in deiner "Item-Struktur" draussen.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Benutzeravatar
udo1toni
Beiträge: 13856
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: JSON Liste in UI darstellen

Beitrag von udo1toni »

Ja, die Rules sind schon etwas speziell :) Kurz gesagt werden die letzten 7 Gespräche in einer Liste angezeigt, mit getrennten Feldern für Anrufer (Nummer, Name) Startzeit und Dauer. Und wenn ein Anruf dazu kommt, muss die Liste entsprechend geshiftet werden, damit der älteste Eintrag raus fällt und der jüngste Eintrag wiederum angehängt werden kann.
Und das eigentliche Problem ist die Erfassung der Gesprächsdauer, die über die Status eines einzelnen Items ermittelt wird, aber dieses eine Item signalisiert Ruhezustand, ankommende, abgehende und aktive Gespräche. Und da die FRITZ!Box blöd ist (oder das Binding…) werden auch bei bestehendem Gespräch weitere - auch automatisch abgelehnte - Gespräche signalisiert, was dann zu einer Fehlmessung führt. TR064 liefert die Gesprächsdauer im Nachhinein, wenn auch nur minutengenau (wer denkt sich sowas aus?), die FRITZ!Box wird es wissen…

Ich habe keine FRITZ!Box im Telefonbetrieb, wie sieht es denn aus, zeigen die die geführten Gespräche auch nur minutengenau an? Ich kann mir das irgendwie gar nicht vorstellen…
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: JSON Liste in UI darstellen

Beitrag von peter-pan »

udo1toni hat geschrieben: 30. Nov 2022 21:24 Ich kann mir das irgendwie gar nicht vorstellen…
Ich hab zwar eine Fritz-Box, aber nur als Router und das normale Binding zur Steuerung meiner Thermostatventile.

So wie ich das aus dem Post von @penguin verstanden habe, gibt es wohl ein JSON-String aus einem Channel des TR064-Binding der die Anrufe anzeigt.

Ich weiss nicht, ob ich das jetzt falsch interpretiert habe, aber ich hab mir dann einfach mal seinen "Musterstring" geschnappt, und ihn "lesbar" gemacht. Zum "Spielen/Testen" hab ich dann den Typ händisch etwas modifiziert und in einem Item abgespeichert. Wenn ich das jetzt nochmal lese, steht da eigentlich

Code: Alles auswählen

Liste der eingegangene Anrufe meiner Fritzbox anzeigt
Wenn ich aber in der Binding-Doku lese, passt das so wie ich es gebastelt hab. Was jetzt letztlich im Feld "Duration" steht weiss ich auch nicht.

Test-String:

Code: Alles auswählen

[{"localNumber":"6457389","remoteNumber":"1234567","date":"2022-11-14T17:18:00+01","type":1,"duration":1},{"localNumber":"6457388","remoteNumber":"0654321","date":"2022-11-13T16:53:00+01","type":2,"duration":6},{"localNumber":"6457389","remoteNumber":"01223456","date":"2022-11-13T16:53:00+01","type":10,"duration":1},{"localNumber":"6457389","remoteNumber":"01223456","date":"2022-11-09T14:53:00+01","type":3,"duration":112}]
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Benutzeravatar
udo1toni
Beiträge: 13856
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: JSON Liste in UI darstellen

Beitrag von udo1toni »

Ah. Ja, da muss man schon aufpassen, ich wollte keinen Musterdatensatz, sondern einen echten Datensatz, nur gerne mit verfälschten Daten, aber eben ansonsten so, wie er vom TR064 Binding geliefert wird, nicht abgehackt.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
scotty
Beiträge: 676
Registriert: 28. Apr 2020 04:44

Re: JSON Liste in UI darstellen

Beitrag von scotty »

Mein Beitrag von gestern, 15:23 Uhr beinhaltet einen Original-Datensatz und zwar den ersten (also letztes Gespräch) mit geänderten Daten aus Datei Event.Log. Der gerundete Wert für "Dauer" entspricht der Angabe aus der Fritzbox.
OH 3.4.5 im Docker auf Synology DS918+ mit USV, Reolink-RLC-511WA, Philips Hue, AVM Fritz!Box 6591C, Alexa, Logitech Harmony und diversen Shelly's

Benutzeravatar
udo1toni
Beiträge: 13856
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: JSON Liste in UI darstellen

Beitrag von udo1toni »

scotty hat geschrieben: 1. Dez 2022 01:19 Mein Beitrag von gestern, 15:23 Uhr beinhaltet einen Original-Datensatz und zwar den ersten (also letztes Gespräch) mit geänderten Daten aus Datei Event.Log. Der gerundete Wert für "Dauer" entspricht der Angabe aus der Fritzbox.
Nein, das ist nicht der Original Datensatz, den ich meine.
Alternativ gibt die FRITZ!Box da kein gültiges JSON aus, sondern Müll. Es müsste schon das vollständige JSON Objekt sein, sonst kann man damit nicht arbeiten.
Wie gesagt, gerne mit manipulierten Daten, aber der gesamte Rahmen müsste stimmen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten