15min Leistungswert

Hej zusammen,
ich habe mir folgendes „gebastelt“…ZIel: Erkennen welche Last ich zu/abschalten kann/muss, um am Ende der 15Minuten den Grenzwert nicht zu reissen.
(Das Skript ist im wesentlichen KI-Generiert)

?php
/*
// ---------------------
// Konfiguration
// ---------------------
$id_IstLast = 33375; // aktuelle Leistung (Momentanwert)
$id_IstMenge = 11508; // FLOAT: aufsummierte Ist-Menge im aktuellen 15-Min-Intervall
$id_Abweichung = 12975; // FLOAT: Abweichung im aktuellen 15-Min-Intervall
$id_LastTime = 32244; // INTEGER: letzter Zeitstempel
$duration = 900.0; // 15 Minuten in Sekunden

$MaxMenge15Min = getvalue(33624)/4; // Maximale BezugsMenge im 15-Min-Intervall

// ---------------------
// 1) Zeitbasis bestimmen
// ---------------------
$now = time();

// Beginn des aktuellen 15-Minuten-Zeitraums bestimmen
$minute = (int)date(‚i‘, $now);
$quarterIndex = floor($minute / 15); // 0,1,2,3
$startMinute = $quarterIndex * 15; // 0,15,30,45

$periodStart = mktime(
(int)date(‚H‘, $now),
$startMinute,
0,
(int)date(‚m‘, $now),
(int)date(‚d‘, $now),
(int)date(‚Y‘, $now)
);

$elapsed = $now - $periodStart;
if ($elapsed < 0) $elapsed = 0;
if ($elapsed > 900) $elapsed = 900;

// ---------------------
// 2) Ist-Menge integrieren
// ---------------------
$IstLast = GetValue($id_IstLast);

$lastTime = GetValue($id_LastTime);

// erstes Mal oder neues 15-Minuten-Intervall?
if ($lastTime < $periodStart || $lastTime == 0) {
// Ist-Menge zurücksetzen
SetValue($id_IstMenge, 0.0);
SetValue($id_Abweichung, 0.0);

// Startwerte setzen
SetValue($id_LastTime, $now);

// noch keine Fläche berechnen
return;

}

// Zeitdifferenz seit letztem Aufruf
$dt = $now - $lastTime;
if ($dt < 0) $dt = 0;

// aktuelle Ist-Leistung laden
$IstMenge = GetValueFloat($id_IstMenge);

// aktuelle Istmenge ermittlen
$deltaMenge = $IstLast * $dt/3600;
$IstMenge += $deltaMenge;

// Speichern
SetValue($id_IstMenge, $IstMenge);
SetValue($id_LastTime, $now);

// ---------------------
// 3) Soll-Gesamtmenge & Abweichung
// ---------------------
$Puffer = $MaxMenge15Min * ($elapsed/$duration);

// Abweichung (= Ist - Soll) in kWh
$Abweichung = round(($MaxMenge15Min - $Puffer - $IstMenge), -2, PHP_ROUND_HALF_DOWN) ;

// Abweichung speichern
SetValue($id_Abweichung, $Abweichung*4);

echo „Start - Puffer - Ist = Abweichung | $MaxMenge15Min-$Puffer-$IstMenge=$Abweichung“;

*/
//-----------------------------------

// ---------------------
// Konfiguration
// ---------------------
$id_IstLast = 33375; // aktuelle Netzlast in W (positiv Bezug, negativ Einspeisung)
$id_IstMenge = 11508; // FLOAT: aufsummierte Ist-Menge im aktuellen 15-Min-Intervall (Wh)
$id_Abweichung = 12975; // INTEGER: zulässige Zusatzleistung in W (+ = zuschalten, - = abschalten)
$id_LastTime = 32244; // FLOAT: letzter Zeitstempel (Unix-Zeit als Float)
$id_MaxLastWatt = 33624; // INTEGER: maximal zulässige Momentanleistung in W
$duration = 900.0; // 15 Minuten in Sekunden

// ---------------------
// 0) Max. 15-Min-Energie aus MaxLast (W) berechnen
// ---------------------
$MaxLastW_int = GetValueInteger($id_MaxLastWatt); // z.B. 13500 W
$MaxLastW = (float)$MaxLastW_int;
$MaxMenge15Min = $MaxLastW * 0.25; // Wh in 15 Minuten (0,25 h)

// ---------------------
// 1) Zeitbasis bestimmen (aktuelles 15-Min-Intervall)
// ---------------------
$now = time();

$minute = (int)date(‚i‘, $now);
$quarterIndex = floor($minute / 15); // 0,1,2,3
$startMinute = $quarterIndex * 15; // 0,15,30,45

$periodStart = mktime(
(int)date(‚H‘, $now),
$startMinute,
0,
(int)date(‚m‘, $now),
(int)date(‚d‘, $now),
(int)date(‚Y‘, $now)
);

$elapsed = $now - $periodStart;
if ($elapsed < 0) $elapsed = 0;
if ($elapsed > 900) $elapsed = 900;

// ---------------------
// 2) Ist-Menge integrieren (Wh)
// ---------------------
$IstLast = (float)GetValue($id_IstLast); // W
$lastTimeF = GetValueFloat($id_LastTime); // Float-Zeitstempel
$lastTime = (int)$lastTimeF;

// erstes Mal oder neues 15-Minuten-Intervall?
if ($lastTime < $periodStart || $lastTime == 0) {
SetValue($id_IstMenge, 0.0);
//SetValueInteger($id_Abweichung, 0);
SetValueFloat($id_LastTime, (float)$now);
return;
}

// Zeitdifferenz seit letztem Aufruf
$dt = $now - $lastTime;
if ($dt < 0) $dt = 0;

// aktuelle Ist-Menge laden (Wh)
$IstMenge = GetValueFloat($id_IstMenge);

// deltaMenge in Wh: P[W] * dt[s] / 3600
$deltaMenge = $IstLast * $dt / 3600.0;
$IstMenge += $deltaMenge;

// Speichern der integrierten Energiemenge und Zeit
SetValue($id_IstMenge, $IstMenge);
SetValueFloat($id_LastTime, (float)$now);

// ---------------------
// 3) zulässige Zusatzleistung aus 15-Minuten-Sicht (Wh → W)
// ---------------------

// Restenergie im 15-Min-Intervall (Wh)
$remainingEnergyWh = $MaxMenge15Min - $IstMenge;

// Restzeit im Intervall (s)
$remainingTimeSec = $duration - $elapsed;

// Zusätzliche Leistung, damit die 15-Min-Grenze eingehalten wird
if ($remainingTimeSec <= 0) {
// Intervall vorbei oder quasi vorbei: keine Reserve mehr
$allowedExtraW_15min = 0.0;
} else {
// P_extra[kW] = remainingEnergy[Wh] / remainingTime[h]
// = remainingEnergy * 3600 / remainingTimeSec / 1000
$allowedExtraKW_15min = ($remainingEnergyWh * 3600.0) / $remainingTimeSec / 1000.0;
$allowedExtraW_15min = $allowedExtraKW_15min * 1000.0;
}

// ---------------------
// 4) Momentangrenze durch MaxLast berücksichtigen
// ---------------------

// Reserve aus Momentanleistung: MaxLast - aktuelle Last
// Beispiel: MaxLast=13500, IstLast=-9400 → 13500 - (-9400) = 22900 W
$allowedExtraW_momentan = $MaxLastW - $IstLast;

// ---------------------
// 5) Finale zulässige Zusatzleistung = strengste Grenze
// ---------------------

// Beide Limits wirken gleichzeitig; nimm das kleinere
$finalAllowedExtraW = min($allowedExtraW_15min, $allowedExtraW_momentan);

// zusätzliche Sicherheitsbegrenzung: niemals mehr als MaxLastW zuschaltbar
if ($finalAllowedExtraW > $MaxLastW) {
$finalAllowedExtraW = $MaxLastW;
}
if ($finalAllowedExtraW < -$MaxLastW) {
$finalAllowedExtraW = -$MaxLastW;
}

// runden und in Integer schreiben
$finalAllowedExtraW = (int)round($finalAllowedExtraW);

// Interpretation in 12975:
// >0 → so viel W kannst du noch zuschalten, ohne 15-Min-Korridor zu sprengen
// <0 → so viel W musst du im Mittel abregeln, um das Intervall noch zu retten
SetValueInteger($id_Abweichung, $finalAllowedExtraW);

// Optional: Debug
//echo "IstLast={$IstLast}W, IstMenge={$IstMenge}Wh, remainingEnergy={$remainingEnergyWh}Wh, " .
// „Extra15min={$allowedExtraW_15min}W, ExtraMom={$allowedExtraW_momentan}W, final={$finalAllowedExtraW}W“;

Kann es sein, dass Du so etwas sehen möchtest?

Nein ich will die Durchschnitts kW in 15min wissen immer zb von 13:00 bis 13:15 dann von 13:15 bis 13:30 und so weiter. Hintergrund ist das wir ab 2027 in Österreich für die Spitzenleistung vom Netzbezug die Netzgebühren zahlen und wenn man dan über 10kW im 15min Durchschnitt kommt wirds teuer fürs gesamte Monat.

So zeichne ich’s auf Mann sieht nur noch nicht viel da der Speicher momentan nicht leer wird.

Interessant, kapiert was Du möchtest. Im Grunde ist es genau das Diagramm, nur müsstest Du die kWh x 4 nehmen. Oder noch besser, man könnte den kW in dieses Diagramm integrieren. Ich versuche mal etwas.

so habe ich es gemacht

wichtig ist immer nur das die Start und Endzeit bast weil die vorgegeben ist

<?php

// Variable mit dem Stromzählerstand in W
$ZaehlerID = 54384;

// Archiv-ID
$archiv = 43615;

// Zielvariable für den Durchschnittswert in kW
$AusgangsVariable = 42435;

// Start = Beginn der aktuellen Viertelstunde
$start = floor(time() / 900) * 900;

// Ende = Ende der aktuellen Viertelstunde
$ende = $start + 900;

echo "Zeitraum: " . date("d.m.Y H:i:s", $start) . " bis " . date("d.m.Y H:i:s", $ende) . PHP_EOL;

// Aggregierte Werte lesen
$wert = AC_GetAggregatedValues($archiv, $ZaehlerID, 6, $start, $ende, 0);

$summe = 0;

foreach ($wert as $werte)
{
    echo "Dauer: " . $werte["Duration"] .
         " TimeStamp: " . date("d.m.Y H:i:s", $werte["TimeStamp"]) .
         " Durchschnitt: " . $werte["Avg"] .
         " MinTime: " . date("d.m.Y H:i:s", $werte["MinTime"]) .
         " MaxTime: " . date("d.m.Y H:i:s", $werte["MaxTime"]) .
         " Maximum: " . $werte["Max"] . PHP_EOL;

    $summe += $werte["Avg"];
}

if (count($wert) > 0)
{
    // Durchschnitt berechnen und von W auf kW umrechnen
    $durchschnitt = ($summe / count($wert)) / 1000;

    // Auf 3 Nachkommastellen runden
    $durchschnitt = round($durchschnitt, 3);

    echo "Durchschnitt: " . $durchschnitt . " kW" . PHP_EOL;

    // In IP-Symcon-Variable schreiben
    SetValue($AusgangsVariable, $durchschnitt);
}
else
{
    echo "Keine Werte im Zeitraum gefunden." . PHP_EOL;

    // Optional 0 schreiben
    SetValue($AusgangsVariable, 0);
}

?>

so rechnet er mir immer was ich momentan eine Durchschnittleistung in der aktuellem 15min habe

So würde es bei mir dann später aussehen.

Umschaltbar zwischen Leistung (kW) und Energie (kWh)

schaut auch nicht schlecht aus als Balken. Hat was.

hab auch eine Variable wo der momentane Durchschnitt hineingeschrieben wird damit ich weis wo ich gerade herum bin.

Screenshot 2026-08-09 213702

deine 26kW würden teuer werden bei uns :sweat_smile:

Wie soll das denn abgerechnet werden? Bei den RLM Messungen haben wir ja auch die Lastspitzenabrechnung. d.h. die höchste Lastspitze einer 1/4 Std. eines Monats oder Jahres gibt einen großen Preisanteil bei der Abrechnung vor.

Soll das in Österreich so bei SLP Messungen kommen?

Unsere Smart Meter übertragen breits die 15min Werte

100% fixirt haben sie das noch nicht aber es wird immer der höchste 15min Wert für das Aktuelle Monat herangenommen und nach dem wird das ganze Monat berechnet das heist wenn du in diesen Monat nur einmal über 10kW 15min Durchschnitt komst wirds je nach dem wie viel drüber deutlich teurer anders herum um so weiter darunter ums so günstiger (aber nicht so stark als wen du drüber wärst) und nach dem berechnet sich der kWh Preis für das Netzentgeld zuästzlich kommt so wie ich das verstanden habe noch ein Fix Betrag pro kWh drauf.

Alles sehr unübersichtlich und bei nur einem Fehler teuer.

Hier eine Übersicht:

Ok, das wird dann eine Abrechnung der Netzentgelte wie heute bereits bei den Grossverbrauchern (RLM Messung). Findest Du das bereits als Preisblatt bei Deinem Netzbetreiber?

Genau in diese Richtung soll es gehen.

Nein noch gibt es nichts fixes kommt erst mit dem 1.1.2027.

Du wirst halt bestraft wenn du auf E-Auto und Wärmepumpe gesetzt hast.

Ich werde mit Symcon das gut vermeiden können aber schauen wir mal

Ok, in meinem Modul wird das zunächst so umgesetzt, dass die laufende Monats-Höchstleistung als Markierungslinie angezeichnet und auch die Höchstleistung an der Linie bezeichnet wird.

Kontrolle:

würde passen.

Jeden Monat würde dieses Spiel dann von vorne beginnen.

Was hältst Du davon, könnte es so passen? Wenn dann mal irgendwann Preise festgelegt wurden könnte man das ganze dann auch noch bepreisen.

1 „Gefällt mir“

Das schaut sehr gut aus mit der Monats Max Linie

Prima, wenn es so passt. Ich hoffe, dass ich die ganzen Module demnächst durch habe.

Genau, diese Abrechnung nach höchster Leistungsspitze animiert ja nicht unbedingt zur Leitungsspitzenvermeidung.

Man kann im Symcon oder direkt am Wechselrichter Peakshaving einrichten und so keine Leistungsspitzen erzeugen. Nur bei einem Fehler ist das für das Monat gelaufen. Wenn jetzt z.B am Monatsanfang der Wechselrichter während vollen Sonnenschein sich aufhängen würde und das Auto mit 11kW weiter geladen wird, und das ein volle 1/4 Stunde lang, dann ist die Leistungsspitze mit 11kW schon passiert. Also braucht man sich das restliche Monat keine Gedanken mehr zur Leistungsspitzenvermeidung machen.

Außerdem animiert das System auch niemanden dazu in den Nachtstunden Leistung zu beziehen, wenn die Stromnetze leer sind. Also E-Auto um 17:00 wenn man heimkommt mit 4kw laden ist billiger als das laden mit 11kW ab Mitternacht. Also lieber das Netz im Winter am Abend wo es eh schon voll ist mit zusätzlichen 4kW belasten.

So wie das nun vorhergesagt wird, wird das Stromnetz einfach nur teurer und wenn man keine Leistungssteuerung hat, dann gute Nacht