Zitat von: alkazaa am 10 April 2026, 21:42:46obwohl neuerdings sogar @rudolfkoenig den Einsatz von KI für diesen Zweck empfiehltEs würde mich doch sehr wundern, wenn er das so pauschal geschrieben hätte.
globale Definition:
my %AREA_CACHE; # Caching Storage, key → { G_tilt => ..., wcc => ... }
my %AREA_CACHE_STATS = ( # Cache Statistic
hits => 0,
misses => 0,
evicts => 0,
size => 0,
);
Dann:
sub ___computeTiltedIrradianceCached {
my $paref = shift;
my $name = $paref->{name};
my $fd = $paref->{fd}; # lfd. Tag-Index 0, 1, 2 ...
my $dday = $paref->{dday}; # abzufragender Tag: 01 .. 31
my $chour = $paref->{chour}; # aktuelle Stunde (00 .. 23)
my $hod = $paref->{hod}; # abzufragende Stunde des Tages 01, 02 ... 24
my $str_tilt = $paref->{tilt}; # String Anstellwinkel / Neigung
my $str_azi = $paref->{azimut}; # String Ausrichtung / Azimut
my $model = $paref->{model} // 0; # 0 - Berechnung mit isotropem Himmelsmodell, 1 - Berechnung nach Hay-Davies
my $b0 = $paref->{b0} // 0.05; # Materialfaktor für IAM, 0.05 .. 0.2
my $rad = $paref->{rad}; # Rad1h = Absolute Globalstrahlung letzte 1 Stunde, kJ/m2
my $dofyear = $paref->{dofyear}; # Tag des Jahres (001 - 366)
.........
.........
my $cache_key = join ':', # Cache‑Key erzeugen
$offset_hours,
$sunalt // 'U',
$sunaz // 'U',
$rad // 'U',
$str_tilt,
$str_azi,
$model,
$b0,
$dofyear;
# --- Cache-Treffer? ---
if (exists $AREA_CACHE{$cache_key}) {
$AREA_CACHE_STATS{hits}++;
return $AREA_CACHE{$cache_key};
}
my $sg = $rad * KJ2WH; # rad=kJ/m²h -> 1kJ = 0,27778 Wh
my $rho = 0.2; # Bodenalbedo
my $pi = 4 * atan2 (1,1); # klassischer Perl-Trick, um π (Pi) mathematisch exakt zu berechnen – ohne es als feste Zahl einzutragen
my $deg = $pi / 180.0;
my $Isc = 1367.0; # Solarkonstante W/m²
$AREA_CACHE_STATS{misses}++;
return 0 if(!defined($sg) || $sg <= 0);
my $sunaz_r = $sunaz * $deg;
my $sunalt_r = $sunalt * $deg;
my $azimut_r = $str_azi * $deg;
my $tilt_r = $str_tilt * $deg;
my $sin_ele = sin ($sunalt_r);
my $cos_ele = cos ($sunalt_r);
return 0 if($sin_ele <= 0.0);
my $I0n = $Isc * (1.0 + 0.033 * cos (2.0 * $pi * $dofyear / 365.0));
my $I0h = $I0n * $sin_ele;
return 0 if($I0h <= 0.0);
my $Kt = $sg / $I0h;
$Kt = max (0.0, min (1.0, $Kt)); # Kt (Clear-Sky-Index), Clamping wichtig
my $kd; # Diffusanteil kd nach Erbs-Polynom
if ($Kt <= 0.22) {
$kd = 1.0 - 0.09 * $Kt;
}
elsif ($Kt <= 0.80) {
$kd = 0.9511
- 0.1604 * $Kt
+ 4.388 * $Kt**2
- 16.638 * $Kt**3
+ 12.336 * $Kt**4;
}
else {
$kd = 0.165;
}
$kd = max (0.0, min (1.0, $kd));
my $sf = $kd * $sg; # diffuse horizontale Strahlung = DHI
my $si = $sg - $sf; # direkte horizontale Strahlung = BHI
$si = max (0.0, $si);
my $cos_thetai = $sin_ele * cos($tilt_r) # Einfallswinkel cos(θi)
+ $cos_ele * sin($tilt_r) * cos($sunaz_r - $azimut_r);
my $cos_thetai_pos = $cos_thetai;
$cos_thetai_pos = 0.0 if $cos_thetai_pos < 0.0;
my $dni = ($sin_ele > 0.01) ? ($si / $sin_ele) : 0.0; # DNI (Direct Normal Irradiance)
my $B_tilt = $dni * $cos_thetai_pos; # Direktstrahlung auf geneigte Fläche
$B_tilt = max (0.0, $B_tilt);
# --- IAM nur für Direktstrahlung (ASHRAE)
my $IAMb = 1.0;
if ($B_tilt > 0.0 && $cos_thetai_pos > 0.0) {
$IAMb = 1.0 - $b0 * (1.0 / $cos_thetai_pos - 1.0); # IAM (Incidence Angle Modifier)
$IAMb = max (0.0, min (1.0, $IAMb));
}
my $B_eff = $B_tilt * $IAMb;
my $D_tilt;
if ($model == 1) { # Diffusanteil auf geneigte Fläche, Modell 1 (Hay-Davies)
my $Ai = $sg > 0.0 ? (($si / $sg) * $Kt) : 0.0;
$Ai = max (0.0, $Ai);
$Ai = min (1.0, $Ai);
my $Rb = $sin_ele > 0.01 ? ($cos_thetai_pos / $sin_ele) : 0.0;
$Rb = max (0.0, $Rb);
$D_tilt = $sf * ($Ai * $Rb + (1.0 - $Ai) * (1.0 + cos($tilt_r)) / 2.0);
}
else {
$D_tilt = $sf * (1.0 + cos($tilt_r)) / 2.0; # Diffusanteil auf geneigte Fläche, Modell 0 (isotrop)
}
$D_tilt = max (0.0, $D_tilt);
my $R_tilt = $rho * $sg * (1.0 - cos($tilt_r)) / 2.0; # Bodenreflexion
$R_tilt = max (0.0, $R_tilt);
my $G_tilt = $B_eff + $D_tilt + $R_tilt; # Gesamteinstrahlung
$G_tilt = max (0.0, $G_tilt);
$G_tilt = round2 ($G_tilt);
$AREA_CACHE{$cache_key} = $G_tilt; # Berechnungsergebnis cachen
$AREA_CACHE_STATS{size} = scalar keys %AREA_CACHE;
return $G_tilt; # effektive Einstrahlung $G_tilt auf die PV-Anlage in W/m²
}
set ... reset pvCorrection cachedZitatNull Zeichen kann zwar theoretisch auch im Topic vorkommen, aber es wird mW nicht praktiziert.
Zitat von: Parallix am 10 April 2026, 11:07:55Kann mir jemand von Euch sagen, wer sich aktuell um das Modul kümmert?Anscheinend hat sich nach den frühem Ausstieg von @MiniBlister nur noch @MadMax (dankenswerterweise) mit der Weiterentwicklung befasst.
sub ReadingsValbyIndex($$$$)
{ my ($device,$reading,$readingindex, $default) = @_;
my $ret = (split(/,/,ReadingsVal($device,$reading,"-1")))[$readingindex];
if ($ret eq "")
{return $default}
else
{return $ret};
}reading02Name EPEX_price
{my ($s,$m,$h,$D,$M,$Y)=localtime();
reading02RecombineExpr if ($h % 2 == 1 and $m == 0) {fhem("get $name EPEX_prices")}; #reread list only every 2nd hour
ReadingsValbyIndex($name,"EPEX_prices",int($m/15)+4*$h,-999)}Zitat von: Dr. Boris Neubert am 10 April 2026, 21:13:54Danke für die Rückmeldung. Nutzt das jetzt kaum jemand oder haben die Nutzer nur keine Lust aufs Testen? Frag ich am falschen Ort?Ort ist m.E. OK.