defmod WR_ctl DOIF ################################################################################################################\ ## 1 Scheduling für das Abholen der Wechselrichter Statistiken\ ## Umschaltung des Schattenmanagements\ ##\ 20_Statistic_EnergyFlow\ {if( !([$SELF:state] eq "off") ## DOIF enabled\ and\ ( [:57] ## Kurz vor jeder vollen Stunde\ )\ or [$SELF:ui_command_2] eq "20_Statistic_EnergyFlow" ## Hier wird das uiTable select ausgewertet\ ) {\ \ ::CommandGet(undef, "WR_2_API 20_Statistic_EnergyFlow");; ## Zuerst WR_2 und anschließend\ set_Exec("wait_Statistic",2,'::CommandGet(undef, "WR_1_API 20_Statistic_EnergyFlow")');; ## WR_1, damit die Schwarm Werte stimmen\ \ if (AttrVal("$SELF","verbose",0) >=3) {\ Log 3, "$SELF cmd_1 : Abfrage der Statistiken";;\ }\ \ set_Reading("ui_command_2","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ ## kann das Kommando nicht sofort wiederholt werden\ }\ }\ \ ################################################################################################################\ ## 2 Start der KI Prognose\ ## Der Reading Name und das Device werden in LogDBRep_PV_KI_Prognose im executeAfterProc eingestellt\ ## "/opt/fhem/python/bin/PV_KI_Prognose.py 192.168.178.40 192.168.178.40 LogDBRep_PV_KI_Prognose WR_1_ctl Yield_fc"\ ##\ 2_KI_Prognose\ {if( !([$SELF:state] eq "off") ## DOIF enabled\ and\ (\ ReadingsVal("LogDBRep_PV_KI_Prognose","PV_KI_Prognose","null") eq "done" ## Die Prognose darf nicht gerade laufen !!!\ or\ ReadingsVal("LogDBRep_PV_KI_Prognose","state","null") eq "initialized"\ )\ and\ (\ ([05:00-22:00] and [:03] ## In der PV-Zeit jede Stunde aktualisieren\ )\ or [$SELF:ui_command_1] eq "2_KI_Prognose" ## Hier wird das uiTable select ausgewertet\ )\ ) {\ \ if ($hour == 5) {\ ::CommandSet(undef, "LogDBRep_PV_KI_Prognose sqlCmd call dwd_load('full',curdate(),'none')");;\ } else {\ ::CommandSet(undef, "LogDBRep_PV_KI_Prognose sqlCmd call dwd_load('update',curdate(),'none')");;\ }\ \ if (AttrVal("$SELF","verbose",0) >=3) {\ Log 3, "$SELF 2_KI_Prognose : Start KI Prognose";;\ }\ \ set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ ## kann das Kommando nicht sofort wiederholt werden\ }\ }\ \ ################################################################################################################\ ## 2 Erstellen des Diagramms im uiTable\ 3_WR_ctl_Diagramm\ {if( !([$SELF:state] eq "off") ## DOIF enabled\ and [$SELF:Yield_fc0_06] ## Wenn die Prognose aktualisiert wurde\ or [$SELF:ui_command_1] eq "3_WR_ctl_Diagramm" ## Hier wird das uiTable select ausgewertet\ ) {\ \ my (@out) = ("") x 2;; ## Es wird für jedes Diagramm ein Array benötigt\ my $timestamp;;\ \ for (my $j=0;;$j<=1;;$j++){ ## loop fc0 und fc1\ for (my $i=5;;$i<=21;;$i++){ ## loop für die PV-Zeit\ $timestamp = sprintf("%s_%02d:00:00", POSIX::strftime("%Y-%m-%d",localtime(time+86400*$j)), $i);;\ $out[$j] .= $timestamp." ".::round(::ReadingsVal("$SELF",sprintf("Yield_fc%d_%02d",$j, $i),0)/1000,2)."\n";;\ } # End $i\ } # End $j\ if (AttrVal("$SELF","verbose",0) >=3) {\ Log 3, "$SELF 3_WR_ctl_Diagramm : Werte für das Diagramm";;\ print($out[0]."\n\n");;\ print($out[1]."\n");;\ }\ ## Yield_fc*_current dient nur als Trigger für die card Diagramme, damit diese im uiTable aktualisiert werden.\ ::DOIF_modify_card_data("$SELF","$SELF","Yield_fc0_current","bar1day",0,$out[0]);; ## Der fc1 wird verschoben, da card nicht\ ::DOIF_modify_card_data("$SELF","$SELF","Yield_fc1_current","bar1day",-86400,$out[1]);; ## den nächsten Tag anzeigen kann\ \ set_Reading("ui_command_1","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ ## kann das Kommando nicht sofort wiederholt werden\ }\ }\ \ ################################################################################################################\ ## 4 WR_1_API setzen der init Werte für die Berechnung des Hausverbrauches. Bei Fehlern in der Verbrauchsanzeige\ ## muss man die ersten Werte des Tages gegen 00:01 aus der DB setzen. \ 4_WR_1_API_init_Werte\ {if( !([$SELF:state] eq "off") ## DOIF enabled\ and\ [00:01]\ or [$SELF:ui_command_2] eq "4_WR_1_API_init_Werte" ## Hier wird das uiTable select ausgewertet\ ) {\ if ($hour > 0) {\ ## Achtung, der init Wert muss auf den ersten Wert des Tages korrigiert werden, dieser ist in der DB\ \ ## Korrektur der Tages Werte\ my $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ SELECT VALUE FROM history\ WHERE DEVICE='WR_0_KSEM'\ AND READING='Active_energy-'\ AND TIMESTAMP > curdate() - interval 1 month\ AND TIMESTAMP <= concat(curdate(),' 00:01')\ ORDER BY TIMESTAMP desc\ LIMIT 1;;") ;;\ fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Day $Active_energy");;\ \ $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ SELECT VALUE FROM history\ WHERE DEVICE='WR_0_KSEM'\ AND READING='Active_energy+'\ AND TIMESTAMP > curdate() - interval 1 month\ AND TIMESTAMP <= concat(curdate(),' 00:01')\ ORDER BY TIMESTAMP desc\ LIMIT 1;;") ;;\ fhem("setreading WR_1_API SW_Meter_init_Grid_Day $Active_energy");;\ \ ## Korrektur der Monats Werte\ $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ SELECT VALUE FROM history\ WHERE DEVICE='WR_0_KSEM'\ AND READING='Active_energy-'\ AND TIMESTAMP > curdate() - interval 1 month\ AND TIMESTAMP <= subdate(curdate(), (day(curdate())-1))\ ORDER BY TIMESTAMP desc\ LIMIT 1;;") ;;\ fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Month $Active_energy");;\ \ $Active_energy = ::CommandGet(undef, "LogDBRep_$SELF_SQL sqlCmdBlocking\ SELECT VALUE FROM history\ WHERE DEVICE='WR_0_KSEM'\ AND READING='Active_energy+'\ AND TIMESTAMP > curdate() - interval 1 month\ AND TIMESTAMP <= LAST_DAY(SUBDATE(curdate(), INTERVAL 1 MONTH))\ ORDER BY TIMESTAMP desc\ LIMIT 1;;") ;;\ fhem("setreading WR_1_API SW_Meter_init_Grid_Month $Active_energy");;\ \ ::CommandGet(undef, "WR_2_API 20_Statistic_EnergyFlow");; ## Zuerst WR_2 und anschließend\ ::CommandGet(undef, "WR_1_API 20_Statistic_EnergyFlow");; ## WR_1, damit die Schwarm Werte stimmen\ \ } else {\ fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Day ".[?WR_0_KSEM:Active_energy-]);;\ fhem("setreading WR_1_API SW_Meter_init_Grid_Day ".[?WR_0_KSEM:Active_energy+]);;\ }\ \ if ($mday eq 1) {\ fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Month ".[?WR_0_KSEM:Active_energy-]);;\ fhem("setreading WR_1_API SW_Meter_init_Grid_Month ".[?WR_0_KSEM:Active_energy+]);;\ \ if ($yday eq 0) {\ fhem("setreading WR_1_API SW_Meter_init_FeedInGrid_Year ".[?WR_0_KSEM:Active_energy-]);;\ fhem("setreading WR_1_API SW_Meter_init_Grid_Year ".[?WR_0_KSEM:Active_energy+]);;\ }\ }\ \ if (AttrVal("$SELF","verbose",0) >=3) {\ Log 3, "$SELF 4_WR_1_API_init_Werte : init Werte gesetzt";;\ }\ \ set_Reading("ui_command_2","---");; ## Hier wird das uiTable select wieder zurückgesetzt, ansonsten\ ## kann das Kommando nicht sofort wiederholt werden\ }\ }\ attr WR_ctl DbLogExclude .* attr WR_ctl DbLogInclude Yield_fc0_day,Yield_fc0_middayhigh.* attr WR_ctl comment Version 2024.04.02 10:00 \ \ Die readings Yield_fc* werden direkt vom KI Prognose Skript in die Datenbank geschrieben und müssen hier nicht extra gelogged werden. attr WR_ctl disable 0 attr WR_ctl group PV Eigenverbrauch attr WR_ctl icon sani_solar attr WR_ctl room 2_PV_Steuerung,Strom->Photovoltaik attr WR_ctl sortby 11 attr WR_ctl uiState {\ package ui_Table;;\ $TABLE = "style='width:100%;;'";;\ \ $TD{0..6}{0} = "style='border-top-style:solid;;border-bottom-style:solid;;border-left-style:solid;;border-left-width:2px;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ $TD{0..6}{1..4} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ $TD{0..6}{5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ \ }\ \ "KI Prognose Kommando Auswahl
Mittags Limit Inverter_Max_Power / KI Status
"|\ widget([$SELF:ui_command_1],"uzsuDropDown,---,2_KI_Prognose,3_WR_ctl_Diagramm") |\ ""|\ ""|\ "MySQL ".[LogDBRep_PV_KI_Prognose:state]."
KI ".([LogDBRep_PV_KI_Prognose:state] ne "done") ? "waiting" : [LogDBRep_PV_KI_Prognose:PV_KI_Prognose]\ \ "Statistiken"|\ Yield(0)|\ Yield('Tag')|\ Yield('4h')|\ Yield('Rest')\ \ card([$SELF:Yield_fc0_current:bar1day],undef,undef,0,17,90,0,"fc0 kWh",undef,"2","130,,,,,,220").card([$SELF:Yield_fc1_current:bar1day],undef,undef,0,17,90,0,"fc1 kWh",undef,"2","130,,,,,,220")|\ "nächste 3h

".Yield(1)."
".Yield(2)."
".Yield(3)|\ "Vor- / Nachmittag

".Yield('Vormittag')."
".Yield('Nachmittag')|\ "Maximum


".Yield("max")."
".Yield("max_time")|\ "Mittagshoch


fc0 ".[$SELF:Yield_fc0_middayhigh_start]." - ".[$SELF:Yield_fc0_middayhigh_stop]."
fc1 ".[$SELF:Yield_fc1_middayhigh_start]." - ".[$SELF:Yield_fc1_middayhigh_stop]\ \ "WR_1 / KSEM
/ PV Reserve / Netz Leistung
"|\ ""|\ sprintf("%d W",[WR_1:SW_Total_PV_P_reserve])|\ (::ReadingsVal("WR_1","Total_Active_P_EM",0) < -10) ? "Einspeisen" : (::ReadingsVal("WR_1","Total_Active_P_EM",0) > 15)? "Netzbezug" : "Standby"|\ sprintf("%d W",[WR_1:Total_Active_P_EM])\ \ "Ertrag aktuell
/ Tag / Monat / Jahr
"|\ ""|\ sprintf("%d kWh",::round([WR_1:SW_Yield_Daily]/1000 ,0))|\ sprintf("%d kWh",::round([WR_1:SW_Yield_Monthly]/1000 ,0))|\ sprintf("%d kWh",::round([WR_1:SW_Yield_Yearly]/1000 ,0))\ \ "Speicher
Temperatur / nutzbare Ladung / Status / Leistung / akt. SOC
"|\ (::ReadingsVal("WR_1_API","DigitalOutputs_ConfigurationFlags",0) == 9) ? "Lüfter An
" : "
".sprintf("%.1f °C",::ReadingsVal("WR_1","Battery_temperature",0))|\ sprintf("%d Wh",::ReadingsVal("WR_1","Actual_Battery_charge_usable_P",0))|\ Status_Speicher()|\ [WR_1:Actual_Battery_charge_-minus_or_discharge_-plus_P]." W
".sprintf("%d %%",[WR_1:Act_state_of_charge])\ \ "WR_1_API
Kommando Auswahl
"|\ widget([$SELF:ui_command_2],"uzsuDropDown,---,20_Statistic_EnergyFlow,4_WR_1_API_init_Werte") |\ ""|\ ""|\ "" attr WR_ctl uiTable {\ package ui_Table;;\ $TABLE = "style='width:100%;;'";;\ \ $TD{0..18}{0} = "style='border-top-style:solid;;border-bottom-style:solid;;border-left-style:solid;;border-left-width:2px;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:36%;;font-weight:bold;;'";;\ $TD{0..18}{1..5} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:1px;;width:8%;;text-align:center;;'";;\ $TD{0..18}{6} = "style='border-top-style:solid;;border-bottom-style:solid;;border-right-style:solid;;border-color:darkgreen;;border-top-width:2px;;border-bottom-width:2px;;border-right-width:2px;;width:8%;;text-align:center;;'";;\ \ sub FUNC_Status {\ my($value, $min, $colorMin, $statusMin, $colorMiddel, $statusMiddle, $max, $colorMax, $statusMax)=@_;;\ my $ret = ($value < $min)? ''.$statusMin.'' : ($value > $max)? ''.$statusMax.'' : ''.$statusMiddle.'';;\ return $ret;;\ }\ \ sub Status_Speicher {\ if (::ReadingsVal("WR_1","Actual_Battery_charge_-minus_or_discharge_-plus_P",0) < -10) {\ return "Laden
".::ReadingsVal("WR_1","State_of_EM","n/a")\ } elsif (::ReadingsVal("WR_1","Actual_Battery_charge_-minus_or_discharge_-plus_P",0) > 15) {\ return "Entladen
".::ReadingsVal("WR_1","State_of_EM","n/a")\ } else {\ return "Standby"."
".::ReadingsVal("WR_1","State_of_EM","n/a")\ }\ }\ sub Yield {\ my($i)=@_;;\ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;;\ \ if ($i eq "4h") {\ return sprintf("%05d 4h",::ReadingsVal("$SELF","Yield_fc0_4h",0));;\ } elsif ($i eq "Tag") {\ return sprintf("%05d Tag",::ReadingsVal("$SELF","Yield_fc0_day",0));;\ } elsif ($i eq "Rest") {\ return sprintf("%05d Rest",::ReadingsVal("$SELF","Yield_fc0_rest",0));;\ } elsif ($i eq "max") {\ return sprintf("%05d Wh",::ReadingsVal("$SELF","Yield_fc0_max",0));;\ } elsif ($i eq "max_time") {\ return ::ReadingsVal("$SELF","Yield_fc0_max_time","null");;\ } elsif ($i eq "Vormittag") {\ return sprintf("%05d Wh",::ReadingsVal("$SELF","Yield_fc0_morning",0));;\ } elsif ($i eq "Nachmittag") {\ return sprintf("%05d Wh",::ReadingsVal("$SELF","Yield_fc0_afternoon",0));;\ }\ my $j = $i + $hour;;\ if ($j > 23) {\ if ($j == 24) {$j = 0}\ elsif ($j == 25) {$j = 1}\ elsif ($j == 26) {$j = 2}\ }\ return sprintf("%02d : %05d Wh",$j,::ReadingsVal("$SELF","Yield_fc0_".sprintf("%02d",$j),0));;\ }\ \ sub WR_ctl_Format {\ my($period,$device,$reading)=@_;;\ my $value = 0;;\ \ my $DayBefore = "LogDBRep_Statistic_previous_Day";;\ my $DayPrevious = ::ReadingsTimestamp("$DayBefore",$device."_".$reading."_Day","null");;\ $DayPrevious = ($DayPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$DayBefore",$device."_".$reading."_Day","null")))) : "null";;\ \ if ($period eq "_Dx") {\ if ($DayPrevious ne "null") {\ return " / gestern";;\ }\ }\ \ my $MonthBefore = "LogDBRep_Statistic_previous_Month";;\ my $MonthPrevious = ::ReadingsTimestamp("$MonthBefore",$device."_".$reading."_Month","null");;\ $MonthPrevious = ($MonthPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$MonthBefore",$device."_".$reading."_Month","null")))) : "null";;\ \ if ($period eq "_Mx") {\ if ($MonthPrevious ne "null") {\ return " / Vormonat";;\ }\ }\ \ my $QuarterBefore = "LogDBRep_Statistic_previous_Quarter";;\ my $QuarterPrevious = "null";;\ if ($period eq "_Qx" or $period eq "_Quarter" or $period eq "time_Quarter") {\ foreach my $loop (1,2,3,4) {\ if (::ReadingsVal("$QuarterBefore","Q".$loop,0) eq "previous") { \ $QuarterPrevious = "Q".$loop \ }\ }\ if ($period eq "_Qx") {\ if ( $QuarterPrevious ne "null") {\ return $QuarterPrevious;;\ }\ }\ }\ \ my $YearBefore = "LogDBRep_Statistic_previous_Year";;\ my $YearPrevious = ::ReadingsTimestamp($YearBefore,$reading."_Year","null");;\ $YearPrevious = ($YearPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp("$YearBefore",$reading."_Year","null")))) : "null";;\ \ if ($period eq "_Yx") {\ if ($YearPrevious ne "null") {\ return " / Vorjahr";;\ }\ }\ \ if ($period eq "_Year") {\ $YearPrevious = ::ReadingsTimestamp($YearBefore,$reading.$period,"null");;\ $YearPrevious = ($YearPrevious ne "null") ? POSIX::strftime("%Y",localtime(::time_str2num(::ReadingsTimestamp($YearBefore,$reading.$period,"null")))) : "null";;\ }\ \ if ($period eq "actual" and $reading eq "Autarky") {\ my $valA = ::ReadingsVal($device, "SW_Total_AC_Active_P",0) - ::ReadingsVal($device, "SW_Home_own_consumption_from_grid",0);;\ my $calcVal = ($valA > 0) ? ::round($valA /($valA + ::ReadingsVal($device, "SW_Home_own_consumption_from_grid",0))*100 ,0) : 0;;\ return sprintf("%3d %%",(($calcVal > 100) ? 100 : $calcVal) );;\ }\ \ if ($period eq "actual" and $reading eq "OwnConsumptionRate") {\ my $valS = ::ReadingsVal($device,"SW_Total_AC_Active_P",0);;\ my $calcVal = ($valS > 0) ? ::round((::ReadingsVal($device,"SW_Home_own_consumption_from_PV",0) +\ ::ReadingsVal($device,"SW_Home_own_consumption_from_Battery",0)) / $valS * 100 ,0) : 0;;\ return sprintf("%3d %%",(($calcVal > 100) ? 100 : $calcVal) );;\ }\ \ if ($period eq "time_Day" and $reading eq "SW_Statistic_Autarky") {\ return POSIX::strftime("%H:%M",localtime(::time_str2num(::ReadingsTimestamp($device, $reading."_Day",0))))\ }\ \ if ($period eq "time_Month" and $reading eq "SW_Statistic_Autarky") {\ return POSIX::strftime("%H:%M",localtime(::time_str2num(::ReadingsTimestamp($device, $reading."_Month",0))));;\ }\ \ if ($period eq "time_Quarter") {\ if ($QuarterPrevious ne "null") {\ return POSIX::strftime("%Y-%m-%d",localtime(::time_str2num(::ReadingsTimestamp($QuarterBefore, $QuarterPrevious,0))));;\ }\ }\ \ if ($period eq "time_Year" and $reading eq "SW_Statistic_Autarky") {\ my $cy = POSIX::strftime("%H:%M",localtime(::time_str2num(::ReadingsTimestamp($device, $reading."_Year",0))));;\ $cy .= ($YearPrevious ne "null") ? " / ".$YearPrevious : "";;\ return $cy;;\ }\ \ if ($period eq "Autarky_Year" or $period eq "OwnConsumptionRate_Year") {\ $value = sprintf("%3d %%",::ReadingsVal($device,$reading."_Year",0));;\ $value .= ($YearPrevious ne "null") ? sprintf(" / %3d %%", ::ReadingsVal($YearBefore,$reading."_Year",0) ) : "";;\ return $value;;\ } elsif ($period eq "_Day") {\ if ($reading eq "SW_Statistic_Autarky" or $reading eq "SW_Statistic_OwnConsumptionRate") {\ $value = sprintf("%3d %%",::ReadingsVal($device,$reading.$period,0) );;\ $value .= ($DayPrevious ne "null") ? sprintf(" / %3d %%", ::ReadingsVal($DayBefore,$device."_".$reading.$period,0) ) : "";;\ } else {\ $value = sprintf("%04d",::ReadingsVal($device,$reading.$period,0)/1000);;\ $value .= ($DayPrevious ne "null") ? sprintf(" / %04d", ::ReadingsVal($DayBefore,$device."_".$reading.$period,0) ) : "";;\ }\ return $value;;\ } elsif ($period eq "_Month") {\ if ($reading eq "SW_Statistic_Autarky" or $reading eq "SW_Statistic_OwnConsumptionRate") {\ $value = sprintf("%3d %%",::ReadingsVal($device,$reading.$period,0) );;\ $value .= ($MonthPrevious ne "null") ? sprintf(" / %3d %%", ::ReadingsVal($MonthBefore,$device."_".$reading.$period,0) ) : "";;\ } else {\ $value = sprintf("%04d",::ReadingsVal($device,$reading.$period,0)/1000);;\ $value .= ($MonthPrevious ne "null") ? sprintf(" / %04d", ::ReadingsVal($MonthBefore,$device."_".$reading.$period,0) ) : "";;\ }\ return $value;;\ } elsif ($period eq "_Quarter") {\ $value = ($QuarterPrevious ne "null") ? sprintf("%04d", ::ReadingsVal($QuarterBefore,$QuarterPrevious."_".$reading,0) ) : "";;\ return $value;;\ } elsif ($period eq "_Year") {\ $value = sprintf("%05d",::ReadingsVal($device,$reading.$period,0)/1000);;\ $value .= ($YearPrevious ne "null") ? sprintf(" / %05d", ::ReadingsVal($YearBefore,$reading.$period,0) ) : "";;\ return $value;;\ }\ return ;;\ }\ \ }\ \ \ "Statistiken ".::POSIX::strftime("%Y-%m-%d",localtime(::time_str2num(::ReadingsTimestamp("WR_1_API", "auth_me_authenticated",0))))." in kWh"|\ "aktuell"|\ "heute".WR_ctl_Format("_Dx","WR_1_API","SW_Statistic_Yield").""|\ |\ "Monat".WR_ctl_Format("_Mx","WR_1_API","SW_Statistic_Yield").""|\ "".WR_ctl_Format("_Qx","none","none").""|\ "Jahr".WR_ctl_Format("_Yx","none","SW_Statistic_Yield").""\ \ "Erzeugung PV-Total"|\ sprintf("%04d W",[WR_1:SW_Total_AC_Active_P])|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_Yield")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_Yield")|\ WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_Yield")|\ WR_ctl_Format("_Year","WR_1_API","SW_Statistic_Yield")\ \ "Bezug von PV"|\ sprintf("%04d W",[WR_1:SW_Home_own_consumption_from_Battery]+[WR_1:SW_Home_own_consumption_from_PV])|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_EnergyHomePv")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_EnergyHomePv")|\ WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_EnergyHomePv")|\ WR_ctl_Format("_Year","WR_1_API","SW_Statistic_EnergyHomePv")\ \ "Bezug von Batterie"|\ sprintf("%04d W",[WR_1:SW_Home_own_consumption_from_Battery])|\ WR_ctl_Format("_Day","WR_1_API","Statistic_EnergyHomeBat")|\ |\ WR_ctl_Format("_Month","WR_1_API","Statistic_EnergyHomeBat")|\ WR_ctl_Format("_Quarter","WR_1_API","Statistic_EnergyHomeBat")|\ WR_ctl_Format("_Year","WR_1_API","Statistic_EnergyHomeBat")\ \ "Bezug vom Netz"|\ sprintf("%04d W",([WR_1:Total_Active_P_EM] >= 0 ? ::round(::ReadingsVal("WR_1","Total_Active_P_EM",0),0) : 0) )|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_EnergyHomeGrid")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_EnergyHomeGrid")|\ WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_EnergyHomeGrid")|\ WR_ctl_Format("_Year","WR_1_API","SW_Statistic_EnergyHomeGrid")\ \ "Bezug ins Haus (Energieverbrauch)"|\ sprintf("%04d W",[WR_1:SW_Home_own_consumption_from_PV]+[WR_1:SW_Home_own_consumption_from_Battery]+[WR_1:SW_Home_own_consumption_from_grid])|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_TotalConsumption")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_TotalConsumption")|\ WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_TotalConsumption")|\ WR_ctl_Format("_Year","WR_1_API","SW_Statistic_TotalConsumption")\ \ "Einspeisung ins Netz"|\ sprintf("%04d W",([WR_1:Total_Active_P_EM] <= 0 ? abs(::round(::ReadingsVal("WR_1","Total_Active_P_EM",0),0)) : 0) )|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")|\ WR_ctl_Format("_Quarter","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")|\ WR_ctl_Format("_Year","WR_1_API","SW_Statistic_EnergyHomeFeedInGrid")\ \ "Autarkiequote"|\ WR_ctl_Format("actual","WR_1","Autarky")|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_Autarky")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_Autarky")|\ |\ WR_ctl_Format("Autarky_Year","WR_1_API","SW_Statistic_Autarky")\ \ "Eigenverbrauchsquote"|\ WR_ctl_Format("actual","WR_1","OwnConsumptionRate")|\ WR_ctl_Format("_Day","WR_1_API","SW_Statistic_OwnConsumptionRate")|\ |\ WR_ctl_Format("_Month","WR_1_API","SW_Statistic_OwnConsumptionRate")|\ |\ WR_ctl_Format("OwnConsumptionRate_Year","WR_1_API","SW_Statistic_OwnConsumptionRate")\ \ "Berechnet um"|\ |\ WR_ctl_Format("time_Day","WR_1_API","SW_Statistic_Autarky")|\ |\ WR_ctl_Format("time_Month","WR_1_API","SW_Statistic_Autarky")|\ WR_ctl_Format("time_Quarter","WR_1_API","")|\ WR_ctl_Format("time_Year","WR_1_API","SW_Statistic_Autarky")\ attr WR_ctl userReadings Yield_fc0_current:Yield_fc0_18.* { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;; ::ReadingsVal("$NAME","Yield_fc0_".sprintf("%02d",$hour),0)/1000 },\ Yield_fc1_current:Yield_fc1_18.* { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; $year += 1900;; $mon += 1 ;; ::ReadingsVal("$NAME","Yield_fc1_".sprintf("%02d",$hour),0)/1000 } attr WR_ctl verbose 3 setstate WR_ctl 2023-06-21 11:33:15 SpeicherMidday_Inverter_Max_Power 9000 setstate WR_ctl 2024-01-24 16:03:00 ui_command_1 --- setstate WR_ctl 2024-01-24 15:57:00 ui_command_2 ---