2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-30 05:57:08 +00:00

76_SolarForecast.pm: contrib 0.51.3

git-svn-id: https://svn.fhem.de/fhem/trunk@24610 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2021-06-11 07:32:00 +00:00
parent 516afe6578
commit 530e6fc72f

View File

@ -256,6 +256,11 @@ my %hattr = ( # H
consumer => { fn => \&_attrconsumer }, consumer => { fn => \&_attrconsumer },
); );
my %htr = ( # Hash even/odd für <tr>
0 => { cl => 'even' },
1 => { cl => 'odd' },
);
my %hff = ( # Flächenfaktoren my %hff = ( # Flächenfaktoren
"0" => { N => 100, NE => 100, E => 100, SE => 100, S => 100, SW => 100, W => 100, NW => 100 }, # http://www.ing-büro-junge.de/html/photovoltaik.html "0" => { N => 100, NE => 100, E => 100, SE => 100, S => 100, SW => 100, W => 100, NW => 100 }, # http://www.ing-büro-junge.de/html/photovoltaik.html
"10" => { N => 90, NE => 93, E => 100, SE => 105, S => 107, SW => 105, W => 100, NW => 93 }, "10" => { N => 90, NE => 93, E => 100, SE => 105, S => 107, SW => 105, W => 100, NW => 93 },
@ -3605,7 +3610,6 @@ sub entryGraphic {
$hash->{HELPER}{SPGROOM} = $FW_room ? $FW_room : ""; # Raum aus dem das SolarForecastSPG-Device die Funktion aufrief $hash->{HELPER}{SPGROOM} = $FW_room ? $FW_room : ""; # Raum aus dem das SolarForecastSPG-Device die Funktion aufrief
$hash->{HELPER}{SPGDETAIL} = $FW_detail ? $FW_detail : ""; # Name des SolarForecastSPG-Devices (wenn Detailansicht) $hash->{HELPER}{SPGDETAIL} = $FW_detail ? $FW_detail : ""; # Name des SolarForecastSPG-Devices (wenn Detailansicht)
# Parameter f. Anzeige extrahieren # Parameter f. Anzeige extrahieren
################################### ###################################
my $width = AttrNum ($name, 'beamWidth', 6); # zu klein ist nicht problematisch my $width = AttrNum ($name, 'beamWidth', 6); # zu klein ist nicht problematisch
@ -3620,15 +3624,12 @@ sub entryGraphic {
my $html_end = AttrVal ($name, 'htmlEnd', undef); # beliebige HTML Strings die nach der Grafik ausgegeben werden my $html_end = AttrVal ($name, 'htmlEnd', undef); # beliebige HTML Strings die nach der Grafik ausgegeben werden
my $w = $width * $maxhours; # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px my $w = $width * $maxhours; # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
my $ret = q{};
# return $ret if ($gsel eq "none");
my $paref = { my $paref = {
hash => $hash, hash => $hash,
name => $name, name => $name,
ftui => $ftui, ftui => $ftui,
maxhours => $maxhours, maxhours => $maxhours,
modulo => 1,
dstyle => qq{style='padding-left: 10px; padding-right: 10px; padding-top: 3px; padding-bottom: 3px;'}, # TD-Style dstyle => qq{style='padding-left: 10px; padding-right: 10px; padding-top: 3px; padding-bottom: 3px;'}, # TD-Style
offset => AttrNum ($name, 'historyHour', 0), offset => AttrNum ($name, 'historyHour', 0),
hourstyle => AttrVal ($name, 'hourStyle', ''), hourstyle => AttrVal ($name, 'hourStyle', ''),
@ -3658,6 +3659,8 @@ sub entryGraphic {
flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik
}; };
my $ret = q{};
if(IsDisabled($name)) { if(IsDisabled($name)) {
$ret .= "<table class='roomoverview'>"; $ret .= "<table class='roomoverview'>";
$ret .= "<tr style='height:".$paref->{height}."px'>"; $ret .= "<tr style='height:".$paref->{height}."px'>";
@ -3687,21 +3690,29 @@ sub entryGraphic {
$paref->{legendtxt} = $legendtxt; $paref->{legendtxt} = $legendtxt;
$ret .= "\n<table class='block'>"; # das \n erleichtert das Lesen der debug Quelltextausgabe $ret .= "\n<table class='block'>"; # das \n erleichtert das Lesen der debug Quelltextausgabe
my $m = $paref->{modulo} % 2;
if ($header) { # Header ausgeben if ($header) { # Header ausgeben
$ret .= "<tr class='odd'>"; # mit einem extra <td></td> ein wenig mehr Platz machen, ergibt i.d.R. weniger als ein Zeichen $ret .= "<tr class='$htr{$m}{cl}'>";
$ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>$header</td>"; $ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>$header</td>";
$ret .= "</tr>"; $ret .= "</tr>";
$paref->{modulo}++;
} }
my $clegend = $paref->{clegend}; my $clegend = $paref->{clegend};
$m = $paref->{modulo} % 2;
if ($legendtxt && ($clegend eq 'top')) { if ($legendtxt && ($clegend eq 'top')) {
$ret .= "<tr class='odd'>"; $ret .= "<tr class='$htr{$m}{cl}'>";
$ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>$legendtxt</td>"; $ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>$legendtxt</td>";
$ret .= "</tr>"; $ret .= "</tr>";
$paref->{modulo}++;
} }
$m = $paref->{modulo} % 2;
if($gsel eq "both" || $gsel eq "forecast") { if($gsel eq "both" || $gsel eq "forecast") {
my %hfch; my %hfch;
my $hfcg = \%hfch; #(hfcg = hash forecast graphic) my $hfcg = \%hfch; #(hfcg = hash forecast graphic)
@ -3730,17 +3741,23 @@ sub entryGraphic {
$ret .= _beamGraphic ($paref); $ret .= _beamGraphic ($paref);
} }
$m = $paref->{modulo} % 2;
if($gsel eq "both" || $gsel eq "flow") { if($gsel eq "both" || $gsel eq "flow") {
$ret .= "<tr class='even'>"; $ret .= "<tr class='$htr{$m}{cl}'>";
my $fg = _flowGraphic ($paref); my $fg = _flowGraphic ($paref);
$ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>$fg</td>"; $ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>$fg</td>";
$ret .= "</tr>"; $ret .= "</tr>";
$paref->{modulo}++;
} }
$m = $paref->{modulo} % 2;
# Legende unten # Legende unten
################# #################
if ($legendtxt && ($clegend eq 'bottom')) { if ($legendtxt && ($clegend eq 'bottom')) {
$ret .= "<tr class='odd'>"; $ret .= "<tr class='$htr{$m}{cl}'>";
$ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>"; $ret .= "<td colspan='".($maxhours+2)."' align='center' style='word-break: normal'>";
$ret .= "$legendtxt</td></tr>"; $ret .= "$legendtxt</td></tr>";
} }
@ -4375,9 +4392,7 @@ sub _beamGraphic {
my $hash = $paref->{hash}; my $hash = $paref->{hash};
my $name = $paref->{name}; my $name = $paref->{name};
my $hfcg = $paref->{hfcg}; my $hfcg = $paref->{hfcg};
my $header = $paref->{header};
my $maxhours = $paref->{maxhours}; my $maxhours = $paref->{maxhours};
my $legendtxt = $paref->{legendtxt};
my $weather = $paref->{weather}; my $weather = $paref->{weather};
my $show_night = $paref->{show_night}; # alle Balken (Spalten) anzeigen ? my $show_night = $paref->{show_night}; # alle Balken (Spalten) anzeigen ?
my $show_diff = $paref->{show_diff}; # zusätzliche Anzeige $di{} in allen Typen my $show_diff = $paref->{show_diff}; # zusätzliche Anzeige $di{} in allen Typen
@ -4394,7 +4409,7 @@ sub _beamGraphic {
my $fcolor2 = $paref->{fcolor2}; my $fcolor2 = $paref->{fcolor2};
my $offset = $paref->{offset}; my $offset = $paref->{offset};
my $thishour = $paref->{thishour}; my $thishour = $paref->{thishour};
my $maxVal = $paref->{maxVal}; # Startwert wenn kein Wert bereits via attr vorgegeben ist my $maxVal = $paref->{maxVal};
my $maxCon = $paref->{maxCon}; my $maxCon = $paref->{maxCon};
my $maxDif = $paref->{maxDif}; my $maxDif = $paref->{maxDif};
my $minDif = $paref->{minDif}; my $minDif = $paref->{minDif};
@ -4410,18 +4425,21 @@ sub _beamGraphic {
my ($val,$z2,$z3,$z4,$he); my ($val,$z2,$z3,$z4,$he);
my $ret; my $ret;
my $m = $paref->{modulo} % 2;
if ($weather) { if ($weather) {
$ret .= "<tr class='even'><td class='solarfc'></td>"; # freier Platz am Anfang $ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>"; # freier Platz am Anfang
my $ii; my $ii;
for my $i (0..($maxhours*2)-1) { for my $i (0..($maxhours*2)-1) {
last if (!exists($hfcg->{$i}{weather})); last if (!exists($hfcg->{$i}{weather}));
next if (!$show_night && defined($hfcg->{$i}{weather}) && ($hfcg->{$i}{weather} > 99) && !$hfcg->{$i}{beam1} && !$hfcg->{$i}{beam2}); next if (!$show_night && defined($hfcg->{$i}{weather})
&& ($hfcg->{$i}{weather} > 99)
&& !$hfcg->{$i}{beam1}
&& !$hfcg->{$i}{beam2});
# Lässt Nachticons aber noch durch wenn es einen Wert gibt , ToDo : klären ob die Nacht richtig gesetzt wurde # Lässt Nachticons aber noch durch wenn es einen Wert gibt , ToDo : klären ob die Nacht richtig gesetzt wurde
$ii++; # wieviele Stunden Icons haben wir bisher beechnet ? $ii++; # wieviele Stunden Icons haben wir bisher beechnet ?
last if ($ii > $maxhours); last if ($ii > $maxhours);
# ToDo : weather_icon sollte im Fehlerfall Title mit der ID besetzen um in FHEMWEB sofort die ID sehen zu können # ToDo : weather_icon sollte im Fehlerfall Title mit der ID besetzen um in FHEMWEB sofort die ID sehen zu können
if (exists($hfcg->{$i}{weather}) && defined($hfcg->{$i}{weather})) { if (exists($hfcg->{$i}{weather}) && defined($hfcg->{$i}{weather})) {
my ($icon_name, $title) = $hfcg->{$i}{weather} > 100 ? weather_icon($hfcg->{$i}{weather}-100) : weather_icon($hfcg->{$i}{weather}); my ($icon_name, $title) = $hfcg->{$i}{weather} > 100 ? weather_icon($hfcg->{$i}{weather}-100) : weather_icon($hfcg->{$i}{weather});
@ -4435,10 +4453,9 @@ sub _beamGraphic {
Log3 ($name, 2, qq{$name - the icon $hfcg->{$i}{weather} not found. Please check attribute "iconPath" of your FHEMWEB instance and/or update your FHEM software}); Log3 ($name, 2, qq{$name - the icon $hfcg->{$i}{weather} not found. Please check attribute "iconPath" of your FHEMWEB instance and/or update your FHEM software});
} }
$ret .= "<td title='$title' class='solarfc' width='$width' style='margin:1px; vertical-align:middle align:center; padding-bottom:1px;'>$val</td>"; # title -> Mouse Over Text $ret .= "<td title='$title' class='solarfc' width='$width' style='margin:1px; vertical-align:middle align:center; padding-bottom:1px;'>$val</td>";
# mit $hfcg->{$i}{weather} = undef kann man unten leicht feststellen ob für diese Spalte bereits ein Icon ausgegeben wurde oder nicht
} }
else { else { # mit $hfcg->{$i}{weather} = undef kann man unten leicht feststellen ob für diese Spalte bereits ein Icon ausgegeben wurde oder nicht
$ret .= "<td></td>"; $ret .= "<td></td>";
$hfcg->{$i}{weather} = undef; # ToDo : prüfen ob noch nötig $hfcg->{$i}{weather} = undef; # ToDo : prüfen ob noch nötig
} }
@ -4448,10 +4465,12 @@ sub _beamGraphic {
} }
if($show_diff eq 'top') { # Zusätzliche Zeile Ertrag - Verbrauch if($show_diff eq 'top') { # Zusätzliche Zeile Ertrag - Verbrauch
$ret .= "<tr class='even'><td class='solarfc'></td>"; # freier Platz am Anfang $ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>";
my $ii; my $ii;
for my $i (0..($maxhours*2)-1) { # gleiche Bedingung wie oben for my $i (0..($maxhours*2)-1) { # gleiche Bedingung wie oben
next if (!$show_night && ($hfcg->{$i}{weather} > 99) && !$hfcg->{$i}{beam1} && !$hfcg->{$i}{beam2}); next if (!$show_night && ($hfcg->{$i}{weather} > 99)
&& !$hfcg->{$i}{beam1}
&& !$hfcg->{$i}{beam2});
$ii++; # wieviele Stunden haben wir bisher angezeigt ? $ii++; # wieviele Stunden haben wir bisher angezeigt ?
last if ($ii > $maxhours); # vorzeitiger Abbruch last if ($ii > $maxhours); # vorzeitiger Abbruch
@ -4462,12 +4481,15 @@ sub _beamGraphic {
$ret .= "<td class='solarfc'></td></tr>"; # freier Platz am Ende $ret .= "<td class='solarfc'></td></tr>"; # freier Platz am Ende
} }
$ret .= "<tr class='even'><td class='solarfc'></td>"; # Neue Zeile mit freiem Platz am Anfang $ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>"; # Neue Zeile mit freiem Platz am Anfang
my $ii = 0; my $ii = 0;
for my $i (0..($maxhours*2)-1) { # gleiche Bedingung wie oben for my $i (0..($maxhours*2)-1) { # gleiche Bedingung wie oben
next if (!$show_night && defined($hfcg->{$i}{weather}) && ($hfcg->{$i}{weather} > 99) && !$hfcg->{$i}{beam1} && !$hfcg->{$i}{beam2}); next if (!$show_night && defined($hfcg->{$i}{weather})
&& ($hfcg->{$i}{weather} > 99)
&& !$hfcg->{$i}{beam1}
&& !$hfcg->{$i}{beam2});
$ii++; $ii++;
last if ($ii > $maxhours); last if ($ii > $maxhours);
@ -4511,7 +4533,7 @@ sub _beamGraphic {
} }
} }
if ($lotype eq 'diff') { # Typ diff if ($lotype eq 'diff') {
# Berechnung der Zonen # Berechnung der Zonen
# he - freier der Raum über den Balken , Zahl positiver Wert + fsize # he - freier der Raum über den Balken , Zahl positiver Wert + fsize
# z2 - positiver Balken inkl Icon # z2 - positiver Balken inkl Icon
@ -4550,14 +4572,12 @@ sub _beamGraphic {
$z2 = $maxDif; $z2 = $maxDif;
$z3 = abs($hfcg->{$i}{diff}); # Nur Betrag ohne Vorzeichen $z3 = abs($hfcg->{$i}{diff}); # Nur Betrag ohne Vorzeichen
} }
# Alle vorbesetzen Werte umrechnen auf echte Ausgabe px # Alle vorbesetzen Werte umrechnen auf echte Ausgabe px
$he = (!$px_pos || !$maxDif) ? 0 : int(($maxDif-$z2)/$maxDif*$px_pos); # Teilung durch 0 vermeiden $he = (!$px_pos || !$maxDif) ? 0 : int(($maxDif-$z2)/$maxDif*$px_pos); # Teilung durch 0 vermeiden
$z2 = ($px_pos - $he) ; $z2 = ($px_pos - $he) ;
$z4 = (!$px_neg || !$minDif) ? 0 : int((abs($minDif)-$z3)/abs($minDif)*$px_neg); # Teilung durch 0 unbedingt vermeiden $z4 = (!$px_neg || !$minDif) ? 0 : int((abs($minDif)-$z3)/abs($minDif)*$px_neg); # Teilung durch 0 unbedingt vermeiden
$z3 = ($px_neg - $z4); $z3 = ($px_neg - $z4);
# Beiden Zonen die Werte ausgeben könnten muß fsize als zusätzlicher Raum zugeschlagen werden ! # Beiden Zonen die Werte ausgeben könnten muß fsize als zusätzlicher Raum zugeschlagen werden !
$he += $fsize; $he += $fsize;
$z4 += $fsize if ($z3); # komplette Grafik ohne negativ Balken, keine Ausgabe von z3 & z4 $z4 += $fsize if ($z3); # komplette Grafik ohne negativ Balken, keine Ausgabe von z3 & z4
@ -4573,7 +4593,7 @@ sub _beamGraphic {
$val = formatVal6($hfcg->{$i}{beam1},$kw,$hfcg->{$i}{weather}); $val = formatVal6($hfcg->{$i}{beam1},$kw,$hfcg->{$i}{weather});
$ret .="<table width='100%' height='100%'>"; # mit width=100% etwas bessere Füllung der Balken $ret .="<table width='100%' height='100%'>"; # mit width=100% etwas bessere Füllung der Balken
$ret .="<tr class='even' style='height:".$he."px'>"; $ret .="<tr class='$htr{$m}{cl}' style='height:".$he."px'>";
$ret .="<td class='solarfc' style='vertical-align:bottom; color:#$fcolor1;'>".$val.'</td></tr>'; $ret .="<td class='solarfc' style='vertical-align:bottom; color:#$fcolor1;'>".$val.'</td></tr>';
if ($hfcg->{$i}{beam1} || $show_night) { # Balken nur einfärben wenn der User via Attr eine Farbe vorgibt, sonst bestimmt class odd von TR alleine die Farbe if ($hfcg->{$i}{beam1} || $show_night) { # Balken nur einfärben wenn der User via Attr eine Farbe vorgibt, sonst bestimmt class odd von TR alleine die Farbe
@ -4599,9 +4619,8 @@ sub _beamGraphic {
my $style = "style='padding-bottom:0px; padding-top:1px; vertical-align:top; margin-left:auto; margin-right:auto;"; my $style = "style='padding-bottom:0px; padding-top:1px; vertical-align:top; margin-left:auto; margin-right:auto;";
$ret .="<table width='100%' height='100%'>\n"; # mit width=100% etwas bessere Füllung der Balken $ret .="<table width='100%' height='100%'>\n"; # mit width=100% etwas bessere Füllung der Balken
# der Freiraum oben kann beim größten Balken ganz entfallen # der Freiraum oben kann beim größten Balken ganz entfallen
$ret .="<tr class='even' style='height:".$he."px'><td class='solarfc'></td></tr>" if ($he); $ret .="<tr class='$htr{$m}{cl}' style='height:".$he."px'><td class='solarfc'></td></tr>" if ($he);
if($hfcg->{$i}{beam1} > $hfcg->{$i}{beam2}) { # wer ist oben, Beam2 oder Beam1 ? Wert und Farbe für Zone 2 & 3 vorbesetzen if($hfcg->{$i}{beam1} > $hfcg->{$i}{beam2}) { # wer ist oben, Beam2 oder Beam1 ? Wert und Farbe für Zone 2 & 3 vorbesetzen
$val = formatVal6($hfcg->{$i}{beam1},$kw,$hfcg->{$i}{weather}); $val = formatVal6($hfcg->{$i}{beam1},$kw,$hfcg->{$i}{weather});
@ -4649,7 +4668,7 @@ sub _beamGraphic {
$val = '&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;' if ($hfcg->{$i}{diff} == 0); # Sonderfall , hier wird die 0 gebraucht ! $val = '&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;' if ($hfcg->{$i}{diff} == 0); # Sonderfall , hier wird die 0 gebraucht !
if ($val) { if ($val) {
$ret .= "<tr class='even' style='height:".$he."px'>"; $ret .= "<tr class='$htr{$m}{cl}' style='height:".$he."px'>";
$ret .= "<td class='solarfc' style='vertical-align:bottom; color:#$fcolor1;'>".$val."</td></tr>"; $ret .= "<td class='solarfc' style='vertical-align:bottom; color:#$fcolor1;'>".$val."</td></tr>";
} }
@ -4663,7 +4682,7 @@ sub _beamGraphic {
else { # ohne Farbe else { # ohne Farbe
$z2 = 2 if ($hfcg->{$i}{diff} == 0); # Sonderfall, hier wird die 0 gebraucht ! $z2 = 2 if ($hfcg->{$i}{diff} == 0); # Sonderfall, hier wird die 0 gebraucht !
if ($z2 && $val) { # z2 weglassen wenn nicht unbedigt nötig bzw. wenn zuvor he mit val keinen Wert hatte if ($z2 && $val) { # z2 weglassen wenn nicht unbedigt nötig bzw. wenn zuvor he mit val keinen Wert hatte
$ret .= "<tr class='even' style='height:".$z2."px'>"; $ret .= "<tr class='$htr{$m}{cl}' style='height:".$z2."px'>";
$ret .= "<td class='solarfc'></td></tr>"; $ret .= "<td class='solarfc'></td></tr>";
} }
} }
@ -4674,13 +4693,13 @@ sub _beamGraphic {
$ret .= "<td align='center' class='solarfc' ".$style."></td></tr>"; $ret .= "<td align='center' class='solarfc' ".$style."></td></tr>";
} }
elsif ($z3) { # ohne Farbe elsif ($z3) { # ohne Farbe
$ret .= "<tr class='even' style='height:".$z3."px'>"; $ret .= "<tr class='$htr{$m}{cl}' style='height:".$z3."px'>";
$ret .= "<td class='solarfc'></td></tr>"; $ret .= "<td class='solarfc'></td></tr>";
} }
if($z4) { # kann entfallen wenn auch z3 0 ist if($z4) { # kann entfallen wenn auch z3 0 ist
$val = ($hfcg->{$i}{diff} < 0) ? formatVal6($hfcg->{$i}{diff},$kw,$hfcg->{$i}{weather}) : '&nbsp;'; $val = ($hfcg->{$i}{diff} < 0) ? formatVal6($hfcg->{$i}{diff},$kw,$hfcg->{$i}{weather}) : '&nbsp;';
$ret .= "<tr class='even' style='height:".$z4."px'>"; $ret .= "<tr class='$htr{$m}{cl}' style='height:".$z4."px'>";
$ret .= "<td class='solarfc' style='vertical-align:top'>".$val."</td></tr>"; $ret .= "<td class='solarfc' style='vertical-align:top'>".$val."</td></tr>";
} }
} }
@ -4688,10 +4707,10 @@ sub _beamGraphic {
if ($show_diff eq 'bottom') { # zusätzliche diff Anzeige if ($show_diff eq 'bottom') { # zusätzliche diff Anzeige
$val = formatVal6($hfcg->{$i}{diff},$kw,$hfcg->{$i}{weather}); $val = formatVal6($hfcg->{$i}{diff},$kw,$hfcg->{$i}{weather});
$val = ($hfcg->{$i}{diff} < 0) ? '<b>'.$val.'<b/>' : ($val > 0 ) ? '+'.$val : $val if ($val ne '&nbsp;'); # negative Zahlen in Fettschrift, 0 aber ohne + $val = ($hfcg->{$i}{diff} < 0) ? '<b>'.$val.'<b/>' : ($val > 0 ) ? '+'.$val : $val if ($val ne '&nbsp;'); # negative Zahlen in Fettschrift, 0 aber ohne +
$ret .= "<tr class='even'><td class='solarfc' style='vertical-align:middle; text-align:center;'>$val</td></tr>"; $ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc' style='vertical-align:middle; text-align:center;'>$val</td></tr>";
} }
$ret .= "<tr class='even'><td class='solarfc' style='vertical-align:bottom; text-align:center;'>"; $ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc' style='vertical-align:bottom; text-align:center;'>";
$ret .= (($hfcg->{$i}{time} == $thishour) && ($offset < 0)) ? '<a class="changed" style="visibility:visible"><span>'.$hfcg->{$i}{time_str}.'</span></a>' : $hfcg->{$i}{time_str}; $ret .= (($hfcg->{$i}{time} == $thishour) && ($offset < 0)) ? '<a class="changed" style="visibility:visible"><span>'.$hfcg->{$i}{time_str}.'</span></a>' : $hfcg->{$i}{time_str};
if($hfcg->{$i}{time} == $thishour) { if($hfcg->{$i}{time} == $thishour) {
@ -4701,6 +4720,8 @@ sub _beamGraphic {
$ret .="</td></tr></table></td>"; $ret .="</td></tr></table></td>";
} }
$paref->{modulo}++;
$ret .= "<td class='solarfc'></td>"; $ret .= "<td class='solarfc'></td>";
$ret .= "</tr>"; $ret .= "</tr>";