?
{
# === BEGIN Heater Peak Control ===
my $soc = ReadingsNum($name,"special_BatWeightedTotalSOC",0);
my $pv = ReadingsNum($name,"RestOfDayPVforecast",0);
my $con = ReadingsNum($name,"RestOfDayConsumptionForecast",0);
my $pvmax = ReadingsVal($name,"Today_MaxPVforecastTime","");
my $net = $pv - $con;
my $runtime = $net / 2100;
my $Eheater = (split " ", AttrVal ($name, 'consumer06', ''))[0]; # Heater-Name von ConsumerXX
my ($sec,$min,$hour) = localtime(); # aktuelle Stunde
my ($peak_hour) = $pvmax =~ /(\d{2}):\d{2}:\d{2}$/; # Peak-Stunde extrahieren
my $in_peak = 0;
$in_peak = 1 if(defined $peak_hour && abs($hour - $peak_hour) <= 3);
my $allow_heater = ( $in_peak && $soc > 80 && $runtime > 1.2); # Entscheidung
my $consmode = (ConsumerVal($name, '06', 'mode', "unklar"));
if (!$allow_heater) # Consumer06 steuern
{
if ($consmode ne "mustNot")
{
fhem("set $name attrKeyVal consumer06 mode=mustNot");
Log3($name, 2, "$name - Heatersteuerung mode war = $consmode - >>>>ab jetzt aktueller mode = mustNot");
}
if (ReadingsVal($Eheater,"state","") ne "off")
{
fhem ("set $Eheater off");
Log3 ($name, 2, qq{$name - userFn -> $name Consumer $Eheater in $name set to --off--});
}
Log3($name, 3, "$name - Heatersteuerung mode=mustNot Laufzeit $runtime - Peak_hour = $peak_hour - in_peak = $in_peak - SOC = $soc setreading $name consumer06 mode mustNot");
}
else
{
if ($consmode ne "can")
{
fhem("set $name attrKeyVal consumer06 mode=can");
Log3($name, 2, "$name - Heatersteuerung mode war = $consmode - >>>>ab jetzt aktueller mode = can");
}
if (ReadingsVal($Eheater,"state","") ne "on")
{
fhem ("set $Eheater on");
Log3 ($name, 2, qq{$name - userFn -> $name Consumer $Eheater in $name set to --on--});
}
Log3($name, 3, "$name - Heatersteuerung runtime = $runtime - Peak_hour = $peak_hour - in_peak = $in_peak - SOC = $soc jetzt ist setreading $name consumer06 mode can");
}
Log3($name, 4, "$name - Heatersteuerung runtime = $runtime - Peak_hour = $peak_hour - in_peak = $in_peak - SOC = $soc");
#########################
## BEGIN ######## loadsfcontribupdate #######
##
## ::loadsfcontribupdate ($name);
##
## ENDE ######## loadsfcontribupdate #######
# BEGIN ######## Load_Contrib_Update #######
#
# Wenn attr userFn_LoadContribcUpdate = 1 dann ...
# lade das aktuelle nur 1 x das Solarforecast Update ...
# aus dem Contrib von DS_Starter.
my $updatefromcontrib = AttrVal ($name, 'userFn_LoadContribcUpdate', "0");
if ($updatefromcontrib eq "1")
{ # lade die aktuelle Dateiversion vom Contrib DS_Starter
Log3 ($name, 2, qq{$name - start download Update Solarforecast from Contrib ====>>> wird gestartet});
fhem ('"wget -qO ./FHEM/76_SolarForecast.pm https://svn.fhem.de/fhem/trunk/fhem/contrib/DS_Starter/76_SolarForecast.pm"');
# setze aber sofort wieder zurück auf 0 (= nicht weiter laden >> 1 x reicht)
Log3 ($name, 2, qq{$name - end download Update Solarforecast from Contrib});
fhem (" attr $name userFn_LoadContribcUpdate 0");
Log3 ($name, 2, qq{$name - attr $name userFn_LoadContribcUpdate 0 ====>>> wurde ausgefuehrt});
}
# ENDE ######## Load_Contrib_Update #######
# BEGIN ######## WP-Heater ################
#
my $ubsm = AttrVal ($name, 'userFn_HeaterManagement', 'off');
Log3 ($name, 5, qq{$name - $ubsm});
if ($ubsm eq 'on')
{
# alles nur wenn attr für Heater 'on' ist
my $dt = timestringsFromOffset (time, 0);
my $hour = $dt->{hour}; # aktuelle Stunde in 24h format (00-23)
my $timestart = 2; # ab welcher Uhrzeit soll es sein. ===>> Wert evtl. anpassen
my $timeend = 8; # bis wieviel Uhr soll es sein. ===>> Wert evtl. anpassen
my $summertime = "8" ; # bis wieviel Grad keine EHK-Einsätze in der Nacht (Aussentenperatur Haeizungsthermostat ===>> Wert evtl. anpassen
my $outtemp = ReadingsNum("MQTT_ESMwp","boiler_data_outdoortemp",0); # ===>> Aussentenperatur Heizungsthermostat
my $forecastpvtodaymin = "20000"; # ca. max Tagesverbrauch ohne viel PV-Überschuss ===>> Wert evtl. anpassen
my $forecastpvtoday = ReadingsNum($name,"Today_PVforecast",0); # Today_PVforecast SF
if ( $outtemp >= $summertime )
{ # Nur ab xy:00 Grad
Log3 ($name, 2, qq{$name - userFn -> WWHeater Temperatur = $outtemp °C - Mindesttemperatur ist überschritten = $summertime °C});
if ( $forecastpvtoday >= $forecastpvtodaymin )
{ # nur wenn Today_PVforecast >= XYZ Watt
Log3 ($name, 2, qq{$name - userFn -> WWHeater Forcast HEUTE = $forecastpvtoday Wh - Mindestforecast HEUTE ist überschritten = $forecastpvtodaymin Wh});
if (int $hour >= $timestart && int $hour < $timeend )
{ # Nur zwischen xy:00 bis max. xy:59 (!!!! $timeend -1 Stunde !!!!) Uhr
my $minsocbat = 30; # nur bis mindesten XY SoC aller Batterien. ===>> Wert evtl. anpassen
my $heater = (split " ", AttrVal ($name, 'consumer06', ''))[0]; # Heater-Name von ConsumerXX
my $soctotal = CurrentVal ($name, 'batsoctotal', 0); # SoC über alle Bat als Durchschnitt
my $pvtot = ReadingsNum ($name, 'RestOfDayPVforecast', 0); # Restliche PV Prognose total heute in Wh
my $caps = CurrentVal ($name, 'batcapsum', 0); # Summe installierte Bat Wh
my $need = $caps - ($soctotal/100 * $caps); # benötigte Ladeenergie Bat bis 100% Ladung
Log3 ($name, 2, qq{$name - userFn -> WWHeater Reading ist = $heater - aktuelle Stunde = $hour aus $dt erzeugt });
Log3 ($name, 2, qq{$name - userFn -> StartZeit von = $timestart bis EndeZeit = $timeend und mindestens ein SoC von $minsocbat % muss in den vorhandenen Batterien gegeben sein });
Log3 ($name, 2, qq{$name - userFn -> Der PV-Tages-Restertrag betraegt $pvtot Wh ???mehr??? als die offene und noch zu ladende Batteriekapazitaet von $need Wh});
Log3 ($name, 2, qq{$name - $ubsm});
if ($soctotal >= ($minsocbat - 2) && $pvtot > $need)
{ # Zwischen xy:00 bis max. xy:59 (!!!! $timeend -1 Stunde !!!!) Uhr
# und % SoC-Vorgabe erfüllt
# und der PV-Tages-Rest-Ertrag > 100% Batteriekapazitaet
# send "on"-Kommando an Heater Device if(ne "on");
if (ReadingsVal($heater,"state","") ne "on") {
fhem ("set $heater on");
Log3 ($name, 2, qq{$name - userFn -> $name Consumer $heater in $name set to --on--});
}
}
else
{
if (($soctotal < $minsocbat) || ($pvtot <= $need))
{ # Wenn die (SoC-Vorgabe unterschritten !!!!! oder !!!! derTages-Rest-Ertrag < 100% Batteriekapazitaet)
# danach sollte der Heater-ConsumerXY wieder nach "seinen" Regeln steuern...
# send "off"-Kommando an Heater Device if(ne "off");
if (ReadingsVal($heater,"state","") ne "off")
{ fhem ("set $heater off");
Log3 ($name, 2, qq{$name - userFn -> $name Consumer $heater in $name set to --off--});
}
}
}
}
}
}
}
# ENDE ######## WP-Heater ################
} my $dt = timestringsFromOffset (time, 0); my $dt = timestringsFromOffset ($name, time, 0); attr global encoding bytestreamgesetzt, das führt zu folgenden Fehlern im Log, wenn die Statusmeldung versandt wird:2026.04.15 14:13:16 1: Encoding problem in data/header (not UTF-8), check Forum #131207
2026.04.15 14:13:16 1: PERL WARNING: substr outside of string at FHEM/HttpUtils.pm line 811.
2026.04.15 14:13:16 1: PERL WARNING: Use of uninitialized value $data in numeric eq (==) at FHEM/HttpUtils.pm line 812.attr global encoding unicodegesetzt. Wird dann die Statusmeldung versandt, gibt es keine Fehler mehr im Log, aber die Meldung kommt mit falschen Umlauten:Taegliche Statusmeldung
Garage hinten:
Temperatur: 21.3
Luftfeuchtigkeit: 36 %
Heizung: 17.1
Vorne: 23.1
Wettervorhersage heute: Bewölkung unverändert
Tag/Nacht: 20.4 / 6.80
Wettervorhersage morgen: Bewölkung unverändert
Tag/Nacht: 19 / 10.6
Batterie PV: 94 %sudo -E /opt/signal/bin/signal-cli --config /var/lib/signal-cli -u +31xxxxxxxx register --reregister --captcha signalcaptcha://signal-hcaptcha.5fad97ac-4e44-b18a-b950b20148ff.registration.P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.haJwZACjZXhwzmnfezOncGFzc2tlecUFSikWaW3xRzETPW0brJMts9_Pl3PQPAz5OlHQypsb9BuOsBVjvGrLk672Qff_5Os8nnUR9zCwzrNrhnAobstzeUhkbD645vU7yN-UK0wzlrjfLbLQPAX-0Cfo6Z6ExW8Di63APjywaET3N2VaMxh-SyXaXjIN-cVCr5uglL8B6UMbaPImUsxxNHVsfgPWwKR5mntA6NQ9IFnxsOMCxYaYU3bySorGzjaEcRVB0WDUNT-lkcvPYdvRPq-BldRsX5NdxAeukyMigFSoUNvfkzIoe0mw82Wi230QdGkTPubrdQxORNoTP-4oxVP2Qe8BwVbn_PfCRNPNU5YEXpmK4wDYdoQTk-zisOwUGj0Ge4EIilwcF2vHp7U5HcSTFKl62gmbb0NKWtg_gJr1B-cdBdgagFVlL_ZjL9fJCZEEie_9DRT4J9XOSPfcvKICHUrHn9e2nMunJHrxxuNCHRuVdLAxdObeelqgkCxjzGZgScc4h2t_Ub_Bm-MzxTe08W7JC4Q7wjgavWTrUki-2riqUAuuavkqti2Oge98e5mjKc4VZzt0LS9sEjHdrCSLfEtB0ttpUbfALwjCiOKex0PTtc_ZD3jcAUBk_YSVurT17QLqyxZXxEYIhmRGoj1U7HQ4cNiL4JJARUNx4LC8BGP6aI_68dkRDqlndfNQUIc2oAOpl1kTVxQ21LDrxCgrt5o5wHIfzZWOhci_Op1l9_XRkPG0LLHdX0AweWZcDfwrIVnjLoQ-BQVD05Ck2t0OxPhmeAKIN1A-s2SWc02j26Ed7F8IIHpeNWMEbRGVx3Ibp6dpMVDp4lpCFUzAr7aligvzFIBN7UX_lHD9XoMwIRud_-MnohkXyIoIvHFyxd9KGpBiJfFzYFQavzEY7DUrp0PaV3yKtgA8zh2lNmLyQwK-Z-oyiUVomFlQW1HeMitI5dqvdyLmjNVp75BSSR5wqi1uG8n1R325txvkU5AJ4fH-JZ__g7H8Q34ed7Zn-8gzffIa_XxGYZRqBHg2-Bd4YQRyBeTumHN64Htbw2J1jLLK_SW6oIsAf9xaHzndLc56zySHfQhwgG9kxsBiztZmKx9bLPlXUR2MYam8TYnDP1CMlIK3HiY0rexoJwT-sQcd2RDcGJiT-ORwwnhCTPHSHISw9nNrW9KMPt80UsXTV52t9KU781z8T1eNiJELf2Ba7H_Iidlc19DdjL2Viio03qBhw_Y5OLJ37m6yunAyixyai5KgKBns_vJIROXfQwmLCe4-qd0l71buDrlUOsZGbRAL8fG0qvoz_XrlcgwjHKhxvFqhtPuUKRo-vEU5KbdI0KJNC5eLjx6ptOY3-BZZ-j1oL_cJeALBo7vuiwWVzIAIR-wsIo4Ada8sVYdSOGEA72ooX1u3gFScEfX8QDmJsaDAXWVFb9X2MaY3HlojTC9iAYMqr7JwjNJqa0jB6gnI8IO8RYnGKArQCTpzrMsj2Z_50K-p-iKCMnSCGLKMm-KSZ07Znc1ZGbx5-uxTrR8yAfkpjj36qwcPDbvtfv1zOcbuA60_bl0Iq4oJRPdrZvqAwogQs9D8MZWUDF6Dhrro3mwybTx9estROfPLzk0oS8XTXFLsNhN_-FpmvEX1HZ1R-NEdXLBkM2odQhfNf0TB5ng0moxvFEjsbbNmjwRGZG7bWYniBOgWLHS1pkNz5K3NGea7iVlxzA_q3c-wprUh9GQC9nW8pE8xjqM5zcvZNl42DGZba3VM_fPR1YPvDzNKmgYwHuwRu3jDX2Mq-KChxTNtvKFTd12MmY9iMCTptkZ8_IDvmk55BoLDS1jlREGia3KoMzk1ZmQ5ZGWoc2hhcmRfaWTOAzGDbw.3o1TrkJo4ZuZfSyjO66Uc5NWD93V1F4uTfbXN-Tt27Y
ZitatSieht evtl. nach dem neuen LRU aus ?nein, aber du hast in deiner userExitFn wahrscheinlich die timestringsFromOffset drin:
FHEM::SolarForecast::timestringsFromOffset ($startts, 0);
FHEM::SolarForecast::timestringsFromOffset ($name, $startts, 0);
2026.04.14 21:43:20 1: Forecast - ERROR executing userExitFn: Can't use an undefined value as a SCALAR reference at ./FHEM/76_SolarForecast.pm line 33873.
26.04.14 21:43:16 0: Server started with 444 defined entities (fhem.pl:30992/2026-03-21 perl:5.036000 os:linux user:fhem pid:830033)
2026.04.14 21:43:20 1: PERL WARNING: Use of uninitialized value $d in hash element at fhem.pl line 4802.
2026.04.14 21:43:20 1: PERL WARNING: Use of uninitialized value $title in regexp compilation at ./FHEM/76_SolarForecast.pm line 33754.

Zitat von: Marko1976 am 14 April 2026, 20:23:56Also das mit dem Forecast Hour/Day versteh ich sowieso nicht, aber wenn ich die Ausführungen oben richtig interpretiere wird immer die vergangene Mende der letzten 1/3 Stunden angegeben, das gleiche für den Schnee.
Aber das ist ja keine Voraussage - irgendwie passt das doch nicht.
Wie kann eine Rückwirkende Angabe sich auf einen Vorhersage beziehen?