Ankündigung

Einklappen
Keine Ankündigung bisher.

HACS Graph-Cards

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #16
    Den ersten Punkt mit an/aus Status unterhalb von 'echten' Plots will ich auch noch umsetzen (ist noch auf der ToDo Liste, aber Konzept im Kopf ist fertig), und zum zweiten Punkt:

    Zitat von henfri Beitrag anzeigen
    Ich würde gerne die X-Achsen koppeln, wenn ich zoome. Geht das?
    Ja, hab ich mal mit rumexperimentiert. Plotly beherrscht mehr als nur eine x-Achse, die dann untereinander dargestellt werden - siehe zweiter Graph in der Animation hier. Zoomed gemeinsam - das funktionierte bei mir in den Experimenten mal besser und mal schlechter. Zur Umsetzung: goto erster Satz oben ....

    /tom

    p.s./edit: Hab natürlich nix dagegen, wenn jemand eine gebrauchsfertige Anweisung dafür liefert.

    Kommentar


      #17
      Da ich nach den windigen Tagen gerade meine Winddaten grafisch darstellen lassen wollte, meine Erfahrungen:
      simple Karten: Machen was sie sollen. Nett, aber recht unnötig.
      Apex Charts: Mächtig, aber man stößt schnell an Grenzen und unvollständige Implementierungen. Der data_generator ist langsam und eingeschränkt nutzbar zum Aufbereiten von Daten.
      Plotly: Toll. Bin begeistert. Kann in meinem Fall alles von Apex, nur mehr. Sehr toll ist, dass der Graph interaktiv ist und man im Graph navigieren kann.

      ABER: (und das habe ich leider versäumt)
      Bei der Anlage der KNX Entitäten muss darauf geachtet werden, dass diese in den HA Recorder aufgenommen werden. Nur dann hat man Zugriff auf die Statistik Funktionen, die genau das ermöglichen, was ich wollte. (max, min, avg ohne Umwege!)

      D.h. man muss die state_class: measurement und die device_class: temperature hinzufügen.
      Code:
          sensor:
            - name: "Wetter_Temperatur_Sueden"
              state_address: "0/3/15"
              type: temperature
              device_class: temperature
              state_class: measurement
      Das habe ich nun bei allen Sensoren nachgeholt, die ich mal grafisch darstellen möchte.

      Zur Erstellung: Schnell kommt man mit ChatGPT zu brauchbaren Ergebnissen. Dann aber kommt meist nur noch Mist. Falsche Dinge werden umgesetzt, falsch wird es umgesetzt, kurzum. Den ersten Graph kann man sich schnell erstellen lassen, danach muss man die Dokumentation anschauen oder vorhandene Beispiele und deren YAML Code anschauen: https://github.com/dbuezas/lovelace-...ssion-index.md

      Kommentar


        #18
        hallo,
        ich habe mich gerade etwas mehr mit der plotly-graph-card beschäftigt.
        Durch das project open3E kann ich meine Viessmann Vitocal recht gut auslesen und bekomme die für relevanten Daten in einem verwertbaren JSON-Format.
        Ich würde die Daten gern aufarbeiten...
        Die Energiewerte für den WW-Bereitung bekomme ich in dieser Form:

        Code:
          "CurrentMonth": {
            "10": 1.3,
            "11": 1.4,
            "12": 1.2,
            "13": 3.4,
            "14": 0,
            "15": 1.3,
            "16": 1.3,
            "17": 1.4,
            "18": 1.5,
            "19": 0,
            "20": 0,
            "21": 0,
            "22": 0,
            "23": 0,
            "24": 0,
            "25": 0,
            "26": 0,
            "27": 0,
            "28": 0,
            "29": 0,
            "30": 0,
            "31": 0,
            "01": 1.6,
            "02": 2,
            "03": 1.2,
            "04": 1.3,
            "05": 1.9,
            "06": 1.4,
            "07": 1.6,
            "08": 1.6,
            "09": 1.9
          },
          "LastMonth": {
            "10": 0,
            "11": 0,
            "12": 0,
            "13": 0,
            "14": 0,
            "15": 0,
            "16": 0,
            "17": 0,
            "18": 0,
            "19": 0,
            "20": 0,
            "21": 0,
            "22": 0,
            "23": 1.3,
            "24": 2.7,
            "25": 1.6,
            "26": 1.8,
            "27": 0,
            "28": 1.2,
            "29": 3.2,
            "30": 0,
            "31": 0,
            "01": 0,
            "02": 0,
            "03": 0,
            "04": 0,
            "05": 0,
            "06": 0,
            "07": 0,
            "08": 0,
            "09": 0
          }
        }​
        ​
        Ich ahbe also alle Werte für diesen und für den letzten Monat. Wie müsste ich diese jetzt aufarbeiten um in plotly ein bar-diagramm zu erzeugen?

        Kommentar


          #19
          In Post #6 weiter oben habe ich 3 Beispieldateien angehängt - diese zeigen, wie man 'Rohdaten' per $fn und Javascript innerhalb von plotly aufbereiten kann (sollte per copy/paste eigentlich auf jedem HA-System laufen - kannst ja mal mit rumspielen).

          Statt der dort fest zugewiesenen Werte in 'const unixtime_werte=[...]' müsstest Du natürlich Deine Entität referenzieren und den darin enthaltenen JSON-String entsprechend aufbereiten. Interessant wird es dabei unterhalb des Kommentars "// Erstellung einer Liste von Datums-/Zeitelementen für jeden Eintrag in unixtime_werte"; am Ende müssen halt zwei zueinanderpassende Listen (Zeitstempel, Werte) in vars.x und vars.y herauskommen.

          Hoffe, das hilft Dir in die richtige Richtung ...

          /tom

          Kommentar


            #20
            Nachtrag: Hatte grad mal Lust, ein bisschen abzuschalten und was anderes zu machen.
            Sooo viel Code ist es dann doch nicht - Hinweise beachten, wie man statt fester Werte eine Entität anflanscht ...

            image.png
            Code:
            type: custom:plotly-graph
            title: Viessmann Vitocal (2 Monate)
            refresh_interval: 900
            raw_plotly_config: true
            config:
              showLink: true
              plotlyServerURL: https://chart-studio.plotly.com
              displayModeBar: true
              toImageButtonOptions:
                format: svg
                filename: custom_image
                height: 500
                width: 700
                scale: 1
            layout:
              paper_bgcolor: transparent
              plot_bgcolor: transparent
              raw_plotly_config: true
              xaxis:
                type: date
                tickformat: "%d.%m."
                tickangle: -45
                hoverformat: "%d.%m.%Y %H:%M"
                titlefont:
                  color: white
                tickfont:
                  color: white
                linewidth: 1
                ticklabelposition: inside
                showlegend: true
              yaxis:
                titlefont:
                  color: white
                tickfont:
                  color: white
                fixedrange: false
                linecolor: grey
                linewidth: 1
                ticklabelposition: inside
                type: number
            entities:
              - name: AT
                entity: ""
                fillcolor: rgba(168, 216, 234, 0.1)
                fill: tozeroy
                type: bar
                fn: |
                  $fn ({ vars, state }) => {
            
                    // hier später statt der untenstehenden festen Definition aus der Entität lesen:
                    // const the_entity = states['sensor.deine_vitocal_json_entität'].state
                    // const the_JSON = JSON.parse(the_entity);
                    
                    const the_JSON = {
                      "CurrentMonth": {
                        "10": 1.3, "11": 1.4, "12": 1.2, "13": 3.4, "14": 0, "15": 1.3, "16": 1.3, "17": 1.4, "18": 1.5,
                        "19": 0, "20": 0, "21": 0, "22": 0, "23": 0, "24": 0, "25": 0, "26": 0, "27": 0, "28": 0,
                        "29": 0, "30": 0, "31": 0, "01": 1.6, "02": 2, "03": 1.2, "04": 1.3, "05": 1.9, "06": 1.4,
                        "07": 1.6, "08": 1.6, "09": 1.9
                      },
                      "LastMonth": {
                        "10": 0, "11": 0, "12": 0, "13": 0, "14": 0, "15": 0, "16": 0, "17": 0, "18": 0, "19": 0,
                        "20": 0, "21": 0, "22": 0, "23": 1.3, "24": 2.7, "25": 1.6, "26": 1.8, "27": 0, "28": 1.2,
                        "29": 3.2, "30": 0, "31": 0, "01": 0, "02": 0, "03": 0, "04": 0, "05": 0, "06": 0, "07": 0,
                        "08": 0, "09": 0
                      }
                    };
            
                    function extractXY(data, delta = 0) {
                        const x = [];
                        const y = [];
            
                        const now = new Date();
                        const thisMonth = now.getMonth() + 1;
                        const thisYear = now.getFullYear();
                        const lastMonthDate = new Date(thisYear, thisMonth - 2, 1);
                        const lastMonth = lastMonthDate.getMonth() + 1;
                        const lastYear = lastMonthDate.getFullYear();
            
                        function collectEntries(source, year, month) {
                            return Object.entries(source).map(([day, value]) => {
                                const dayNum = parseInt(day, 10);
                                const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(dayNum).padStart(2, '0')}T23:59:00`;
                                const timestampUTC = new Date(dateStr).getTime();
                                return [timestampUTC, parseFloat(value)];
                            });
                        }
            
                        const entries = [
                            ...collectEntries(data.LastMonth, lastYear, lastMonth),
                            ...collectEntries(data.CurrentMonth, thisYear, thisMonth)
                        ];
            
                        entries.sort((a, b) => a[0] - b[0]);
            
                        // Jahreswechsel/Januar noch nicht berücksichtigt!
                        for (const entry of entries) {
                            const date = new Date(entry[0]);
                            const yyyy = date.getFullYear();
                            const mm = String(date.getMonth() + 1).padStart(2, '0');
                            const dd = String(date.getDate()).padStart(2, '0');
                            const formatted = `${yyyy}-${mm}-${dd} 23:59:59`;
                            x.push(formatted);
                            y.push(parseFloat(entry[1].toFixed(2)));
                        }
            
                        return { x, y };
                    }
            
                    const result = extractXY(the_JSON);
            
                    vars.x = result.x;
                    vars.y = result.y;
                  }
                x: $fn ({ vars }) => vars.x
                "y": $fn ({ vars }) => vars.y

            Benutzung: Obigen Code kopieren und auf dem Dashboard als Karte hinzufügen (copy/paste in's YAML der Karte).
            Viel Spaß beim Spielen mit den Plotly-Parametern!

            /tom
            Zuletzt geändert von Tom Bombadil; 18.07.2025, 15:50.

            Kommentar


              #21
              wow... krass.
              Vielen Dank. hab ich eben erst gesehen...
              Wir sind erst vor 3 Wochen eingezogen. Komm also nur auf der Arbeit zum "spielen".

              Ich werde es heute mal testen...

              Kommentar


                #22
                Viel Spaß - ich sehe eigentlich nur ein Hauptproblem damit: Der Wert, den Du standarmäßig in einer Entity (zB Sensor) speichern kannst, ist auf 255 Zeichen begrenzt. Das von Dir verlinkte JSON hat fast 800 Zeichen. Ich kenne zwar die Art und Weise nicht, wie Du an die Daten der Vitocal kommst, aber vermutlich wirst Du auf genau dieses Problem stoßen.

                Lösung:
                Sensor-Attribute haben diese Beschränkung nicht. Du müsstest also beim Auslesen der Daten den Wert nicht im eigentlichen Zielsensor setzen, sondern diesem dafür ein entsprechendes Attribut verpassen. Wie das geht, siehst Du z.B. hier - der sensor 'trovis_hk123_heizkurven' bekommt da per Template jede Menge neue Attribute (x-werte, hk1_tagkurve, hk1_nachtkurve ...), die mit Werten befüllt werden. Dann im Script nicht auf .state zugreifen, sondern auf Dein Attribut - fertig. Viel Erfolg!

                /tom

                Kommentar


                  #23
                  die Werte kommen bei mir aus MQTT... bisher kann ich die werte nur im MQTT-Explorer sehen. Wie ich einen einzelnen wert in einen Sensor bekomme verstehe ich.
                  leider erschlägt mich das verlinkte Github beispiel.

                  Alao habe ich versucht mir das auf home-assistant.io zu erlesen. aber so richtig schlau werde ich daraus noch nicht...

                  mein Sensor in MQTT sieht so aus..

                  PHP-Code:


                  name"EnergyConsumptionDomesticHotWaterMonthMatrix"

                          
                  state_topic"open3e/0x680_680_1311_EnergyConsumptionDomesticHotWaterMonthMatrix"

                          
                  json_attributes_topic"open3e/0x680_680_1311_EnergyConsumptionDomesticHotWaterMonthMatrix"        

                          
                  unique_idvitocal_energy_dhw_monthly

                          device
                  :

                            
                  identifiers: ["vitocal_200s"]

                            
                  name"Vitocal 200S"

                            
                  manufacturer"Viessmann"

                            
                  model"Vitocal 200S" 
                  alledings klappt das so einfach nicht, wie zu erwarten war...​

                  Kommentar


                    #24
                    Vorweg: Bei MQTT bin ich leider raus - nutze ich nicht. Kannst Du mal einen Screenshot aus den Entwicklertools posten, wie der Sensor aussieht, in dem das JSON abgelegt ist (mit angezeigten Attributen)?

                    Wie schon geschrieben - in das Attribute 'state' (=der Inhalt) eines Sensors passen nur 255 Zeichen rein, das wird das Problem sein. Ist durch HA so fest vorgegeben, kannste nicht ohne weiteres ändern. Egal was die Datenquelle ist - wenn mehr kommt als reinpasst, dann knallt es (Dein JSON hat über 800 Zeichen - die Fehlermeldung solltest Du vermutlich auch im Log sehen).

                    Du musst Dir also ein eigenes Attribut definieren, das diese Limitierung nicht hat. Und das geht über Template Sensoren:

                    Code:
                    sensor:
                    
                      - platform: template
                    
                        sensors:
                    
                          dein_neuer_sensor:
                            unique_id: dein_neuer_sensor
                            friendly_name: "Dein neuer Sensor"
                            value_template: ""
                            attribute_templates:
                              dein_JSON_attribut: >-
                                {% set quelldaten = wie_und_woher_auch_immer %}
                                {{ quelldaten }}
                    Sobald der Sensor die Daten im Zusatzattribut hat, kannst Du darauf im JavaScript wie folgt zugreifen:

                    Code:
                    const the_JSON = states['sensor.dein_neuer_sensor'].attributes.dein_JSON_attribut;
                    Sollte MQTT die Daten natürlivh bereits in einem Zusatzattribut ablegen statt im 'state' des Zielsensors, dann kannst Du Dir das ganze Gegrabbel natürlich sparen und gleich auf dieses Attribut zugreifen (daher die Bitte, mal einen Screenshot zu schicken, wo denn das JSON überhaupt drin steht - irgendwoher musst Du es ja haben).

                    /tom

                    Kommentar


                      #25
                      das json habe ich aus dem MQTT-explorer.
                      dort kann ich es mir anzeigen lassen. Normalerweose nehme ich ja nur ein einzelnes Element aus dem json und das ist recht einfach.

                      ich sende:
                      PHP-Code:
                      {"mode""read-json""data":[1311]} 
                      und bekomme die Antwort:
                      PHP-Code:
                      0x680_680_1311_EnergyConsumptionDomesticHotWaterMonthMatrix = {"CurrentMonth": {"01"1.6"02"2.0"03"1.2"04"1.3"05"1.9"06"1.4"07"1.6"08"1.6"09"1.9"10"1.3"11"1.4"12"1.2"13"3.4"14"0.0"15"1.3"16"1.3"17"1.4"18"1.5"19"1.2"20"0.0"21"0.0"22"0.0"23"0.0"24"0.0"25"0.0"26"0.0"27"0.0"28"0.0"29"0.0"30"0.0"31"0.0}, "LastMonth": {"01"0.0"02"0.0"03"… 
                      über MQTT kann ich dann die "Antwort" in einen Sensor packen...

                      Kommentar


                        #26
                        Wie schon geschrieben - die Antwort ist zu lang für einen 'normalen' HA Sensor.

                        Du hast ja im Grunde 2 Aufgabenstellungen:
                        • JSON per MQTT abgreifen und in HA in einem Attribut abspeichern,
                        • JSON aus dem Attribut heraus visualisieren.
                        Den zweiten Teil sehe ich als so gut wie erledigt an - Beispielcode hast Du, der Rest ist Herumspielen mit Plotly-Einstellungen.
                        Zum ersten Teil kann Dir vielleicht jemand anders helfen, MQTT habe ich bisher nicht gebraucht / benutzt, daher bin ich da keine Hilfe.

                        /tom

                        p.s. Vielleicht in einem separaten Thread weitermachen, sonst gibt's noch ne Rüge von der Rennleitung, weil wir den hier zumüllen.

                        Kommentar


                          #27
                          Hallo, ich bin zufällig auf deine Card Übersicht gestoßen, ich suche eine einfache Card, ähnlich wie History-Graph, die aber über 3 Spalten, heist über die ganze Seitenbreite anzeigt, welche kann das und wie?

                          Gruß Harry

                          Kommentar


                            #28
                            Das ist eine Sache vom Layout und nicht von der Karte. Bspw. mit dem Layout Abschnitte kannst du angeben, wieviele Spalten die Karte belegen soll. Es gibt verschiedene Layouts für verschiedene Anwendungen. Hier kommt es dann auf das Gesamtlayout deines Spezialfalls an. Für die grobe erste Gestaltung kann dir eine KI sehr schnell einigermaßen brauchbare Resultate liefern.

                            Kommentar

                            Lädt...
                            X