FHEM Forum

FHEM - Energiemanagement und Energieerzeugung => Verbrauchsmessung => Thema gestartet von: ch.eick am 30 Juli 2025, 15:26:34

Titel: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 30 Juli 2025, 15:26:34
Hallo zusammen,
das Thema kommt bereits in anderen Threads vor, ist jedoch nie weiter voran gegangen.
Ich habe mir erlaubt es nun hier nochmals zu öffnen.

Die nächste Stufe in diesem generischen Device wäre dann die Preisberchnung für die jeweiligen Wiederverkäufer, also aWATTar und Tibber.
Somit könnte man in einem Device generisch auf epexspot für die PV-Anlagen Betreiber reagieren und zusätzlich die Preise für die Wiederverkäufer abbilden.
Äquivalent zu meinen beiden Beispielen von EVU_aWATTar_connect und EVU_Tibber_connect würde man dann noch die max/min Preise und Trigger Fenster mit abbilden können.

Andere Threads:
Tibber & Tibber Pulse (https://forum.fhem.de/index.php?topic=130407.0)
aWATTar in Deutschland verfügbar (https://forum.fhem.de/index.php?topic=98991.0)


Um bei der Strompreis Frage direkt die Börsenpreise zu bekommen, ohne sich an Tibber oder aWATTar zu hängen möchte ich mal diesen Link ins Rennen werfen.
epexspot Part of EEX Group (https://www.epexspot.com/en/market-results?market_area=DE-LU&auction=MRC&trading_date=2025-07-30&delivery_date=2025-07-31&underlying_year=&modality=Auction&sub_modality=DayAhead&technology=&data_mode=table&period=&production_period=)
Das sieht für mich nach der Quelle der Börsenpreise aus.
Mit etwas HTTPMOD und regex bekommt man dort die Basis Preise für den aktuellen und den nächsten Tag.

Aufgerufen mit dem aktuellen Datum und nochmals mit dem Datum des Folgetages

delivery_date=2025-07-30
https://www.epexspot.com/en/market-results?market_area=DE-LU&auction=MRC&trading_date=2025-07-29&delivery_date=2025-07-30&underlying_year=&modality=Auction&sub_modality=DayAhead&technology=&data_mode=table&period=&production_period=


^.*<td>(\d+\.\d\d)<\/td>\n.*<\/tr>Ein Ausschnitt der Seite
<div class="custom-tables 60min">
    <div class="fixed-column js-table-times">
        <span class="fixed-head-column">Hours</span>
        <ul>
                                           
                                                            <li class="child  no-children"><a href="#">00 - 01</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">01 - 02</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">02 - 03</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">03 - 04</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">04 - 05</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">05 - 06</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">06 - 07</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">07 - 08</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">08 - 09</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">09 - 10</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">10 - 11</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">11 - 12</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">12 - 13</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">13 - 14</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">14 - 15</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">15 - 16</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">16 - 17</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">17 - 18</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">18 - 19</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">19 - 20</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">20 - 21</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">21 - 22</a></li>
                                                                               
                                                            <li class="child  no-children"><a href="#">22 - 23</a></li>
                                                                               
                                                            <li class="child impair no-children"><a href="#">23 - 24</a></li>
                                                        </ul>
    </div>
    <div class="js-table-values">
                    <table data-head="31.07.25" class="table-01 table-length-1">
                <thead>
               
                <tr class="white">
                    <th style="height:30px;" colspan="8"></th>
                </tr>

                                                                            <tr>
                                                            <th><div class="msk">Index</span></div></th>
                                                            <th><div class="msk">Price <br /><span>(€/MWh)</span></div></th>
                                                    </tr>
                                                                <tr class="flex-row white">
                            <th>Baseload</th>
                            <th>
                                <div class="flex day-1">
                                    <span>85.52</span>
                                </div>
                            </th>
                        </tr>
                                            <tr class="flex-row ">
                            <th>Peakload</th>
                            <th>
                                <div class="flex day-2">
                                    <span>74.36</span>
                                </div>
                            </th>
                        </tr>
                   
                    <tr class="white">
                        <th style="height:30px;" colspan="8"></th>
                    </tr>
                               
                <tr>
                                            <th>Buy Volume<br /><span>(MWh)</span></th>
                                            <th>Sell Volume<br /><span>(MWh)</span></th>
                                            <th>Volume<br /><span>(MWh)</span></th>
                                            <th>Price<br /><span>(€/MWh)</span></th>
                                    </tr>
                </thead>
                <tbody>
                                    <tr class="child ">
                                                                                    <td>23,099.6</td>
                                                            <td>18,950.4</td>
                                                            <td>23,099.6</td>
                                                            <td>88.93</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>24,126.0</td>
                                                            <td>19,595.7</td>
                                                            <td>24,126.0</td>
                                                            <td>82.11</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>23,931.6</td>
                                                            <td>20,025.3</td>
                                                            <td>23,931.6</td>
                                                            <td>79.00</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>23,874.7</td>
                                                            <td>19,953.6</td>
                                                            <td>23,874.7</td>
                                                            <td>77.27</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>24,133.1</td>
                                                            <td>19,459.7</td>
                                                            <td>24,133.1</td>
                                                            <td>78.51</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>24,589.7</td>
                                                            <td>19,024.1</td>
                                                            <td>24,589.7</td>
                                                            <td>85.43</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>25,273.5</td>
                                                            <td>18,546.6</td>
                                                            <td>25,273.5</td>
                                                            <td>98.14</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>26,838.6</td>
                                                            <td>20,687.2</td>
                                                            <td>26,838.6</td>
                                                            <td>100.46</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>29,825.2</td>
                                                            <td>22,822.4</td>
                                                            <td>29,825.2</td>
                                                            <td>94.09</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>31,294.3</td>
                                                            <td>25,892.7</td>
                                                            <td>31,294.3</td>
                                                            <td>88.91</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>32,706.4</td>
                                                            <td>28,762.1</td>
                                                            <td>32,706.4</td>
                                                            <td>74.17</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>35,475.1</td>
                                                            <td>31,458.2</td>
                                                            <td>35,475.1</td>
                                                            <td>70.04</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>35,768.2</td>
                                                            <td>33,463.3</td>
                                                            <td>35,768.2</td>
                                                            <td>61.15</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>35,079.4</td>
                                                            <td>34,255.8</td>
                                                            <td>35,079.4</td>
                                                            <td>48.05</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>34,328.9</td>
                                                            <td>34,332.6</td>
                                                            <td>34,332.6</td>
                                                            <td>35.06</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>34,064.1</td>
                                                            <td>33,364.6</td>
                                                            <td>34,064.1</td>
                                                            <td>55.07</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>33,072.7</td>
                                                            <td>30,866.0</td>
                                                            <td>33,072.7</td>
                                                            <td>72.43</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>31,141.2</td>
                                                            <td>27,142.0</td>
                                                            <td>31,141.2</td>
                                                            <td>84.56</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>30,058.3</td>
                                                            <td>24,311.1</td>
                                                            <td>30,058.3</td>
                                                            <td>96.90</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>28,776.4</td>
                                                            <td>21,491.7</td>
                                                            <td>28,776.4</td>
                                                            <td>111.92</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>27,862.8</td>
                                                            <td>20,213.6</td>
                                                            <td>27,862.8</td>
                                                            <td>128.27</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>27,061.7</td>
                                                            <td>19,947.4</td>
                                                            <td>27,061.7</td>
                                                            <td>125.11</td>
                                                                        </tr>
                                    <tr class="child ">
                                                                                    <td>24,824.9</td>
                                                            <td>19,010.5</td>
                                                            <td>24,824.9</td>
                                                            <td>114.16</td>
                                                                        </tr>
                                    <tr class="child impair">
                                                                                    <td>23,882.1</td>
                                                            <td>18,008.9</td>
                                                            <td>23,882.1</td>
                                                            <td>102.79</td>
                                                                        </tr>
                                </tbody>
            </table>
            </div>
</div>
       
            <div class="footnote-text-block">
        We would like to inform you that we expect a display issue on our website, which may impact the Market Results display for all instruments on the Long Clock Change day. Therefore, we highly recommend referring to the Market Results as published on the Market Data sftp server.
    </div>

Und man bekommt 24 readings mit dem Preis in €/MWh zurück.

Mit der Abfrage für Intraday bekommt man ebenso die 15 Minuten Preise für den aktuellen Tag, jedoch nicht für den nächsten.
https://www.epexspot.com/en/market-results?market_area=DE-LU&auction=IDA1&trading_date=2025-07-30&delivery_date=2025-07-30&underlying_year=&modality=Auction&sub_modality=Intraday&technology=&data_mode=table&period=&production_period=

VG  Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: Wolle02 am 31 Juli 2025, 12:20:43
Ich habe den Code von hier genommen: https://forum.fhem.de/index.php?msg=1336809 (https://forum.fhem.de/index.php?msg=1336809)

Ich bekomme dann Readings mit den Preisen für jede Stunde.

energy.todayHours.12.hour 12 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.0.priceExcludingVat 0.089 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.0.priceIncludingVat 0.1058 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.0.type taxes 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.1.priceExcludingVat 0.0612 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.1.priceIncludingVat 0.0728 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.1.type power 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.2.priceExcludingVat 0.11 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.2.priceIncludingVat 0.1309 2025-07-31 07:00:10
energy.todayHours.12.priceComponents.2.type grid 2025-07-31 07:00:10
energy.todayHours.12.priceExcludingVat 0.2601 2025-07-31 07:00:10
energy.todayHours.12.priceIncludingVat 0.3095 2025-07-31 07:00:10

Preiskomponente 0 sind wohl die Steuern.
Preiskomponente 2 sind wohl die Netzentgelte
Preiskomponente 1 sind scheinbar die reinen Strompreise an der EEX in €/kWh inklusive und exklusive der Mehrwertsteuer.

Ich nehm dann für die Weiterverarbeitung der Preis "including VAT".
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 31 Juli 2025, 17:19:46
Zitat von: Wolle02 am 31 Juli 2025, 12:20:43Ich habe den Code von hier genommen: https://forum.fhem.de/index.php?msg=1336809 (https://forum.fhem.de/index.php?msg=1336809)
Das wäre die Afrage von Tibber und nicht die Quelle für die epexspot Preise.
Hier würde ich gerne die Quelle der Daten abfragen und die Preise von Tibber und aWATTar dann als zusatz mit den Endpreisen berechnen wollen.
Also am Besten nur ein Device für den Börsenpreise und die Wiedeverkäufer dann zum Auswählen.
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: Wolle02 am 31 Juli 2025, 18:15:31
Zitat von: ch.eick am 31 Juli 2025, 17:19:46Das wäre die Afrage von Tibber und nicht die Quelle für die epexspot Preise.

Bist du sicher?
Wenn ich deinen Link von oben nehme:
https://www.epexspot.com/en/market-results?market_area=DE-LU&auction=MRC&trading_date=2025-07-30&delivery_date=2025-07-31&underlying_year=&modality=Auction&sub_modality=DayAhead&technology=&data_mode=table&period=&production_period=
dann wird mir für die Stunde 12 (also 12-13 Uhr) ein Preis von 61,15 €/MWh angezeigt; also 0,06115 €/kWh.
Das entspricht nach Rundung exakt meinem Reading für die Stunde 12.
energy.todayHours.12.priceComponents.1.priceExcludingVat 0.0612 2025-07-31 07:00:10

Was verstehe ich grade nicht?
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 01 August 2025, 11:40:18
Zitat von: Wolle02 am 31 Juli 2025, 18:15:31
Zitat von: ch.eick am 31 Juli 2025, 17:19:46Das wäre die Afrage von Tibber und nicht die Quelle für die epexspot Preise.
Was verstehe ich grade nicht?
In Deiner Abfrage gehst Du auf Tibber (https://tibber.com/de/api/lookup/price-overview?postalCode=12345), die sich letztendlich die Preise auch von epexspot holen. Leider hat jeder Wiederverkäufer wie Tibber oder aWATTar so seine Eigenheiten und die volle Leistung bekommt man erst als Kunde. Das ist der Grund, warum ich gerne die Preise direkt von der Quelle beziehen und die Wiederverkäufer als zusätzliche Berechnung ins Device aufnehme möchte. EVUs hat man auch schon kommen und gehen sehen.
Für die reinen PV-Anlagen Betreiber ist der epexspot Preis auch ohne EVU mit Stunden Tarif relevant.
Momentan frage ich auch mit meinem EVU_Tibber_connect (https://svn.fhem.de/fhem/trunk/fhem/contrib/ch.eick/Stromb%c3%b6rse/EVU_Tibber/) ab, jedoch bin ich kein Kunde und das rechnet sich auch seit Jahren nicht für mich.

VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: alkazaa am 15 Oktober 2025, 15:28:53
Hier mal als aktuelles Beispiel die viertelstündlichen EPEX Preise für day und dayahead: https://forum.fhem.de/index.php?msg=1349563
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: alkazaa am 19 Oktober 2025, 12:31:04
Moin!
Ich habe jetzt mein HTTPMOD device zum Auslesen der EPEX day und dayahead Preise auf der von ch.eick angelegten wiki Seite https://wiki.fhem.de/wiki/Stromb%C3%B6rse#3._EPEX_Spot veröffentlicht.
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: Wolle02 am 19 Oktober 2025, 13:29:54
Hier noch ein etwas kürzeres JsonMod, das die gleichen Ergebnisse liefert:

defmod EEX JsonMod https://api.energy-charts.info/price?bzn=DE-LU
attr EEX event-on-change-reading .*
attr EEX interval 0 * * * *
attr EEX readingList complete();;
attr EEX timestamp-on-change-reading .*
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 19 Dezember 2025, 14:01:57
Hallo zusammen,
ich habe nun eine Arbeitsversion geschaffen, die das Thema Strombörse zusammen fassen soll.

Ziel:
- Eine Stelle um Anbieter mit Börsenpreisen zusammen zu fassen
- Basis soll die direkte Abfrage der EPEX_Spot Preise sein, also ohne einem Anbieter dazwischen, der auch nur die Börse in Leipzig abfragt
- Im FHEMWEB sollte es eine ansprechende Aufbereitung geben (was gerne noch diskutiert werden kann)
- Es soll auch für interessierte, z.B. ohne Tibber Vertrag möglich sein. Das bedeutet, man kann die Tibber Preise berechnen lassen, die man
  ansonsten ja nur bekommt, wenn man bereits ein Kunde ist.

Aktueller Stand:
- Es gibt zwei Devices
  1. Stromboerse_connect, was ein HTTPMOD ist
  2. Stromboerse, was ein DOIF im Perl Modus mit uitable und uistate ist

- Einstellbar ist
  1. EPEX_Spot  - Leipziger Börse
  2. Tibber      - Leipziger Börse und berechnet darüber die Kosten
  3. Tibber_Live - Euer Account bei Tibber
  4. aWATTar    - Leipziger Börse und berechnet darüber die Kosten

- Es gibt für fc0 und fc1 ein rudimentäres SVG für den schnellen Überblick.
- Brauchbare Werte werden einheitlich, zusätzlich berechnet (hier würde ich auch gerne noch Ideen entgegennehmen)
- Es gibt min/max Zeiten
- In der Basis läuft es auch ohne MySQL Datenbank, wenn man die entsprechenden Stellen raus löscht
- Mit einer Oracle MySQL Datenbank (die meisten kennen mich ja schon) hat man erweiterte Möglichkeiten

- Für die Berechnung muss man die eigenen lokalen Kosten des Anbieters und des Netzbetreibers eintragen

  conf_EVU_Tibber_Grundgebuehr_EUR_Jahr 57.84
  conf_EVU_Tibber_Korrektur 0.755
  conf_EVU_Tibber_Zuschlag_ct_kWh 2.15

  conf_EVU_aWATTar_Grundgebuehr_EUR_Jahr 46.20
  conf_EVU_aWATTar_Zuschlag_ct_kWh 0

  conf_Netz_Jahresverbrauch_kWh 5099

  conf_VAT  1.19

  conf_VNB  Mainzer Netze GmbH (64560)

  conf_VNB_Arbeitspreis_ct_kWh 7.54
  conf_VNB_KWKG_ct_kWh 0.446
  conf_VNB_Konzession_ct_kWh 1.32
  conf_VNB_MSB_iMSys_EUR_Jahr 120
  conf_VNB_MSB_mME_EUR_Jahr 16.81
  conf_VNB_Messstelle mME
  conf_VNB_Netzentgelt_ct_kWh 6.72
  conf_VNB_Paragraph_19_Umlage_ct_kWh 1.559
  conf_VNB_Stromsteuer_ct_kWh 2.05

  Die einzelnen Preise habe ich von der letzten Preiserhöhung meines EVUs genommen und mit ChatGBT nochmal verifiziert.
  Das müsstet Ihr dann auch für Eure Gegend machen.
  Wichtig ist auch Euer Jahresverbrauch, da die jährlichen Fixkosten auf ct/kWh verteilt werden.

  Erklärung zu conf_EVU_Tibber_Korrektur
    Da ich einen fremden Zugang zum Testen auslese passen natürlich die lokalen Preise des Netzbetreibers nicht. Mein Netzbetreiber hat
    ziemlich hohe Kosten, was generell zu hohen Preisen in meiner Gegend führt. Um einen direkten Vergleich zu haben ist nun ein
    conf_EVU_Tibber_Korrektur eingeflossen, worüber ich einen direkten Vergleich machen kann.

ToDos:
- Für Tibber_Live müssen noch die Kosten und Verbräuche aus dem EVU_Tibber_connect übernommen werden
- Die Statistiken aus der Datenbank kommen auch noch
- Tibber_Live mit dem Pulse Lesekopf kommt noch
- In der unteren uitable kommen dann noch die Statistiken rein

Achtung, für die, die das bisherige EVU_Tibber_connect verwendet haben. Bitte beachtet, dass im neuen Device die Preise jetzt in ct und nicht mehr in € angezeigt werden, falls Ihr bereits eigene Auswertungen oder Grafana Darstellungen gemacht habt.

Screenshot 2025-12-19 154505.png

VG  Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 23 Dezember 2025, 13:55:54
Moin,
ich habe nochmal in den userReadings einige Änderungen vorgenommen.

- Berechnungen für avg, min, max und Trigger Preise beginnen jetzt jeweils mit der
  Stunde der Abfragung da die Preise davor ja nicht mehr relevant sind.

- Durch den Wechsel auf den 15 Minuten Takt kann ein trigger Fenster auch mal ziemlich
  kurz werden. Mit dem reading fc[0|1]_trigger_dauer wird nun auch die Dauer berechnet.

Als nächstes starte ich jetzt mit der Übername vom Tibber_Live.

VG    Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 09 Januar 2026, 17:54:12
Moin,
im contrib wurde das Stromboerse und Stromboerse_connect Device aktualisiert.

Da ist nun einiges für Tibber_Live dazu gekommen und es sollte auch bereits funktionieren.
Das alte EVU_Tibber müsste für Tests natürlich deaktiviert werden.

- Im Device Stromboerse_connect in den Attibuten die eigenen Netto EVU und Netzbetreiber Kosten eintragen
- Den eigenen Jahres Stromverbrauch eintragen
- Bei Tibber_Live wird noch auf den alten Key Store Eintrag zugegriffen
- Die set Menünamen im Stromboerse_connect sind leider noch nicht so plausiebel benannt, da denke ich gerade noch etwas drüber nach

- Im Device Stromboerse wählt man dann unter Börse aus, was man haben möchte
- Unter Tibber_Live ist dann ein connect/disconnect möglich, was natürlich nur Kunden machen können

Die Genauigkeit der Berechnung für Tibber und aWATTar hängt sehr stark davon ab, ob Ihr Eure Einzelpreise richtig eingetragen habt!

Bitte betrachtes das Device als einen Preview und gebt mir Euren Eindruck zurück.

VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 21 Januar 2026, 20:16:51
Hallo zusammen,
im contrib liegt eine neue Version vom Stromboerse_connect, und vom Stromboerse Device.

Durch den 15 Minuten Takt der Strombörse und bei Tibber gibt es immer wieder 15 Minuten Fenster als Trigger, was für die mir bekannten Starkverbraucher ein sehr kurzer Trigger ist. Aus diesem Grund beinhaltet diese Version ein Überspringen von 15 Minuten Fenstern, damit etwas Ruhe in den Trigger kommt.

Weiterhin habe ich eine Start/Stop Zeit für den Speicher eingebaut, bei dem die Preisbestimmung 30% unter dem Maximalpreis liegt. Damit sollten 20% Speicherverluste und zusätzlich 10% Marge ausgeglichen werden. Der normale Trigger Preis kann auch weniger wie 20% abstand zum Maximal Preis liegen, wodurch ein Laden des Speichers sinnlos wird, da die Speiche Verluste zu hoch liegen.
Den Prozentsatz lege ich später noch in ein Attribut.

Die reading Namen haben sich ebenfalls dadurch etwas geändert.

Als zukünftige Erweiterung für die Preisberechnung kann ich mir noch den §14a mit Modul 1 und Modul 3 vorstellen, da man da das Netzentgeld noch reduzieren kann.

VG  Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 25 Januar 2026, 12:11:33
Moin zusammen,
es gibt schon wieder ein Update, diesmal mit vielen Code Bereinigungen und wieder Neuerungen, also Vorsicht, es ist immer noch eine Arbeitsversion.
VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 26 Februar 2026, 17:29:56
Tachchen,
im contrib ist ein neues Update für Stomboerse_connect, jetzt läuft es schon schön rund.

Falls jemand das nutzt und im Grafana schöne Stufen haben möchte, dann könnte ich auf Nachfrage noch für Oracle MySQL > Version 8 passende SQLs liefern.
Daran hatte ich die letzten Wochen noch echt zu knapsen ;-)

VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 02 März 2026, 10:52:04
Hallo nochmal,
hier wäre mal mein aktuelles Leistungsdiagramm mit den Strombörse Triggern, bei dem ich ziemlich mit der Darstellung vom Tagesverlauf gekämpft habe.
Die Strombörse habe ich durch einen Offset nach oben ins Diagramm geschoben. Man sieht den Preisverlauf im 15 Minuten Takt und die einzelnen Trigger als Stufen.
Ist die Stufe oben, so ist der Trigger aktiv.
Für die Net und Bat Freigabe sind etwas unterschiedliche Berechnungen gewählt, was dann zu abweichenden Zeiten führt.
Trigger Zeiten von 15 Minuten werden unterdrückt, da das ansonsten zu zappelig wäre und zu einem ständigen Ein/Ausschalten der Starkverbraucher führen würde.
Im Diagramm wird immer nur das nächste Ereignis der Trigger im Tagesverlauf angezeigt, dass sich jedoch aufgrund der sich veränderten Daten auch immer wieder etwas verschieben kann. Aus diesem Grund habe ich auch die Berechnung auf ein mal pro Stunde reduziert.
Screenshot 2026-03-02 104134.png

VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 02 März 2026, 11:07:52
Nächste Schritte wären jetzt die Kostenberechnung, die bei den Tibber Kunden über deren Portal kommen, jedoch nicht bei den eventuell interessierten, die noch keine Kunden sind.

Für die early birds hätte ich hier mal ein MySQL, das die Kosten innerhalb der Datenbank berechnet und dort auch direkt einträgt, es erfolgt somit keine Ausgabe als Tabelle, was jedoch auch möglich wäre. Momentan habe ich jedoch Probleme mit dem DBI vom FHEM zur Datenbank :-(
Die Ausgabe soll gleich der von Tibber sein, damit ein Wechsel nicht direkt mit Anpassungen innerhalb der Datenbank einhergeht.

- Für den INSERT sind die Kommentare zu entfernen

- Der eigene Zähler müsste an dieser Stelle eingetragen werden
    WHERE DEVICE  = 'WR_0_KSEM'
      AND READING = 'Active_energy+'

- Man kann natürlich die Zeiträume ändern, das Muster ist nur für den aktuellen Tag ausgelegt

-- INSERT INTO history (TIMESTAMP, DEVICE, TYPE, READING, VALUE)


WITH price AS (
  SELECT
    TIMESTAMP AS interval_start,
    VALUE AS price_ct_per_kWh   -- z.B. Cent/kWh
  FROM history
  WHERE DEVICE = 'Stromboerse_connect'
    AND READING = 'fc0_total'
    AND TIMESTAMP >= CURDATE()
    AND TIMESTAMP < CURDATE() + INTERVAL 1 DAY
),

consumption AS (
  SELECT
    interval_start,
    CASE
      WHEN interval_start = CURDATE() THEN 0
      WHEN VALUE < LAG(VALUE) OVER (ORDER BY interval_start) THEN NULL
      ELSE VALUE - LAG(VALUE) OVER (ORDER BY interval_start)
    END AS kWh_15min
  FROM (
    SELECT
      FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(TIMESTAMP) / 900) * 900) AS interval_start,
      VALUE,
      ROW_NUMBER() OVER (
        PARTITION BY FLOOR(UNIX_TIMESTAMP(TIMESTAMP) / 900)
        ORDER BY TIMESTAMP DESC
      ) AS rn
    FROM history
    WHERE DEVICE  = 'WR_0_KSEM'
      AND READING = 'Active_energy+'
      AND TIMESTAMP >= CURDATE() - INTERVAL 15 MINUTE
  ) t
  WHERE rn = 1
    AND interval_start >= CURDATE()
    AND interval_start < CURDATE() + INTERVAL 1 DAY
)

SELECT *
FROM (
  SELECT
    c.interval_start                   AS TIMESTAMP,
    'Stromboerse_connect'              AS DEVICE,
    'cost'                             AS TYPE,
    'nodes_cost'                       AS READING,
ROUND(COALESCE(c.kWh_15min,0) * COALESCE(p.price_ct_per_kWh,0) / 100, 6 ) AS VALUE
  FROM consumption c
LEFT JOIN price p
       ON p.interval_start = c.interval_start
) AS new_values

-- ON DUPLICATE KEY UPDATE
--   VALUE = new_values.VALUE;

VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 04 März 2026, 17:24:26
Hallo zusammen,
die nächste Version ist da und liegt im contrib.
Bitte denkt daran für die Kostenberechnung Euren letzten Jahresverbrauch einzutragen, da darüber die Grundkosten auf Preis/kWh umgerechnet werden.

- Fehler Korrekturen

- Code Optimierungen

- SQL Optimierungen
  Es wurde versucht einzelne INSERT jeweils zu massen INSERT umzustellen, was performanter ist

- Kostenberechnung bei Tibber ohne Vertrag
  Hier wird ein lokales SmartMeter oder ein Lesekopf auf dem Zähler benötigt
  Das SmartMeter wird in den Attributen definiert
  Die Berechnung erfolgt in der Datenbank und wird im Anschluss auch als readings im Device angezeigt

- Änderung beim fc_max zu fc_max1 und fc_max2
  In den letzten Tagen gab es Abends jeweils einen extrem hohen Maximalpreis, der dem fc_trigger_max_price
  unverhältnismäßeg nach eben gerissen hat. Mit der Umstellung gibt es nun auch noch den zweit höchsten Preis,
  der bei einer Abweichung von 20% zum fc_max1 genommen wird. Hierdurch wird das fc0_trigger_max Fenster größer.

- Beim fc0_trigger_*_stop wurde leider eine viertel Stunde zu spät gestoppt, was jetzt korrigiert ist.

Beim Device Stromboerse muss man auch etwas korrigieren und ich habe mal ganz unten das lokale SmartMeter eingeblendet.
Screenshot 2026-03-04 173800.png

Generell war ich auch die wichtigen letzten Wintermonate ziemlich enttäuscht von den Preisen. Natürlich waren sie hoch, wie schon lange.
Wichtiger jedoch waren die Schwankungen im Winter nicht so stark, dass sich ein Laden des Speichers gelohnt hätte, was ich in der Simulation auf 20% unter dem Maximalpreis eingestellt hatte. Auch ein Verschieben meiner Starkverbraucher hätte in Summe nicht soviel gesparrt, wie mich Tibber gekostet hätte. Ich scheine wohl ein sehr gutes EVU gepaart mit einer größeren PV zu haben.
Gedanklich werde ich mich mal mit dem Modul 1+3 des § 14a EnWG beschäftigen und testen, ob man über die Netzgebühren etwas sparen kann.

VG  Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: rabehd am 19 März 2026, 20:32:48
Ich habe es auch mal ausprobiert.

Zitatnodes_consumption_day  Please define LogDBRep_Stromboerse_connect_SQL first
nodes_consumption_month  Please define LogDBRep_Stromboerse_connect_SQL first
nodes_consumption_year  Please define LogDBRep_Stromboerse_connect_SQL first
nodes_cost_avg  Please define LogDBRep_Stromboerse_connect_SQL first
nodes_cost_max  Please define LogDBRep_Stromboerse_connect_SQL first
nodes_cost_min  Please define LogDBRep_Stromboerse_connect_SQL first
total_cost_day  Please define LogDBRep_Stromboerse_connect_SQL first
total_cost_month  Please define LogDBRep_Stromboerse_connect_SQL first
total_cost_year  Please define LogDBRep_Stromboerse_connect_SQL first

Was habe ich in der hier übersehen?
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 19 März 2026, 20:41:18
In meinem contrib findest Du noch ein DbRep Device, das Du entsprechend als LogDBRep_Stromboerse_connect_SQL benennen musst. Damit werden aus der DbLog Werte geholt und geschrieben.

VG Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 19 März 2026, 20:43:56
Besonders wichtig für die Berechnung sind Eure Preise des EVU und Netzbetreiber, die sollten in den Abrechnungen oder im Internet zufinden sein.
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: rabehd am 20 März 2026, 09:22:13
Zitat von: ch.eick am 19 März 2026, 20:41:18In meinem contrib findest Du noch ein DbRep Device, das Du entsprechend als LogDBRep_Stromboerse_connect_SQL benennen musst. Damit werden aus der DbLog Werte geholt und geschrieben.

VG Christian

Danke, hatte ich nicht für notwendig erachtet.

Ist das auch ein Versäumnis von mir?
ZitatDBD::MariaDB::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AS new ON DUPLICATE KEY UPDATE VALUE = new.VALUE' at line 1 at ./FHEM/93_DbRep.pm line 7073.
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 20 März 2026, 10:02:50
Zitat von: rabehd am 20 März 2026, 09:22:13Ist das auch ein Versäumnis von mir?
ZitatDBD::MariaDB::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AS new ON DUPLICATE KEY UPDATE VALUE = new.VALUE' at line 1 at ./FHEM/93_DbRep.pm line 7073.
Sorry, ich verwende die original Oracle MySQL Datenbank.
Du könntest gerne den MySQL Syntax auf MariaDB anpassen, eventuell hiltft ChatGBT auch einwenig.
MariaDB ist wohl etwas schlanker und hat nicht alle aktuellen Änderungen von MySQL. Im original MySQL bekomme ich die aktuellen Sicherheitsänderungen, was mir wichtig ist.

Ich schau mal was ChatGBT für MariaDB als Kompatibel vorschlägt.

Beispiel vom userReadings

nodes_TIMESTAMP:current_price.* {
...
MySQL Version >8 Syntax zu MariaDB übersetzen

MYSQL V8

INSERT INTO history (TIMESTAMP, DEVICE, TYPE, READING, VALUE)
      WITH price AS (
        SELECT
          TIMESTAMP AS interval_start,
          VALUE AS price_ct_per_kWh
        FROM history
        WHERE DEVICE = '$name'
          AND READING = 'fc0_total'
          AND TIMESTAMP >= CURDATE()
          AND TIMESTAMP < CURDATE() + INTERVAL 1 DAY
      ),
     
      consumption AS (
        SELECT
          interval_start,
          CASE
            WHEN interval_start = CURDATE() THEN 0
            WHEN VALUE < LAG(VALUE) OVER (ORDER BY interval_start) THEN NULL
            ELSE VALUE - LAG(VALUE) OVER (ORDER BY interval_start)
          END AS kWh_15min
        FROM (
          SELECT
            FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(TIMESTAMP) / 900) * 900) AS interval_start,
            VALUE,
            ROW_NUMBER() OVER (
              PARTITION BY FLOOR(UNIX_TIMESTAMP(TIMESTAMP) / 900)
              ORDER BY TIMESTAMP DESC
            ) AS rn
          FROM history
          WHERE DEVICE  = '$conf_Netz_Zaehler'
            AND READING = '$conf_Netz_Zaehler_Reading'
            AND TIMESTAMP >= CURDATE() - INTERVAL 2 DAY
        ) t
        WHERE rn = 1
          AND interval_start >= CURDATE()
          AND interval_start < CURDATE() + INTERVAL 1 DAY
      )
     
      SELECT *
      FROM (
        SELECT
          c.interval_start                   AS TIMESTAMP,
          '$name'              AS DEVICE,
          'cost'                             AS TYPE,
          'nodes_cost'                       AS READING,
      ROUND(COALESCE(c.kWh_15min,0) * COALESCE(p.price_ct_per_kWh,0) / 100, 6 ) AS VALUE
        FROM consumption c
      LEFT JOIN price p
             ON p.interval_start = c.interval_start
      ) AS new
      WHERE TIMESTAMP >= CURDATE()
      ON DUPLICATE KEY UPDATE
        VALUE = new.VALUE;



Dein MySQL-8 Statement ist syntaktisch völlig korrekt – aber genau diese Kombination ist in MariaDB oft problematisch:

❗ INSERT ... WITH ... SELECT ... ON DUPLICATE KEY UPDATE
→ funktioniert je nach MariaDB-Version nicht zuverlässig



🔧 Saubere MariaDB-kompatible Lösung

Die stabilste Variante ist:
👉 CTE in ein Derived Table (Subquery) kapseln

INSERT INTO history (TIMESTAMP, DEVICE, TYPE, READING, VALUE)
SELECT *
FROM (
    WITH price AS (
        SELECT
            TIMESTAMP AS interval_start,
            VALUE AS price_ct_per_kWh
        FROM history
        WHERE DEVICE = '$name'
          AND READING = 'fc0_total'
          AND TIMESTAMP >= CURDATE()
          AND TIMESTAMP < CURDATE() + INTERVAL 1 DAY
    ),

    consumption AS (
        SELECT
            interval_start,
            CASE
                WHEN interval_start = CURDATE() THEN 0
                WHEN VALUE < LAG(VALUE) OVER (ORDER BY interval_start) THEN NULL
                ELSE VALUE - LAG(VALUE) OVER (ORDER BY interval_start)
            END AS kWh_15min
        FROM (
            SELECT
                FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(TIMESTAMP) / 900) * 900) AS interval_start,
                VALUE,
                ROW_NUMBER() OVER (
                    PARTITION BY FLOOR(UNIX_TIMESTAMP(TIMESTAMP) / 900)
                    ORDER BY TIMESTAMP DESC
                ) AS rn
            FROM history
            WHERE DEVICE  = '$conf_Netz_Zaehler'
              AND READING = '$conf_Netz_Zaehler_Reading'
              AND TIMESTAMP >= CURDATE() - INTERVAL 2 DAY
        ) t
        WHERE rn = 1
          AND interval_start >= CURDATE()
          AND interval_start < CURDATE() + INTERVAL 1 DAY
    )

    SELECT
        c.interval_start AS TIMESTAMP,
        '$name'          AS DEVICE,
        'cost'           AS TYPE,
        'nodes_cost'     AS READING,
        ROUND(
            COALESCE(c.kWh_15min,0) * COALESCE(p.price_ct_per_kWh,0) / 100,
            6
        ) AS VALUE
    FROM consumption c
    LEFT JOIN price p
           ON p.interval_start = c.interval_start
) AS new
WHERE TIMESTAMP >= CURDATE()

ON DUPLICATE KEY UPDATE
    VALUE = new.VALUE;



⚠️ Warum das nötig ist

MariaDB hat hier mehrere Eigenheiten:

CTE + INSERT + UPDATE Kombination buggy

ON DUPLICATE KEY UPDATE kann Probleme mit CTE-Aliasen machen

Window Functions (LAG, ROW_NUMBER) sind ok – aber nur sauber in Subqueries



💡 Alternative (noch robuster)

Falls du auf Nummer sicher gehen willst (z. B. ältere MariaDB):

👉 CTE komplett vermeiden → nur Subqueries verwenden

Das wird länger, aber 100 % kompatibel.



🧠 Kurzfazit

Dein MySQL-8 Code = ✔️ korrekt

Für MariaDB:

❌ Direkt übernehmen → oft Fehler

✅ In SELECT FROM (WITH ...) AS new kapseln → stabil


⚠️ Wichtige Unterschiede MySQL vs. MariaDB

MySQL 8: INSERT ... WITH ... SELECT direkt möglich

MariaDB:

CTE (WITH) erst ab 10.2

Stabil mit INSERT erst ab 10.3+

Reihenfolge manchmal empfindlicher
In solch einer Session sollte die Umsetzung recht gut funktionieren. Es würde mich sehr freuen, wenn Du mir das dann getestet zusendest, dann würde ich im contrib zusätzlich das userReadings für MariaDB ablegen.


VG  Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 20 März 2026, 10:33:33
By the way...

Wenn Ihr kein Tibber-Live verwenden möchtet, könntet Ihr einfach die userReadings davon entfernen und bei Bedarf später wieder mit der aktuellsten Version einsteigen.
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: rabehd am 20 März 2026, 16:43:09
Zitat von: ch.eick am 20 März 2026, 10:02:50Es würde mich sehr freuen, wenn Du mir das dann getestet zusendest, dann würde ich im contrib zusätzlich das userReadings für MariaDB ablegen.

Ich habe alle Vorkommen ersetzt und keine Fehlermeldung mehr.

Aus:
AS new
WHERE TIMESTAMP >= CURDATE()
ON DUPLICATE KEY UPDATE
VALUE = new.VALUE;
wird:

WHERE TIMESTAMP >= CURDATE()
ON DUPLICATE KEY UPDATE
VALUE = VALUES(VALUE);
--AS new muss auch weg
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 20 März 2026, 16:49:37
Hallo rabehd,
in MySQL > V8 ist dieser Syntax bereits abgekündigt :-) , aber gut wenn es dann in MariaDB läuft.

Läuft der Rest mit dem "with" dann auch?
Welche MariaDb Version müsste dann verwendet werden?
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 25 März 2026, 13:00:20
Hallo zusammen,
da hatte sich noch ein Fehler beim userReadings current_level eingeschlichen.
Es liegt im contrib und kann selectiv ausgetauscht werden.

VG   Christian
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: rabehd am 25 März 2026, 13:47:39
Zitat von: ch.eick am 20 März 2026, 16:49:37Läuft der Rest mit dem "with" dann auch?
Welche MariaDb Version müsste dann verwendet werden?

Sorry, dazu bin ich noch nicht gekommen. Sollte in den nächste Tagen klappen.

Aktuell bin ich an meiner lorawan-Wetterstation dran. Aber mit dem Herstellersupport war es in wenigen Stunden erledigt. Solchen Service habe ich in Europe zuletzt 1995 erlebt.
Titel: Aw: HTTPMOD: Aktueller Strompreis EEX Strombörse Leipzig abfragen
Beitrag von: ch.eick am 25 März 2026, 13:51:33
Zitat von: rabehd am 25 März 2026, 13:47:39Aktuell bin ich an meiner lorawan-Wetterstation dran. Aber mit dem Herstellersupport war es in wenigen Stunden erledigt. Solchen Service habe ich in Europe zuletzt 1995 erlebt.
Mir reicht der DWD und wunderground, da brauche ich keine extra HW und über die Prognose läuft ein entsprechendes Wettermodel :-)