mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-02 00:48:53 +00:00
76_SolarForecast: contrib 0.82.1
git-svn-id: https://svn.fhem.de/fhem/trunk@27939 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
8a8048818f
commit
6bef274ea9
@ -140,6 +140,7 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"0.82.1" => "08.09.2023 rebuild implementation of DWD AI support ",
|
||||||
"0.82.0" => "02.09.2023 first implementation of DWD AI support, new ctrlDebug aiProcess aiData, reset aiData ",
|
"0.82.0" => "02.09.2023 first implementation of DWD AI support, new ctrlDebug aiProcess aiData, reset aiData ",
|
||||||
"0.81.1" => "30.08.2023 show forecast qualities when pressing quality icon in forecast grafic, store rad1h (model DWD) in ".
|
"0.81.1" => "30.08.2023 show forecast qualities when pressing quality icon in forecast grafic, store rad1h (model DWD) in ".
|
||||||
"pvhistory, removed: affectCloudfactorDamping, affectRainfactorDamping ",
|
"pvhistory, removed: affectCloudfactorDamping, affectRainfactorDamping ",
|
||||||
@ -414,7 +415,8 @@ my $pvccache = $attr{global}{modpath}."/FHEM/FhemUtils/PVC_SolarForecast_"
|
|||||||
my $plantcfg = $attr{global}{modpath}."/FHEM/FhemUtils/PVCfg_SolarForecast_"; # Filename-Fragment für PV Anlagenkonfiguration (wird mit Devicename ergänzt)
|
my $plantcfg = $attr{global}{modpath}."/FHEM/FhemUtils/PVCfg_SolarForecast_"; # Filename-Fragment für PV Anlagenkonfiguration (wird mit Devicename ergänzt)
|
||||||
my $csmcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVCsm_SolarForecast_"; # Filename-Fragment für Consumer Status (wird mit Devicename ergänzt)
|
my $csmcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVCsm_SolarForecast_"; # Filename-Fragment für Consumer Status (wird mit Devicename ergänzt)
|
||||||
my $scpicache = $attr{global}{modpath}."/FHEM/FhemUtils/ScApi_SolarForecast_"; # Filename-Fragment für Werte aus SolCast API (wird mit Devicename ergänzt)
|
my $scpicache = $attr{global}{modpath}."/FHEM/FhemUtils/ScApi_SolarForecast_"; # Filename-Fragment für Werte aus SolCast API (wird mit Devicename ergänzt)
|
||||||
my $aicache = $attr{global}{modpath}."/FHEM/FhemUtils/AI_SolarForecast_"; # Filename-Fragment für AI Trainingsdaten (wird mit Devicename ergänzt)
|
my $aitrained = $attr{global}{modpath}."/FHEM/FhemUtils/AItra_SolarForecast_"; # Filename-Fragment für AI Trainingsdaten (wird mit Devicename ergänzt)
|
||||||
|
my $airaw = $attr{global}{modpath}."/FHEM/FhemUtils/AIraw_SolarForecast_"; # Filename-Fragment für AI Input Daten = Raw Trainigsdaten
|
||||||
|
|
||||||
my $calcmaxd = 30; # Anzahl Tage die zur Berechnung Vorhersagekorrektur verwendet werden
|
my $calcmaxd = 30; # Anzahl Tage die zur Berechnung Vorhersagekorrektur verwendet werden
|
||||||
my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des Weather-DWD_Opendata Devices mindestens gesetzt sein müssen
|
my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des Weather-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||||
@ -552,6 +554,7 @@ my %hget = ( # Ha
|
|||||||
nextHours => { fn => \&_getlistNextHours, needcred => 0 },
|
nextHours => { fn => \&_getlistNextHours, needcred => 0 },
|
||||||
rooftopData => { fn => \&_getRoofTopData, needcred => 0 },
|
rooftopData => { fn => \&_getRoofTopData, needcred => 0 },
|
||||||
solApiData => { fn => \&_getlistSolCastData, needcred => 0 },
|
solApiData => { fn => \&_getlistSolCastData, needcred => 0 },
|
||||||
|
valDecTree => { fn => \&_getaiDecTree, needcred => 0 },
|
||||||
);
|
);
|
||||||
|
|
||||||
my %hattr = ( # Hash für Attr-Funktion
|
my %hattr = ( # Hash für Attr-Funktion
|
||||||
@ -912,7 +915,9 @@ my %hcsr = (
|
|||||||
# $data{$type}{$name}{consumers} # Consumer Hash
|
# $data{$type}{$name}{consumers} # Consumer Hash
|
||||||
# $data{$type}{$name}{strings} # Stringkonfiguration Hash
|
# $data{$type}{$name}{strings} # Stringkonfiguration Hash
|
||||||
# $data{$type}{$name}{solcastapi} # Zwischenspeicher API-Daten
|
# $data{$type}{$name}{solcastapi} # Zwischenspeicher API-Daten
|
||||||
# $data{$type}{$name}{aidectree} # AI Decision Tree Daten
|
# $data{$type}{$name}{aidectree}{object} # AI Decision Tree Object
|
||||||
|
# $data{$type}{$name}{aidectree}{aitrained} # AI Decision Tree trainierte Daten
|
||||||
|
# $data{$type}{$name}{aidectree}{airaw} # Rohdaten für AI Input = Raw Trainigsdaten
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Init Fn
|
# Init Fn
|
||||||
@ -1102,8 +1107,8 @@ sub Define {
|
|||||||
$params->{cachename} = 'solcastapi';
|
$params->{cachename} = 'solcastapi';
|
||||||
_readCacheFile ($params);
|
_readCacheFile ($params);
|
||||||
|
|
||||||
$params->{file} = $aicache.$name; # AI Cache File einlesen wenn vorhanden
|
$params->{file} = $aitrained.$name; # AI Cache File einlesen wenn vorhanden
|
||||||
$params->{cachename} = 'aidectree';
|
$params->{cachename} = 'aitrained';
|
||||||
_readCacheFile ($params);
|
_readCacheFile ($params);
|
||||||
|
|
||||||
singleUpdateState ( {hash => $hash, state => 'initialized', evt => 1} );
|
singleUpdateState ( {hash => $hash, state => 'initialized', evt => 1} );
|
||||||
@ -1125,7 +1130,7 @@ sub _readCacheFile {
|
|||||||
my $file = $paref->{file};
|
my $file = $paref->{file};
|
||||||
my $cachename = $paref->{cachename};
|
my $cachename = $paref->{cachename};
|
||||||
|
|
||||||
if ($cachename eq 'aidectree') {
|
if ($cachename eq 'aitrained') {
|
||||||
my ($err, $dtree) = fileRetrieve ($file);
|
my ($err, $dtree) = fileRetrieve ($file);
|
||||||
|
|
||||||
if (!$err && $dtree) {
|
if (!$err && $dtree) {
|
||||||
@ -1133,8 +1138,8 @@ sub _readCacheFile {
|
|||||||
my $valid = isa_ok($dtree, 'AI::DecisionTree');
|
my $valid = isa_ok($dtree, 'AI::DecisionTree');
|
||||||
|
|
||||||
if ($valid == 1) {
|
if ($valid == 1) {
|
||||||
$data{$type}{$name}{$cachename} = $dtree;
|
$data{$type}{$name}{aidectree}{aitrained} = $dtree;
|
||||||
$data{$type}{$name}{current}{aiinitstate} = 'ok';
|
$data{$type}{$name}{current}{aitrainstate} = 'ok';
|
||||||
Log3($name, 3, qq{$name - cached data "$cachename" restored});
|
Log3($name, 3, qq{$name - cached data "$cachename" restored});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1262,9 +1267,9 @@ sub Set {
|
|||||||
##########################
|
##########################
|
||||||
my $aiist = CurrentVal ($hash, 'aiinitstate', '');
|
my $aiist = CurrentVal ($hash, 'aiinitstate', '');
|
||||||
|
|
||||||
if ($aiist eq 'ok') {
|
#if ($aiist eq 'ok') {
|
||||||
$setlist .= "aiDecTree:addInstances,train ";
|
$setlist .= "aiDecTree:addInstances,addRawData,train ";
|
||||||
}
|
#}
|
||||||
|
|
||||||
my $params = {
|
my $params = {
|
||||||
hash => $hash,
|
hash => $hash,
|
||||||
@ -2077,17 +2082,15 @@ sub _setreset { ## no critic "not used"
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($prop eq 'aiData') {
|
if($prop eq 'aiData') {
|
||||||
my $err;
|
delete $data{$type}{$name}{current}{aiinitstate};
|
||||||
my $dtree = AiDetreeVal ($hash, undef);
|
|
||||||
|
|
||||||
if ($dtree) {
|
|
||||||
delete $data{$type}{$name}{aidectree};
|
|
||||||
($err, $dtree) = aiInit ($paref);
|
|
||||||
return $err if($err);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete $data{$type}{$name}{current}{aitrainstate};
|
delete $data{$type}{$name}{current}{aitrainstate};
|
||||||
delete $data{$type}{$name}{current}{aiaddistate};
|
delete $data{$type}{$name}{current}{aiaddistate};
|
||||||
|
delete $data{$type}{$name}{current}{aigetresult};
|
||||||
|
#my $dtree = AiDetreeVal ($hash, 'object', undef);
|
||||||
|
|
||||||
|
#if ($dtree) {
|
||||||
|
aiInit ($paref);
|
||||||
|
#}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2289,6 +2292,10 @@ sub _setaiDecTree { ## no critic "not used"
|
|||||||
aiAddInstance ($paref);
|
aiAddInstance ($paref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($prop eq 'addRawData') {
|
||||||
|
aiAddRawData ($paref);
|
||||||
|
}
|
||||||
|
|
||||||
if($prop eq 'train') {
|
if($prop eq 'train') {
|
||||||
aiTrain ($paref);
|
aiTrain ($paref);
|
||||||
}
|
}
|
||||||
@ -2343,6 +2350,14 @@ sub Get {
|
|||||||
"valCurrent:noArg "
|
"valCurrent:noArg "
|
||||||
;
|
;
|
||||||
|
|
||||||
|
## KI spezifische Getter
|
||||||
|
##########################
|
||||||
|
my $aiist = CurrentVal ($hash, 'aiinitstate', '');
|
||||||
|
|
||||||
|
if ($aiist eq 'ok') {
|
||||||
|
$getlist .= "valDecTree:aiRawData ";
|
||||||
|
}
|
||||||
|
|
||||||
return if(IsDisabled($name));
|
return if(IsDisabled($name));
|
||||||
|
|
||||||
my $params = {
|
my $params = {
|
||||||
@ -3804,6 +3819,24 @@ sub _getlistSolCastData {
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
# Getter aiDecTree
|
||||||
|
###############################################################
|
||||||
|
sub _getaiDecTree { ## no critic "not used"
|
||||||
|
my $paref = shift;
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $arg = $paref->{arg} // return;
|
||||||
|
|
||||||
|
my $ret;
|
||||||
|
|
||||||
|
if($arg eq 'aiRawData') {
|
||||||
|
$ret = listDataPool ($hash, 'aiRawData');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
sub Attr {
|
sub Attr {
|
||||||
my $cmd = shift;
|
my $cmd = shift;
|
||||||
@ -4194,7 +4227,7 @@ sub Shutdown {
|
|||||||
writeCacheToFile ($hash, "solcastapi", $scpicache.$name); # Cache File SolCast API Werte schreiben
|
writeCacheToFile ($hash, "solcastapi", $scpicache.$name); # Cache File SolCast API Werte schreiben
|
||||||
|
|
||||||
if (CurrentVal ($hash, 'aitrainstate', '') eq 'ok') {
|
if (CurrentVal ($hash, 'aitrainstate', '') eq 'ok') {
|
||||||
writeCacheToFile ($hash, "aidectree", $aicache.$name); # AI Cache schreiben
|
writeCacheToFile ($hash, "aidectree", $aitrained.$name); # AI Cache schreiben
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -4238,7 +4271,7 @@ sub Delete {
|
|||||||
$plantcfg.$name,
|
$plantcfg.$name,
|
||||||
$csmcache.$name,
|
$csmcache.$name,
|
||||||
$scpicache.$name,
|
$scpicache.$name,
|
||||||
$aicache.$name
|
$aitrained.$name
|
||||||
);
|
);
|
||||||
|
|
||||||
for my $f (@ftd) {
|
for my $f (@ftd) {
|
||||||
@ -4284,10 +4317,10 @@ sub writeCacheToFile {
|
|||||||
my @data;
|
my @data;
|
||||||
my ($error, $err, $lw);
|
my ($error, $err, $lw);
|
||||||
|
|
||||||
if ($cachename eq 'aidectree') {
|
if ($cachename eq 'aitrained') {
|
||||||
return if(ref $data{$type}{$name}{$cachename} ne 'AI::DecisionTree');
|
my $dtree = AiDetreeVal ($hash, 'aitrained', '');
|
||||||
|
return if(ref $dtree ne 'AI::DecisionTree');
|
||||||
|
|
||||||
my $dtree = $data{$type}{$name}{$cachename};
|
|
||||||
$error = fileStore ($dtree, $file);
|
$error = fileStore ($dtree, $file);
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
@ -4303,6 +4336,26 @@ sub writeCacheToFile {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($cachename eq 'airaw') {
|
||||||
|
my $data = AiRawdataVal ($hash, '', '', '');
|
||||||
|
|
||||||
|
if ($data) {
|
||||||
|
$error = fileStore ($data, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
$err = qq{ERROR while writing AI data to file "$file": $error};
|
||||||
|
Log3 ($name, 1, "$name - $err");
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lw = gettimeofday();
|
||||||
|
$hash->{LCACHEFILE} = "last write time: ".FmtTime($lw)." File: $file";
|
||||||
|
singleUpdateState ( {hash => $hash, state => "wrote cachefile $cachename successfully", evt => 1} );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ($cachename eq 'plantconfig') {
|
if ($cachename eq 'plantconfig') {
|
||||||
@data = _savePlantConfig ($hash);
|
@data = _savePlantConfig ($hash);
|
||||||
return 'Plant configuration is empty, no data where written' if(!@data);
|
return 'Plant configuration is empty, no data where written' if(!@data);
|
||||||
@ -10245,6 +10298,7 @@ sub _addHourAiInstance {
|
|||||||
$paref->{rho} = $rho;
|
$paref->{rho} = $rho;
|
||||||
|
|
||||||
aiAddInstance ($paref); # AI Instanz hinzufügen
|
aiAddInstance ($paref); # AI Instanz hinzufügen
|
||||||
|
aiAddRawData ($paref);
|
||||||
|
|
||||||
delete $paref->{ood};
|
delete $paref->{ood};
|
||||||
delete $paref->{rho};
|
delete $paref->{rho};
|
||||||
@ -10502,16 +10556,18 @@ sub aiAddInstance { ## no critic "not used"
|
|||||||
return if(!isDWDUsed ($hash));
|
return if(!isDWDUsed ($hash));
|
||||||
|
|
||||||
my $err;
|
my $err;
|
||||||
my $dtree = AiDetreeVal ($hash, undef);
|
my $dtree = AiDetreeVal ($hash, 'object', undef);
|
||||||
|
|
||||||
if (!$dtree) {
|
if (!$dtree) {
|
||||||
($err, $dtree) = aiInit ($paref);
|
$err = aiInit ($paref);
|
||||||
return if($err);
|
return if($err);
|
||||||
|
$dtree = AiDetreeVal ($hash, 'object', undef);
|
||||||
}
|
}
|
||||||
|
|
||||||
my ($pvrl, $temp, $wcc, $wrp, $rad1h);
|
my ($pvrl, $temp, $wcc, $wrp, $rad1h);
|
||||||
|
|
||||||
for my $pvd (sort keys %{$data{$type}{$name}{pvhist}}) {
|
for my $pvd (sort keys %{$data{$type}{$name}{pvhist}}) {
|
||||||
|
next if(!$pvd);
|
||||||
if ($ood) {
|
if ($ood) {
|
||||||
next if($pvd ne $paref->{day});
|
next if($pvd ne $paref->{day});
|
||||||
}
|
}
|
||||||
@ -10547,10 +10603,11 @@ sub aiAddInstance { ## no critic "not used"
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
$data{$type}{$name}{current}{aiaddistate} = 'ok';
|
|
||||||
|
|
||||||
debugLog ($paref, 'aiProcess', qq{AI Instance added - day: $pvd, hod: $hod, rad1h: $rad1h, pvrl: $pvrl, wcc: $cbin, wrp: $rbin, temp: $tbin});
|
debugLog ($paref, 'aiProcess', qq{AI Instance added - day: $pvd, hod: $hod, rad1h: $rad1h, pvrl: $pvrl, wcc: $cbin, wrp: $rbin, temp: $tbin});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data{$type}{$name}{aidectree}{object} = $dtree;
|
||||||
|
$data{$type}{$name}{current}{aiaddistate} = 'ok';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($taa) {
|
if ($taa) {
|
||||||
@ -10572,11 +10629,12 @@ sub aiTrain { ## no critic "not used"
|
|||||||
return if(!isDWDUsed ($hash));
|
return if(!isDWDUsed ($hash));
|
||||||
|
|
||||||
my $err;
|
my $err;
|
||||||
my $dtree = AiDetreeVal ($hash, undef);
|
my $dtree = AiDetreeVal ($hash, 'object', undef);
|
||||||
|
|
||||||
if (!$dtree) {
|
if (!$dtree) {
|
||||||
($err, $dtree) = aiInit ($paref);
|
$err = aiInit ($paref);
|
||||||
return if($err);
|
return if($err);
|
||||||
|
$dtree = AiDetreeVal ($hash, 'object', undef);
|
||||||
}
|
}
|
||||||
|
|
||||||
eval { $dtree->train
|
eval { $dtree->train
|
||||||
@ -10586,12 +10644,12 @@ sub aiTrain { ## no critic "not used"
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
debugLog ($paref, 'aiData', qq{AI trained: }.Dumper $data{$type}{$name}{aidectree});
|
$data{$type}{$name}{aidectree}{aitrained} = $dtree;
|
||||||
|
$err = writeCacheToFile ($hash, 'aitrained', $aitrained.$name); # AI Cache schreiben
|
||||||
$err = writeCacheToFile ($hash, 'aidectree', $aicache.$name); # AI Cache schreiben
|
|
||||||
|
|
||||||
if (!$err) {
|
if (!$err) {
|
||||||
debugLog ($paref, 'aiProcess', qq{AI trained and saved data into file: }.$aicache.$name);
|
debugLog ($paref, 'aiData', qq{AI trained: }.Dumper $data{$type}{$name}{aidectree}{aitrained});
|
||||||
|
debugLog ($paref, 'aiProcess', qq{AI trained and saved data into file: }.$aitrained.$name);
|
||||||
debugLog ($paref, 'aiProcess', qq{Training instances and their associated information where purged from the AI object});
|
debugLog ($paref, 'aiProcess', qq{Training instances and their associated information where purged from the AI object});
|
||||||
$data{$type}{$name}{current}{aitrainstate} = 'ok';
|
$data{$type}{$name}{current}{aitrainstate} = 'ok';
|
||||||
}
|
}
|
||||||
@ -10616,11 +10674,10 @@ sub aiGetResult { ## no critic "not used"
|
|||||||
|
|
||||||
return $err if(!isDWDUsed ($hash) || !$hod || !$nhidx);
|
return $err if(!isDWDUsed ($hash) || !$hod || !$nhidx);
|
||||||
|
|
||||||
my $dtree = AiDetreeVal ($hash, undef);
|
my $dtree = AiDetreeVal ($hash, 'aitrained', undef);
|
||||||
|
|
||||||
if (!$dtree) {
|
if (!$dtree) {
|
||||||
($err, $dtree) = aiInit ($paref);
|
return 'AI trained object is missed';
|
||||||
return $err if($err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $rad1h = NexthoursVal ($hash, $nhidx, "rad1h", undef);
|
my $rad1h = NexthoursVal ($hash, $nhidx, "rad1h", undef);
|
||||||
@ -10679,12 +10736,84 @@ sub aiInit { ## no critic "not used"
|
|||||||
|
|
||||||
my $dtree = new AI::DecisionTree ( verbose => 0, noise_mode => 'pick_best' );
|
my $dtree = new AI::DecisionTree ( verbose => 0, noise_mode => 'pick_best' );
|
||||||
|
|
||||||
$data{$type}{$name}{aidectree} = $dtree;
|
$data{$type}{$name}{aidectree}{object} = $dtree;
|
||||||
$data{$type}{$name}{current}{aiinitstate} = 'ok';
|
$data{$type}{$name}{current}{aiinitstate} = 'ok';
|
||||||
|
|
||||||
Log3 ($name, 3, "$name - AI::DecisionTree new initialized");
|
Log3 ($name, 3, "$name - AI::DecisionTree new initialized");
|
||||||
|
|
||||||
return ($err, $dtree);
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# den Index für AI raw Daten erzeugen
|
||||||
|
################################################################
|
||||||
|
sub aiMakeIdxRaw {
|
||||||
|
my $t = time;
|
||||||
|
my $day = shift // strftime "%d", localtime($t);
|
||||||
|
my $hod = shift;
|
||||||
|
|
||||||
|
my $ridx = strftime "%Y%m", localtime($t);
|
||||||
|
$ridx .= $day.$hod;
|
||||||
|
|
||||||
|
return $ridx;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Daten in die Raw Datensammlung hinzufügen
|
||||||
|
################################################################
|
||||||
|
sub aiAddRawData { ## no critic "not used"
|
||||||
|
my $paref = shift;
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $type = $paref->{type};
|
||||||
|
my $ood = $paref->{ood} // 0; # only one (cuurent) day
|
||||||
|
my $rho = $paref->{rho}; # only this hour of day
|
||||||
|
|
||||||
|
my ($pvrl, $temp, $wcc, $wrp, $rad1h);
|
||||||
|
|
||||||
|
for my $pvd (sort keys %{$data{$type}{$name}{pvhist}}) {
|
||||||
|
next if(!$pvd);
|
||||||
|
if ($ood) {
|
||||||
|
next if($pvd ne $paref->{day});
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $hod (sort keys %{$data{$type}{$name}{pvhist}{$pvd}}) {
|
||||||
|
next if(!$hod || $hod eq '99' || ($rho && $hod ne $rho));
|
||||||
|
|
||||||
|
my $ridx = aiMakeIdxRaw ($pvd, $hod);
|
||||||
|
|
||||||
|
$pvrl = HistoryVal ($hash, $pvd, $hod, 'pvrl', undef);
|
||||||
|
next if(!$pvrl);
|
||||||
|
|
||||||
|
$rad1h = HistoryVal ($hash, $pvd, $hod, 'rad1h', undef);
|
||||||
|
next if(!$rad1h);
|
||||||
|
|
||||||
|
$temp = HistoryVal ($hash, $pvd, $hod, 'temp', 20);
|
||||||
|
$wcc = HistoryVal ($hash, $pvd, $hod, 'wcc', 0);
|
||||||
|
$wrp = HistoryVal ($hash, $pvd, $hod, 'wrp', 0);
|
||||||
|
|
||||||
|
my $tbin = temp2bin ($temp);
|
||||||
|
my $cbin = cloud2bin ($wcc);
|
||||||
|
my $rbin = rain2bin ($wrp);
|
||||||
|
|
||||||
|
$data{$type}{$name}{aidectree}{airaw}{$ridx}{rad1h} = $rad1h;
|
||||||
|
$data{$type}{$name}{aidectree}{airaw}{$ridx}{temp} = $tbin;
|
||||||
|
$data{$type}{$name}{aidectree}{airaw}{$ridx}{wcc} = $cbin;
|
||||||
|
$data{$type}{$name}{aidectree}{airaw}{$ridx}{wrp} = $rbin;
|
||||||
|
$data{$type}{$name}{aidectree}{airaw}{$ridx}{hod} = $hod;
|
||||||
|
$data{$type}{$name}{aidectree}{airaw}{$ridx}{pvrl} = $pvrl;
|
||||||
|
|
||||||
|
debugLog ($paref, 'aiProcess', qq{AI Raw data added - idx: $ridx, day: $pvd, hod: $hod, rad1h: $rad1h, pvrl: $pvrl, wcc: $cbin, wrp: $rbin, temp: $tbin});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $err = writeCacheToFile ($hash, 'airaw', $airaw.$name);
|
||||||
|
|
||||||
|
if (!$err) {
|
||||||
|
debugLog ($paref, 'aiProcess', qq{AI raw data saved into file: }.$airaw.$name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
@ -11326,6 +11455,24 @@ sub listDataPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($htol eq "aiRawData") {
|
||||||
|
$h = $data{$type}{$name}{aidectree}{airaw};
|
||||||
|
if (!keys %{$h}) {
|
||||||
|
return qq{aiRawData values cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$h}) {
|
||||||
|
my $hod = AiRawdataVal ($hash, $idx, 'hod', "-");
|
||||||
|
my $rad1h = AiRawdataVal ($hash, $idx, 'rad1h', "-");
|
||||||
|
my $wcc = AiRawdataVal ($hash, $idx, 'wcc', "-");
|
||||||
|
my $wrp = AiRawdataVal ($hash, $idx, 'wrp', "-");
|
||||||
|
my $pvrl = AiRawdataVal ($hash, $idx, 'pvrl', "-");
|
||||||
|
my $temp = AiRawdataVal ($hash, $idx, 'temp', "-");
|
||||||
|
$sq .= "\n" if($sq);
|
||||||
|
$sq .= "$idx => hod: $hod, rad1h: $rad1h, wcc: $wcc, wrp: $wrp, pvrl: $pvrl, temp: $temp";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $sq;
|
return $sq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13121,20 +13268,67 @@ return $def;
|
|||||||
###################################################################################################
|
###################################################################################################
|
||||||
# Wert AI::DecisionTree Objects zurückliefern
|
# Wert AI::DecisionTree Objects zurückliefern
|
||||||
# Usage:
|
# Usage:
|
||||||
# AiDetreeVal ($hash, $def)
|
# AiDetreeVal ($hash, key, $def)
|
||||||
|
#
|
||||||
|
# key: object - das AI Object
|
||||||
|
# aitrained - AI trainierte Daten
|
||||||
|
# airaw - Rohdaten für AI Input = Raw Trainigsdaten
|
||||||
#
|
#
|
||||||
# $def: Defaultwert
|
# $def: Defaultwert
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
sub AiDetreeVal {
|
sub AiDetreeVal {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
my $key = shift;
|
||||||
my $def = shift;
|
my $def = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
if (defined $data{$type}{$name}{aidectree}) {
|
if (defined $data{$type}{$name}{aidectree} &&
|
||||||
return $data{$type}{$name}{aidectree};
|
defined $data{$type}{$name}{aidectree}{$key}) {
|
||||||
|
return $data{$type}{$name}{aidectree}{$key};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $def;
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################################################################################
|
||||||
|
# Wert AI Raw Data zurückliefern
|
||||||
|
# Usage:
|
||||||
|
# AiRawdataVal ($hash, $idx, $key, $def)
|
||||||
|
# AiRawdataVal ($hash, '', '', $def) -> den gesamten Hash airaw lesen
|
||||||
|
#
|
||||||
|
# $idx: - Index
|
||||||
|
# $key: rad1h - Strahlungsdaten
|
||||||
|
# temp - Temeperatur als Bin
|
||||||
|
# wcc - Bewölkung als Bin
|
||||||
|
# wrp - Regenwert als Bin
|
||||||
|
# hod - Stunde des Tages
|
||||||
|
# pvrl - reale PV Erzeugung
|
||||||
|
#
|
||||||
|
# $def: Defaultwert
|
||||||
|
#
|
||||||
|
###################################################################################################
|
||||||
|
sub AiRawdataVal {
|
||||||
|
my $hash = shift;
|
||||||
|
my $idx = shift;
|
||||||
|
my $key = shift;
|
||||||
|
my $def = shift;
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
|
if (!$idx && !$key) {
|
||||||
|
if (defined $data{$type}{$name}{aidectree}{airaw}) {
|
||||||
|
return $data{$type}{$name}{aidectree}{airaw};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined $data{$type}{$name}{aidectree}{airaw} &&
|
||||||
|
defined $data{$type}{$name}{aidectree}{airaw}{$idx} &&
|
||||||
|
defined $data{$type}{$name}{aidectree}{airaw}{$idx}{$key}) {
|
||||||
|
return $data{$type}{$name}{aidectree}{airaw}{$idx}{$key};
|
||||||
}
|
}
|
||||||
|
|
||||||
return $def;
|
return $def;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user