76_SolarForecast: contrib V1.57.3
git-svn-id: https://svn.fhem.de/fhem/trunk@30217 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -160,8 +160,10 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
"1.57.3" => "24.08.2025 set default Performance Ratio PRDEF to 0.9, prevent crash when Victron API does not return an Array ".
|
"1.57.3" => "25.08.2025 set default Performance Ratio PRDEF to 0.9, prevent crash when Victron API does not return an Array ".
|
||||||
"check global attribute dnsServer in all SF Models, expand plantControl->genPVdeviation for perspective change ",
|
"check global attribute dnsServer in all SF Models, expand plantControl->genPVdeviation for perspective change ".
|
||||||
|
"Household consumption calculation uniformly converted to vector calculation ".
|
||||||
|
"new ctrlSpecialReadings->dummyConsumption ",
|
||||||
"1.57.2" => "15.08.2025 _attrconsumer: The validity of the components of the key etotal is checked ".
|
"1.57.2" => "15.08.2025 _attrconsumer: The validity of the components of the key etotal is checked ".
|
||||||
"_transferMeterValues: modul accept meter reset > 0 at day start ",
|
"_transferMeterValues: modul accept meter reset > 0 at day start ",
|
||||||
"1.57.1" => "10.08.2025 fix warning, Forum: https://forum.fhem.de/index.php?msg=1346055 ",
|
"1.57.1" => "10.08.2025 fix warning, Forum: https://forum.fhem.de/index.php?msg=1346055 ",
|
||||||
@@ -972,10 +974,10 @@ my %hqtxt = ( # H
|
|||||||
DE => qq{produziert wie vorhergesagt 😊} },
|
DE => qq{produziert wie vorhergesagt 😊} },
|
||||||
pltp => { EN => qq{produced less than predicted 😓},
|
pltp => { EN => qq{produced less than predicted 😓},
|
||||||
DE => qq{weniger produziert als vorhergesagt 😓} },
|
DE => qq{weniger produziert als vorhergesagt 😓} },
|
||||||
wusond => { EN => qq{wait until sunset},
|
wusond => { EN => qq{waiting for data ...},
|
||||||
DE => qq{bis zum Sonnenuntergang warten} },
|
DE => qq{warte auf Daten ...} },
|
||||||
snbefb => { EN => qq{Should not be empty. Maybe the device has just been redefined.},
|
snbefb => { EN => qq{the data will be available tomorrow},
|
||||||
DE => qq{Sollte nicht leer sein. Vielleicht wurde das Device erst neu definiert.} },
|
DE => qq{die Daten werden morgen verfügbar sein} },
|
||||||
scnp => { EN => qq{Scheduling of the consumer is not provided},
|
scnp => { EN => qq{Scheduling of the consumer is not provided},
|
||||||
DE => qq{Die Einplanung des Verbrauchers ist nicht vorgesehen} },
|
DE => qq{Die Einplanung des Verbrauchers ist nicht vorgesehen} },
|
||||||
vrmcr => { EN => qq{Please set the Victron VRM Portal credentials with "set LINK vrmCredentials".},
|
vrmcr => { EN => qq{Please set the Victron VRM Portal credentials with "set LINK vrmCredentials".},
|
||||||
@@ -1133,8 +1135,8 @@ my %htitles = (
|
|||||||
DE => qq{nicht bewertet} },
|
DE => qq{nicht bewertet} },
|
||||||
aimstt => { EN => qq{Perl module AI::DecisionTree is missing},
|
aimstt => { EN => qq{Perl module AI::DecisionTree is missing},
|
||||||
DE => qq{Perl Modul AI::DecisionTree ist nicht vorhanden} },
|
DE => qq{Perl Modul AI::DecisionTree ist nicht vorhanden} },
|
||||||
dumtxt => { EN => qq{Consumption that cannot be allocated to registered consumers},
|
dumtxt => { EN => qq{unassignable consumption (takes into account any hidden consumers)},
|
||||||
DE => qq{Verbrauch der den registrierten Verbrauchern nicht zugeordnet werden kann} },
|
DE => qq{nicht zuordenbarer Verbrauch (berücksichtigt evtl. versteckte Verbraucher)} },
|
||||||
rdcactiv => { EN => qq{Plant derating active},
|
rdcactiv => { EN => qq{Plant derating active},
|
||||||
DE => qq{Anlagenabregelung aktiv} },
|
DE => qq{Anlagenabregelung aktiv} },
|
||||||
rdcnoact => { EN => qq{no Plant derating},
|
rdcnoact => { EN => qq{no Plant derating},
|
||||||
@@ -1383,6 +1385,7 @@ my %hcsr = (
|
|||||||
runTimeLastAPIAnswer => { fnr => 2, fn => \&CurrentVal, par => '', par1 => '', unit => '', def => '-' },
|
runTimeLastAPIAnswer => { fnr => 2, fn => \&CurrentVal, par => '', par1 => '', unit => '', def => '-' },
|
||||||
runTimeLastAPIProc => { fnr => 2, fn => \&CurrentVal, par => '', par1 => '', unit => '', def => '-' },
|
runTimeLastAPIProc => { fnr => 2, fn => \&CurrentVal, par => '', par1 => '', unit => '', def => '-' },
|
||||||
allStringsFullfilled => { fnr => 2, fn => \&CurrentVal, par => '', par1 => '', unit => '', def => 0 },
|
allStringsFullfilled => { fnr => 2, fn => \&CurrentVal, par => '', par1 => '', unit => '', def => 0 },
|
||||||
|
dummyConsumption => { fnr => 2, fn => \&CurrentVal, par => 'dummyConsumption', par1 => '', unit => ' W', def => 0 },
|
||||||
todayConForecastTillSunset => { fnr => 2, fn => \&CurrentVal, par => 'tdConFcTillSunset', par1 => '', unit => ' Wh', def => 0 },
|
todayConForecastTillSunset => { fnr => 2, fn => \&CurrentVal, par => 'tdConFcTillSunset', par1 => '', unit => ' Wh', def => 0 },
|
||||||
runTimeTrainAI => { fnr => 3, fn => \&CircularVal, par => 99, par1 => '', unit => ' s', def => '-' },
|
runTimeTrainAI => { fnr => 3, fn => \&CircularVal, par => 99, par1 => '', unit => ' s', def => '-' },
|
||||||
todayConsumption => { fnr => 3, fn => \&CircularVal, par => 99, par1 => '', unit => ' Wh', def => 0 },
|
todayConsumption => { fnr => 3, fn => \&CircularVal, par => 99, par1 => '', unit => ' Wh', def => 0 },
|
||||||
@@ -12015,22 +12018,35 @@ sub _createSummaries {
|
|||||||
$node2inv2dc += $pac2dc if($ifeed eq 'hybrid' || ($ifeed eq 'default' && $isource eq 'bat')); # AC->DC (Batterie- oder Hybrid-Wechselrichter)
|
$node2inv2dc += $pac2dc if($ifeed eq 'hybrid' || ($ifeed eq 'default' && $isource eq 'bat')); # AC->DC (Batterie- oder Hybrid-Wechselrichter)
|
||||||
}
|
}
|
||||||
|
|
||||||
my $othprod = 0; # Summe Otherproducer
|
my $ppall = 0; # Summe Otherproducer
|
||||||
|
|
||||||
for my $pn (1..MAXPRODUCER) { # Erzeugung sonstiger Producer hinzufügen
|
for my $pn (1..MAXPRODUCER) { # Erzeugung sonstiger Producer hinzufügen
|
||||||
$pn = sprintf "%02d", $pn;
|
$pn = sprintf "%02d", $pn;
|
||||||
$othprod += ProducerVal ($name, $pn, 'pgeneration', 0);
|
$ppall += ProducerVal ($name, $pn, 'pgeneration', 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $consumption = sprintf "%.0f", ($pv2node + $pv2bat + $othprod - $gfeedin + $gcon - $batin + $batout); # ohne PV2Grid
|
my $vector = __calcVectorConsumption ( { name => $name,
|
||||||
|
batout => $batout,
|
||||||
|
batin => $batin,
|
||||||
|
pv2bat => $pv2bat,
|
||||||
|
pv2node => $pv2node,
|
||||||
|
dc2inv2node => $dc2inv2node,
|
||||||
|
node2inv2dc => $node2inv2dc,
|
||||||
|
ppall => $ppall,
|
||||||
|
gfeedin => $gfeedin,
|
||||||
|
gcon => $gcon
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
my $consumption = $vector->{vectorconsumption};
|
||||||
my $selfconsumption = sprintf "%.0f", ($pv2node + $pv2bat - $gfeedin - $batin);
|
my $selfconsumption = sprintf "%.0f", ($pv2node + $pv2bat - $gfeedin - $batin);
|
||||||
$selfconsumption = $selfconsumption < 0 ? 0 : $selfconsumption;
|
$selfconsumption = $selfconsumption < 0 ? 0 : $selfconsumption;
|
||||||
|
|
||||||
my $surplus = sprintf "%.0f", ($pv2node - $pv2grid + $othprod - $consumption); # aktueller Überschuß
|
my $surplus = sprintf "%.0f", ($pv2node - $pv2grid + $ppall - $consumption); # aktueller Überschuß
|
||||||
$surplus = 0 if($surplus < 0); # wegen Vergleich nompower vs. surplus
|
$surplus = 0 if($surplus < 0); # wegen Vergleich nompower vs. surplus
|
||||||
|
|
||||||
if ($debug =~ /collectData/xs) {
|
if ($debug =~ /collectData/xs) {
|
||||||
Log3 ($name, 1, "$name DEBUG> current Power values -> PV2Node: $pv2node W, PV2Bat: $pv2bat, PV2Grid: $pv2grid W, Other: $othprod W, GridIn: $gfeedin W, GridCon: $gcon W");
|
Log3 ($name, 1, "$name DEBUG> current Power values -> PV2Node: $pv2node W, PV2Bat: $pv2bat, PV2Grid: $pv2grid W, Other: $ppall W, GridIn: $gfeedin W, GridCon: $gcon W");
|
||||||
Log3 ($name, 1, "$name DEBUG> current Power Battery -> BatIn: $batin W (Node2Inv2DC: $node2inv2dc W), BatOut: $batout W (DC2Inv2Node: $dc2inv2node W)");
|
Log3 ($name, 1, "$name DEBUG> current Power Battery -> BatIn: $batin W (Node2Inv2DC: $node2inv2dc W), BatOut: $batout W (DC2Inv2Node: $dc2inv2node W)");
|
||||||
Log3 ($name, 1, "$name DEBUG> current Consumption result -> $consumption W");
|
Log3 ($name, 1, "$name DEBUG> current Consumption result -> $consumption W");
|
||||||
}
|
}
|
||||||
@@ -12052,8 +12068,8 @@ sub _createSummaries {
|
|||||||
push @{$data{$name}{current}{surplusslidereg}}, $surplus; # Schieberegister PV Überschuß
|
push @{$data{$name}{current}{surplusslidereg}}, $surplus; # Schieberegister PV Überschuß
|
||||||
limitArray ($data{$name}{current}{surplusslidereg}, SPLSLIDEMAX);
|
limitArray ($data{$name}{current}{surplusslidereg}, SPLSLIDEMAX);
|
||||||
|
|
||||||
storeReading ('Current_GridFeedIn', (int $gfeedin). ' W'); # V 1.37.0
|
storeReading ('Current_GridFeedIn', (sprintf "%.0f", $gfeedin). ' W');
|
||||||
storeReading ('Current_GridConsumption', (int $gcon). ' W'); # V 1.37.0
|
storeReading ('Current_GridConsumption', (sprintf "%.0f", $gcon). ' W');
|
||||||
storeReading ('Current_Consumption', $consumption. ' W');
|
storeReading ('Current_Consumption', $consumption. ' W');
|
||||||
storeReading ('Current_SelfConsumption', $selfconsumption. ' W');
|
storeReading ('Current_SelfConsumption', $selfconsumption. ' W');
|
||||||
storeReading ('Current_SelfConsumptionRate', $selfconsumptionrate. ' %');
|
storeReading ('Current_SelfConsumptionRate', $selfconsumptionrate. ' %');
|
||||||
@@ -12062,19 +12078,81 @@ sub _createSummaries {
|
|||||||
storeReading ('Today_PVreal', $pvre. ' Wh');
|
storeReading ('Today_PVreal', $pvre. ' Wh');
|
||||||
storeReading ('Tomorrow_ConsumptionForecast', $tconsum. ' Wh') if(defined $tconsum);
|
storeReading ('Tomorrow_ConsumptionForecast', $tconsum. ' Wh') if(defined $tconsum);
|
||||||
|
|
||||||
storeReading ('NextHours_Sum01_PVforecast', (int $next1HoursSum->{PV}). ' Wh');
|
storeReading ('NextHours_Sum01_PVforecast', (sprintf "%.0f", $next1HoursSum->{PV}). ' Wh');
|
||||||
storeReading ('NextHours_Sum02_PVforecast', (int $next2HoursSum->{PV}). ' Wh');
|
storeReading ('NextHours_Sum02_PVforecast', (sprintf "%.0f", $next2HoursSum->{PV}). ' Wh');
|
||||||
storeReading ('NextHours_Sum03_PVforecast', (int $next3HoursSum->{PV}). ' Wh');
|
storeReading ('NextHours_Sum03_PVforecast', (sprintf "%.0f", $next3HoursSum->{PV}). ' Wh');
|
||||||
storeReading ('NextHours_Sum04_PVforecast', (int $next4HoursSum->{PV}). ' Wh');
|
storeReading ('NextHours_Sum04_PVforecast', (sprintf "%.0f", $next4HoursSum->{PV}). ' Wh');
|
||||||
storeReading ('RestOfDayPVforecast', (int $restOfDaySum->{PV}). ' Wh');
|
storeReading ('RestOfDayPVforecast', (sprintf "%.0f", $restOfDaySum->{PV}). ' Wh');
|
||||||
storeReading ('Tomorrow_PVforecast', (int $tomorrowSum->{PV}). ' Wh');
|
storeReading ('Tomorrow_PVforecast', (sprintf "%.0f", $tomorrowSum->{PV}). ' Wh');
|
||||||
storeReading ('Today_PVforecast', (int $todaySumFc->{PV}). ' Wh');
|
storeReading ('Today_PVforecast', (sprintf "%.0f", $todaySumFc->{PV}). ' Wh');
|
||||||
storeReading ('NextHours_Sum04_ConsumptionForecast', (int $next4HoursSum->{Consumption}).' Wh');
|
storeReading ('NextHours_Sum04_ConsumptionForecast', (sprintf "%.0f", $next4HoursSum->{Consumption}).' Wh');
|
||||||
storeReading ('RestOfDayConsumptionForecast', (int $restOfDaySum->{Consumption}). ' Wh');
|
storeReading ('RestOfDayConsumptionForecast', (sprintf "%.0f", $restOfDaySum->{Consumption}). ' Wh');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Hausverbrauch aus dem Leistungsfluß in/aus Knoten ermitteln
|
||||||
|
# (erfasst auch Verlustleistung in den Batteriewechselrichtern)
|
||||||
|
# und alternativ linear
|
||||||
|
# alles ohne PV2Grid
|
||||||
|
################################################################
|
||||||
|
sub __calcVectorConsumption {
|
||||||
|
my $paref = shift;
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $batout = $paref->{batout};
|
||||||
|
my $batin = $paref->{batin};
|
||||||
|
my $pv2bat = $paref->{pv2bat};
|
||||||
|
my $pv2node = $paref->{pv2node};
|
||||||
|
my $dc2inv2node = $paref->{dc2inv2node};
|
||||||
|
my $node2inv2dc = $paref->{node2inv2dc};
|
||||||
|
my $ppall = $paref->{ppall};
|
||||||
|
my $gfeedin = $paref->{gfeedin};
|
||||||
|
my $gcon = $paref->{gcon};
|
||||||
|
|
||||||
|
my $vector;
|
||||||
|
$vector->{batDischarge2HomeNode} = 0;
|
||||||
|
my $node2bat = 0; # Verbindung Inv.Knoten <-> Batterie ((-) Bat -> Knoten, (+) Knoten -> Bat)
|
||||||
|
my $bat2home = 0;
|
||||||
|
|
||||||
|
## Vectorverbrauch
|
||||||
|
####################
|
||||||
|
if ($batout || $batin) { # Batterie wird geladen oder entladen
|
||||||
|
$node2bat = ($batin - $batout) - $pv2bat + $dc2inv2node - $node2inv2dc; # positiv: Richtung Inverter Knoten -> Bat, negativ: Richtung Bat -> Inverter Knoten
|
||||||
|
$node2bat = 0 if(($dc2inv2node || $node2inv2dc) && $node2bat != 0);
|
||||||
|
|
||||||
|
if ($node2bat < 0 && !$dc2inv2node && !$pv2bat) { # Batterieentladung direkt ins Hausnetz wenn kein Batterie- / Hybridwechselrichter und kein Batterieladegerät aktiv
|
||||||
|
$bat2home = abs $node2bat;
|
||||||
|
$node2bat = 0;
|
||||||
|
$vector->{batDischarge2HomeNode} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$node2bat = $dc2inv2node - $pv2bat; # falls Batterie Idle und Smartloader arbeitet
|
||||||
|
$node2bat = 0 if($dc2inv2node && $node2bat > 0); # muß negativ (0) sein: Richtung Bat -> Inv.Knoten, wichtig zur Festlegung Richtung und Inv. Knoten Summierung
|
||||||
|
}
|
||||||
|
|
||||||
|
my $pnodesum = $ppall + $pv2node + $dc2inv2node - $node2inv2dc; # Erzeugung Summe im Inverter-Knoten
|
||||||
|
$pnodesum += $node2bat < 0 ? abs $node2bat : 0; # z.B. Batterie ist voll und SolarLader liefert an Knoten
|
||||||
|
$pnodesum = __normDecPlaces ($pnodesum);
|
||||||
|
|
||||||
|
my $node2home = $pnodesum - $gfeedin - ($node2bat > 0 ? $node2bat : 0); # Energiefluß vom Knoten zum Haus
|
||||||
|
$node2home = __normDecPlaces ($node2home);
|
||||||
|
|
||||||
|
$vector->{vectorconsumption} = sprintf "%.0f", ($gcon + $node2home + $bat2home); # V 1.52.0 Anpassung Consumption wegen Verlustleistungsdifferenzen
|
||||||
|
|
||||||
|
## Linearverbrauch
|
||||||
|
####################
|
||||||
|
$vector->{linearconsumption} = sprintf "%.0f", ($pv2node + $pv2bat + $ppall - $gfeedin + $gcon - $batin + $batout);
|
||||||
|
|
||||||
|
$vector->{bat2home} = $bat2home;
|
||||||
|
$vector->{pnodesum} = $pnodesum;
|
||||||
|
$vector->{node2home} = $node2home;
|
||||||
|
$vector->{node2bat} = $node2bat;
|
||||||
|
|
||||||
|
return $vector;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Consumer - Energieverbrauch aufnehmen
|
# Consumer - Energieverbrauch aufnehmen
|
||||||
# - Masterdata ergänzen
|
# - Masterdata ergänzen
|
||||||
@@ -12091,6 +12169,8 @@ sub _manageConsumerData {
|
|||||||
my $nhour = $chour + 1;
|
my $nhour = $chour + 1;
|
||||||
$paref->{nhour} = sprintf "%02d", $nhour;
|
$paref->{nhour} = sprintf "%02d", $nhour;
|
||||||
|
|
||||||
|
my $pcurrsum = 0;
|
||||||
|
|
||||||
for my $c (sort{$a<=>$b} keys %{$data{$name}{consumers}}) {
|
for my $c (sort{$a<=>$b} keys %{$data{$name}{consumers}}) {
|
||||||
$paref->{consumer} = $c;
|
$paref->{consumer} = $c;
|
||||||
my $consumer = ConsumerVal ($hash, $c, 'name', '');
|
my $consumer = ConsumerVal ($hash, $c, 'name', '');
|
||||||
@@ -12105,8 +12185,6 @@ sub _manageConsumerData {
|
|||||||
if ($paread) {
|
if ($paread) {
|
||||||
my $eup = $up =~ /^kW$/xi ? 1000 : 1;
|
my $eup = $up =~ /^kW$/xi ? 1000 : 1;
|
||||||
$pcurr = ReadingsNum ($consumer, $paread, 0) * $eup;
|
$pcurr = ReadingsNum ($consumer, $paread, 0) * $eup;
|
||||||
|
|
||||||
storeReading ("consumer${c}_currentPower", $pcurr.' W');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## Verbrauch auslesen + speichern
|
## Verbrauch auslesen + speichern
|
||||||
@@ -12130,8 +12208,6 @@ sub _manageConsumerData {
|
|||||||
|
|
||||||
$data{$name}{consumers}{$c}{old_etotal} = $etot;
|
$data{$name}{consumers}{$c}{old_etotal} = $etot;
|
||||||
$data{$name}{consumers}{$c}{old_etottime} = $t;
|
$data{$name}{consumers}{$c}{old_etottime} = $t;
|
||||||
|
|
||||||
storeReading ("consumer${c}_currentPower", $pcurr.' W');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined $ehist && $etot >= $ehist && ($etot - $ehist) >= $ethreshold) {
|
if (defined $ehist && $etot >= $ehist && ($etot - $ehist) >= $ethreshold) {
|
||||||
@@ -12169,8 +12245,16 @@ sub _manageConsumerData {
|
|||||||
delete $paref->{val};
|
delete $paref->{val};
|
||||||
}
|
}
|
||||||
|
|
||||||
readingsDelete ($hash, "consumer${c}_currentPower") if(!$etotread && !$paread);
|
if (!$etotread && !$paread) {
|
||||||
|
delete $data{$name}{consumers}{$c}{currpower};
|
||||||
|
readingsDelete ($hash, "consumer${c}_currentPower");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data{$name}{consumers}{$c}{currpower} = $pcurr;
|
||||||
|
storeReading ("consumer${c}_currentPower", $pcurr.' W');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pcurrsum += $pcurr;
|
||||||
$paref->{pcurr} = $pcurr;
|
$paref->{pcurr} = $pcurr;
|
||||||
|
|
||||||
__getAutomaticState ($paref); # Automatic Status des Consumers abfragen
|
__getAutomaticState ($paref); # Automatic Status des Consumers abfragen
|
||||||
@@ -12232,6 +12316,8 @@ sub _manageConsumerData {
|
|||||||
storeReading ("consumer${c}_planned_stop", $stoptime) if($stoptime); # Consumer Stop geplant
|
storeReading ("consumer${c}_planned_stop", $stoptime) if($stoptime); # Consumer Stop geplant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data{$name}{current}{dummyConsumption} = CurrentVal ($name, 'consumption', 0) - $pcurrsum; # aktueller Verbrauch - Summe aller ConsumerPower
|
||||||
|
|
||||||
delete $paref->{consumer};
|
delete $paref->{consumer};
|
||||||
delete $paref->{nhour};
|
delete $paref->{nhour};
|
||||||
|
|
||||||
@@ -17898,13 +17984,11 @@ sub _flowGraphic {
|
|||||||
my $exth2cdist = $paref->{flowgh2cDist}; # vertikaler Abstand Home -> Consumer Zeile
|
my $exth2cdist = $paref->{flowgh2cDist}; # vertikaler Abstand Home -> Consumer Zeile
|
||||||
my $lang = $paref->{lang};
|
my $lang = $paref->{lang};
|
||||||
|
|
||||||
my $gconMetered = ReadingsNum ($name, 'Current_GridConsumption', 0);
|
my $gconMetered = CurrentVal ($name, 'gridconsumption', 0);
|
||||||
my $node2gridMetered = ReadingsNum ($name, 'Current_GridFeedIn', 0); # vom Inverter-Knoten zum Grid
|
my $node2gridMetered = CurrentVal ($name, 'gridfeedin', 0); # vom Inverter-Knoten zum Grid
|
||||||
my $cselfMetered = ReadingsNum ($name, 'Current_SelfConsumption', 0);
|
my $cselfMetered = CurrentVal ($name, 'selfconsumption', 0);
|
||||||
my $consptn = CurrentVal ($name, 'consumption', 0);
|
|
||||||
my $showgenerators = CurrentVal ($name, 'showGenerators', 0); # Generatoren-Zeile anzeigen
|
my $showgenerators = CurrentVal ($name, 'showGenerators', 0); # Generatoren-Zeile anzeigen
|
||||||
|
|
||||||
my $cons_dmy = $consptn;
|
|
||||||
my $scale = FGSCALEDEF;
|
my $scale = FGSCALEDEF;
|
||||||
my $stna = $name;
|
my $stna = $name;
|
||||||
$stna .= int (rand (1500));
|
$stna .= int (rand (1500));
|
||||||
@@ -17925,8 +18009,8 @@ sub _flowGraphic {
|
|||||||
($err) = isDeviceValid ( { name => $name, obj => 'setupBatteryDev'.$bn, method => 'attr' } );
|
($err) = isDeviceValid ( { name => $name, obj => 'setupBatteryDev'.$bn, method => 'attr' } );
|
||||||
next if($err);
|
next if($err);
|
||||||
|
|
||||||
my $batinpow = ReadingsNum ($name, 'Current_PowerBatIn_'.$bn, undef);
|
my $batinpow = BatteryVal ($name, $bn, 'bpowerin', undef);
|
||||||
my $batoutpow = ReadingsNum ($name, 'Current_PowerBatOut_'.$bn, undef);
|
my $batoutpow = BatteryVal ($name, $bn, 'bpowerout', undef);
|
||||||
$batin += $batinpow if(defined $batinpow);
|
$batin += $batinpow if(defined $batinpow);
|
||||||
$batout += $batoutpow if(defined $batoutpow);
|
$batout += $batoutpow if(defined $batoutpow);
|
||||||
}
|
}
|
||||||
@@ -18027,45 +18111,45 @@ sub _flowGraphic {
|
|||||||
my $gconMetered_direction = "M250,515 L670,590";
|
my $gconMetered_direction = "M250,515 L670,590";
|
||||||
my $bat2home_direction = "M1200,515 L730,590";
|
my $bat2home_direction = "M1200,515 L730,590";
|
||||||
|
|
||||||
my $node2bat = 0; # Verbindung Inv.Knoten <-> Batterie ((-) Bat -> Knoten, (+) Knoten -> Bat)
|
## Knotensummen Erzeuger - Batterie - Home ermitteln -> Hausverbrauch ermitteln
|
||||||
my $bat2home = 0;
|
#################################################################################
|
||||||
|
my $vector = __calcVectorConsumption ( { name => $name,
|
||||||
|
batout => $batout,
|
||||||
|
batin => $batin,
|
||||||
|
pv2bat => $pv2bat,
|
||||||
|
pv2node => $pv2node,
|
||||||
|
dc2inv2node => $dc2inv2node,
|
||||||
|
node2inv2dc => $node2inv2dc,
|
||||||
|
ppall => $ppall,
|
||||||
|
gfeedin => $node2gridMetered,
|
||||||
|
gcon => $gconMetered
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if ($batout || $batin) { # Batterie wird geladen oder entladen
|
my $consptn = $vector->{vectorconsumption};
|
||||||
$node2bat = ($batin - $batout) - $pv2bat + $dc2inv2node - $node2inv2dc; # positiv: Richtung Knoten -> Bat, negativ: Richtung Bat -> Inv.Knoten
|
|
||||||
$node2bat = 0 if(($dc2inv2node || $node2inv2dc) && $node2bat != 0);
|
|
||||||
|
|
||||||
if ($node2bat < 0 && !$dc2inv2node && !$pv2bat) { # Batterieentladung direkt ins Hausnetz wenn kein Batterie- / Hybridwechselrichter und kein Batterieladegerät aktiv
|
if ($vector->{batDischarge2HomeNode}) {
|
||||||
$bat2home = abs $node2bat;
|
|
||||||
$node2bat = 0;
|
|
||||||
$bat2home_style = "$stna active_normal";
|
$bat2home_style = "$stna active_normal";
|
||||||
$bat2home_direction = "M1200,515 L730,590";
|
$bat2home_direction = "M1200,515 L730,590";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
$node2bat = $dc2inv2node - $pv2bat; # falls Batterie Idle und Smartloader arbeitet
|
|
||||||
$node2bat = 0 if($dc2inv2node && $node2bat > 0); # muß negativ (0) sein: Richtung Bat -> Inv.Knoten, wichtig zur Festlegung Richtung und Inv. Knoten Summierung
|
|
||||||
}
|
|
||||||
|
|
||||||
## Knotensummen Erzeuger - Batterie - Home ermitteln
|
my $bat2home = $vector->{bat2home}; # Batterie -> Hausknoten
|
||||||
######################################################
|
my $pnodesum = $vector->{pnodesum}; # Summe Inverterknoten
|
||||||
my $pnodesum = $ppall + $pv2node + $dc2inv2node - $node2inv2dc; # Erzeugung Summe im Inverter-Knoten
|
my $node2home = $vector->{node2home}; # Inverterknoten -> Haus
|
||||||
$pnodesum += $node2bat < 0 ? abs $node2bat : 0; # z.B. Batterie ist voll und SolarLader liefert an Knoten
|
my $node2bat = $vector->{node2bat}; # Inverterknoten -> Batterie
|
||||||
$pnodesum = __normDecPlaces ($pnodesum);
|
|
||||||
|
|
||||||
my $node2home = $pnodesum - $node2gridMetered - ($node2bat > 0 ? $node2bat : 0); # Energiefluß vom Knoten zum Haus
|
|
||||||
$node2home = __normDecPlaces ($node2home);
|
|
||||||
|
|
||||||
$consptn = $gconMetered + $node2home + $bat2home; # V 1.52.0 Anpassung Consumption wegen Verlustleistungsdifferenzen
|
|
||||||
|
|
||||||
## definierte Verbraucher ermitteln
|
## definierte Verbraucher ermitteln
|
||||||
#####################################
|
#####################################
|
||||||
my $cnsmr = {}; # Consumer Hilfshash Referenz
|
my $cnsmr = {}; # Consumer Hilfshash Referenz
|
||||||
|
my $concurpsum = 0; # Summierung aller Consumerverbräuche
|
||||||
|
|
||||||
for my $c (sort{$a<=>$b} keys %{$data{$name}{consumers}}) { # definierte Verbraucher ermitteln
|
for my $c (sort{$a<=>$b} keys %{$data{$name}{consumers}}) { # definierte Verbraucher ermitteln
|
||||||
next if(isConsumerNoshow ($hash, $c) =~ /[13]/xs); # auszublendende Consumer nicht berücksichtigen
|
next if(isConsumerNoshow ($hash, $c) =~ /[13]/xs); # auszublendende Consumer nicht berücksichtigen
|
||||||
$cnsmr->{$c}{p} = ReadingsNum ($name, "consumer${c}_currentPower", 0);
|
$cnsmr->{$c}{p} = ConsumerVal ($name, $c, 'currpower', 0);
|
||||||
$cnsmr->{$c}{shortalias} = ConsumerVal ($name, $c, 'aliasshort', ''); # Consumer Kurzalias
|
$cnsmr->{$c}{shortalias} = ConsumerVal ($name, $c, 'aliasshort', ''); # Consumer Kurzalias
|
||||||
$cnsmr->{$c}{ptyp} = 'consumer';
|
$cnsmr->{$c}{ptyp} = 'consumer';
|
||||||
|
$concurpsum += $cnsmr->{$c}{p};
|
||||||
}
|
}
|
||||||
|
|
||||||
my $consumercount = keys %{$cnsmr};
|
my $consumercount = keys %{$cnsmr};
|
||||||
@@ -18077,6 +18161,9 @@ sub _flowGraphic {
|
|||||||
}
|
}
|
||||||
values %{$cnsmr};
|
values %{$cnsmr};
|
||||||
|
|
||||||
|
## Verbrauch Dummy bestimmen
|
||||||
|
##############################
|
||||||
|
my $cons_dmy = $consptn - $concurpsum;
|
||||||
|
|
||||||
## Producer / Inverter Koordinaten Steuerhash
|
## Producer / Inverter Koordinaten Steuerhash
|
||||||
###############################################
|
###############################################
|
||||||
@@ -18222,7 +18309,6 @@ END0
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$cons_dmy -= $cnsmrpower;
|
|
||||||
$cicon = FW_makeImage ($cicon, '');
|
$cicon = FW_makeImage ($cicon, '');
|
||||||
($scale, $cicon) = __normIconScale ($name, $cicon);
|
($scale, $cicon) = __normIconScale ($name, $cicon);
|
||||||
|
|
||||||
@@ -26744,6 +26830,7 @@ to ensure that the system configuration is correct.
|
|||||||
<tr><td> <b>currentRunMtsConsumer_XX</b> </td><td>the running time (minutes) of the consumer "XX" since the last switch-on. (last running cycle) </td></tr>
|
<tr><td> <b>currentRunMtsConsumer_XX</b> </td><td>the running time (minutes) of the consumer "XX" since the last switch-on. (last running cycle) </td></tr>
|
||||||
<tr><td> <b>dayAfterTomorrowPVforecast</b> </td><td>provides the forecast of PV generation for the day after tomorrow (if available) without autocorrection (raw data) </td></tr>
|
<tr><td> <b>dayAfterTomorrowPVforecast</b> </td><td>provides the forecast of PV generation for the day after tomorrow (if available) without autocorrection (raw data) </td></tr>
|
||||||
<tr><td> <b>daysUntilBatteryCare_XX</b> </td><td>Days until the next battery XX maintenance (reaching the charge 'maxSoC' from attribute ctrlBatSocManagementXX) </td></tr>
|
<tr><td> <b>daysUntilBatteryCare_XX</b> </td><td>Days until the next battery XX maintenance (reaching the charge 'maxSoC' from attribute ctrlBatSocManagementXX) </td></tr>
|
||||||
|
<tr><td> <b>dummyConsumption</b> </td><td>Provides the current household consumption that cannot be attributed to consumers. Also includes power loss components. </td></tr>
|
||||||
<tr><td> <b>lastretrieval_time</b> </td><td>the last retrieval time of the selected radiation data API </td></tr>
|
<tr><td> <b>lastretrieval_time</b> </td><td>the last retrieval time of the selected radiation data API </td></tr>
|
||||||
<tr><td> <b>lastretrieval_timestamp</b> </td><td>the timestamp of the last retrieval time of the selected radiation data API </td></tr>
|
<tr><td> <b>lastretrieval_timestamp</b> </td><td>the timestamp of the last retrieval time of the selected radiation data API </td></tr>
|
||||||
<tr><td> <b>remainingSurplsHrsMinPwrBat_XX</b> </td><td>the remaining number of hours on the current day in which the PV surplus (Wh) is higher than the </td></tr>
|
<tr><td> <b>remainingSurplsHrsMinPwrBat_XX</b> </td><td>the remaining number of hours on the current day in which the PV surplus (Wh) is higher than the </td></tr>
|
||||||
@@ -27257,7 +27344,7 @@ to ensure that the system configuration is correct.
|
|||||||
<tr><td> </td><td> </td></tr>
|
<tr><td> </td><td> </td></tr>
|
||||||
<tr><td> <b>genPVdeviation</b> </td><td>Defines the method for calculating the deviation between forecast and actual PV generation. </td></tr>
|
<tr><td> <b>genPVdeviation</b> </td><td>Defines the method for calculating the deviation between forecast and actual PV generation. </td></tr>
|
||||||
<tr><td> </td><td>The reading <b>Today_PVdeviation</b> is created depending on this setting. </td></tr>
|
<tr><td> </td><td>The reading <b>Today_PVdeviation</b> is created depending on this setting. </td></tr>
|
||||||
<tr><td> </td><td>The optional addition ‘:reverse’ specifies that PV generation > forecast is displayed as a positive value instead of a negative value (change of perspective). </td></tr>
|
<tr><td> </td><td>The optional addition ':reverse' specifies that PV generation > forecast is evaluated as a positive value instead of a negative value (change of perspective). </td></tr>
|
||||||
<tr><td> </td><td><b>daily[:reverse]</b> - Calculation and creation of Today_PVdeviation takes place after sunset (default) </td></tr>
|
<tr><td> </td><td><b>daily[:reverse]</b> - Calculation and creation of Today_PVdeviation takes place after sunset (default) </td></tr>
|
||||||
<tr><td> </td><td><b>continuously[:reverse]</b> - Calculation and creation of Today_PVdeviation is continuous </td></tr>
|
<tr><td> </td><td><b>continuously[:reverse]</b> - Calculation and creation of Today_PVdeviation is continuous </td></tr>
|
||||||
<tr><td> </td><td> </td></tr>
|
<tr><td> </td><td> </td></tr>
|
||||||
@@ -29400,7 +29487,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<tr><td> <b>conForecastTillNextSunrise</b> </td><td>Verbrauchsprognose von aktueller Stunde bis zum kommenden Sonnenaufgang </td></tr>
|
<tr><td> <b>conForecastTillNextSunrise</b> </td><td>Verbrauchsprognose von aktueller Stunde bis zum kommenden Sonnenaufgang </td></tr>
|
||||||
<tr><td> <b>currentAPIinterval</b> </td><td>das aktuelle Abrufintervall der gewählten Strahlungsdaten-API in Sekunden </td></tr>
|
<tr><td> <b>currentAPIinterval</b> </td><td>das aktuelle Abrufintervall der gewählten Strahlungsdaten-API in Sekunden </td></tr>
|
||||||
<tr><td> <b>currentRunMtsConsumer_XX</b> </td><td>die Laufzeit (Minuten) des Verbrauchers "XX" seit dem letzten Einschalten. (letzter Laufzyklus) </td></tr>
|
<tr><td> <b>currentRunMtsConsumer_XX</b> </td><td>die Laufzeit (Minuten) des Verbrauchers "XX" seit dem letzten Einschalten. (letzter Laufzyklus) </td></tr>
|
||||||
<tr><td> <b>dayAfterTomorrowPVforecast</b> </td><td>liefert die Vorhersage der PV Erzeugung für Übermorgen (sofern verfügbar) ohne Autokorrektur (Rohdaten). </td></tr>
|
<tr><td> <b>dayAfterTomorrowPVforecast</b> </td><td>Liefert die Vorhersage der PV Erzeugung für Übermorgen (sofern verfügbar) ohne Autokorrektur (Rohdaten). </td></tr>
|
||||||
|
<tr><td> <b>dummyConsumption</b> </td><td>Liefert den aktuellen, Verbrauchern nicht zuordenbaren Hausverbrauch. Enthält auch Verlustleistungsanteile. </td></tr>
|
||||||
<tr><td> <b>daysUntilBatteryCare_XX</b> </td><td>Tage bis zur nächsten Batterie XX Pflege (Erreichen der Ladung 'maxSoC' aus Attribut ctrlBatSocManagementXX) </td></tr>
|
<tr><td> <b>daysUntilBatteryCare_XX</b> </td><td>Tage bis zur nächsten Batterie XX Pflege (Erreichen der Ladung 'maxSoC' aus Attribut ctrlBatSocManagementXX) </td></tr>
|
||||||
<tr><td> <b>lastretrieval_time</b> </td><td>der letzte Abrufzeitpunkt der gewählten Strahlungsdaten-API </td></tr>
|
<tr><td> <b>lastretrieval_time</b> </td><td>der letzte Abrufzeitpunkt der gewählten Strahlungsdaten-API </td></tr>
|
||||||
<tr><td> <b>lastretrieval_timestamp</b> </td><td>der Timestamp der letzen Abrufzeitpunkt der gewählten Strahlungsdaten-API </td></tr>
|
<tr><td> <b>lastretrieval_timestamp</b> </td><td>der Timestamp der letzen Abrufzeitpunkt der gewählten Strahlungsdaten-API </td></tr>
|
||||||
@@ -29913,7 +30001,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<tr><td> </td><td> </td></tr>
|
<tr><td> </td><td> </td></tr>
|
||||||
<tr><td> <b>genPVdeviation</b> </td><td>Legt die Methode zur Berechnung der Abweichung von prognostizierter und realer PV Erzeugung fest. </td></tr>
|
<tr><td> <b>genPVdeviation</b> </td><td>Legt die Methode zur Berechnung der Abweichung von prognostizierter und realer PV Erzeugung fest. </td></tr>
|
||||||
<tr><td> </td><td>Das Reading <b>Today_PVdeviation</b> wird in Abhängigkeit dieser Einstellung erstellt. </td></tr>
|
<tr><td> </td><td>Das Reading <b>Today_PVdeviation</b> wird in Abhängigkeit dieser Einstellung erstellt. </td></tr>
|
||||||
<tr><td> </td><td>Der optionale Zusatz ':reverse' legt fest, dass PV-Erzeugung > Prognose als positiver statt negativer Wert dargestellt wird (Perspektivwechsel). </td></tr>
|
<tr><td> </td><td>Der optionale Zusatz ':reverse' legt fest, dass PV-Erzeugung > Prognose als positiver statt negativer Wert gewertet wird (Perspektivwechsel). </td></tr>
|
||||||
<tr><td> </td><td><b>daily[:reverse]</b> - Berechnung und Erstellung von Today_PVdeviation erfolgt nach Sonnenuntergang (default) </td></tr>
|
<tr><td> </td><td><b>daily[:reverse]</b> - Berechnung und Erstellung von Today_PVdeviation erfolgt nach Sonnenuntergang (default) </td></tr>
|
||||||
<tr><td> </td><td><b>continuously[:reverse]</b> - Berechnung und Erstellung von Today_PVdeviation erfolgt fortlaufend </td></tr>
|
<tr><td> </td><td><b>continuously[:reverse]</b> - Berechnung und Erstellung von Today_PVdeviation erfolgt fortlaufend </td></tr>
|
||||||
<tr><td> </td><td> </td></tr>
|
<tr><td> </td><td> </td></tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user