Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. ioBroker Allgemein
  4. TibberLink Adapter

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.7k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.1k

TibberLink Adapter

Geplant Angeheftet Gesperrt Verschoben ioBroker Allgemein
630 Beiträge 85 Kommentatoren 197.0k Aufrufe 78 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • N Offline
    N Offline
    nkoebe
    schrieb am zuletzt editiert von
    #618

    Bei der Rechnung denke ich schon (ich werde erst diesen Monat umgestellt).
    Ich bin mir aber nicht sicher, ob sie das bei der API Abfrage über den Adapter auch schon berücksichtigen.
    Wenn es soweit ist, kann ich ja berichten.
    Es sei denn, jemand hier kann das schon bestätigen...

    1 Antwort Letzte Antwort
    0
    • M Offline
      M Offline
      Michi_Pi
      schrieb am zuletzt editiert von
      #619

      Ich sehe den normalen Preis, und bei der Monatsabrechnung wird dann die Netzentgeltreduzierung abgezogen.

      N H A 3 Antworten Letzte Antwort
      0
      • M Michi_Pi

        Ich sehe den normalen Preis, und bei der Monatsabrechnung wird dann die Netzentgeltreduzierung abgezogen.

        N Offline
        N Offline
        nkoebe
        schrieb am zuletzt editiert von
        #620

        @Michi_Pi

        Danke für die Info! Das hatte ich ehrlicher Weise auch so erwartet.

        Hier ist das JS Skript (ich hab Copilot benutzt, selber programmiert hab ich nix...):

        // ------------------------------
        // Konfiguration
        // ------------------------------
        
        // Netzengelt (wird von Tibber-Preis abgezogen)
        const NETZENTGELT = 11.5; // ct/kWh
        
        // §14a Tarifaufschläge je nach Uhrzeit
        const TARIF = {
           low: 1.19,       // 00–06 Uhr
           standard: 11.88, // 06–15 Uhr & 20–24 Uhr
           high: 17.75      // 15–20 Uhr
        };
        
        // Datenquelle Tibberlink Adapter
        const PRICE_BASE = "tibberlink.0.Homes.a51c83ea-7122-4cf7-9b33-8aa17f703c0a.PricesToday.";
        // Zielobjekt für VIS Chart
        const CHART_OID = "0_userdata.0.VIS.flexchartAngepassteStrompreis";
        
        // ------------------------------
        // Hilfsfunktionen
        // ------------------------------
        
        /**
        * Normalisiert Rohwerte in ct/kWh.
        * - Werte <5 werden als € interpretiert und in ct umgerechnet.
        * - Negative oder NaN werden verworfen.
        */
        function normalizeToCt(baseRaw) {
           if (isNaN(baseRaw) || baseRaw < 0) return NaN;
           return baseRaw < 5 ? baseRaw * 100 : baseRaw;
        }
        
        /**
        * Liefert Tarifaufschlag für eine Viertelstunde (Index 0–95).
        */
        function getTarifAdd(q) {
           const h = Math.floor(q / 4);
           if (h < 6) return TARIF.low;
           else if (h < 15) return TARIF.standard;
           else if (h < 20) return TARIF.high;
           else return TARIF.standard;
        }
        
        /**
        * Baut drei Linien für die Tarifzonen (Low/Standard/High).
        */
        function getTarifSeriesCt(xAxis) {
           const low = new Array(96).fill(null);
           const standard = new Array(96).fill(null);
           const high = new Array(96).fill(null);
        
           for (let q = 0; q < 96; q++) {
               const h = Math.floor(q / 4);
               if (h < 6) low[q] = TARIF.low;
               else if (h < 15) standard[q] = TARIF.standard;
               else if (h < 20) high[q] = TARIF.high;
               else standard[q] = TARIF.standard;
           }
        
           return [
               { name: "Tarif Low", type: "line", step: "end", symbol: "none", data: low,
                 lineStyle: { width: 1.5, color: "green" }, areaStyle: { color: "rgba(0,200,0,0.3)" } },
               { name: "Tarif Standard", type: "line", step: "end", symbol: "none", data: standard,
                 lineStyle: { width: 1.5, color: "orange" }, areaStyle: { color: "rgba(255,165,0,0.3)" } },
               { name: "Tarif High", type: "line", step: "end", symbol: "none", data: high,
                 lineStyle: { width: 1.5, color: "red" }, areaStyle: { color: "rgba(255,0,0,0.3)" } }
           ];
        }
        
        /**
        * Liefert aktuellen Viertelstundenindex (0–95).
        */
        function getCurrentQuarterIndex() {
           const now = new Date();
           return now.getHours() * 4 + Math.floor(now.getMinutes() / 15);
        }
        
        /**
        * Berechnet angepasste Preise nach §14a (Basispreis – Netzengelt + Tarifaufschlag).
        */
        function getAdjustedQuarterPricesCt() {
           const res = [];
           for (let q = 0; q < 96; q++) {
               const s = getState(`${PRICE_BASE}${q}.total`);
               const baseCt = normalizeToCt(s?.val !== undefined ? Number(s.val) : NaN);
               if (isNaN(baseCt)) { res.push(null); continue; }
               res.push(Number((baseCt - NETZENTGELT + getTarifAdd(q)).toFixed(2)));
           }
           return res;
        }
        
        /**
        * Baut X-Achse mit 96 Zeitlabels (00:00, 00:15, …).
        */
        function buildXAxis96() {
           const labels = [];
           for (let q = 0; q < 96; q++) {
               const h = Math.floor(q / 4);
               const m = (q % 4) * 15;
               labels.push(`${("0"+h).slice(-2)}:${("0"+m).slice(-2)}`);
           }
           return labels;
        }
        
        /**
        * Ermittelt die 4 günstigsten Stundenblöcke (Durchschnitt aus 4 Viertelstunden).
        */
        function getBest4AdjustedHourBlocks() {
           const adjusted = getAdjustedQuarterPricesCt();
           const hours = [];
        
           for (let h = 0; h < 24; h++) {
               const start = h * 4;
               const block = adjusted.slice(start, start + 4).filter(v => v !== null);
               if (block.length === 4) {
                   const avg = block.reduce((a, b) => a + b, 0) / block.length;
                   hours.push({ hour: h, avg });
               }
           }
        
           return hours.sort((a, b) => a.avg - b.avg).slice(0, 4);
        }
        // ------------------------------
        // Chart JSON (96 Werte, 2 Linien)
        // ------------------------------
        
        function buildChartJSON96() {
           // §14a angepasste Preise
           const adjusted = getAdjustedQuarterPricesCt();
        
           // Originalpreise (nur normalisiert)
           const original = [];
           for (let q = 0; q < 96; q++) {
               const s = getState(`${PRICE_BASE}${q}.total`);
               const baseCt = normalizeToCt(s?.val !== undefined ? Number(s.val) : NaN);
               original.push(isNaN(baseCt) ? null : Number(baseCt.toFixed(2)));
           }
        
           // X-Achse mit Zeitlabels
           const xAxis = buildXAxis96();
        
           // Wertebereich für Farbskala
           const numeric = adjusted.filter(v => v !== null && !isNaN(v));
           const minVal = numeric.length ? Math.min(...numeric) : 0;
           const maxVal = numeric.length ? Math.max(...numeric) : 1;
        
           // Chart-Definition
           const chart = {
               backgroundColor: "#666666",
               tooltip: { trigger: "axis", axisPointer: { type: "cross" } },
               grid: { left: "10%", right: "4%", top: "8%", bottom: "8%" },
        
               // Achsen
               xAxis: {
                   type: "category", boundaryGap: false, data: xAxis,
                   axisLabel: { color: "rgb(230,230,230)" },
                   axisLine: { lineStyle: { color: "rgb(230,230,230)" } },
                   axisTick: { lineStyle: { color: "rgb(230,230,230)" } }
               },
               yAxis: {
                   type: "value",
                   axisLabel: { formatter: "{value} ct", color: "rgb(230,230,230)" },
                   axisLine: { lineStyle: { color: "rgb(230,230,230)" } },
                   axisTick: { lineStyle: { color: "rgb(230,230,230)" } }
               },
        
               // Farbskala (wird nicht angezeigt, nur für Farbverläufe)
               visualMap: {
                   min: minVal,
                   max: maxVal,
                   inRange: { color: ["green", "yellow", "red"] },
                   show: false
               },
        
               // Datenserien
               series: [
                   {
                       name: "Angepasster Preis",
                       type: "line",
                       step: "end",
                       symbol: "none",
                       data: adjusted,
                       lineStyle: { width: 2 },
        
                       // vertikale Linie "Jetzt"
                       markLine: {
                           data: [{ name: "Jetzt", xAxis: xAxis[getCurrentQuarterIndex()] }],
                           lineStyle: { color: "rgb(230,230,230)", type: "dashed", width: 2 },
                           label: { formatter: "Jetzt", color: "rgb(230,230,230)" }
                       },
        
                       // Flächen für Tarifzonen + beste 4 Stundenblöcke
                       markArea: {
                           data: [
                               // feste Tarifzonen
                               [{ xAxis: xAxis[0], itemStyle: { color: "rgba(0,200,0,0.1)" }, name: "Low" }, { xAxis: xAxis[24] }],
                               [{ xAxis: xAxis[24], itemStyle: { color: "rgba(255,165,0,0.1)" }, name: "Standard" }, { xAxis: xAxis[60] }],
                               [{ xAxis: xAxis[60], itemStyle: { color: "rgba(255,0,0,0.1)" }, name: "High" }, { xAxis: xAxis[80] }],
                               [{ xAxis: xAxis[80], itemStyle: { color: "rgba(255,165,0,0.1)" }, name: "Standard" }, { xAxis: xAxis[95] }],
        
                               // dynamisch: beste 4 Stundenblöcke (hellblau mit Label)
                               ...getBest4AdjustedHourBlocks().map(b => [
                                   {
                                       xAxis: xAxis[b.hour * 4],
                                       itemStyle: { color: "rgba(0,150,255,0.3)" },
                                       label: {
                                           show: true,
                                           color: "rgb(230,230,230)",
                                           formatter: `${xAxis[b.hour * 4]} - ${xAxis[(b.hour + 1) * 4]}\n(Ø ${b.avg.toFixed(2)} ct)`
                                       }
                                   },
                                   { xAxis: xAxis[(b.hour + 1) * 4] }
                               ])
                           ]
                       }
                   },
        
                   // Vergleichslinie: Originalpreise
                   {
                       name: "Normalpreis",
                       type: "line",
                       step: "end",
                       symbol: "none",
                       data: original,
                       lineStyle: { type: "dashed", width: 1, color: "#999999" },
                       itemStyle: { color: "#999999" }
                   },
        
                   // Tariflinien (Low/Standard/High)
                   ...getTarifSeriesCt(xAxis)
               ]
           };
        
           return JSON.stringify(chart);
        }
        // ------------------------------
        // Trigger: alle 96 OIDs überwachen
        // ------------------------------
        
        // Liste aller 96 Viertelstunden-OIDs aus Tibberlink
        const quarterOids = Array.from({ length: 96 }, (_, i) => `${PRICE_BASE}${i}.total`);
        
        /**
        * Schreibt das Chart-JSON ins Zielobjekt.
        */
        function writeChart() {
           try {
               const json = buildChartJSON96();   // Chart-Definition erzeugen
               setState(CHART_OID, json, true);   // Ergebnis ins VIS-Objekt schreiben
           } catch (e) {
               console.error("Fehler beim Erstellen des Chart-JSON:", e);
           }
        }
        
        // Aktualisierung bei jeder Änderung eines Viertelstundenwertes
        on({ id: quarterOids, change: "ne" }, () => {
           writeChart();
        });
        
        // Initiales Schreiben beim Start des Scripts
        writeChart();
        
        

        1 Antwort Letzte Antwort
        0
        • M Michi_Pi

          Ich sehe den normalen Preis, und bei der Monatsabrechnung wird dann die Netzentgeltreduzierung abgezogen.

          H Offline
          H Offline
          HansJochen
          schrieb am zuletzt editiert von
          #621

          @Michi_Pi sagte in TibberLink Adapter:

          Ich sehe den normalen Preis, und bei der Monatsabrechnung wird dann die Netzentgeltreduzierung abgezogen.

          Schade, ich hätte eigentlich gehofft, dass Tibber das schlauer übermittelt. Das ist ja nicht nur ein Anzeige-Thema, sondern auch relevant für die Berechnung des Zeitfensters. Ich fände es cool, wenn der Tibberlink Adapter eine Korrekturmöglichkeit integriert. Die Netzgebühren sind ja sehr statisch, dann müssten die Betroffenen halt einmal im Jahr die Gebührenstaffel von Hand eintragen.

          Das nur als Anregung. Mein Netzbetreiber bietet keine für mich attraktiven 14a Zeitfenster, so dass ich Modul 3 gar nicht erst beauftragt habe.

          1 Antwort Letzte Antwort
          0
          • N Offline
            N Offline
            nkoebe
            schrieb am zuletzt editiert von
            #622

            Das wäre natürlich elegant, wenn es im Adapter für 14a eine Config gäbe.
            Man könnte die Tarife mit den Zeitfenstern angeben und das normale Entgelt und das würde dann die Preise entsprechend berechnen...

            1 Antwort Letzte Antwort
            0
            • M Michi_Pi

              Ich sehe den normalen Preis, und bei der Monatsabrechnung wird dann die Netzentgeltreduzierung abgezogen.

              A Online
              A Online
              ArnoD
              schrieb am zuletzt editiert von
              #623

              @Michi_Pi
              Das bedeutet, dass Tibber falsche Bruttopreise über die API übermittelt?
              Das erstaunt mich doch sehr, da die regionalen Unterschiede im Netzentgelt ja im Bruttopreis aktuell berücksichtigt werden.
              Ich könnte mir sogar vorstellen, dass es hier mit den Verbraucherzentralen Ärger geben könnte, die sehen das nicht so locker, wenn falsche Preise angegeben werden.
              Ich hoffe das Tibber das dann noch ändert.

              1 Antwort Letzte Antwort
              0
              • S Online
                S Online
                Schimi
                schrieb am zuletzt editiert von
                #624

                nach meinen Infos... wird bei Modul1 der betrag mit der Gesamtrechnung abgezogen (ist auch richtig, ist ja keine kWh Reduzierung)...
                Bei Modul 3 soll es direkt in der anzeige richtig angezeigt werden (und auch abgerechnet), zumindest hört man es von den wenigen die Modul 3 bereits haben (youtube)

                1 Antwort Letzte Antwort
                0
                • H Offline
                  H Offline
                  HansJochen
                  schrieb am zuletzt editiert von
                  #625

                  @Michi_Pi habe ich Dich falsch verstanden oder ist das bei Dir anders? Ich dachte, Du hast Modul 3 und bekommst die für Deine Region "normalen" Netzentgelte im Brutto Preis übermittelt und erst am Monatsende wird das dann über die Abrechnung korrigiert?

                  M 1 Antwort Letzte Antwort
                  0
                  • M Offline
                    M Offline
                    Michi_Pi
                    schrieb am zuletzt editiert von
                    #626

                    Hi, nein ich hab nur Modul 1. Modul 3 ist in meiner Region leider auch nicht attraktiv. Da der dieses Zeitfenster nur für die Sommermonate anwendet.

                    1 Antwort Letzte Antwort
                    0
                    • H HansJochen

                      @Michi_Pi habe ich Dich falsch verstanden oder ist das bei Dir anders? Ich dachte, Du hast Modul 3 und bekommst die für Deine Region "normalen" Netzentgelte im Brutto Preis übermittelt und erst am Monatsende wird das dann über die Abrechnung korrigiert?

                      M Offline
                      M Offline
                      Michi_Pi
                      schrieb am zuletzt editiert von
                      #627

                      @HansJochen sagte in TibberLink Adapter:

                      @Michi_Pi habe ich Dich falsch verstanden oder ist das bei Dir anders? Ich dachte, Du hast Modul 3 und bekommst die für Deine Region "normalen" Netzentgelte im Brutto Preis übermittelt und erst am Monatsende wird das dann über die Abrechnung korrigiert?

                      Ja genau, so ist es.

                      1 Antwort Letzte Antwort
                      0
                      • H Offline
                        H Offline
                        HansJochen
                        schrieb am zuletzt editiert von
                        #628

                        @Michi_Pi

                        Okay, aber Du hast ja Modul 1, nicht Modul 3. Dann sind die Netzentgelte für die Aussteuerung ja auch einigermaßen egal, weil sie zu jeder Zeit gleich sind und Du trotzdem zum günstigsten Zeitfenster gelenkt wirst. Bisschen überraschend, dass Tibber anscheinend bei Modul 3 die echten Brutto Preise übermittelt und bei Modul 1 nicht. Vielleicht ist das aber auch nur für Einzelne und nur für eine Übergangszeit anders, abhängig vom Netzbetreiber o.ä. Falls Tibber das bei Dir mal ändert, schreib es doch gerne hier.

                        Mit Modul 3 ist hier keiner, oder? Das ist ja noch einigermaßen neu.

                        1 Antwort Letzte Antwort
                        0
                        • R Offline
                          R Offline
                          ReblausGT
                          Developer
                          schrieb am zuletzt editiert von
                          #629

                          Ich warte auf meine Modul 3 Schaltung.... dann kann ich das auch testen. Nur leider zeiht sich die Bearbeitung beim Netzbetreiber extrem.

                          1 Antwort Letzte Antwort
                          0
                          • M Offline
                            M Offline
                            Michi_Pi
                            schrieb am zuletzt editiert von
                            #630

                            glaub Tibber bastelt da eh noch ständig rum. Am Anfang des Jahres bin ich noch auf Tibber zugegangen und hab ihnen meine Vergünstigungen mitgeteilt damit ich das überhaupt monatlich abgezogen bekommen hatte. Zudem ist es ja auch nicht ganz einfach, da ja auch jeder Netzbetreiber andere Tarife hat. Dieses Jahr hätte bei mir Modul 3 noch Sinn gemacht, nächstes Jahr nicht mehr. Zu dem Rollout hat mein Netzbetreiben auch nicht wirklich Ambitionen. Mit dem Gateway standen die schon bei mir, aber wegen schlechtem Empfang gingen Sie wieder und seither auch keine Rückmeldung. Auch nicht das mir eine externe Antenne oder dergleichen Angeboten wurde damit das funktionieren würde.

                            1 Antwort Letzte Antwort
                            0
                            Antworten
                            • In einem neuen Thema antworten
                            Anmelden zum Antworten
                            • Älteste zuerst
                            • Neuste zuerst
                            • Meiste Stimmen


                            Support us

                            ioBroker
                            Community Adapters
                            Donate
                            FAQ Cloud / IOT
                            HowTo: Node.js-Update
                            HowTo: Backup/Restore
                            Downloads
                            BLOG

                            436

                            Online

                            32.4k

                            Benutzer

                            81.5k

                            Themen

                            1.3m

                            Beiträge
                            Community
                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                            ioBroker Community 2014-2025
                            logo
                            • Anmelden

                            • Du hast noch kein Konto? Registrieren

                            • Anmelden oder registrieren, um zu suchen
                            • Erster Beitrag
                              Letzter Beitrag
                            0
                            • Home
                            • Aktuell
                            • Tags
                            • Ungelesen 0
                            • Kategorien
                            • Unreplied
                            • Beliebt
                            • GitHub
                            • Docu
                            • Hilfe