Strompreisvorhersage aus Strompreismodul (die nächste Viertelstunde)

Hallo in die Runde. Ich möchte gerne aus dem Strompreismodul, welches eine Variable für die Marktdaten zur Verfügung stellt, nicht den aktuellen Preis auslesen (das macht das Modul ja), sondern die nächsten zu erwartenden 15 Minuten. Hintergrund, ich möchte bestimmte Geräte im Vorfeld aktiv schalten, bzw. rechtzeitig runterfahren.

Die Marktdaten haben folgendes String-Format:

[{"start":1770505200,"end":1770506100,"price":31.95476},{"start":1770506100,"end":1770507000,"price":30.89447},{"start":1770507000,"end":1770507900,"price":30.758809999999997},{"start":1770507900,"end":1770508800,"price":30.40062},{"start":1770508800,"end":1770509700,"price":30.93969},{"start":1770509700,"end":1770510600,"price":30.92303},{"start":1770510600,"end":1770511500,"price":30.4149},{"start":1770511500,"end":1770512400,"price":30.3078},{"start":1770512400,"end":1770513300,"price":30.7481},{"start":1770513300,"end":1770514200,"price":30.461309999999997},{"start":1770514200,"end":1770515100,"price":30.35897},{"start":1770515100,"end":1770516000,"price":30.31375},{"start":1770516000,"end":1770516900,"price":30.454169999999998},{"start":1770516900,"end":1770517800,"price":30.3673},{"start":1770517800,"end":1770518700,"price":30.24116},{"start":1770518700,"end":1770519600,"price":30.275669999999998},{"start":1770519600,"end":1770520500,"price":30.1531},{"start":1770520500,"end":1770521400,"price":30.1055},{"start":1770521400,"end":1770522300,"price":30.170949999999998},{"start":1770522300,"end":1770523200,"price":30.163809999999998},{"start":1770523200,"end":1770524100,"price":30.23521},{"start":1770524100,"end":1770525000,"price":30.21379},{"start":1770525000,"end":1770525900,"price":30.223309999999998},{"start":1770525900,"end":1770526800,"price":30.34469},{"start":1770526800,"end":1770527700,"price":29.60332},{"start":1770527700,"end":1770528600,"price":29.9032},{"start":1770528600,"end":1770529500,"price":30.33755},{"start":1770529500,"end":1770530400,"price":30.815929999999998},{"start":1770530400,"end":1770531300,"price":29.69971},{"start":1770531300,"end":1770532200,"price":30.130489999999998},{"start":1770532200,"end":1770533100,"price":30.319699999999997},{"start":1770533100,"end":1770534000,"price":30.89328},{"start":1770534000,"end":1770534900,"price":30.289949999999997},{"start":1770534900,"end":1770535800,"price":30.907559999999997},{"start":1770535800,"end":1770536700,"price":30.94683},{"start":1770536700,"end":1770537600,"price":31.06107},{"start":1770537600,"end":1770538500,"price":30.98848},{"start":1770538500,"end":1770539400,"price":31.09796},{"start":1770539400,"end":1770540300,"price":31.04084},{"start":1770540300,"end":1770541200,"price":30.85877},{"start":1770541200,"end":1770542100,"price":31.28003},{"start":1770542100,"end":1770543000,"price":31.21339},{"start":1770543000,"end":1770543900,"price":30.95278},{"start":1770543900,"end":1770544800,"price":30.852819999999998},{"start":1770544800,"end":1770545700,"price":31.01466},{"start":1770545700,"end":1770546600,"price":30.86115},{"start":1770546600,"end":1770547500,"price":30.59816},{"start":1770547500,"end":1770548400,"price":30.375629999999997},{"start":1770548400,"end":1770549300,"price":30.505339999999997},{"start":1770549300,"end":1770550200,"price":30.375629999999997},{"start":1770550200,"end":1770551100,"price":30.39943},{"start":1770551100,"end":1770552000,"price":30.12811},{"start":1770552000,"end":1770552900,"price":30.176899999999996},{"start":1770552900,"end":1770553800,"price":30.04719},{"start":1770553800,"end":1770554700,"price":30.31494},{"start":1770554700,"end":1770555600,"price":30.335169999999998},{"start":1770555600,"end":1770556500,"price":30.05671},{"start":1770556500,"end":1770557400,"price":30.357779999999998},{"start":1770557400,"end":1770558300,"price":30.487489999999998},{"start":1770558300,"end":1770559200,"price":30.814739999999997},{"start":1770559200,"end":1770560100,"price":30.52557},{"start":1770560100,"end":1770561000,"price":30.82188},{"start":1770561000,"end":1770561900,"price":31.274079999999998},{"start":1770561900,"end":1770562800,"price":31.99998},{"start":1770562800,"end":1770563700,"price":30.85996},{"start":1770563700,"end":1770564600,"price":31.669159999999998},{"start":1770564600,"end":1770565500,"price":32.54857},{"start":1770565500,"end":1770566400,"price":33.57197},{"start":1770566400,"end":1770567300,"price":33.08526},{"start":1770567300,"end":1770568200,"price":33.85162},{"start":1770568200,"end":1770569100,"price":34.449},{"start":1770569100,"end":1770570000,"price":34.80719},{"start":1770570000,"end":1770570900,"price":34.305009999999996},{"start":1770570900,"end":1770571800,"price":34.67391},{"start":1770571800,"end":1770572700,"price":34.633449999999996},{"start":1770572700,"end":1770573600,"price":34.31096},{"start":1770573600,"end":1770574500,"price":34.68224},{"start":1770574500,"end":1770575400,"price":34.27764},{"start":1770575400,"end":1770576300,"price":33.74571},{"start":1770576300,"end":1770577200,"price":33.142379999999996},{"start":1770577200,"end":1770578100,"price":33.48034},{"start":1770578100,"end":1770579000,"price":32.45694},{"start":1770579000,"end":1770579900,"price":31.94167},{"start":1770579900,"end":1770580800,"price":31.48352},{"start":1770580800,"end":1770581700,"price":32.04996},{"start":1770581700,"end":1770582600,"price":31.86075},{"start":1770582600,"end":1770583500,"price":31.58467},{"start":1770583500,"end":1770584400,"price":31.17531},{"start":1770584400,"end":1770585300,"price":31.721519999999998},{"start":1770585300,"end":1770586200,"price":31.54064},{"start":1770586200,"end":1770587100,"price":31.25266},{"start":1770587100,"end":1770588000,"price":30.97182},{"start":1770588000,"end":1770588900,"price":31.16698},{"start":1770588900,"end":1770589800,"price":30.96349},{"start":1770589800,"end":1770590700,"price":30.793319999999998},{"start":1770590700,"end":1770591600,"price":30.107879999999998}]

Ich bin nach wie vor nicht in der Lage solche anspruchsvollen Skripte zu schreiben, aber vielleicht hat jemand einen Ansatz oder Idee für mich parat. Würde mich freuen.

Gruß

Marc

Guten Morgen,

die daten sehen nach Json aus.

habe das ganze mal in Gemini geschmissen

<?php 
// --- Konfiguration --- //
Hier die IDs deiner Variablen eintragen define
("ID_PREIS_DATA_JSON", 12345); // Quell-Variable (String mit JSON) 
define("ID_AKTUELLER_PREIS", 54321); // Ziel-Variable (Float) 

// --- Logik --- //
1. Daten aus der Quell-Variable einlesen 
$jsonContent = GetValueString(ID_PREIS_DATA_JSON);
$data = json_decode($jsonContent, true);
if ($data === null || !is_array($data)) { 
  IPS_LogMessage("Strompreis-Skript", "Fehler: JSON-Daten konnten nicht dekodiert werden oder sind leer.");
  return; 
} 
$now = time();
$currentPrice = null; // 2. Den passenden Zeit-Slot finden
foreach ($data as $slot) 
{ // Prüfen, ob die aktuelle Zeit im Intervall [start, end] liegt
  if ($now >= $slot['start'] && $now < $slot['end']) {
    $currentPrice = $slot['price'];
    break;
  }
} 

// 3. Ergebnis mit RequestAction schreiben
if ($currentPrice !== null) {
  // RequestAction triggert die Standard-Aktion der Variable // Dies ist sauberer als SetValue, da es Modul-Logik berücksichtigt
  RequestAction(ID_AKTUELLER_PREIS, $currentPrice);
} else {
  // Falls kein Slot gefunden wurde (z.B. Daten am Ende des Tages abgelaufen)
  IPS_LogMessage("Strompreis-Skript", "Kein Preis für " . date("H:i", $now) . " in den Daten vorhanden.");
}
```

der Code wurde von mir jetzt nicht getestet aber ich habe ihn mal überflogen und das sollte passsen.

Gruß Max

1 „Gefällt mir“

So,

ich habe es mal um einige Fehler bereinigt bekommen. Allerdings bekomme ich als Ergebnis 0,00.

Es werden aber keine Fehler mehr gemeldet:

<?php 

// --- Konfiguration --- //
//Hier die IDs deiner Variablen eintragen 
define ("ID_PREIS_DATA_JSON", 42953); // Quell-Variable (String mit JSON) 
define ("ID_AKTUELLER_PREIS", 32744); // Ziel-Variable (Float) 

// --- Logik --- //
//1. Daten aus der Quell-Variable einlesen 
$jsonContent = GetValue(ID_PREIS_DATA_JSON);
$data = json_decode($jsonContent, true);
if ($data === null || !is_array($data)) { 
  IPS_LogMessage("Strompreis-Skript", "Fehler: JSON-Daten konnten nicht dekodiert werden oder sind leer.");
  return; 
} 
$now = time();
$currentPrice = null; 
// 2. Den passenden Zeit-Slot finden
foreach ($data as $slot) 
{ // Prüfen, ob die aktuelle Zeit im Intervall [start, end] liegt
  if ($now >= $slot['start'] && $now < $slot['end']) {
    $currentPrice = $slot['price'];
    break;
  }
} 

// 3. Ergebnis mit RequestAction schreiben
if ($currentPrice !== null) {
  // RequestAction triggert die Standard-Aktion der Variable // Dies ist sauberer als SetValue, da es Modul-Logik berücksichtigt
  RequestAction(ID_AKTUELLER_PREIS, $currentPrice);
} else {
  // Falls kein Slot gefunden wurde (z.B. Daten am Ende des Tages abgelaufen)
  IPS_LogMessage("Strompreis-Skript", "Kein Preis für " . date("H:i", $now) . " in den Daten vorhanden.");
}

?>

Aber Danke schon mal bis hierhin.

Gruß

Marc

So,

ich habe es tatsächlich hinbekommen! Trotz fehlender Skript-Kenntnisse.

Hier das funktionierende Skript. Da war noch ein weiterer Fehler drin, weil mir im Ergebnis immer der aktuelle Preis angezeigt wurde und nicht der folgende. Dafür musste die Variable $now noch um 900 (also 15 Minuten) erhöht werden.

Wen es interessiert hier das funktionierende Skript:

<?php 

// --- Konfiguration --- //
//Hier die IDs deiner Variablen eintragen 
define ("ID_PREIS_DATA_JSON", 12345); // Quell-Variable (String mit JSON) 
define ("ID_AKTUELLER_PREIS", 54321); // Ziel-Variable (Float) 

// --- Logik --- //
//1. Daten aus der Quell-Variable einlesen 
$jsonContent = GetValue(ID_PREIS_DATA_JSON);
$data = json_decode($jsonContent, true);
if ($data === null || !is_array($data)) { 
  IPS_LogMessage("Strompreis-Skript", "Fehler: JSON-Daten konnten nicht dekodiert werden oder sind leer.");
  return; 
} 
$now = time() +900; //15 Minuten später !!!
$currentPrice = null; 
// 2. Den passenden Zeit-Slot finden
foreach ($data as $slot) 
{ // Prüfen, ob die aktuelle Zeit im Intervall [start, end] liegt
  if ($now >= $slot['start'] && $now < $slot['end']) {
    $currentPrice = $slot['price'];
    break;
  }
} 

// 3. Ergebnis mit RequestAction schreiben
if ($currentPrice !== null) {
  // RequestAction triggert die Standard-Aktion der Variable // Dies ist sauberer als SetValue, da es Modul-Logik berücksichtigt
  //RequestAction(ID_AKTUELLER_PREIS, $currentPrice);
  SetValue (ID_AKTUELLER_PREIS, $currentPrice);
} else {
  // Falls kein Slot gefunden wurde (z.B. Daten am Ende des Tages abgelaufen)
  IPS_LogMessage("Strompreis-Skript", "Kein Preis für " . date("H:i", $now) . " in den Daten vorhanden.");
}

?>

Danke nochmal @maxr

1 „Gefällt mir“

Freud mich das es geholfen hat.

Hatte heute morgen leider keine Zeit mehr es bei mir in Symcon wirklich aus zu probieren.

Letztendlich muss man sich einfach nur trauen das was man will Mal in Gemini oder Co ein zu geben, da kommt man schon weiter.

Ehrlich gesagt weiß ich gar nicht was Gemini ist. Hat ja alles geklappt. :ok_hand:

Eine KI von Google :slight_smile: