2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-07 16:59:18 +00:00

76_Solarforcast: contrib 0.71.2

git-svn-id: https://svn.fhem.de/fhem/trunk@26605 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2022-10-28 07:57:31 +00:00
parent 6b7ff4d910
commit 2d944a08dc

View File

@ -1,5 +1,5 @@
######################################################################################################################## ########################################################################################################################
# $Id: 76_SolarForecast.pm 21735 2022-10-27 23:53:24Z DS_Starter $ # $Id: 76_SolarForecast.pm 21735 2022-10-28 23:53:24Z DS_Starter $
######################################################################################################################### #########################################################################################################################
# 76_SolarForecast.pm # 76_SolarForecast.pm
# #
@ -130,7 +130,7 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"0.71.2" => "27.10.2022 fix 'connection refused ...' ", "0.71.2" => "27.10.2022 fix 'connection lost ...' ",
"0.71.1" => "26.10.2022 save no datasets with pv_estimate = 0 (__solCast_ApiResponse) to save time/space ". "0.71.1" => "26.10.2022 save no datasets with pv_estimate = 0 (__solCast_ApiResponse) to save time/space ".
"changed some graphic default settings, typo todayRemaingAPIcalls, input check currentBatteryDev ". "changed some graphic default settings, typo todayRemaingAPIcalls, input check currentBatteryDev ".
"change attr Css to flowGraphicCss ", "change attr Css to flowGraphicCss ",
@ -575,8 +575,8 @@ my %htitles = (
DE => qq{Ein -> Verbraucher ausschalten} }, DE => qq{Ein -> Verbraucher ausschalten} },
iens => { EN => qq{On -> no off-command defined!}, iens => { EN => qq{On -> no off-command defined!},
DE => qq{Ein -> kein off-Kommando definiert!} }, DE => qq{Ein -> kein off-Kommando definiert!} },
upd => { EN => qq{Update}, upd => { EN => qq{Click for update},
DE => qq{Update} }, DE => qq{Klick für Update} },
on => { EN => qq{switched on}, on => { EN => qq{switched on},
DE => qq{eingeschaltet} }, DE => qq{eingeschaltet} },
off => { EN => qq{switched off}, off => { EN => qq{switched off},
@ -1935,6 +1935,7 @@ sub Get {
my $params = { my $params = {
hash => $hash, hash => $hash,
name => $name, name => $name,
type => $hash->{TYPE},
opt => $opt, opt => $opt,
arg => $arg arg => $arg
}; };
@ -2527,6 +2528,7 @@ sub Attr {
my $params = { my $params = {
hash => $hash, hash => $hash,
name => $name, name => $name,
type => $hash->{TYPE},
cmd => $cmd, cmd => $cmd,
aName => $aName, aName => $aName,
aVal => $aVal aVal => $aVal
@ -3001,7 +3003,7 @@ sub centralTask {
return if(IsDisabled($name)); return if(IsDisabled($name));
readingsSingleUpdate($hash, 'state', 'running', 0); readingsSingleUpdate($hash, 'state', 'running', 0); # vermeidet 'connection lost ...'
my $ret = createStringConfig ($hash); # die String Konfiguration erstellen my $ret = createStringConfig ($hash); # die String Konfiguration erstellen
if ($ret) { if ($ret) {
@ -3020,6 +3022,7 @@ sub centralTask {
my $centpars = { my $centpars = {
hash => $hash, hash => $hash,
name => $name, name => $name,
type => $type,
t => $t, t => $t,
date => $date, date => $date,
minute => $minute, minute => $minute,
@ -3039,7 +3042,7 @@ sub centralTask {
_specialActivities ($centpars); # zusätzliche Events generieren + Sonderaufgaben _specialActivities ($centpars); # zusätzliche Events generieren + Sonderaufgaben
_transferWeatherValues ($centpars); # Wetterwerte übertragen _transferWeatherValues ($centpars); # Wetterwerte übertragen
createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen
if (isSolCastUsed ($hash)) { if (isSolCastUsed ($hash)) {
_getRoofTopData ($centpars); # SolCast API Strahlungswerte abrufen _getRoofTopData ($centpars); # SolCast API Strahlungswerte abrufen
@ -3060,11 +3063,11 @@ sub centralTask {
_createSummaries ($centpars); # Zusammenfassungen erstellen _createSummaries ($centpars); # Zusammenfassungen erstellen
_calcTodayPVdeviation ($centpars); # Vorhersageabweichung erstellen (nach Sonnenuntergang) _calcTodayPVdeviation ($centpars); # Vorhersageabweichung erstellen (nach Sonnenuntergang)
createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen
calcCorrAndQuality ($centpars); # neue Korrekturfaktor/Qualität berechnen und speichern calcCorrAndQuality ($centpars); # neue Korrekturfaktor/Qualität berechnen und speichern
createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen
saveEnergyConsumption ($centpars); # Energie Hausverbrauch speichern saveEnergyConsumption ($centpars); # Energie Hausverbrauch speichern
@ -3073,7 +3076,7 @@ sub centralTask {
genStatisticReadings ($centpars); # optionale Statistikreadings erstellen genStatisticReadings ($centpars); # optionale Statistikreadings erstellen
createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen createReadingsFromArray ($hash, \@da, $evt); # Readings erzeugen
} }
else { else {
InternalTimer(gettimeofday()+5, "FHEM::SolarForecast::centralTask", $hash, 0); InternalTimer(gettimeofday()+5, "FHEM::SolarForecast::centralTask", $hash, 0);
@ -3201,14 +3204,13 @@ sub _specialActivities {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $date = $paref->{date}; # aktuelles Datum my $date = $paref->{date}; # aktuelles Datum
my $chour = $paref->{chour}; my $chour = $paref->{chour};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $t = $paref->{t}; # aktuelle Zeit my $t = $paref->{t}; # aktuelle Zeit
my $day = $paref->{day}; my $day = $paref->{day};
my $type = $hash->{TYPE};
my ($ts,$ts1,$pvfc,$pvrl,$gcon); my ($ts,$ts1,$pvfc,$pvrl,$gcon);
$ts1 = $date." ".sprintf("%02d",$chour).":00:00"; $ts1 = $date." ".sprintf("%02d",$chour).":00:00";
@ -3239,17 +3241,6 @@ sub _specialActivities {
$data{$type}{$name}{consumers}{$c}{onoff} = "off"; $data{$type}{$name}{consumers}{$c}{onoff} = "off";
} }
} }
## zusätzliche Events erzeugen - PV Vorhersage bis Ende des kommenden Tages
#############################################################################
for my $idx (sort keys %{$data{$type}{$name}{nexthours}}) {
my $nhts = NexthoursVal ($hash, $idx, "starttime", undef);
my $nhfc = NexthoursVal ($hash, $idx, "pvforecast", undef);
next if(!defined $nhts || !defined $nhfc);
my ($dt, $h) = $nhts =~ /([\w-]+)\s(\d{2})/xs;
push @$daref, "AllPVforecastsToEvent<>".$nhfc." Wh<>".$dt." ".$h.":59:59";
}
## bestimmte einmalige Aktionen ## bestimmte einmalige Aktionen
################################## ##################################
@ -3257,7 +3248,7 @@ sub _specialActivities {
my $tlim = "00"; my $tlim = "00";
if($chour =~ /^($tlim)$/x) { if($chour =~ /^($tlim)$/x) {
if(!exists $hash->{HELPER}{H00DONE}) { if(!exists $hash->{HELPER}{H00DONE}) {
$date = strftime "%Y-%m-%d", localtime($t-7200); # Vortag (2 h Differenz reichen aus) $date = strftime "%Y-%m-%d", localtime($t-7200); # Vortag (2 h Differenz reichen aus)
$ts = $date." 23:59:59"; $ts = $date." 23:59:59";
$pvfc = ReadingsNum($name, "Today_Hour24_PVforecast", 0); $pvfc = ReadingsNum($name, "Today_Hour24_PVforecast", 0);
@ -3307,7 +3298,8 @@ sub _specialActivities {
} }
writeDataToFile ($hash, "consumers", $csmcache.$name); # Cache File Consumer schreiben writeDataToFile ($hash, "consumers", $csmcache.$name); # Cache File Consumer schreiben
__createAdditionalEvents ($paref); # zusätzliche Events erzeugen - PV Vorhersage bis Ende des kommenden Tages
__delSolCastObsoleteData ($paref); # Bereinigung obsoleter Daten im solcastapi Hash __delSolCastObsoleteData ($paref); # Bereinigung obsoleter Daten im solcastapi Hash
$hash->{HELPER}{H00DONE} = 1; $hash->{HELPER}{H00DONE} = 1;
@ -3320,6 +3312,28 @@ sub _specialActivities {
return; return;
} }
#############################################################################
# zusätzliche Events erzeugen - PV Vorhersage bis Ende des kommenden Tages
#############################################################################
sub __createAdditionalEvents {
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
my $daref = $paref->{daref};
for my $idx (sort keys %{$data{$type}{$name}{nexthours}}) {
my $nhts = NexthoursVal ($hash, $idx, "starttime", undef);
my $nhfc = NexthoursVal ($hash, $idx, "pvforecast", undef);
next if(!defined $nhts || !defined $nhfc);
my ($dt, $h) = $nhts =~ /([\w-]+)\s(\d{2})/xs;
push @$daref, "AllPVforecastsToEvent<>".$nhfc." Wh<>".$dt." ".$h.":59:59";
}
return;
}
############################################################################# #############################################################################
# solcastapi Hash veraltete Daten löschen # solcastapi Hash veraltete Daten löschen
############################################################################# #############################################################################
@ -3327,10 +3341,9 @@ sub __delSolCastObsoleteData {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $date = $paref->{date}; # aktuelles Datum my $date = $paref->{date}; # aktuelles Datum
my $type = $hash->{TYPE};
if (!keys %{$data{$type}{$name}{solcastapi}}) { if (!keys %{$data{$type}{$name}{solcastapi}}) {
return; return;
} }
@ -3362,7 +3375,7 @@ sub _transferDWDRadiationValues {
my $raname = ReadingsVal($name, "currentRadiationDev", ""); # Radiation Forecast Device my $raname = ReadingsVal($name, "currentRadiationDev", ""); # Radiation Forecast Device
return if(!$raname || !$defs{$raname}); return if(!$raname || !$defs{$raname});
my $type = $hash->{TYPE}; my $type = $paref->{type};
my $err = checkdwdattr ($name,$raname,\@draattrmust); my $err = checkdwdattr ($name,$raname,\@draattrmust);
$paref->{state} = $err if($err); $paref->{state} = $err if($err);
@ -3389,6 +3402,7 @@ sub _transferDWDRadiationValues {
my $params = { my $params = {
hash => $hash, hash => $hash,
name => $name, name => $name,
type => $type,
rad => $rad, rad => $rad,
t => $t, t => $t,
hod => $hod, hod => $hod,
@ -3466,6 +3480,7 @@ sub __calcDWDforecast {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $rad = $paref->{rad}; # Nominale Strahlung aus DWD Device my $rad = $paref->{rad}; # Nominale Strahlung aus DWD Device
my $num = $paref->{num}; # Nexthour my $num = $paref->{num}; # Nexthour
my $t = $paref->{t}; # aktueller Unix Timestamp my $t = $paref->{t}; # aktueller Unix Timestamp
@ -3473,8 +3488,6 @@ sub __calcDWDforecast {
my $fh1 = $paref->{fh1}; my $fh1 = $paref->{fh1};
my $fd = $paref->{fd}; my $fd = $paref->{fd};
my $type = $hash->{TYPE};
my $stch = $data{$type}{$name}{strings}; # String Configuration Hash my $stch = $data{$type}{$name}{strings}; # String Configuration Hash
my $reld = $fd == 0 ? "today" : $fd == 1 ? "tomorrow" : "unknown"; my $reld = $fd == 0 ? "today" : $fd == 1 ? "tomorrow" : "unknown";
@ -3599,13 +3612,12 @@ sub ___readCorrfAndQuality {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $num = $paref->{num}; # Nexthour my $num = $paref->{num}; # Nexthour
my $fh1 = $paref->{fh1}; my $fh1 = $paref->{fh1};
my $fd = $paref->{fd}; my $fd = $paref->{fd};
my $range = $paref->{range}; my $range = $paref->{range};
my $type = $hash->{TYPE};
my $uac = ReadingsVal ($name, "pvCorrectionFactor_Auto", "off"); # Auto- oder manuelle Korrektur my $uac = ReadingsVal ($name, "pvCorrectionFactor_Auto", "off"); # Auto- oder manuelle Korrektur
my $pvcorr = ReadingsNum ($name, "pvCorrectionFactor_".sprintf("%02d",$fh1), 1.00); # PV Korrekturfaktor (auto oder manuell) my $pvcorr = ReadingsNum ($name, "pvCorrectionFactor_".sprintf("%02d",$fh1), 1.00); # PV Korrekturfaktor (auto oder manuell)
my $hc = $pvcorr; # Voreinstellung RAW-Korrekturfaktor my $hc = $pvcorr; # Voreinstellung RAW-Korrekturfaktor
@ -3647,13 +3659,12 @@ sub _transferSolCastRadiationValues {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $t = $paref->{t}; # Epoche Zeit my $t = $paref->{t}; # Epoche Zeit
my $chour = $paref->{chour}; my $chour = $paref->{chour};
my $date = $paref->{date}; my $date = $paref->{date};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $type = $hash->{TYPE};
return if(!keys %{$data{$type}{$name}{solcastapi}}); return if(!keys %{$data{$type}{$name}{solcastapi}});
my @strings = sort keys %{$data{$type}{$name}{strings}}; my @strings = sort keys %{$data{$type}{$name}{strings}};
@ -3678,6 +3689,7 @@ sub _transferSolCastRadiationValues {
my $params = { my $params = {
hash => $hash, hash => $hash,
name => $name, name => $name,
type => $type,
wantdt => $wantdt, wantdt => $wantdt,
hod => $hod, hod => $hod,
fh1 => $fh1, fh1 => $fh1,
@ -3723,13 +3735,12 @@ sub __calcSolCastEstimates {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $wantdt = $paref->{wantdt}; my $wantdt = $paref->{wantdt};
my $hod = $paref->{hod}; my $hod = $paref->{hod};
my $fd = $paref->{fd}; my $fd = $paref->{fd};
my $num = $paref->{num}; my $num = $paref->{num};
my $type = $hash->{TYPE};
my $reld = $fd == 0 ? "today" : $fd == 1 ? "tomorrow" : "unknown"; my $reld = $fd == 0 ? "today" : $fd == 1 ? "tomorrow" : "unknown";
my $clouddamp = AttrVal($name, "cloudFactorDamping", $cldampdef); # prozentuale Berücksichtigung des Bewölkungskorrekturfaktors my $clouddamp = AttrVal($name, "cloudFactorDamping", $cldampdef); # prozentuale Berücksichtigung des Bewölkungskorrekturfaktors
@ -3854,12 +3865,11 @@ sub ___readPercAndQuality {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $num = $paref->{num}; # Nexthour my $num = $paref->{num}; # Nexthour
my $fh1 = $paref->{fh1}; my $fh1 = $paref->{fh1};
my $fd = $paref->{fd}; my $fd = $paref->{fd};
my $type = $hash->{TYPE};
my $uac = ReadingsVal ($name, "pvCorrectionFactor_Auto", "off"); # Auto- oder manuelle Korrektur my $uac = ReadingsVal ($name, "pvCorrectionFactor_Auto", "off"); # Auto- oder manuelle Korrektur
my $perc = ReadingsNum ($name, "pvSolCastPercentile_".sprintf("%02d",$fh1), 50); # Estimate Percentil my $perc = ReadingsNum ($name, "pvSolCastPercentile_".sprintf("%02d",$fh1), 50); # Estimate Percentil
my $hcfound = "use manual percentile selection"; my $hcfound = "use manual percentile selection";
@ -3956,11 +3966,10 @@ sub _calcMaxEstimateToday {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $date = $paref->{date}; my $date = $paref->{date};
my $type = $hash->{TYPE};
my $maxest = 0; my $maxest = 0;
my $maxtim = '-'; my $maxtim = '-';
@ -3997,7 +4006,7 @@ sub _transferInverterValues {
$indev = $a->[0] // ""; $indev = $a->[0] // "";
return if(!$indev || !$defs{$indev}); return if(!$indev || !$defs{$indev});
my $type = $hash->{TYPE}; my $type = $paref->{type};
my ($pvread,$pvunit) = split ":", $h->{pv}; # Readingname/Unit für aktuelle PV Erzeugung my ($pvread,$pvunit) = split ":", $h->{pv}; # Readingname/Unit für aktuelle PV Erzeugung
my ($edread,$etunit) = split ":", $h->{etotal}; # Readingname/Unit für Energie total (PV Erzeugung) my ($edread,$etunit) = split ":", $h->{etotal}; # Readingname/Unit für Energie total (PV Erzeugung)
@ -4075,7 +4084,7 @@ sub _transferWeatherValues {
my $err = checkdwdattr ($name,$fcname,\@dweattrmust); my $err = checkdwdattr ($name,$fcname,\@dweattrmust);
$paref->{state} = $err if($err); $paref->{state} = $err if($err);
my $type = $hash->{TYPE}; my $type = $paref->{type};
my ($time_str); my ($time_str);
my $fc0_SunRise = ReadingsVal($fcname, "fc0_SunRise", "00:00"); # Sonnenaufgang heute my $fc0_SunRise = ReadingsVal($fcname, "fc0_SunRise", "00:00"); # Sonnenaufgang heute
@ -4176,7 +4185,7 @@ sub _transferMeterValues {
$medev = $a->[0] // ""; $medev = $a->[0] // "";
return if(!$medev || !$defs{$medev}); return if(!$medev || !$defs{$medev});
my $type = $hash->{TYPE}; my $type = $paref->{type};
my ($gc,$gcunit) = split ":", $h->{gcon}; # Readingname/Unit für aktuellen Netzbezug my ($gc,$gcunit) = split ":", $h->{gcon}; # Readingname/Unit für aktuellen Netzbezug
my ($gf,$gfunit) = split ":", $h->{gfeedin}; # Readingname/Unit für aktuelle Netzeinspeisung my ($gf,$gfunit) = split ":", $h->{gfeedin}; # Readingname/Unit für aktuelle Netzeinspeisung
@ -4320,13 +4329,12 @@ sub _manageConsumerData {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $t = $paref->{t}; # aktuelle Zeit my $t = $paref->{t}; # aktuelle Zeit
my $date = $paref->{date}; # aktuelles Datum my $date = $paref->{date}; # aktuelles Datum
my $chour = $paref->{chour}; my $chour = $paref->{chour};
my $day = $paref->{day}; my $day = $paref->{day};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $type = $hash->{TYPE};
my $nhour = $chour+1; my $nhour = $chour+1;
$paref->{nhour} = sprintf("%02d",$nhour); $paref->{nhour} = sprintf("%02d",$nhour);
@ -4505,9 +4513,8 @@ sub __calcEnergyPieces {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $c = $paref->{consumer}; my $type = $paref->{type};
my $c = $paref->{consumer};
my $type = $hash->{TYPE};
my $etot = HistoryVal ($hash, $paref->{day}, sprintf("%02d",$paref->{nhour}), "csmt${c}", 0); my $etot = HistoryVal ($hash, $paref->{day}, sprintf("%02d",$paref->{nhour}), "csmt${c}", 0);
@ -4581,11 +4588,10 @@ sub ___csmSpecificEpieces {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $etot = $paref->{etot}; my $etot = $paref->{etot};
my $t = $paref->{t}; my $t = $paref->{t};
my $type = $hash->{TYPE};
if(ConsumerVal ($hash, $c, "onoff", "off") eq "on") { # Status "Aus" verzögern um Pausen im Waschprogramm zu überbrücken if(ConsumerVal ($hash, $c, "onoff", "off") eq "on") { # Status "Aus" verzögern um Pausen im Waschprogramm zu überbrücken
$data{$type}{$name}{consumers}{$c}{lastOnTime} = $t; $data{$type}{$name}{consumers}{$c}{lastOnTime} = $t;
@ -4677,7 +4683,7 @@ sub __planSwitchTimes {
return if(ConsumerVal ($hash, $c, "planstate", undef)); # Verbraucher ist schon geplant/gestartet/fertig return if(ConsumerVal ($hash, $c, "planstate", undef)); # Verbraucher ist schon geplant/gestartet/fertig
my $type = $hash->{TYPE}; my $type = $paref->{type};
my $debug = AttrVal ($name, "debug", 0); my $debug = AttrVal ($name, "debug", 0);
my $nh = $data{$type}{$name}{nexthours}; my $nh = $data{$type}{$name}{nexthours};
@ -4821,14 +4827,13 @@ sub ___planMust {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $maxref = $paref->{maxref}; my $maxref = $paref->{maxref};
my $elem = $paref->{elem}; my $elem = $paref->{elem};
my $mintime = $paref->{mintime}; my $mintime = $paref->{mintime};
my $stopdiff = $paref->{stopdiff}; my $stopdiff = $paref->{stopdiff};
my $type = $hash->{TYPE};
my $maxts = timestringToTimestamp ($maxref->{$elem}{starttime}); # Unix Timestamp des max. Überschusses heute my $maxts = timestringToTimestamp ($maxref->{$elem}{starttime}); # Unix Timestamp des max. Überschusses heute
my $half = ceil ($mintime / 2 / 60); # die halbe Gesamtlaufzeit in h als Vorlaufzeit einkalkulieren my $half = ceil ($mintime / 2 / 60); # die halbe Gesamtlaufzeit in h als Vorlaufzeit einkalkulieren
my $startts = $maxts - ($half * 3600); my $startts = $maxts - ($half * 3600);
@ -4861,14 +4866,13 @@ return;
sub ___setConsumerPlanningState { sub ___setConsumerPlanningState {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $ps = $paref->{ps}; # Planstatus my $ps = $paref->{ps}; # Planstatus
my $startts = $paref->{startts}; # Unix Timestamp für geplanten Switch on my $startts = $paref->{startts}; # Unix Timestamp für geplanten Switch on
my $stopts = $paref->{stopts}; # Unix Timestamp für geplanten Switch off my $stopts = $paref->{stopts}; # Unix Timestamp für geplanten Switch off
my $type = $hash->{TYPE};
my $name = $hash->{NAME};
my ($starttime,$stoptime); my ($starttime,$stoptime);
if ($startts) { if ($startts) {
@ -4937,9 +4941,8 @@ sub ___setPlanningDeleteMeth {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $type = $hash->{TYPE};
my $sonkey = ConsumerVal ($hash, $c, "planswitchon", ""); my $sonkey = ConsumerVal ($hash, $c, "planswitchon", "");
my $soffkey = ConsumerVal ($hash, $c, "planswitchoff", ""); my $soffkey = ConsumerVal ($hash, $c, "planswitchoff", "");
@ -4966,10 +4969,9 @@ sub __setTimeframeState {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $t = $paref->{t}; # aktueller Unixtimestamp my $t = $paref->{t}; # aktueller Unixtimestamp
my $type = $hash->{TYPE};
my $startts = ConsumerVal ($hash, $c, "planswitchon", undef); # geplante Unix Startzeit my $startts = ConsumerVal ($hash, $c, "planswitchon", undef); # geplante Unix Startzeit
my $stopts = ConsumerVal ($hash, $c, "planswitchoff", undef); # geplante Unix Stopzeit my $stopts = ConsumerVal ($hash, $c, "planswitchoff", undef); # geplante Unix Stopzeit
@ -4991,10 +4993,9 @@ sub __setConsRcmdState {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; # aktueller Unixtimestamp my $c = $paref->{consumer}; # aktueller Unixtimestamp
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $type = $hash->{TYPE};
my $surplus = CurrentVal ($hash, "surplus", 0); # aktueller Energieüberschuß my $surplus = CurrentVal ($hash, "surplus", 0); # aktueller Energieüberschuß
my $nompower = ConsumerVal ($hash, $c, "power", 0); # Consumer nominale Leistungsaufnahme (W) my $nompower = ConsumerVal ($hash, $c, "power", 0); # Consumer nominale Leistungsaufnahme (W)
@ -5022,12 +5023,11 @@ sub __switchConsumer {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $t = $paref->{t}; # aktueller Unixtimestamp my $t = $paref->{t}; # aktueller Unixtimestamp
my $state = $paref->{state}; my $state = $paref->{state};
my $type = $hash->{TYPE};
$state = ___switchConsumerOn ($paref); # Verbraucher Einschaltbedingung prüfen + auslösen $state = ___switchConsumerOn ($paref); # Verbraucher Einschaltbedingung prüfen + auslösen
$state = ___switchConsumerOff ($paref); # Verbraucher Ausschaltbedingung prüfen + auslösen $state = ___switchConsumerOff ($paref); # Verbraucher Ausschaltbedingung prüfen + auslösen
$state = ___setConsumerSwitchingState ($paref); # Consumer aktuelle Schaltzustände ermitteln & setzen $state = ___setConsumerSwitchingState ($paref); # Consumer aktuelle Schaltzustände ermitteln & setzen
@ -5217,13 +5217,12 @@ return $state;
sub ___setConsumerSwitchingState { sub ___setConsumerSwitchingState {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $t = $paref->{t}; my $t = $paref->{t};
my $state = $paref->{state}; my $state = $paref->{state};
my $type = $hash->{TYPE};
my $name = $hash->{NAME};
my $pstate = simplifyCstate (ConsumerVal ($hash, $c, "planstate", "")); my $pstate = simplifyCstate (ConsumerVal ($hash, $c, "planstate", ""));
my $calias = ConsumerVal ($hash, $c, "alias", ""); # Consumer Device Alias my $calias = ConsumerVal ($hash, $c, "alias", ""); # Consumer Device Alias
my $auto = ConsumerVal ($hash, $c, "auto", 1); my $auto = ConsumerVal ($hash, $c, "auto", 1);
@ -5299,11 +5298,10 @@ sub __remainConsumerTime {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $t = $paref->{t}; # aktueller Unixtimestamp my $t = $paref->{t}; # aktueller Unixtimestamp
my $type = $hash->{TYPE};
my ($planstate,$startstr,$stoptstr) = __getPlanningStateAndTimes ($paref); my ($planstate,$startstr,$stoptstr) = __getPlanningStateAndTimes ($paref);
my $stopts = ConsumerVal ($hash, $c, "planswitchoff", undef); # geplante Unix Stopzeit my $stopts = ConsumerVal ($hash, $c, "planswitchoff", undef); # geplante Unix Stopzeit
@ -5376,7 +5374,7 @@ sub _transferBatteryValues {
my ($badev,$a,$h) = useBattery ($name); my ($badev,$a,$h) = useBattery ($name);
return if(!$badev); return if(!$badev);
my $type = $hash->{TYPE}; my $type = $paref->{type};
my ($pin,$piunit) = split ":", $h->{pin}; # Readingname/Unit für aktuelle Batterieladung my ($pin,$piunit) = split ":", $h->{pin}; # Readingname/Unit für aktuelle Batterieladung
my ($pou,$pounit) = split ":", $h->{pout}; # Readingname/Unit für aktuelle Batterieentladung my ($pou,$pounit) = split ":", $h->{pout}; # Readingname/Unit für aktuelle Batterieentladung
@ -5529,8 +5527,7 @@ sub _estConsumptionForecast {
$medev = $am->[0] // ""; $medev = $am->[0] // "";
return if(!$medev || !$defs{$medev}); return if(!$medev || !$defs{$medev});
my $type = $hash->{TYPE}; my $type = $paref->{type};
my $acref = $data{$type}{$name}{consumers}; my $acref = $data{$type}{$name}{consumers};
## Verbrauchsvorhersage für den nächsten Tag ## Verbrauchsvorhersage für den nächsten Tag
@ -5737,10 +5734,9 @@ sub _calcReadingsTomorrowPVFc {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $type = $hash->{TYPE};
my $h = $data{$type}{$name}{nexthours}; my $h = $data{$type}{$name}{nexthours};
my $hods = AttrVal($name, 'createTomorrowPVFcReadings', ''); my $hods = AttrVal($name, 'createTomorrowPVFcReadings', '');
return if(!keys %{$h} || !$hods); return if(!keys %{$h} || !$hods);
@ -5770,11 +5766,11 @@ sub _createSummaries {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $chour = $paref->{chour}; # aktuelle Stunde my $chour = $paref->{chour}; # aktuelle Stunde
my $minute = $paref->{minute}; # aktuelle Minute my $minute = $paref->{minute}; # aktuelle Minute
my $type = $hash->{TYPE};
$minute = (int $minute) + 1; # Minute Range umsetzen auf 1 bis 60 $minute = (int $minute) + 1; # Minute Range umsetzen auf 1 bis 60
## Initialisierung ## Initialisierung
@ -6022,9 +6018,8 @@ return;
sub collectAllRegConsumers { sub collectAllRegConsumers {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $type = $hash->{TYPE};
delete $data{$type}{$name}{current}{consumerdevs}; delete $data{$type}{$name}{current}{consumerdevs};
@ -6219,6 +6214,7 @@ sub entryGraphic {
my $paref = { my $paref = {
hash => $hash, hash => $hash,
name => $name, name => $name,
type => $hash->{TYPE},
ftui => $ftui, ftui => $ftui,
maxhours => $maxhours, maxhours => $maxhours,
modulo => 1, modulo => 1,
@ -6699,10 +6695,9 @@ sub _showConsumerInGraphicBeam {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $hfcg = $paref->{hfcg}; my $hfcg = $paref->{hfcg};
my $type = $hash->{TYPE};
# get consumer list and display it in Graphics # get consumer list and display it in Graphics
################################################ ################################################
my @consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln my @consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln
@ -6768,7 +6763,7 @@ sub _graphicConsumerLegend {
my $name = $paref->{name}; # Consumer AdviceIcon my $name = $paref->{name}; # Consumer AdviceIcon
my ($clegendstyle, $clegend) = split('_', $paref->{clegend}); my ($clegendstyle, $clegend) = split('_', $paref->{clegend});
my $type = $hash->{TYPE}; my $type = $paref->{type};
my @consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln my @consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln
$clegend = '' if(($clegendstyle eq 'none') || (!int(@consumers))); $clegend = '' if(($clegendstyle eq 'none') || (!int(@consumers)));
@ -7643,7 +7638,7 @@ END0
my @consumers; my @consumers;
if ($flowgcons) { if ($flowgcons) {
my $type = $hash->{TYPE}; my $type = $paref->{type};
@consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln @consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln
$consumercount = scalar @consumers; $consumercount = scalar @consumers;
@ -8099,7 +8094,7 @@ sub _calcCAQfromDWDcloudcover {
} }
if(defined $range) { if(defined $range) {
my $type = $hash->{TYPE}; my $type = $paref->{type};
Log3 ($name, 5, "$name - write correction factor into circular Hash: Factor $factor, Hour $h, Range $range"); Log3 ($name, 5, "$name - write correction factor into circular Hash: Factor $factor, Hour $h, Range $range");
@ -8123,17 +8118,16 @@ return;
################################################################ ################################################################
sub __avgCloudcoverCorrFromHistory { sub __avgCloudcoverCorrFromHistory {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
my $hour = $paref->{hour}; # Stunde des Tages für die der Durchschnitt bestimmt werden soll my $hour = $paref->{hour}; # Stunde des Tages für die der Durchschnitt bestimmt werden soll
my $day = $paref->{day}; # aktueller Tag my $day = $paref->{day}; # aktueller Tag
$hour = sprintf("%02d",$hour); $hour = sprintf("%02d",$hour);
my $name = $hash->{NAME};
my $type = $hash->{TYPE};
my $pvhh = $data{$type}{$name}{pvhist}; my $pvhh = $data{$type}{$name}{pvhist};
my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr numHistDays gesetzt ? und welcher Wert my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr numHistDays gesetzt ? und welcher Wert
my @k = sort {$a<=>$b} keys %{$pvhh}; my @k = sort {$a<=>$b} keys %{$pvhh};
my $ile = $#k; # Index letztes Arrayelement my $ile = $#k; # Index letztes Arrayelement
@ -8367,7 +8361,7 @@ sub _calcCAQwithSolCastPercentil {
Log3 ($name, 5, "$name - write percentile into circular Hash: $perc, Hour $h"); Log3 ($name, 5, "$name - write percentile into circular Hash: $perc, Hour $h");
my $type = $hash->{TYPE}; my $type = $paref->{type};
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{percentile} = $perc; # bestes Percentil für die jeweilige Stunde speichern $data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{percentile} = $perc; # bestes Percentil für die jeweilige Stunde speichern
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{percentile} = $dnum; # Percentil Qualität $data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{percentile} = $dnum; # Percentil Qualität
@ -8385,14 +8379,13 @@ return;
################################################################ ################################################################
sub __avgSolCastPercFromHistory { sub __avgSolCastPercFromHistory {
my $paref = shift; my $paref = shift;
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
my $hour = $paref->{hour}; # Stunde des Tages für die der Durchschnitt bestimmt werden soll my $hour = $paref->{hour}; # Stunde des Tages für die der Durchschnitt bestimmt werden soll
my $day = $paref->{day}; # aktueller Tag my $day = $paref->{day}; # aktueller Tag
$hour = sprintf("%02d",$hour); $hour = sprintf("%02d",$hour);
my $name = $hash->{NAME};
my $type = $hash->{TYPE};
my $pvhh = $data{$type}{$name}{pvhist}; my $pvhh = $data{$type}{$name}{pvhist};
my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr numHistDays gesetzt ? und welcher Wert my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr numHistDays gesetzt ? und welcher Wert