Photovoltaik Eigenverbrauch,Bilanz,Prognose (Kostal Plenticore; KSEM; BYD HV)

Begonnen von ch.eick, 07 Oktober 2020, 16:09:12

Vorheriges Thema - Nächstes Thema

ch.eick

Moin,
ich habe den code in diesem https://forum.fhem.de/index.php/topic,114849.msg1169307.html#msg1169307 Post wieder aktualisiert.

Das Nachladen auf 100% sollte somit 2 Stunden vor Sonnenuntergang erfolgen.
Und wie gesagt, im Winter soll das ganze nicht erfolgen, also immer auf 100% gehalten werden, wenn es die Sonne zulässt.

VG
   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

Mumpitz

Zitat von: ch.eick am 06 August 2021, 11:01:38
Moin,
ich habe den code in diesem https://forum.fhem.de/index.php/topic,114849.msg1169307.html#msg1169307 Post wieder aktualisiert.

Das Nachladen auf 100% sollte somit 2 Stunden vor Sonnenuntergang erfolgen.
Und wie gesagt, im Winter soll das ganze nicht erfolgen, also immer auf 100% gehalten werden, wenn es die Sonne zulässt.

VG
   Christian

Bin es am testen, bin gespannt!

ch.eick

Hallo zusammen,
aus gegebenem Anlass möchte ich Euch bitte mal die Total_Efficiency Eurer Speicher zu überprüfen. Leider liegt dies bei meinem Speicher schon nach nicht ganz zwei Jahren um fast 10 % unter der bei der Inbetriebnahme. Ich habe bei EFT bereits ein Ticket aufgemacht und sollte natürlich zuerst mal die FW auf den letzten Stand bringen und einige Vollzyklen zwischen MinSOC und 100% fahren. Das hat bisher allerdings nichts gebracht und die Total_Efficiency ist innerhalb von 14 Tagen immer weiter gefallen.
Also achtet alle bitte auf Eure Garantiezeit.

VG
   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Vorankündigung: Ich habe das stateFormat nun bei mir bereits im WR_1_Speicher_1_ExternControl übernommen und auch alle readings aus dem WR_1_Speicher_1_ExternTrigger
      Hierdurch wird das DUMMY WR_1_Speicher_1_ExternTrigger überflüssig werden und es verschwindet komplett.
      Das konfigurieren der Einstellungen , wie es mit den Pull Downs im WR_1_Speicher_1_ExternTrigger erfolgt ist beim DOIF auch möglich, man lernt ja nie aus :-)

EDIT 2021 09 03: Nun ist auch die Zeitsteuerung im Status, was die Schweizer unter uns freuen wird ;-)
EDIT 2021 09 03: Die Abhängigkeiten der Parameter wurden weiter verfeinert
EDIT 2021 09 03: Der Fehler
ZitatPERL WARNING: Argument "30000 Wh" isn't numeric in numeric ge (>=) at (eval 2565240) line 33.
wurde korrigiert.
EDIT 2021 09 03: Auf dem zweiten Bild sieht man jetzt, dass z.B. nach 15:00 Uhr die Mittagssteuerung von grünen Werten wieder auf schwarz gewechselt hat.
                   Somit ist diese Steuerung abgelaufen und man sieht nur die konfigurierten Einstellungen.
                   Rechts oben hat sich die Ladeleistung noch nicht erhöht, was wahrscheinlich durch die WR Steuerung entschieden wurde. Das beobachte ich noch weiter, denn
                   die Limitierung der Leistung ist jetzt länger als drei Minuten her.
EDIT 2021 09 03: Es ist noch Farbe zu den Werten gekommen, um zu sehen was aktiv ist und wie die Werte zusammenspielen. <<< Das ist noch experimentell
EDIT 2021 09 03: Die Werte wurden in der Tabelle nochmal anders angeordnet

EDIT 2021 09 02: jetzt mit noch mehr Information, Einheiten und aktuellen Werten aus dem WR
EDIT 2021 09 02: noch ein kleines Update

Hallo Ihr Freunde der Speichersteuerung :-)

Ich habe mir mal Gedanken zum stateFormat von WR_1_Speicher_1_ExternTrigger gemacht, da dort ja sehr viele Konfigurations- und Laufzeit Parameter abgelegt sind.
Das hat mich schon die Ganze Zeit beschäftigt, wie man das übersichtlicher anzeigen könnte. hier nun mein momentaner Stand für den RAW Editor, also ersatz für das stateFormat.


attr WR_1_Speicher_1_ExternTrigger stateFormat {\
my $WR     = "WR_1";;\
my $DUMMY  = "";;\
\
my $Entladung                        = ReadingsVal($name,"SpeicherEntladung","n/a");;\
\
my $Power                            = ReadingsVal($WR,"Actual_Battery_charge_-minus_or_discharge_-plus_P","0");;\
my $Status                           = ($Power < -10) ? "<span style='color:#00FF00'>Laden</span>" : ($Power > 15)?  "<span style='color:#FF0000'>Entladen</span>"  : "<span style='color:orange'>Standby</span>";;\
    $Power                            = $Power." W";;\
\
my $Solar_Calculation_fc0_day        = ReadingsVal($WR,"Solar_Calculation_fc0_day","0");;\
\
my $Trigger                          = ReadingsVal($name,"SpeicherTrigger","none");;\
my $ExternTrigger                    = ReadingsVal($name,"SpeicherExternTrigger","none");;\
my $ZeitStart                        = ReadingsVal($name,"SpeicherZeitStart","n/a");;\
my $ZeitEnde                         = ReadingsVal($name,"SpeicherZeitEnde","n/a");;\
     \
my $CmdRepeatActive                  = ReadingsVal($name,"SpeicherCmdRepeatActive","0");;\
my $CmdRepeatRunning                 = ReadingsVal($name,"SpeicherCmdRepeatRunning","0");;\
\
my $MaxSOCControlActive              = ReadingsVal($name,"SpeicherMaxSOCControlActive","0");;\
my $MaxSOCControlRunning             = ReadingsVal($name,"SpeicherMaxSOCControlRunning","0");; \
\
my $MiddayControlActive              = ReadingsVal($name,"SpeicherMiddayControlActive","0");;\
my $MiddayControlRunning             = ReadingsVal($name,"SpeicherMiddayControlRunning","0");;\
\
my $Solar_middayhigh_fc0_start       = ReadingsVal($WR,"Solar_middayhigh_fc0_start","00:00");;\
    $Solar_middayhigh_fc0_start       = ($MaxSOCControlRunning == 1 and $MiddayControlRunning == 1) ? "12:00" : $Solar_middayhigh_fc0_start ;;\
\
my $Solar_middayhigh_fc0_stop        = ReadingsVal($WR,"Solar_middayhigh_fc0_stop","00:00");;\
my $MaxSOC_Actual                    = ReadingsVal($name,"SpeicherMaxSOC_Actual","0");;\
my $Act_state_of_charge              = sprintf("%d",ReadingsVal($WR,"Act_state_of_charge","0"));;\
my $MaxSOC_DayBefore                 = sprintf("%d %%",ReadingsVal($name,"SpeicherMaxSOC_DayBefore","0"));;\
my $MaxSOC_fc1_Limit                 = ReadingsVal($name,"SpeicherMaxSOC_fc1_Limit","0");;\
my $MaxSOC_MinSOC_Time               = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SpeicherMaxSOC_MinSOC_MinSOC",0))));;\
my $MaxSOC_MinSOC_MinSOC             = sprintf("%d %%",ReadingsVal($name,"SpeicherMaxSOC_MinSOC_MinSOC","0"));;\
\
my $Midday_NotBefore                 = ReadingsVal($name,"SpeicherMidday_NotBefore","0");;\
my $Midday_MaxSOC                    = ReadingsVal($name,"SpeicherMidday_MaxSOC","0");;\
\
my $Midday_MaxChargePowerAbs_morning = sprintf("%d W"   ,ReadingsVal($name,"SpeicherMidday_MaxChargePowerAbs_morning","0"));;\
\
    $Midday_MaxChargePowerAbs_morning = ( $MiddayControlRunning == 1 and\
                                      time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore") and\
                                          time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          $Midday_MaxSOC > $Act_state_of_charge ) ? "<span style='color:#00FF00'>$Midday_MaxChargePowerAbs_morning</span>" : $Midday_MaxChargePowerAbs_morning ;;\
\
my $Midday_MaxChargePowerAbs_midday  = sprintf("%d"   ,ReadingsVal($name,"SpeicherMidday_MaxChargePowerAbs_midday","0"));;\
    $Midday_MaxChargePowerAbs_midday  = ( $Midday_MaxChargePowerAbs_midday == 0) ? "dynamisch" : $Midday_MaxChargePowerAbs_midday." W" ;; \
    $Midday_MaxChargePowerAbs_midday  = ( $MiddayControlRunning == 1 and\
                                      time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Midday_MaxChargePowerAbs_midday</span>" : $Midday_MaxChargePowerAbs_midday ;;\
\
    $Midday_NotBefore                 = ( $MiddayControlRunning == 1 and\
                                      time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore") and\
                                      time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $MaxSOC_MinSOC_MinSOC")) ? "< <span style='color:#FF0000'>$Midday_NotBefore</span>" :\
                                        ( $MiddayControlRunning == 1 and\
                                      time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") ) ? "> <span style='color:#00FF00'>$Midday_NotBefore</span>" : $Midday_NotBefore ;;\
\
    $Midday_MaxSOC                    = ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore")) ? $Midday_MaxSOC." %" :\
                                    ( $MiddayControlRunning == 1 and\
                                      time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          $Midday_MaxSOC > $Act_state_of_charge ) ? "<span style='color:#00FF00'>$Midday_MaxSOC %</span>" : \
( time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start")) ? $Midday_MaxSOC." %" : "<span style='color:#FF0000'>$Midday_MaxSOC %</span>" ;;\
\
    $Solar_middayhigh_fc0_start       = ( $MiddayControlRunning == 1 and\
                                      time >= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Solar_middayhigh_fc0_start</span>" : $Solar_middayhigh_fc0_start ;;\
    $Solar_middayhigh_fc0_stop        = ( $MiddayControlRunning == 1 and\
                                      time >= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Solar_middayhigh_fc0_stop</span>" : $Solar_middayhigh_fc0_stop ;;\
\
\
my $Midday_Inverter_Max_Power        = sprintf("%d W"   ,ReadingsVal($name,"SpeicherMidday_Inverter_Max_Power","0"));;\
    $Midday_Inverter_Max_Power        = ($MiddayControlRunning      == 1                ) ? ">= <span style='color:#00FF00'> $Midday_Inverter_Max_Power</span>" : $Midday_Inverter_Max_Power ;;\
\
my $MinSOC_fc1_Limit                 = ReadingsVal($name,"SpeicherMinSOC_fc1_Limit","0");;\
my $MinSOC_Sommer                    = sprintf("%d %%"  ,ReadingsVal($name,"SpeicherMinSOC_Sommer","0"));;\
    $MinSOC_Sommer                    = ($Solar_Calculation_fc0_day >= $MinSOC_fc1_Limit) ? "<span style='color:#00FF00'>$MinSOC_Sommer</span>"             : $MinSOC_Sommer ;;\
\
my $MinSOC_Winter                    = sprintf("%d %%"  ,ReadingsVal($name,"SpeicherMinSOC_Winter","0"));;\
    $MinSOC_Winter                    = ($Solar_Calculation_fc0_day <  $MinSOC_fc1_Limit) ? "<span style='color:#00FF00'>$MinSOC_Winter</span>"             : $MinSOC_Winter ;;\
\
    $MinSOC_fc1_Limit                 = ($Solar_Calculation_fc0_day >= $MinSOC_fc1_Limit) ? ">= <span style='color:#00FF00'>$MinSOC_fc1_Limit Wh</span>"    : $MinSOC_fc1_Limit." Wh" ;;\
    $MaxSOC_fc1_Limit                 = ($Solar_Calculation_fc0_day >= $MaxSOC_fc1_Limit) ? ">= <span style='color:#00FF00'>$MaxSOC_fc1_Limit Wh</span>" : $MaxSOC_fc1_Limit." Wh" ;;\
\
    $MaxSOC_Actual                    = ($MaxSOCControlRunning == 1) ? "<span style='color:#00FF00'>$MaxSOC_Actual %</span>"      : $MaxSOC_Actual." %" ;;\
    $Act_state_of_charge              = $Act_state_of_charge." %";;\
    $CmdRepeatRunning                 = ($CmdRepeatRunning     == 1) ? "<span style='color:#00FF00'>$CmdRepeatRunning</span>"     : $CmdRepeatRunning ;;\
    $MaxSOCControlRunning             = ($MaxSOCControlRunning == 1) ? "<span style='color:#00FF00'>$MaxSOCControlRunning</span>" : $MaxSOCControlRunning ;;\
    $MiddayControlRunning             = ($MiddayControlRunning == 1) ? "<span style='color:#00FF00'>$MiddayControlRunning</span>" : $MiddayControlRunning ;;\
\
    $ZeitStart                        = ($Entladung eq "Zeit") ? "<span style='color:#00FF00'>$ZeitStart</span>" : $ZeitStart ;;\
    $ZeitEnde                         = ($Entladung eq "Zeit") ? "<span style='color:#00FF00'>$ZeitEnde</span>"  : $ZeitEnde  ;;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0>\
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'> </td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Speicher<dd>Steuerung / Status / Leistung / aktueller SOC</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Entladung."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Status."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Power."<br>".$Act_state_of_charge."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Trigger<dd>Status / ExternTrigger / Start / Ende</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Trigger."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ExternTrigger."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ZeitStart."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ZeitEnde."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Kommando Wiederholung<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$CmdRepeatActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$CmdRepeatRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MaxSOC Kontrolle<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOCControlActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOCControlRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MaxSOC Limit<dd>fc1_Limit / Minimum SOC Zeit / gestern / aktuell</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_fc1_Limit."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$MaxSOC_MinSOC_Time."<br>".$MaxSOC_MinSOC_MinSOC."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_DayBefore."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_Actual."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Mittags Kontrolle<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MiddayControlActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MiddayControlRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Mittags Limits<dd>Inverter_Max_Power / Laden nicht vor / Start /Stop<br><br>MaxSOC morgens / Power morgens / Power mittags</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Midday_Inverter_Max_Power."<br><br>".$Midday_MaxSOC."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Midday_NotBefore."<br><br>".$Midday_MaxChargePowerAbs_morning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_middayhigh_fc0_start."<br><br>".$Midday_MaxChargePowerAbs_midday."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_middayhigh_fc0_stop."<br><br><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MinSOC Steuerung<dd>fc1_Limit / Winter / Sommer</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_fc1_Limit."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_Winter."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_Sommer."</td></tr>\
</table>\
</html>"\
}\



Das passt dann jetzt auch zum WR_1_API . Eure Meinung ist wie immer willkommen

VG
   Christian

Im Anhang auch mal ein Screenshot vom Ergebnis
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,
damit im FHEMWEB alles gleich aussieht habe ich für das WR_1 Device jetzt auch das Tabellen Design erstellt


attr WR_1 stateFormat {\
my $DUMMY  = "";;\
\
my $Power          = ReadingsVal($name,"Actual_Battery_charge_-minus_or_discharge_-plus_P",0);;\
my $StatusSpeicher = ($Power < -10) ? "<span style='color:#00FF00'>Laden</span>" : ($Power > 15)?  "<span style='color:#FF0000'>Entladen</span>"  : "<span style='color:orange'>Standby</span>";;\
    $Power          = $Power." W";;\
\
\
my $Battery_temperature                  = sprintf("%.1f °C",ReadingsVal($name,"Battery_temperature",0));;\
my $Actual_Battery_charge_usable_P       = sprintf("%d W",ReadingsVal($name,"Actual_Battery_charge_usable_P",0));;\
         \
my $Act_state_of_charge                  = sprintf("%d %%",ReadingsVal($name,"Act_state_of_charge","0"));;\
my $SW_Total_DC_P_sumOfAllPVInputs       = sprintf("%d W",ReadingsVal($name,"SW_Total_DC_P_sumOfAllPVInputs","0"));;\
my $SW_Total_PV_P_reserve                = sprintf("%d W",ReadingsVal($name,"SW_Total_PV_P_reserve","0"));;\
\
my $SW_Home_own_consumption_from_PV      = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_PV",0));;\
my $SW_Home_own_consumption_from_Battery = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_Battery",0));;\
my $SW_Home_own_consumption_from_grid    = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_grid",0));;\
my $SW_Home_own_consumption              = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption",0)+ReadingsVal($name,"Home_own_consumption_from_grid",0));;\
\
my $Total_Active_P_EM  = ReadingsVal($name,"Total_Active_P_EM",0);;\
my $StatusNetz         = ($Total_Active_P_EM < 0) ? "<span style='color:#00FF00'>Einspeisen</span>" : "<span style='color:#FF0000'>Netzbezug</span>";;\
    $Total_Active_P_EM  = $Total_Active_P_EM." W";;\
\
my $SW_Yield_Daily   = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Daily",0)/1000 ,0));;\
my $SW_Yield_Monthly = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Monthly",0)/1000 ,0));;\
my $SW_Yield_Yearly  = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Yearly",0)/1000 ,0));;\
my $SW_Yield_Total   = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Total",0)/1000 ,0));;\
\
my $Solar_Calculation_fc0_4h   = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_4h",0)/1000 ,0));;\
my $Solar_Calculation_fc0_day  = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_day",0)/1000 ,0));;\
my $Solar_Calculation_fc0_rest = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_rest",0)/1000 ,0));;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0>\
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'> </td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Wechselrichter / KSEM<dd>Max DC / PV Reserve / Netz Leistung</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Total_DC_P_sumOfAllPVInputs."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Total_PV_P_reserve."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$StatusNetz."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Total_Active_P_EM."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Leistung<dd>von PV / von Batterie / vom Netz / ins Haus</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption_from_PV."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption_from_Battery."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption_from_grid."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Ertrag<dd>Tag / Monat / Jahr / Total</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Daily."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Monthly."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Yearly."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Total."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Prognose<dd>Tag / 4 Stunden / Resttag</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_Calculation_fc0_day."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_Calculation_fc0_4h."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_Calculation_fc0_rest."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Speicher<dd>Temperatur / nutzbare Ladung / Leistung / aktueller SOC</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Battery_temperature."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Actual_Battery_charge_usable_P."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$StatusSpeicher."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Power."<br>".$Act_state_of_charge."</td></tr>\
</table>\
</html>"\
}\



RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,

hier nochmal ein Update zum aktuellen Stand.

Neu, also noch nicht im Wiki ist die Status Tabelle
(siehe Bild 1)
und die dynamische Berechnung mit welcher Stärke der Speicher mittags geladen werden soll. Hier kann man aber auch einen festen Wert vorgeben, wobei ich jedoch letzte Tage festgestellt hatte, das es abhängig von der Länge des Mittagshochs dann doch noch zu einer weiteren Ladung am Nachmittag kommt. Mit der jetzigen dynamic verändert sich die Ladeleistung und soll zum Ende des Mittagshochs den Speicher nahezu auf den gewünschten SOC gebracht haben. Somit hat schlechtes Wetter am Nachmittag kaum noch eine Chance.

Die Prognose aktualisiert sich natürlich stündlich und hätte somit auch sofort Einfluss auf das Ladeverhalten.

Das Bild 2 ist mal ein Graph von gestern und heute.

- Gestern war kein Mittagshoch, also hat er schon morgens sofort geladen, unterbrochen von der Wärmepumpe, weil die Frau putzen wollte :-)
- Heute war wieder wärmeres Wasser gefordert, deshalb blieb ab 9 Uhr fast nichts für den Speicher übrig
- Ab 12 wurde dann stärker geladen, also in Abhängigkeit der Zeit 12:00 - 15:00 Uhr und der zu erreichenden SOC Differenz (das fine Tuning ist noch im Gange, weil ich das erst gestern eingebaut habe)

Bild 2 unten ist die Prognose in hell grün für heute und rot, was bereits gestern berechnet wurde.
Das zackige grüne ist die aktuelle Leistung.

Bild 3
zeigt das Ladefenster vom Mittag, bei dem um 15:00 Uhr das Mittagshoch beendet war.
Von 14:00 - 15:00 Uhr wurde die Ladekurve nicht mehr so aggressiv nachgeführt, damit am Nachmittag auch noch etwas geladen wird.
Dadurch lief die orange- und die blaue Kurve aufeinander zu und verengte sich.
Ab 15:00 Uhr wurde dann die Limitierung aufgehoben und der Plenticore hat wieder selber entschieden.

VG
    Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Zitat von: Mumpitz am 09 September 2021, 14:14:09
Ist es möglich das sich hier ein Fehler eingeschlichen hat? Im WR_1 Device habe ich doch die Werte des Ertrags von heute, Tag, Monat, Jahr und Total nicht, oder? Die müssten doch vom API Device stammen?
Moin,
ich hatte das neue stateFormat noch nicht gepostet :-)

Und im WR_1 werden diese Werte über modBus geliefert, jedoch nicht alle Statistiken. Es kommt dabei auch schon mal zu Abweichungen, je nachdem wann man drauf schaut.
Diese vier Statistiken lasse ich jedoch im Device, da nicht jeder das API Device verwenden möchte.

VG
   Christian

Hier kommen dann mal alle drei stateFormat als RAW, so wie ich sie nun verwende und getestet habe.

WR_1

attr WR_1 stateFormat {\
my $DUMMY  = "";;\
\
my $Power          = ReadingsVal($name,"Actual_Battery_charge_-minus_or_discharge_-plus_P",0);;\
my $StatusSpeicher = ($Power < -10) ? "<span style='color:#00FF00'>Laden</span>" : ($Power > 15)?  "<span style='color:#FF0000'>Entladen</span>"  : "<span style='color:orange'>Standby</span>";;\
    $Power          = $Power." W";;\
\
\
my $Battery_temperature                  = sprintf("%.1f °C",ReadingsVal($name,"Battery_temperature",0));;\
my $Actual_Battery_charge_usable_P       = sprintf("%d W",ReadingsVal($name,"Actual_Battery_charge_usable_P",0));;\
         \
my $Act_state_of_charge                  = sprintf("%d %%",ReadingsVal($name,"Act_state_of_charge","0"));;\
my $SW_Total_DC_P_sumOfAllPVInputs       = sprintf("%d W",ReadingsVal($name,"SW_Total_DC_P_sumOfAllPVInputs","0"));;\
my $SW_Total_PV_P_reserve                = sprintf("%d W",ReadingsVal($name,"SW_Total_PV_P_reserve","0"));;\
\
my $SW_Home_own_consumption_from_PV      = sprintf("%d",ReadingsVal($name,"SW_Home_own_consumption_from_PV",0));;\
    $SW_Home_own_consumption_from_PV = ($SW_Home_own_consumption_from_PV >= 0) ? $SW_Home_own_consumption_from_PV." W" : "0 W";;\
my $SW_Home_own_consumption_from_Battery = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_Battery",0));;\
my $SW_Home_own_consumption_from_grid    = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption_from_grid",0));;\
my $SW_Home_own_consumption              = sprintf("%d W",ReadingsVal($name,"SW_Home_own_consumption",0)+ReadingsVal($name,"Home_own_consumption_from_grid",0));;\
\
my $Total_Active_P_EM  = ReadingsVal($name,"Total_Active_P_EM",0);;\
my $StatusNetz         = ($Total_Active_P_EM < -10) ? "<span style='color:#00FF00'>Einspeisen</span>" : ($Total_Active_P_EM > 15)?  "<span style='color:#FF0000'>Netzbezug</span>"  : "<span style='color:orange'>Standby</span>";;\
    $Total_Active_P_EM  = $Total_Active_P_EM." W";;\
\
my $SW_Yield_Daily   = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Daily",0)/1000 ,0));;\
my $SW_Yield_Monthly = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Monthly",0)/1000 ,0));;\
my $SW_Yield_Yearly  = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Yearly",0)/1000 ,0));;\
my $SW_Yield_Total   = sprintf("%d kWh",round(ReadingsVal($name,"SW_Yield_Total",0)/1000 ,0));;\
\
my $Solar_Calculation_fc0_4h   = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_4h",0)/1000 ,0));;\
my $Solar_Calculation_fc0_day  = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_day",0)/1000 ,0));;\
my $Solar_Calculation_fc0_rest = sprintf("%d kWh",round(ReadingsVal($name,"Solar_Calculation_fc0_rest",0)/1000 ,0));;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0 style='width: 100%'>\
<colgroup>\
   <col span='1' style='width: 52%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
</colgroup>\
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'> </td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Wechselrichter / KSEM<dd>Max DC / PV Reserve / Netz Leistung</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Total_DC_P_sumOfAllPVInputs."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Total_PV_P_reserve."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$StatusNetz."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Total_Active_P_EM."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Leistung<dd>von PV / von Batterie / vom Netz / ins Haus</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption_from_PV."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption_from_Battery."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption_from_grid."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Home_own_consumption."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Ertrag<dd>Tag / Monat / Jahr / Total</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Daily."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Monthly."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Yearly."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$SW_Yield_Total."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Prognose<dd>Tag / 4 Stunden / Resttag</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_Calculation_fc0_day."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_Calculation_fc0_4h."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_Calculation_fc0_rest."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Speicher<dd>Temperatur / nutzbare Ladung / Leistung / aktueller SOC</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Battery_temperature."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Actual_Battery_charge_usable_P."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$StatusSpeicher."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Power."<br>".$Act_state_of_charge."</td></tr>\
</table>\
</html>"\
}\


WR_1_API

attr WR_1_API stateFormat {\
my $calcVal=0;;\
my $WR="WR_1";;\
\
my $pvt   = sprintf("%04d W",ReadingsVal($WR,"SW_Total_AC_Active_P",0) );;\
my $pvtd  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_Yield_Day",0)/1000 );;\
my $pvtm  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_Yield_Month",0)/1000 );;\
my $pvty  = sprintf("%05d kWh",ReadingsVal("$name","SW_Statistic_Yield_Year",0)/1000 );;\
\
my $pv  = sprintf("%04d W",ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0)+ReadingsVal($WR,"SW_Home_own_consumption_from_PV",0) );;\
my $pvd  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomePv_Day",0)/1000 );;\
my $pvm  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomePv_Month",0)/1000 );;\
my $pvy  = sprintf("%05d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomePv_Year",0)/1000 );;\
\
my $gfi  =  sprintf("%04d W",(ReadingsVal($WR,"Total_Active_P_EM",0)<=0 ? abs(round(ReadingsVal($WR,"Total_Active_P_EM",0),0)):  0) );;\
my $gfid = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomeFeedInGrid_Day",0)/1000 );;\
my $gfim = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomeFeedInGrid_Month",0)/1000 );;\
my $gfiy = sprintf("%05d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomeFeedInGrid_Year",0)/1000 );;\
\
my $eb   = sprintf("%04d W",(ReadingsVal($WR,"Total_Active_P_EM",0)>=0 ? round(ReadingsVal($WR,"Total_Active_P_EM",0),0) : 0) );;\
my $ebd  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomeGrid_Day",0)/1000 );;\
my $ebm  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomeGrid_Month",0)/1000 );;\
my $eby  = sprintf("%05d kWh",ReadingsVal("$name","SW_Statistic_EnergyHomeGrid_Year",0)/1000 );;\
\
my $pvb   = sprintf("%04d W",ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0));;\
my $pvbd  = sprintf("%04d kWh",ReadingsVal("$name","Statistic_EnergyHomeBat_Day",0)/1000 );;\
my $pvbm  = sprintf("%04d kWh",ReadingsVal("$name","Statistic_EnergyHomeBat_Month",0)/1000 );;\
my $pvby  = sprintf("%05d kWh",ReadingsVal("$name","Statistic_EnergyHomeBat_Year",0)/1000 );;\
\
my $et   = sprintf("%04d W",(ReadingsVal($WR,"SW_Home_own_consumption_from_PV",0)+ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0)+ReadingsVal($WR,"SW_Home_own_consumption_from_grid",0)) );;\
my $etd  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_TotalConsumption_Day",0)/1000 );;\
my $etm  = sprintf("%04d kWh",ReadingsVal("$name","SW_Statistic_TotalConsumption_Month",0)/1000 );;\
my $ety  = sprintf("%05d kWh",ReadingsVal("$name","SW_Statistic_TotalConsumption_Year",0)/1000 );;\
\
my $valA = ReadingsVal($WR, "SW_Total_AC_Active_P",0)-ReadingsVal($WR, "SW_Home_own_consumption_from_grid",0);;\
    $calcVal = ($valA > 0) ? round($valA /($valA + ReadingsVal($WR, "SW_Home_own_consumption_from_grid",""))*100 ,0) : 0;;\
my $aq = sprintf("%4d %%",(($calcVal > 100) ? 100 : $calcVal) );;\
\
my $aqd  = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_Autarky_Day",0) );;\
my $aqm  = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_Autarky_Month",0) );;\
my $aqy  = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_Autarky_Year",0) );;\
\
my $valS = ReadingsVal($WR,"SW_Total_AC_Active_P",0);;\
    $calcVal = ($valS > 0) ? round((ReadingsVal($WR,"SW_Home_own_consumption_from_PV",0) + ReadingsVal($WR,"SW_Home_own_consumption_from_Battery",0)) / $valS * 100 ,0) : 0;;\
my $sq   =  sprintf("%4d %%",(($calcVal > 100) ? 100 : $calcVal) );;\
\
my $sqd  = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_OwnConsumptionRate_Day",0) );;\
my $sqm  = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_OwnConsumptionRate_Month",0) );;\
my $sqy  = sprintf("%4d %%",ReadingsVal("$name","SW_Statistic_OwnConsumptionRate_Year",0) );;\
\
my $date = POSIX::strftime("%Y-%m-%d",localtime(time_str2num(ReadingsTimestamp($name, "auth_me_authenticated",0))));;\
my $md = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "auth_me_authenticated",0))));;\
my $cd   = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SW_Statistic_Autarky_Day",0))));;\
my $cm   = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SW_Statistic_Autarky_Month",0))));;\
my $cy   = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SW_Statistic_Autarky_Year",0))));;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0 style='width: 100%'>\
<colgroup>\
   <col span='1' style='width: 52%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
</colgroup>\
<tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'>Statistik vom $date</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>aktuell</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Heute</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Monat</td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold;;text-align:center'>Jahr</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Erzeugung PV-Total</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvt."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvtd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvtm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvty."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Bezug von PV</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pv."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvy."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Bezug von Batterie</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvb."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvbd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvbm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$pvby."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Bezug ins Haus (Energieverbrauch)</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$et."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$etd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$etm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$ety."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Bezug vom Netz</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$eb."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$ebd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$ebm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$eby."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Einspeisung ins Netz</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$gfi."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$gfid."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$gfim."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$gfiy."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Autarkiequote</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$aq."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$aqd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$aqm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$aqy."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Eigenverbrauchsquote</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$sq."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$sqd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$sqm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$sqy."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Berechnet um</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$md."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$cd."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$cm."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$cy."</td></tr>\
</table></html>"\
}\


WR_1_Speicher_1_ExternControl
Hierfür bitte vorher noch alle readings aus dem alten, nicht mehr verwendeten DUMMY übernehmen.
Da die readings nun direkt im DOIF sind, sind natürlich auch die Code Stements anzupassen.

attr WR_1_Speicher_1_ExternControl stateFormat {\
my $WR     = "WR_1";;\
my $DUMMY  = "";;\
\
my $Entladung                        = ReadingsVal($name,"SpeicherEntladung","n/a");;\
\
my $Power                            = ReadingsVal($WR,"Actual_Battery_charge_-minus_or_discharge_-plus_P","0");;\
my $Status                           = ($Power < -10) ? "<span style='color:#00FF00'>Laden</span>" : ($Power > 15) ?  "<span style='color:#FF0000'>Entladen</span>" : "<span style='color:orange'>Standby</span>";;\
    $Power                            = $Power." W";;\
\
my $Solar_Calculation_fc0_day        = ReadingsVal($WR,"Solar_Calculation_fc0_day","0");;\
        \
my $Trigger                          = ReadingsVal($name,"SpeicherTrigger","none");;\
my $ExternTrigger                    = ReadingsVal($name,"SpeicherExternTrigger","none");;\
my $ZeitStart                        = ReadingsVal($name,"SpeicherZeitStart","n/a");;\
my $ZeitEnde                         = ReadingsVal($name,"SpeicherZeitEnde","n/a");;\
                                                                                                             \
my $CmdRepeatActive                  = ReadingsVal($name,"SpeicherCmdRepeatActive","0");;\
my $CmdRepeatRunning                 = ReadingsVal($name,"SpeicherCmdRepeatRunning","0");;\
        \
my $MaxSOCControlActive              = ReadingsVal($name,"SpeicherMaxSOCControlActive","0");;\
my $MaxSOCControlRunning             = ReadingsVal($name,"SpeicherMaxSOCControlRunning","0");; \
        \
my $MiddayControlActive              = ReadingsVal($name,"SpeicherMiddayControlActive","0");;\
my $MiddayControlRunning             = ReadingsVal($name,"SpeicherMiddayControlRunning","0");;\
        \
my $Solar_middayhigh_fc0_start       = ReadingsVal($WR,"Solar_middayhigh_fc0_start","00:00");;\
    $Solar_middayhigh_fc0_start       = ($MaxSOCControlRunning == 1 and $MiddayControlRunning == 1) ? "12:00" : $Solar_middayhigh_fc0_start ;;\
\
my $Solar_middayhigh_fc0_stop        = ReadingsVal($WR,"Solar_middayhigh_fc0_stop","00:00");;\
my $MaxSOC_Actual                    = ReadingsVal($name,"SpeicherMaxSOC_Actual","0");;\
my $Act_state_of_charge              = sprintf("%d",ReadingsVal($WR,"Act_state_of_charge","0"));;\
my $MaxSOC_DayBefore                 = sprintf("%d %%",ReadingsVal($name,"SpeicherMaxSOC_DayBefore","0"));;\
my $MaxSOC_fc1_Limit                 = ReadingsVal($name,"SpeicherMaxSOC_fc1_Limit","0");;\
my $MaxSOC_MinSOC_Time               = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SpeicherMaxSOC_MinSOC_MinSOC",0))));;\
my $MaxSOC_MinSOC_MinSOC             = sprintf("%d %%",ReadingsVal($name,"SpeicherMaxSOC_MinSOC_MinSOC","0"));;\
\
my $Midday_NotBefore                 = ReadingsVal($name,"SpeicherMidday_NotBefore","0");;\
my $Midday_MaxSOC                    = ReadingsVal($name,"SpeicherMidday_MaxSOC","0");;\
\
my $Midday_MaxChargePowerAbs_morning = sprintf("%d W"   ,ReadingsVal($name,"SpeicherMidday_MaxChargePowerAbs_morning","0"));;\
\
    $Midday_MaxChargePowerAbs_morning = ( $MiddayControlRunning == 1 and\
                                              time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore") and\
                                          time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          $Midday_MaxSOC > $Act_state_of_charge ) ? "<span style='color:#00FF00'>$Midday_MaxChargePowerAbs_morning</span>" : $Midday_MaxChargePowerAbs_morning ;;\
\
my $Midday_MaxChargePowerAbs_midday  = sprintf("%d"   ,ReadingsVal($name,"SpeicherMidday_MaxChargePowerAbs_midday","0"));;\
    $Midday_MaxChargePowerAbs_midday  = ( $Midday_MaxChargePowerAbs_midday == 0) ? "dynamisch" : $Midday_MaxChargePowerAbs_midday." W" ;; \
    $Midday_MaxChargePowerAbs_midday  = ( $MiddayControlRunning == 1 and\
                                              time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Midday_MaxChargePowerAbs_midday</span>" : $Midday_MaxChargePowerAbs_midday ;;\
\
    $Midday_NotBefore                 = ( $MiddayControlRunning == 1 and\
                                              time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore") and\
                                              time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $MaxSOC_MinSOC_Time")) ? "< <span style='color:#FF0000'>$Midday_NotBefore</span>" :\
                                        ( $MiddayControlRunning == 1 and\
                                              time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") ) ? "> <span style='color:#00FF00'>$Midday_NotBefore</span>" : $Midday_NotBefore ;;\
\
    $Midday_MaxSOC                    = ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore")) ? $Midday_MaxSOC." %" :\
                                            ( $MiddayControlRunning == 1 and\
                                              time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          $Midday_MaxSOC > $Act_state_of_charge ) ? "<span style='color:#00FF00'>$Midday_MaxSOC %</span>" : \
                                                                                ( time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start")) ? $Midday_MaxSOC." %" : "<span style='color:#FF0000'>$Midday_MaxSOC %</span>" ;;\
\
    $Solar_middayhigh_fc0_start       = ( $MiddayControlRunning == 1 and\
                                              time >= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Solar_middayhigh_fc0_start</span>" : $Solar_middayhigh_fc0_start ;;\
    $Solar_middayhigh_fc0_stop        = ( $MiddayControlRunning == 1 and\
                                              time >= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Solar_middayhigh_fc0_stop</span>" : $Solar_middayhigh_fc0_stop ;;\
\
\
my $Midday_Inverter_Max_Power        = sprintf("%d W"   ,ReadingsVal($name,"SpeicherMidday_Inverter_Max_Power","0"));;\
    $Midday_Inverter_Max_Power        = ($MiddayControlRunning      == 1                ) ? ">= <span style='color:#00FF00'> $Midday_Inverter_Max_Power</span>" : $Midday_Inverter_Max_Power ;;\
\
my $MinSOC_fc1_Limit                 = ReadingsVal($name,"SpeicherMinSOC_fc1_Limit","0");;\
my $MinSOC_Sommer                    = sprintf("%d %%"  ,ReadingsVal($name,"SpeicherMinSOC_Sommer","0"));;\
    $MinSOC_Sommer                    = ($Solar_Calculation_fc0_day >= $MinSOC_fc1_Limit) ? "<span style='color:#00FF00'>$MinSOC_Sommer</span>"             : $MinSOC_Sommer ;;\
\
my $MinSOC_Winter                    = sprintf("%d %%"  ,ReadingsVal($name,"SpeicherMinSOC_Winter","0"));;\
    $MinSOC_Winter                    = ($Solar_Calculation_fc0_day <  $MinSOC_fc1_Limit) ? "<span style='color:#00FF00'>$MinSOC_Winter</span>"             : $MinSOC_Winter ;;\
\
    $MinSOC_fc1_Limit                 = ($Solar_Calculation_fc0_day >= $MinSOC_fc1_Limit) ? ">= <span style='color:#00FF00'>$MinSOC_fc1_Limit Wh</span>"    : $MinSOC_fc1_Limit." Wh" ;;\
    $MaxSOC_fc1_Limit                 = ($Solar_Calculation_fc0_day >= $MaxSOC_fc1_Limit) ? ">= <span style='color:#00FF00'>$MaxSOC_fc1_Limit Wh</span>" : $MaxSOC_fc1_Limit." Wh" ;;\
\
    $MaxSOC_Actual                    = ($MaxSOCControlRunning == 1) ? "<span style='color:#00FF00'>$MaxSOC_Actual %</span>"      : $MaxSOC_Actual." %" ;;\
    $Act_state_of_charge              = $Act_state_of_charge." %";;\
    $CmdRepeatRunning                 = ($CmdRepeatRunning     == 1) ? "<span style='color:#00FF00'>$CmdRepeatRunning</span>"     : $CmdRepeatRunning ;;\
    $MaxSOCControlRunning             = ($MaxSOCControlRunning == 1) ? "<span style='color:#00FF00'>$MaxSOCControlRunning</span>" : $MaxSOCControlRunning ;;\
    $MiddayControlRunning             = ($MiddayControlRunning == 1) ? "<span style='color:#00FF00'>$MiddayControlRunning</span>" : $MiddayControlRunning ;;\
\
    $ZeitStart                        = ($Entladung eq "Zeit") ? "<span style='color:#00FF00'>$ZeitStart</span>" : $ZeitStart ;;\
    $ZeitEnde                         = ($Entladung eq "Zeit") ? "<span style='color:#00FF00'>$ZeitEnde</span>"  : $ZeitEnde  ;;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0 style='width: 100%'>\
<colgroup>\
   <col span='1' style='width: 52%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
</colgroup> <tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'> </td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Speicher<dd>Steuerung / Status / Leistung / aktueller SOC</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Entladung."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Status."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Power."<br>".$Act_state_of_charge."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Trigger<dd>Status / ExternTrigger / Start / Ende</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Trigger."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ExternTrigger."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ZeitStart."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ZeitEnde."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Kommando Wiederholung<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$CmdRepeatActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$CmdRepeatRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MaxSOC Kontrolle<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOCControlActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOCControlRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MaxSOC Limit<dd>fc1_Limit / Minimum SOC Zeit / gestern / Ziel</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_fc1_Limit."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$MaxSOC_MinSOC_Time."<br>".$MaxSOC_MinSOC_MinSOC."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_DayBefore."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_Actual."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Mittags Kontrolle<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MiddayControlActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MiddayControlRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Mittags Limits<dd>Inverter_Max_Power / Laden nicht vor / Start /Stop<br><br>MaxSOC morgens / Power morgens / Power mittags</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Midday_Inverter_Max_Power."<br><br>".$Midday_MaxSOC."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Midday_NotBefore."<br><br>".$Midday_MaxChargePowerAbs_morning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_middayhigh_fc0_start."<br><br>".$Midday_MaxChargePowerAbs_midday."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_middayhigh_fc0_stop."<br><br><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MinSOC Steuerung<dd>fc1_Limit / Winter / Sommer</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_fc1_Limit."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_Winter."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_Sommer."</td></tr>\
</table>\
</html>"\
}\
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Und hier noch etwas zum Testen, für die ganz verwegenen Anwender ;-)

Hier sind alle Änderungen des WR_1_Speicher_1_ExternControl beinhaltet.
- aktuelles stateFormat
- Code Korrekturen
   * kleinere Änderung von readings Namen
   * uiTable Events beim DOELSEIF
   * dynamische Leistungsberechnung für die Speicherladung im Mittagshoch
   * Einige überflüssige Wiederholungen von Speicher Kommandos wurden entfernt
   * In diesem Listing habe ich cmd_12 für die direkte Abfrage des BYD HV bereits herausgenommen, da den wohl außer mir keiner hat :-)

- uiTable Definitionen, die eine zweite Tabelle im FHEMWEB erzeugen, um die Konfiguration von WR_1_Speicher_1_ExternControl direkt zu verändern.
   Das Layout entpricht in Grundzügen der stateFormat Definition, ist aber noch lange nicht fertig.

   * Man kann z.B. auch einen DOIF Zweig aus einem Pull Down Menü ausführen lassen.
   * Die Unterfunktionen werden über 0/1 deaktiviert/aktiviert
   * Werte lassen sich verändern
   * Uhrzeiten sind Einstellbar

Aber Achtung, das ist mein Lernstand von gestern Nacht!
Ich möchte jetzt noch stateFormat und uiTable in eine Tabelle überführen, wo ich jedoch noch nicht genügend Kenntnisse habe.

VG
   Christian

WR_1_Speicher_1_ExternControl

defmod WR_1_Speicher_1_ExternControl DOIF ################################################################################################################\
## 1 Speicher Status vom WR_1_Speicher_1 aktualisieren.\
##   Dies geschieht über das WR_1_API Device, da der Speicher direkt am Wechselrichter angeschlossen ist.\
##\
([:58])\
  {\
   CommandGet(undef, "WR_1_API 21_Battery_Information");;\
   CommandGet(undef, "WR_1_API 22_Battery_InternControl");;\
   CommandGet(undef, "WR_1_API 23_Battery_ExternControl");;\
   CommandGet(undef, "WR_1_API 25_Battery_EM_State");;\
\
   ## Schattenmanagement \
   if ($hour == 8)   {\
     CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 0");;                             ## Komplett aus\
   };;\
   if ($hour == 18) {\
     CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 2");;                             ## Im Westen unten einschalten\
   };;\
   if ($hour == 21) {\
     CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 1");;                             ## Schattenmanagement für den Osten vorbereiten\
   };;\
  }\
\
################################################################################################################\
## 2 Wenn die Ladung im Herbst/Winter unter MinSoc geht allen PV Überschuss in die Batterie laden\
##\
## Im Winter kann der MinSoc, durch den WR Eigenverbrauch, unterschritten werden, deshalb wird vorher auf\
## smarte_laden umgeschaltet, bis die Batterie wieder einen hohen Soc erreicht hat. Siehe cmd_3 laden_beendet\
##\
DOELSEIF\
([$SELF:ui_command] eq "smart_laden start" or\
  [WR_1:Solar_Calculation_fc0_day] < [$SELF:SpeicherMinSOC_fc1_Limit] and       ## Im Herbst/Winter ist wenig zu erwarten\
  [WR_1:Act_state_of_charge] <= [WR_1_API:Battery_InternControl_MinSoc] and     ## Achtung der Speicherstand wird zu niedrig\
  [WR_1_API:Battery_InternControl_MinHomeConsumption] <= 100 )                  ## Der Speicher steht auf Entladen\
  {\
   CommandGet(undef, "WR_1_Speicher_1 BatteryInformation");;\
   CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption [WR_1_API:Battery_Info_WorkCapacity]");; ## Speicher für Entladung sperren\
   if (AttrVal("$SELF","verbose",0) >=3)\
       {Log 3, "$SELF cmd_2  : smart_laden aktiviert"};;\
   CommandSetReading(undef, "$SELF SpeicherExternTrigger gesperrt");;            ## Externe Trigger verriegeln \
   if (AttrVal("$SELF","verbose",0) >=3)\
       {Log 3, "$SELF cmd_2  : SpeicherExternTrigger, Entlademodus gesperrt"};;\
  }\
\
################################################################################################################\
## 3 Beim erreichen von 90% Soc die Entladung wieder frei geben oder\
##   bei Zeitsteuerung und guter Prognose auch schon bei 40%\
DOELSEIF\
([$SELF:ui_command] eq "smart_laden beenden" or\
  [WR_1_API:Battery_InternControl_MinHomeConsumption] > 100 and                 ## Der Speicher wird voll und wieder\
  ([WR_1:Act_state_of_charge] >= 90                                             ## zum Entladen frei gegeben\
   or\
   [$SELF:SpeicherEntladung]  eq "Zeit" and                                     ## Bei Zeitsteuerung\
   [WR_1:Act_state_of_charge] >= 40 and                                         ## und einem Stand von Soc 40%\
   ([WR_1:Solar_Calculation_fc0_day] > [$SELF:SpeicherMaxSOC_fc1_Limit]         ## wenn es heute oder \
    or\
    [WR_1:Solar_Calculation_fc1_day] > [$SELF:SpeicherMaxSOC_fc1_Limit])        ## morgen viel Leistung gibt\
  )\
)\
\
{\
  if ( ReadingsVal("$SELF","SpeicherEntladung","Automatik") eq "Automatik" ) {  ## Bei Automatik sofort auf Entladen\
    if (AttrVal("$SELF","verbose",0) >=3)\
      {Log 3, "$SELF cmd_3  : Batterie auf [WR_1:Act_state_of_charge] %, Entlademodus freigegeben"};;\
    CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");;\
    CommandSetReading(undef, "$SELF SpeicherExternTrigger none");;\
  } else {                                                                      ## Ansonsten die Zeitsteuerung oder den\
    if (AttrVal("$SELF","verbose",0) >=3)\
      {Log 3, "$SELF cmd_3  : Batterie auf [WR_1:Act_state_of_charge] %, SpeicherExternTrigger, freigegeben"};;\
    CommandSetReading(undef, "$SELF SpeicherExternTrigger frei");;               ## Trigger freigeben\
    CommandSetReading(undef, "$SELF SpeicherTrigger entladen");;                 ## Signalisiere entladen im stateFormat\
  }\
}\
\
################################################################################################################\
## 4 Freigabe der Batterie mit externem Trigger\
##   z.B. ([07:00-16:00]\
DOELSEIF\
([$SELF:SpeicherExternTrigger] eq "frei" and                                   ## Verriegelung, wenn zwangsgeladen werden muss\
\
   ([$SELF:SpeicherEntladung] eq "Trigger" and                                  ## Triggersteuerung\
    [$SELF:SpeicherTrigger]   eq "entladen"                                     ## also Speicherentladung freigeben\
    or                                                                         \
    [$SELF:SpeicherEntladung] eq "Zeit" and                                     ## oder bei Zeitsteuerung wenn das\
    [[$SELF:SpeicherZeitStart]-[$SELF:SpeicherZeitEnde]])                       ## Zeitfenster aktiv ist\
\
  )\
{\
  CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");;            ## Speicher für Entladung freigeben\
  CommandSetReading(undef, "$SELF SpeicherTrigger entladen");;                   ## Signalisiere entladen im stateFormat\
  if (AttrVal("$SELF","verbose",0) >=3)\
    {Log 3, "$SELF cmd_4  : SpeicherExternTrigger, Entlademodus freigegeben"};;\
}\
\
################################################################################################################\
## 5 Sperren der Batterie mit externem Trigger\
##   z.B. [16:00-07:00]\
DOELSEIF\
([$SELF:SpeicherExternTrigger] eq "frei" and                                   ## Verriegelung, wenn zwangsgeladen werden muss\
                               \
   ([$SELF:SpeicherEntladung]  eq "Trigger" and                                 ## Triggersteuerung\
    [$SELF:SpeicherTrigger]    eq "gesperrt"                                    ## also Speicherentladung sperren\
    or                                                                         \
    [$SELF:SpeicherEntladung]  eq "Zeit" and                                    ## oder bei Zeitsteuerung wenn das\
    [[$SELF:SpeicherZeitEnde]-[$SELF:SpeicherZeitStart]])                       ## Zeitfenster verlassen wurde\
\
  )\
{\
  CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption [WR_1_API:Battery_Info_WorkCapacity]");;  ## Speicher für Entladung sperren\
  CommandSetReading(undef, "$SELF SpeicherTrigger gesperrt");;                   ## Signalisiere gesperrt im stateFormat\
  if (AttrVal("$SELF","verbose",0) >=3)\
    {Log 3, "$SELF cmd_5  : SpeicherExternTrigger, Entlademodus gesperrt (Tarif oder Trigger)"};;\
}\
\
################################################################################################################\
## 6 Wiederhole alle 180s die Kommandos der ExternControl Steuerung\
##\
DOELSEIF\
([$SELF:ui_command] eq "3 Minuten Wiederholung" or\
  [WR_1_API:Battery_Control] > 0 and                                            ## Wenn die ExternControl am WR konfiguriert ist\
  [$SELF:SpeicherCmdRepeatActive]  == 1 and                                     ## Wenn die ExternControl Aktiviert ist\
  [$SELF:SpeicherCmdRepeatRunning] == 1 and                                     ## Wenn es  ExternControl Kommandos zum Senden gibt\
  [  {sunrise_abs("HORIZON=+5.0",0,"6:00","08:35")}                             \
   - {sunset_abs("HORIZON=+8.0",0,"15:00","21:00")} ] and [+180] )              ## alle 3 Minuten den Befehl wiederholen\
  \
  {\
   CommandSetReading(undef, "$SELF ui_command ---");;\
   my $MaxChargePowerTime = 0;;\
   my $MaxChargePowerAbs_midday = 0;;\
\
   if ([$SELF:SpeicherMiddayControlRunning] == 1 ) {                            ## Wurde ein Mittagshoch ermittelt und aktiviert?\
\
     if ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [$SELF:SpeicherMidday_NotBefore]") and\
           [WR_1:Act_state_of_charge] >= [WR_1_API:Battery_InternControl_MinSoc] *3 ) {\
       CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs 0");;     ## nicht vor z.B. 09:00 Uhr starten. Ladung auf 0 Watt setzen\
       if (AttrVal("$SELF","verbose",0) >=3) {                                  ## Es wird nur langsam geladen und MaxSOC limitiert.\
         Log 3, "$SELF cmd_6  : SpeicherMiddayControl vor [$SELF:SpeicherMidday_NotBefore] Uhr noch nicht laden";;\
       };;\
     } else { \
       if ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_start]") ) {   ## Ist noch Vormittag?\
         CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs [$SELF:SpeicherMidday_MaxChargePowerAbs_morning]");;\
         CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMidday_MaxSOC]");;\
         if (AttrVal("$SELF","verbose",0) >=3) {                                ## Es wird nur langsam geladen und MaxSOC limitiert.\
           Log 3, "$SELF cmd_6  : SpeicherMiddayControl vor [WR_1:Solar_middayhigh_fc0_start] limitieren";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxChargePowerAbs auf [$SELF:SpeicherMidday_MaxChargePowerAbs_morning] limitiert";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSOC auf [$SELF:SpeicherMidday_MaxSOC] % limitiert";;\
         };;\
       };;\
     };;\
\
     if (time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_start]") <= time and  ## Es ist Mittag\
         time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_stop]") ) {\
\
       if ([$SELF:SpeicherMaxSOCControlRunning] == 1 and                                                             ## Somit bleibt weniger Platz im Speicher und es ist\
           time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." 12:00") ) {                             ##    besser nicht vor 12:00 Uhr zu beginnen.\
         CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs 0");;\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_6  : SpeicherMiddayControlActive laden wegen MaxSoc von [WR_1:Solar_middayhigh_fc0_start] auf 12:00 Uhr verschoben"};;\
       } else {                                                                                                      ## auch jetzt nicht mit voller Leistung laden\
\
         if ([$SELF:SpeicherMidday_MaxChargePowerAbs_midday] == 0) {                                                 ## dynamische Leistungsermittlung oder vorgewählter Wert\
           $MaxChargePowerTime = round((time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_stop]") - time) / 3600 , 2);;  ## Mittags Ladezeit bestimmen\
           if ( $MaxChargePowerTime < 1 ) { $MaxChargePowerTime = 1;;};;\
           $MaxChargePowerAbs_midday  = round( [WR_1:Battery_work_capacity] * ([$SELF:SpeicherMaxSOC_Actual] - [WR_1:Act_state_of_charge]) / 100 / $MaxChargePowerTime , 0);;\
           if ($MaxChargePowerAbs_midday < 0) { $MaxChargePowerAbs_midday = 0 };;                                     ## Nicht unter 0\
           Log 3, "$SELF Test   : Mittags $MaxChargePowerTime h mit $MaxChargePowerAbs_midday W laden";;\
         } else {\
           $MaxChargePowerAbs_midday = [$SELF:SpeicherMidday_MaxChargePowerAbs_midday];;                              ## Nimm den vorgewählten Wert\
         };;\
\
         CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs $MaxChargePowerAbs_midday");;\
         CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual]");;\
         if (AttrVal("$SELF","verbose",0) >=3) {\
           Log 3, "$SELF cmd_6  : SpeicherMiddayControlActive laden von [WR_1:Solar_middayhigh_fc0_start] bis [WR_1:Solar_middayhigh_fc0_stop] freigegeben";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxChargePowerAbs auf $MaxChargePowerAbs_midday limitiert";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual] % halten"\
         };;\
       };;\
     };;\
\
     if (time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_stop]") ) {    ## Es ist Nachmittag und die\
       CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 0");;                                             ## Mittagssteuerung wird abgeschaltet\
       CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual]");;\
       if (AttrVal("$SELF","verbose",0) >=3) {\
         Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual] % halten";;\
         Log 3, "$SELF cmd_6  : SpeicherMiddayControl nach [WR_1:Solar_middayhigh_fc0_stop] beendet";;\
       };;\
     };;\
   };;\
\
   if ([$SELF:SpeicherMaxSOCControlRunning] == 1 and                                           ## Nur MaxSOC soll begrenzt werden\
       [$SELF:SpeicherMaxSOC_Actual] <= 100      and                                          \
       [$SELF:SpeicherMiddayControlRunning] == 0) {                                            ##  sobald die Mittagssteuerung fertig ist\
     CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual]");;\
     if (AttrVal("$SELF","verbose",0) >=3)\
       {Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual] % halten"};;\
   };;\
\
   if (AttrVal("$SELF","verbose",0) >=4)\
     {Log 3, "$SELF cmd_6  : ExternControl Kommandowiederholung erledigt"};;\
  }\
\
################################################################################################################\
## 7 Bestimmung eines möglichen SOC für den nächsten Morgen und\
##   Vorbereitung für ein Leistungshoch am Mittag\
##\
DOELSEIF\
([WR_1_API:Battery_Control] > 0 and                                                           ## Ist die ExternControl am WR aktiviert\
  ([$SELF:SpeicherMaxSOCControlActive] == 1 or                                                 ## Ist MaxSOC Limit konfiguriert\
   [$SELF:SpeicherMiddayControlActive] == 1 ) and                                              ## Ist Midday Kontrolle konfiguriert\
   [$SELF:SpeicherMaxSOC_MinSOC_Time] eq "NULL" and                                            ## Wurde ein minimum SOC bereits ermittelt\
   [{sunrise_abs("HORIZON=+4.0",0,"5:50","08:35")} - 10:00 ] and\
   [WR_1:SW_Home_own_consumption_from_PV] == [WR_1:SW_Home_own_consumption] )                  ## Die PV Leistung reicht für's Haus\
\
  {\
   my $MinSOC_Time   = "gefunden";;                                                             ## Nur einmal am Tag bearbeiten\
   my $MinSOC_MinSOC = round(ReadingsVal("WR_1","Act_state_of_charge", 0),0);;                  ## Festgestellter MinSOC am Morgen\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_MinSOC_Time ".$MinSOC_Time);;\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_MinSOC_MinSOC ".$MinSOC_MinSOC);;\
   if (AttrVal("$SELF","verbose",0) >=3) {                                                     ## merken und melden\
     Log 3, "$SELF cmd_7  : SpeicherMaxSOC_MinSOC_Time ".$MinSOC_Time." ".$MinSOC_MinSOC." %";;\
   };;\
\
#############\
\
   if ([$SELF:SpeicherMaxSOCControlActive] ==   1 and\
       [WR_1_API:Battery_InternControl_MinHomeConsumption]         <  100 and                  ## Der Speicher darf nicht im smart_laden sein\
       [Pool_Counter:countsPerDay] == 0 and                                                    ## Achtung der Pool und auch die LWP\
       [LWP_Counter:countsPerDay]  == 0 ) {                                                    ##    sollten nicht mehr früh morgens laufen\
\
     my $SpeicherSOCMinimum = [WR_1_API:Battery_InternControl_MinSoc]*3;;                       ## 3x MinSOC als reserve vorsehen\
     my $SpeicherSOCDayBefore = round(ReadingsVal("$SELF","SpeicherMaxSOC_DayBefore", 100),0);; ## wie voll war er gestern noch?\
     my $SpeicherSOCNew       = 0;;\
     my $SpeicherSOCDelta     = 0;;\
\
     if ([WR_1:Solar_Calculation_fc1_day] > [$SELF:SpeicherMaxSOC_fc1_Limit] and\
         $MinSOC_MinSOC                   > $SpeicherSOCMinimum ) {                            ## Ist der Speicher voller als er müsste?\
\
       if (AttrVal("$SELF","verbose",0) >=3){\
         Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore ".$SpeicherSOCDayBefore." %";;\
         Log 3, "$SELF cmd_7  : Leistung Prognose [WR_1:Solar_Calculation_fc1_day] wh > Schwellwert [$SELF:SpeicherMaxSOC_fc1_Limit] wh";;\
         Log 3, "$SELF cmd_7  : Speicherladung aktuell $MinSOC_MinSOC % > Minimum $SpeicherSOCMinimum %";;\
       };;\
       $SpeicherSOCDelta = $MinSOC_MinSOC - $SpeicherSOCMinimum;;                               ## Was wäre noch übrig?\
       if ($SpeicherSOCDelta <= 10) {                                                          ## Das lohnt sich nicht\
         $SpeicherSOCNew = $SpeicherSOCDayBefore;;                                              ## den Wert von gestern einfach beibehalten\
         CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual ".$SpeicherSOCDayBefore);;\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore ".$SpeicherSOCDayBefore." % gesichert"};;\
       } else {\
         $SpeicherSOCNew = round(($SpeicherSOCDayBefore+$SpeicherSOCDayBefore-$SpeicherSOCDelta)/2 ,0);;  ## um den Durchschnitt verringern\
##         CommandSetReading(undef, "$SELF SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew);;          ## den neuen Wert für morgen merken\
         CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual ".$SpeicherSOCNew);;             ## Das soll heute in den Speicher\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew." % neu berechnet und gesichert"};;\
       };;\
\
       if ($SpeicherSOCNew > 0) {                                                              ## Es gibt einen neuen MaxSoc\
         CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 1");;                     ## Senden starten\
         CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 1");;                         ## Wiederholung starten\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_Actual ".$SpeicherSOCNew." % geplant"};;\
       } else {                                                                                ## MaxSoc wird nicht begrenzt\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_Actual wird nicht begrenzt"};;\
       };;\
\
     } else {                                                                                  ## MaxSoc wird nicht begrenzt\
       if ($MinSOC_MinSOC  < $SpeicherSOCMinimum ) {                                           ## MaxSoc leicht erhöhen, da er etwas zu niedrig war\
         $SpeicherSOCNew   = round($SpeicherSOCDayBefore+$SpeicherSOCMinimum-$MinSOC_MinSOC ,0);;\
         $SpeicherSOCDelta = round($SpeicherSOCMinimum-$MinSOC_MinSOC ,0);;\
         CommandSetReading(undef, "$SELF SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew);;\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore wurde um ".$SpeicherSOCDelta." erhöht"};;\
       }\
       if (AttrVal("$SELF","verbose",0) >=3)\
         {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_Actual wird nicht begrenzt, da die Prognose zu schlecht ist"};;\
     };;\
   };;\
\
   if ([$SELF:SpeicherMiddayControlActive] == 1 and                                            ## Soll für mittags noch Platz gehalten werden?\
       [WR_1:Solar_middayhigh_fc0] == 1 ) {                                                    \
                           \
     CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 1");;                         ## Die Mittagskontrolle aktivieren\
     CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 1");;\
     if (AttrVal("$SELF","verbose",0) >=3){                      ## (die Uhrzeiten wurden bereits durch Solar_forecast() im WR_1 Device eingetragen)\
       Log 3, "$SELF cmd_7  : Batterie SpeicherMiddayControlRunning vorbereitet";;\
       Log 3, "$SELF cmd_7  : Batterie Solar_middayhigh_fc0_start [WR_1:Solar_middayhigh_fc0_start] gesetzt";;\
       Log 3, "$SELF cmd_7  : Batterie Solar_middayhigh_fc0_stop  [WR_1:Solar_middayhigh_fc0_stop] gesetzt";;\
     };;\
   } else {                                                                                    ## Kein Mittagshoch\
     Log 3, "$SELF cmd_7  : SpeicherMiddayControl es wird kein Middayhigh geben";;\
   };;\
\
#############\
\
  }\
\
################################################################################################################\
## 8 Reset der ExternControl Kommandos\
##\
DOELSEIF\
([{sunset_abs("HORIZON=+8.0",0,"15:00","21:00")}])                                            ## hier sollte das Ende der PV-Zeit sein\
\
  {\
   CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 0");;                               ## Stop das regelmäßige senden der Kommandos\
                   \
   CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 0");;                           ## Midday Steuerung zurücksetzen\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual 100");;                                ## SpeicherMaxSOC_Actual auf Default\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_DayBefore [WR_1:Act_state_of_charge]");;      ## Den vor Tages Wert merken\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_MinSOC_Time NULL");;                          ## Die MinSOC Time löschen\
       \
   CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 0");;                           ## Midday Steuerung zurücksetzen\
\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc0 0");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc0_start 00:00");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc0_stop 00:00");;\
\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc1 0");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc1_start 00:00");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc1_stop 00:00");;\
\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_8  : ExternControl zurückgesetzt"};;\
  }\
\
################################################################################################################\
## 9 Umschaltung des MinSOC wenn zu wenig Leistung erwartet wird, das ist dann im Herbst/Winter\
##\
DOELSEIF\
([WR_1:Solar_Calculation_fc1_day]        < [$SELF:SpeicherMinSOC_fc1_Limit] and               ## Wenn morgen das Minimum an Leistung nicht erreicht wird\
  [WR_1_API:Battery_InternControl_MinSoc] < [$SELF:SpeicherMinSOC_Winter]    and               ## und der MinSoc unter der Winter Wert eingestellt ist\
  [$SELF:SpeicherMaxSOC_MinSOC_Time] eq "gefunden" )\
\
  {\
   CommandSet(undef, "WR_1_API 22_04_Battery_MinSoc [$SELF:SpeicherMinSOC_Winter]");;           ## Den MinSOC anheben, um eine eventuelle\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_9  : Batterie MinSoc auf Winterbetrieb"};;                              ## Notladung zu verhindern\
   CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 0");;                               ## Stop das regelmäßige senden der Kommandos\
   CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 0");;                           ## Im Winter Betrieb keine MaxSOC Begrenzung\
   CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 0");;                           ## und keine Midday Steuerung\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_9  : MaxSOC Begrenzung und Midday Steuerung im Winterbetrieb deaktiviert"};;\
  }\
\
################################################################################################################\
## 10 Umschaltung des MinSoc wenn viel Leistung erwartet wir, das wäre dann Frühling/Sommer\
##\
DOELSEIF\
([WR_1:Solar_Calculation_fc1_day]        > [$SELF:SpeicherMinSOC_fc1_Limit] and               ## sobald viel Ladung erwartet wird und der MinSoc noch\
  [WR_1_API:Battery_InternControl_MinSoc] > [$SELF:SpeicherMinSOC_Sommer]    and               ## noch im Winter Modus ist\
  [10:09] )                                                                                   \
          \
  {                                                                                           \
   CommandSet(undef, "WR_1_API 22_04_Battery_MinSoc [$SELF:SpeicherMinSOC_Sommer]");;           ## den MinSOC auf Sommerbetrieb herabsetzen, es kann\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_10 : Batterie MinSoc auf Sommerbetrieb"};;                              ## wieder mehr Leistung genutzt werden\
  }\
\
################################################################################################################\
## 11 Der Speicher ist voll geladen. Hier wird das ständige nachladen auf 100 % vermieden.\
##\
DOELSEIF\
( [WR_1:Solar_Calculation_fc0_day] > [$SELF:SpeicherMaxSOC_fc1_Limit] and                     ## 1) sobald viel Leistung erwartet wird und der Speicher voll ist\
   [WR_1:Act_state_of_charge] == 100 or                                                        ##    den MaxSOC wieder reduzieren, damit nicht immer nachgeladen wird\
  ([$SELF:SpeicherMaxSOC_Actual] == 95 and                                                     ## 2) oder das Nachladen gestoppt wurde\
   [WR_1:Act_state_of_charge] <  98  and                                                       ##    und der SOC unte 98 % gefallen ist\
   [{sunset_abs("HORIZON=+8.0",-7200,"15:00","21:00")}]) )                                     ##    zwei Stunden vor Sonnenuntergang eventuell wieder nachladen\
\
  {\
   if ([WR_1:Act_state_of_charge] < 98) {\
     CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual 100");;                              ## Eventuell noch mal nachladen\
     if (AttrVal("$SELF","verbose",0) >=3) {\
       Log 3, "$SELF cmd_11 : Battery_ExternControl_MaxSocRel auf 100 % nachladen";;\
     };;\
   } else {\
     CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual 95");;\
     CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 1");;                             ## Start regelmäßiges senden der Kommandos\
     CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 1");;                         ## MaxSOC Begrenzung weil Speicher bereits 100 % hat\
     if (AttrVal("$SELF","verbose",0) >=3) {\
       Log 3, "$SELF cmd_11 : Battery_ExternControl_MaxSocRel auf 95 % reduziert";;\
     };;\
   }\
  }\
\

attr WR_1_Speicher_1_ExternControl DbLogExclude .*
attr WR_1_Speicher_1_ExternControl alias WR_1_Speicher_1_ExternControl
attr WR_1_Speicher_1_ExternControl comment Version 2021.09.09 14:50\
\
Hier können externe Trigger für die Ladung und Entladung Der Batterie gesetzt werden.\
Die Zeiten können z.B. durch den WeekDayTimer entsprechend an einen Stromtarif angepasst werden.\
Das reading SpeicherEntladung Automatik/Zeit/SpeicherTrigger ermöglicht es die Zeitsteuerung zu überschreiben.\
\
ExternTrigger\
Das reading dient dem Freigeben und Sperren der externen Trigger, z.B. um im Herbst/Winter das smart_laden zu steuern.\
Es verriegelt somit die Zeitsteuerung oder den SpeicherTrigger.\
\
SpeicherEntladung:Automatik,Zeit,SpeicherTrigger \
Automatik - Der Speicher wird vom Wechselrichter gesteuert, oder über die eigene ExternControl der API\
Zeit - Das Laden und Entladen wird mit den Zeitwerten beeinflusst\
SpeicherTrigger - beeinflusst das Laden und Entladen direkt ohne die Zeitsteuerung\
\
SpeicherTrigger:entladen,gesperrt\
Dieser Trigger kann durch ander Logik gesetzt werden.\
Auch hier wäre eine Zeitsteuerung denkbar, die entladen/gesperrt entsprechend umschaltet.\
\
SpeicherZeitStart/SpeicherZeitEnde\
Die Zeitangaben können manuell fest gesetzt werden, oder über zusätzliche Timer täglich neu überschrieben werden.\
Eine gültige Zeit und entsprechendes Timeing obliegt dem Anwender.\
Zwischen Start und Ende wird der Speicher zum Entladen freigegeben und zwischen Ende und Start gesperrt.\
\
Speicher*ControlActive\
Das jeweilige reading aktiviert diese Teilkomponente für die Steuerung.\
Ein jeweiliges Speicher*ControlRunning signalisiert, ob gerade die Bedingungen erfüllt sind.\
\
SpeicherCmdRepeatActive\
Es muss im WR die externe Speicher Steuerung aktiviert sein.\
Möchte man trotzdem die Sendung der ExternControl Kommandos stoppen, obwohl die Bedingungen erfüllt sind,\
kann man dieses reading zum Deaktivieren auf 0 setzen.\
\
SpeicherMiddayControl\
Über die Solar_forecast() Funktion wird ein Middayhigh ermittelt, wenn der WR nur 70% einspeisen darf.\
\
SpeicherMaxSOCControl\
Es wird versucht den Speicher am Abend nicht zu 100% zu laden, aber morgens noch mit 3* MinSOC aus der Nacht zu kommen.\
\
SpeicherMinSOC\
Dies gehört zur Basis Steuerung und schaltet den MinSOC von Sommer auf Winter Betrieb,\
um eine Notladung aus dem Netz zu vermeiden.
attr WR_1_Speicher_1_ExternControl do always
attr WR_1_Speicher_1_ExternControl group PV Eigenverbrauch
attr WR_1_Speicher_1_ExternControl icon measure_battery_100
attr WR_1_Speicher_1_ExternControl readingList SpeicherExternTrigger SpeicherCmdRepeatActive SpeicherZeitStart SpeicherZeitEnde SpeicherEntladung SpeicherTrigger SpeicherMiddayControlActive SpeicherMidday_Inverter_Max_Power SpeicherMidday_MaxChargePowerAbs_morning SpeicherMidday_MaxChargePowerAbs_midday SpeicherMidday_MaxSOC SpeicherMidday_NotBefore SpeicherMinSOC_Sommer SpeicherMinSOC_Winter SpeicherMinSOC_fc1_Limit SpeicherMaxSOCControlActive SpeicherMaxSOC_Actual SpeicherMaxSOC_DayBefore SpeicherMaxSOC_fc1_Limit
attr WR_1_Speicher_1_ExternControl room Strom->Photovoltaik
attr WR_1_Speicher_1_ExternControl setList SpeicherExternTrigger:frei,gesperrt SpeicherCmdRepeatActive:0,1 SpeicherZeitStart:time SpeicherZeitEnde:time SpeicherEntladung:Automatik,Zeit,Trigger SpeicherTrigger:entladen,gesperrt,none SpeicherMiddayControlActive:0,1 SpeicherMidday_Inverter_Max_Power:slider,3000,500,20000 SpeicherMidday_MaxChargePowerAbs_morning:slider,0,50,4700 SpeicherMidday_MaxChargePowerAbs_midday:slider,0,100,4700 SpeicherMidday_MaxSOC:slider,20,5,50 SpeicherMidday_NotBefore:time SpeicherMinSOC_Sommer:slider,5,1,20 SpeicherMinSOC_Winter:slider,5,1,20 SpeicherMinSOC_fc1_Limit:slider,7000,500,17000 SpeicherMaxSOCControlActive:0,1 SpeicherMaxSOC_Actual:slider,60,5,100 SpeicherMaxSOC_DayBefore:slider,15,5,100 SpeicherMaxSOC_fc1_Limit:slider,10000,2000,50000
attr WR_1_Speicher_1_ExternControl sortby 122


Hier fehlen noch stateFormat und uiTable, aber der Post war zu lang :-)
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Zitat von: ch.eick am 09 September 2021, 15:07:26
Und hier noch etwas zum Testen, für die ganz verwegenen Anwender ;-)

Hier sind alle Änderungen des WR_1_Speicher_1_ExternControl beinhaltet.
- aktuelles stateFormat
- Code Korrekturen
   * kleinere Änderung von readings Namen
   * uiTable Events beim DOELSEIF
   * dynamische Leistungsberechnung für die Speicherladung im Mittagshoch
   * Einige überflüssige Wiederholungen von Speicher Kommandos wurden entfernt
   * In diesem Listing habe ich cmd_12 für die direkte Abfrage des BYD HV bereits herausgenommen, da den wohl außer mir keiner hat :-)

- uiTable Definitionen, die eine zweite Tabelle im FHEMWEB erzeugen, um die Konfiguration von WR_1_Speicher_1_ExternControl direkt zu verändern.
   Das Layout entpricht in Grundzügen der stateFormat Definition, ist aber noch lange nicht fertig.

   * Man kann z.B. auch einen DOIF Zweig aus einem Pull Down Menü ausführen lassen.
   * Die Unterfunktionen werden über 0/1 deaktiviert/aktiviert
   * Werte lassen sich verändern
   * Uhrzeiten sind Einstellbar

Aber Achtung, das ist mein Lernstand von gestern Nacht!
Ich möchte jetzt noch stateFormat und uiTable in eine Tabelle überführen, wo ich jedoch noch nicht genügend Kenntnisse habe.

VG
   Christian

WR_1_Speicher_1_ExternControl

defmod WR_1_Speicher_1_ExternControl DOIF ################################################################################################################\
## 1 Speicher Status vom WR_1_Speicher_1 aktualisieren.\
##   Dies geschieht über das WR_1_API Device, da der Speicher direkt am Wechselrichter angeschlossen ist.\
##\
([:58])\
  {\
   CommandGet(undef, "WR_1_API 21_Battery_Information");;\
   CommandGet(undef, "WR_1_API 22_Battery_InternControl");;\
   CommandGet(undef, "WR_1_API 23_Battery_ExternControl");;\
   CommandGet(undef, "WR_1_API 25_Battery_EM_State");;\
\
   ## Schattenmanagement \
   if ($hour == 8)   {\
     CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 0");;                             ## Komplett aus\
   };;\
   if ($hour == 18) {\
     CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 2");;                             ## Im Westen unten einschalten\
   };;\
   if ($hour == 21) {\
     CommandSet(undef, "WR_1_API 40_02_Generator_ShadowMgmt 1");;                             ## Schattenmanagement für den Osten vorbereiten\
   };;\
  }\
\
################################################################################################################\
## 2 Wenn die Ladung im Herbst/Winter unter MinSoc geht allen PV Überschuss in die Batterie laden\
##\
## Im Winter kann der MinSoc, durch den WR Eigenverbrauch, unterschritten werden, deshalb wird vorher auf\
## smarte_laden umgeschaltet, bis die Batterie wieder einen hohen Soc erreicht hat. Siehe cmd_3 laden_beendet\
##\
DOELSEIF\
([$SELF:ui_command] eq "smart_laden start" or\
  [WR_1:Solar_Calculation_fc0_day] < [$SELF:SpeicherMinSOC_fc1_Limit] and       ## Im Herbst/Winter ist wenig zu erwarten\
  [WR_1:Act_state_of_charge] <= [WR_1_API:Battery_InternControl_MinSoc] and     ## Achtung der Speicherstand wird zu niedrig\
  [WR_1_API:Battery_InternControl_MinHomeConsumption] <= 100 )                  ## Der Speicher steht auf Entladen\
  {\
   CommandGet(undef, "WR_1_Speicher_1 BatteryInformation");;\
   CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption [WR_1_API:Battery_Info_WorkCapacity]");; ## Speicher für Entladung sperren\
   if (AttrVal("$SELF","verbose",0) >=3)\
       {Log 3, "$SELF cmd_2  : smart_laden aktiviert"};;\
   CommandSetReading(undef, "$SELF SpeicherExternTrigger gesperrt");;            ## Externe Trigger verriegeln \
   if (AttrVal("$SELF","verbose",0) >=3)\
       {Log 3, "$SELF cmd_2  : SpeicherExternTrigger, Entlademodus gesperrt"};;\
  }\
\
################################################################################################################\
## 3 Beim erreichen von 90% Soc die Entladung wieder frei geben oder\
##   bei Zeitsteuerung und guter Prognose auch schon bei 40%\
DOELSEIF\
([$SELF:ui_command] eq "smart_laden beenden" or\
  [WR_1_API:Battery_InternControl_MinHomeConsumption] > 100 and                 ## Der Speicher wird voll und wieder\
  ([WR_1:Act_state_of_charge] >= 90                                             ## zum Entladen frei gegeben\
   or\
   [$SELF:SpeicherEntladung]  eq "Zeit" and                                     ## Bei Zeitsteuerung\
   [WR_1:Act_state_of_charge] >= 40 and                                         ## und einem Stand von Soc 40%\
   ([WR_1:Solar_Calculation_fc0_day] > [$SELF:SpeicherMaxSOC_fc1_Limit]         ## wenn es heute oder \
    or\
    [WR_1:Solar_Calculation_fc1_day] > [$SELF:SpeicherMaxSOC_fc1_Limit])        ## morgen viel Leistung gibt\
  )\
)\
\
{\
  if ( ReadingsVal("$SELF","SpeicherEntladung","Automatik") eq "Automatik" ) {  ## Bei Automatik sofort auf Entladen\
    if (AttrVal("$SELF","verbose",0) >=3)\
      {Log 3, "$SELF cmd_3  : Batterie auf [WR_1:Act_state_of_charge] %, Entlademodus freigegeben"};;\
    CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");;\
    CommandSetReading(undef, "$SELF SpeicherExternTrigger none");;\
  } else {                                                                      ## Ansonsten die Zeitsteuerung oder den\
    if (AttrVal("$SELF","verbose",0) >=3)\
      {Log 3, "$SELF cmd_3  : Batterie auf [WR_1:Act_state_of_charge] %, SpeicherExternTrigger, freigegeben"};;\
    CommandSetReading(undef, "$SELF SpeicherExternTrigger frei");;               ## Trigger freigeben\
    CommandSetReading(undef, "$SELF SpeicherTrigger entladen");;                 ## Signalisiere entladen im stateFormat\
  }\
}\
\
################################################################################################################\
## 4 Freigabe der Batterie mit externem Trigger\
##   z.B. ([07:00-16:00]\
DOELSEIF\
([$SELF:SpeicherExternTrigger] eq "frei" and                                   ## Verriegelung, wenn zwangsgeladen werden muss\
\
   ([$SELF:SpeicherEntladung] eq "Trigger" and                                  ## Triggersteuerung\
    [$SELF:SpeicherTrigger]   eq "entladen"                                     ## also Speicherentladung freigeben\
    or                                                                         \
    [$SELF:SpeicherEntladung] eq "Zeit" and                                     ## oder bei Zeitsteuerung wenn das\
    [[$SELF:SpeicherZeitStart]-[$SELF:SpeicherZeitEnde]])                       ## Zeitfenster aktiv ist\
\
  )\
{\
  CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption 50");;            ## Speicher für Entladung freigeben\
  CommandSetReading(undef, "$SELF SpeicherTrigger entladen");;                   ## Signalisiere entladen im stateFormat\
  if (AttrVal("$SELF","verbose",0) >=3)\
    {Log 3, "$SELF cmd_4  : SpeicherExternTrigger, Entlademodus freigegeben"};;\
}\
\
################################################################################################################\
## 5 Sperren der Batterie mit externem Trigger\
##   z.B. [16:00-07:00]\
DOELSEIF\
([$SELF:SpeicherExternTrigger] eq "frei" and                                   ## Verriegelung, wenn zwangsgeladen werden muss\
                               \
   ([$SELF:SpeicherEntladung]  eq "Trigger" and                                 ## Triggersteuerung\
    [$SELF:SpeicherTrigger]    eq "gesperrt"                                    ## also Speicherentladung sperren\
    or                                                                         \
    [$SELF:SpeicherEntladung]  eq "Zeit" and                                    ## oder bei Zeitsteuerung wenn das\
    [[$SELF:SpeicherZeitEnde]-[$SELF:SpeicherZeitStart]])                       ## Zeitfenster verlassen wurde\
\
  )\
{\
  CommandSet(undef, "WR_1_API 22_03_Battery_MinHomeConsumption [WR_1_API:Battery_Info_WorkCapacity]");;  ## Speicher für Entladung sperren\
  CommandSetReading(undef, "$SELF SpeicherTrigger gesperrt");;                   ## Signalisiere gesperrt im stateFormat\
  if (AttrVal("$SELF","verbose",0) >=3)\
    {Log 3, "$SELF cmd_5  : SpeicherExternTrigger, Entlademodus gesperrt (Tarif oder Trigger)"};;\
}\
\
################################################################################################################\
## 6 Wiederhole alle 180s die Kommandos der ExternControl Steuerung\
##\
DOELSEIF\
([$SELF:ui_command] eq "3 Minuten Wiederholung" or\
  [WR_1_API:Battery_Control] > 0 and                                            ## Wenn die ExternControl am WR konfiguriert ist\
  [$SELF:SpeicherCmdRepeatActive]  == 1 and                                     ## Wenn die ExternControl Aktiviert ist\
  [$SELF:SpeicherCmdRepeatRunning] == 1 and                                     ## Wenn es  ExternControl Kommandos zum Senden gibt\
  [  {sunrise_abs("HORIZON=+5.0",0,"6:00","08:35")}                             \
   - {sunset_abs("HORIZON=+8.0",0,"15:00","21:00")} ] and [+180] )              ## alle 3 Minuten den Befehl wiederholen\
  \
  {\
   CommandSetReading(undef, "$SELF ui_command ---");;\
   my $MaxChargePowerTime = 0;;\
   my $MaxChargePowerAbs_midday = 0;;\
\
   if ([$SELF:SpeicherMiddayControlRunning] == 1 ) {                            ## Wurde ein Mittagshoch ermittelt und aktiviert?\
\
     if ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [$SELF:SpeicherMidday_NotBefore]") and\
           [WR_1:Act_state_of_charge] >= [WR_1_API:Battery_InternControl_MinSoc] *3 ) {\
       CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs 0");;     ## nicht vor z.B. 09:00 Uhr starten. Ladung auf 0 Watt setzen\
       if (AttrVal("$SELF","verbose",0) >=3) {                                  ## Es wird nur langsam geladen und MaxSOC limitiert.\
         Log 3, "$SELF cmd_6  : SpeicherMiddayControl vor [$SELF:SpeicherMidday_NotBefore] Uhr noch nicht laden";;\
       };;\
     } else { \
       if ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_start]") ) {   ## Ist noch Vormittag?\
         CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs [$SELF:SpeicherMidday_MaxChargePowerAbs_morning]");;\
         CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMidday_MaxSOC]");;\
         if (AttrVal("$SELF","verbose",0) >=3) {                                ## Es wird nur langsam geladen und MaxSOC limitiert.\
           Log 3, "$SELF cmd_6  : SpeicherMiddayControl vor [WR_1:Solar_middayhigh_fc0_start] limitieren";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxChargePowerAbs auf [$SELF:SpeicherMidday_MaxChargePowerAbs_morning] limitiert";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSOC auf [$SELF:SpeicherMidday_MaxSOC] % limitiert";;\
         };;\
       };;\
     };;\
\
     if (time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_start]") <= time and  ## Es ist Mittag\
         time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_stop]") ) {\
\
       if ([$SELF:SpeicherMaxSOCControlRunning] == 1 and                                                             ## Somit bleibt weniger Platz im Speicher und es ist\
           time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." 12:00") ) {                             ##    besser nicht vor 12:00 Uhr zu beginnen.\
         CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs 0");;\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_6  : SpeicherMiddayControlActive laden wegen MaxSoc von [WR_1:Solar_middayhigh_fc0_start] auf 12:00 Uhr verschoben"};;\
       } else {                                                                                                      ## auch jetzt nicht mit voller Leistung laden\
\
         if ([$SELF:SpeicherMidday_MaxChargePowerAbs_midday] == 0) {                                                 ## dynamische Leistungsermittlung oder vorgewählter Wert\
           $MaxChargePowerTime = round((time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_stop]") - time) / 3600 , 2);;  ## Mittags Ladezeit bestimmen\
           if ( $MaxChargePowerTime < 1 ) { $MaxChargePowerTime = 1;;};;\
           $MaxChargePowerAbs_midday  = round( [WR_1:Battery_work_capacity] * ([$SELF:SpeicherMaxSOC_Actual] - [WR_1:Act_state_of_charge]) / 100 / $MaxChargePowerTime , 0);;\
           if ($MaxChargePowerAbs_midday < 0) { $MaxChargePowerAbs_midday = 0 };;                                     ## Nicht unter 0\
           Log 3, "$SELF Test   : Mittags $MaxChargePowerTime h mit $MaxChargePowerAbs_midday W laden";;\
         } else {\
           $MaxChargePowerAbs_midday = [$SELF:SpeicherMidday_MaxChargePowerAbs_midday];;                              ## Nimm den vorgewählten Wert\
         };;\
\
         CommandSet(undef, "WR_1_API 23_07_Battery_ExternControl_MaxChargePowerAbs $MaxChargePowerAbs_midday");;\
         CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual]");;\
         if (AttrVal("$SELF","verbose",0) >=3) {\
           Log 3, "$SELF cmd_6  : SpeicherMiddayControlActive laden von [WR_1:Solar_middayhigh_fc0_start] bis [WR_1:Solar_middayhigh_fc0_stop] freigegeben";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxChargePowerAbs auf $MaxChargePowerAbs_midday limitiert";;\
           Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual] % halten"\
         };;\
       };;\
     };;\
\
     if (time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." [WR_1:Solar_middayhigh_fc0_stop]") ) {    ## Es ist Nachmittag und die\
       CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 0");;                                             ## Mittagssteuerung wird abgeschaltet\
       CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual]");;\
       if (AttrVal("$SELF","verbose",0) >=3) {\
         Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual] % halten";;\
         Log 3, "$SELF cmd_6  : SpeicherMiddayControl nach [WR_1:Solar_middayhigh_fc0_stop] beendet";;\
       };;\
     };;\
   };;\
\
   if ([$SELF:SpeicherMaxSOCControlRunning] == 1 and                                           ## Nur MaxSOC soll begrenzt werden\
       [$SELF:SpeicherMaxSOC_Actual] <= 100      and                                          \
       [$SELF:SpeicherMiddayControlRunning] == 0) {                                            ##  sobald die Mittagssteuerung fertig ist\
     CommandSet(undef, "WR_1_API 23_09_Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual]");;\
     if (AttrVal("$SELF","verbose",0) >=3)\
       {Log 3, "$SELF cmd_6  : Battery_ExternControl_MaxSocRel [$SELF:SpeicherMaxSOC_Actual] % halten"};;\
   };;\
\
   if (AttrVal("$SELF","verbose",0) >=4)\
     {Log 3, "$SELF cmd_6  : ExternControl Kommandowiederholung erledigt"};;\
  }\
\
################################################################################################################\
## 7 Bestimmung eines möglichen SOC für den nächsten Morgen und\
##   Vorbereitung für ein Leistungshoch am Mittag\
##\
DOELSEIF\
([WR_1_API:Battery_Control] > 0 and                                                           ## Ist die ExternControl am WR aktiviert\
  ([$SELF:SpeicherMaxSOCControlActive] == 1 or                                                 ## Ist MaxSOC Limit konfiguriert\
   [$SELF:SpeicherMiddayControlActive] == 1 ) and                                              ## Ist Midday Kontrolle konfiguriert\
   [$SELF:SpeicherMaxSOC_MinSOC_Time] eq "NULL" and                                            ## Wurde ein minimum SOC bereits ermittelt\
   [{sunrise_abs("HORIZON=+4.0",0,"5:50","08:35")} - 10:00 ] and\
   [WR_1:SW_Home_own_consumption_from_PV] == [WR_1:SW_Home_own_consumption] )                  ## Die PV Leistung reicht für's Haus\
\
  {\
   my $MinSOC_Time   = "gefunden";;                                                             ## Nur einmal am Tag bearbeiten\
   my $MinSOC_MinSOC = round(ReadingsVal("WR_1","Act_state_of_charge", 0),0);;                  ## Festgestellter MinSOC am Morgen\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_MinSOC_Time ".$MinSOC_Time);;\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_MinSOC_MinSOC ".$MinSOC_MinSOC);;\
   if (AttrVal("$SELF","verbose",0) >=3) {                                                     ## merken und melden\
     Log 3, "$SELF cmd_7  : SpeicherMaxSOC_MinSOC_Time ".$MinSOC_Time." ".$MinSOC_MinSOC." %";;\
   };;\
\
#############\
\
   if ([$SELF:SpeicherMaxSOCControlActive] ==   1 and\
       [WR_1_API:Battery_InternControl_MinHomeConsumption]         <  100 and                  ## Der Speicher darf nicht im smart_laden sein\
       [Pool_Counter:countsPerDay] == 0 and                                                    ## Achtung der Pool und auch die LWP\
       [LWP_Counter:countsPerDay]  == 0 ) {                                                    ##    sollten nicht mehr früh morgens laufen\
\
     my $SpeicherSOCMinimum = [WR_1_API:Battery_InternControl_MinSoc]*3;;                       ## 3x MinSOC als reserve vorsehen\
     my $SpeicherSOCDayBefore = round(ReadingsVal("$SELF","SpeicherMaxSOC_DayBefore", 100),0);; ## wie voll war er gestern noch?\
     my $SpeicherSOCNew       = 0;;\
     my $SpeicherSOCDelta     = 0;;\
\
     if ([WR_1:Solar_Calculation_fc1_day] > [$SELF:SpeicherMaxSOC_fc1_Limit] and\
         $MinSOC_MinSOC                   > $SpeicherSOCMinimum ) {                            ## Ist der Speicher voller als er müsste?\
\
       if (AttrVal("$SELF","verbose",0) >=3){\
         Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore ".$SpeicherSOCDayBefore." %";;\
         Log 3, "$SELF cmd_7  : Leistung Prognose [WR_1:Solar_Calculation_fc1_day] wh > Schwellwert [$SELF:SpeicherMaxSOC_fc1_Limit] wh";;\
         Log 3, "$SELF cmd_7  : Speicherladung aktuell $MinSOC_MinSOC % > Minimum $SpeicherSOCMinimum %";;\
       };;\
       $SpeicherSOCDelta = $MinSOC_MinSOC - $SpeicherSOCMinimum;;                               ## Was wäre noch übrig?\
       if ($SpeicherSOCDelta <= 10) {                                                          ## Das lohnt sich nicht\
         $SpeicherSOCNew = $SpeicherSOCDayBefore;;                                              ## den Wert von gestern einfach beibehalten\
         CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual ".$SpeicherSOCDayBefore);;\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore ".$SpeicherSOCDayBefore." % gesichert"};;\
       } else {\
         $SpeicherSOCNew = round(($SpeicherSOCDayBefore+$SpeicherSOCDayBefore-$SpeicherSOCDelta)/2 ,0);;  ## um den Durchschnitt verringern\
##         CommandSetReading(undef, "$SELF SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew);;          ## den neuen Wert für morgen merken\
         CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual ".$SpeicherSOCNew);;             ## Das soll heute in den Speicher\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew." % neu berechnet und gesichert"};;\
       };;\
\
       if ($SpeicherSOCNew > 0) {                                                              ## Es gibt einen neuen MaxSoc\
         CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 1");;                     ## Senden starten\
         CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 1");;                         ## Wiederholung starten\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_Actual ".$SpeicherSOCNew." % geplant"};;\
       } else {                                                                                ## MaxSoc wird nicht begrenzt\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_Actual wird nicht begrenzt"};;\
       };;\
\
     } else {                                                                                  ## MaxSoc wird nicht begrenzt\
       if ($MinSOC_MinSOC  < $SpeicherSOCMinimum ) {                                           ## MaxSoc leicht erhöhen, da er etwas zu niedrig war\
         $SpeicherSOCNew   = round($SpeicherSOCDayBefore+$SpeicherSOCMinimum-$MinSOC_MinSOC ,0);;\
         $SpeicherSOCDelta = round($SpeicherSOCMinimum-$MinSOC_MinSOC ,0);;\
         CommandSetReading(undef, "$SELF SpeicherMaxSOC_DayBefore ".$SpeicherSOCNew);;\
         if (AttrVal("$SELF","verbose",0) >=3)\
           {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_DayBefore wurde um ".$SpeicherSOCDelta." erhöht"};;\
       }\
       if (AttrVal("$SELF","verbose",0) >=3)\
         {Log 3, "$SELF cmd_7  : SpeicherMaxSOC_Actual wird nicht begrenzt, da die Prognose zu schlecht ist"};;\
     };;\
   };;\
\
   if ([$SELF:SpeicherMiddayControlActive] == 1 and                                            ## Soll für mittags noch Platz gehalten werden?\
       [WR_1:Solar_middayhigh_fc0] == 1 ) {                                                    \
                           \
     CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 1");;                         ## Die Mittagskontrolle aktivieren\
     CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 1");;\
     if (AttrVal("$SELF","verbose",0) >=3){                      ## (die Uhrzeiten wurden bereits durch Solar_forecast() im WR_1 Device eingetragen)\
       Log 3, "$SELF cmd_7  : Batterie SpeicherMiddayControlRunning vorbereitet";;\
       Log 3, "$SELF cmd_7  : Batterie Solar_middayhigh_fc0_start [WR_1:Solar_middayhigh_fc0_start] gesetzt";;\
       Log 3, "$SELF cmd_7  : Batterie Solar_middayhigh_fc0_stop  [WR_1:Solar_middayhigh_fc0_stop] gesetzt";;\
     };;\
   } else {                                                                                    ## Kein Mittagshoch\
     Log 3, "$SELF cmd_7  : SpeicherMiddayControl es wird kein Middayhigh geben";;\
   };;\
\
#############\
\
  }\
\
################################################################################################################\
## 8 Reset der ExternControl Kommandos\
##\
DOELSEIF\
([{sunset_abs("HORIZON=+8.0",0,"15:00","21:00")}])                                            ## hier sollte das Ende der PV-Zeit sein\
\
  {\
   CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 0");;                               ## Stop das regelmäßige senden der Kommandos\
                   \
   CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 0");;                           ## Midday Steuerung zurücksetzen\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual 100");;                                ## SpeicherMaxSOC_Actual auf Default\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_DayBefore [WR_1:Act_state_of_charge]");;      ## Den vor Tages Wert merken\
   CommandSetReading(undef, "$SELF SpeicherMaxSOC_MinSOC_Time NULL");;                          ## Die MinSOC Time löschen\
       \
   CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 0");;                           ## Midday Steuerung zurücksetzen\
\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc0 0");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc0_start 00:00");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc0_stop 00:00");;\
\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc1 0");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc1_start 00:00");;\
   CommandSetReading(undef, "WR_1 Solar_middayhigh_fc1_stop 00:00");;\
\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_8  : ExternControl zurückgesetzt"};;\
  }\
\
################################################################################################################\
## 9 Umschaltung des MinSOC wenn zu wenig Leistung erwartet wird, das ist dann im Herbst/Winter\
##\
DOELSEIF\
([WR_1:Solar_Calculation_fc1_day]        < [$SELF:SpeicherMinSOC_fc1_Limit] and               ## Wenn morgen das Minimum an Leistung nicht erreicht wird\
  [WR_1_API:Battery_InternControl_MinSoc] < [$SELF:SpeicherMinSOC_Winter]    and               ## und der MinSoc unter der Winter Wert eingestellt ist\
  [$SELF:SpeicherMaxSOC_MinSOC_Time] eq "gefunden" )\
\
  {\
   CommandSet(undef, "WR_1_API 22_04_Battery_MinSoc [$SELF:SpeicherMinSOC_Winter]");;           ## Den MinSOC anheben, um eine eventuelle\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_9  : Batterie MinSoc auf Winterbetrieb"};;                              ## Notladung zu verhindern\
   CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 0");;                               ## Stop das regelmäßige senden der Kommandos\
   CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 0");;                           ## Im Winter Betrieb keine MaxSOC Begrenzung\
   CommandSetReading(undef, "$SELF SpeicherMiddayControlRunning 0");;                           ## und keine Midday Steuerung\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_9  : MaxSOC Begrenzung und Midday Steuerung im Winterbetrieb deaktiviert"};;\
  }\
\
################################################################################################################\
## 10 Umschaltung des MinSoc wenn viel Leistung erwartet wir, das wäre dann Frühling/Sommer\
##\
DOELSEIF\
([WR_1:Solar_Calculation_fc1_day]        > [$SELF:SpeicherMinSOC_fc1_Limit] and               ## sobald viel Ladung erwartet wird und der MinSoc noch\
  [WR_1_API:Battery_InternControl_MinSoc] > [$SELF:SpeicherMinSOC_Sommer]    and               ## noch im Winter Modus ist\
  [10:09] )                                                                                   \
          \
  {                                                                                           \
   CommandSet(undef, "WR_1_API 22_04_Battery_MinSoc [$SELF:SpeicherMinSOC_Sommer]");;           ## den MinSOC auf Sommerbetrieb herabsetzen, es kann\
   if (AttrVal("$SELF","verbose",0) >=3)\
     {Log 3, "$SELF cmd_10 : Batterie MinSoc auf Sommerbetrieb"};;                              ## wieder mehr Leistung genutzt werden\
  }\
\
################################################################################################################\
## 11 Der Speicher ist voll geladen. Hier wird das ständige nachladen auf 100 % vermieden.\
##\
DOELSEIF\
( [WR_1:Solar_Calculation_fc0_day] > [$SELF:SpeicherMaxSOC_fc1_Limit] and                     ## 1) sobald viel Leistung erwartet wird und der Speicher voll ist\
   [WR_1:Act_state_of_charge] == 100 or                                                        ##    den MaxSOC wieder reduzieren, damit nicht immer nachgeladen wird\
  ([$SELF:SpeicherMaxSOC_Actual] == 95 and                                                     ## 2) oder das Nachladen gestoppt wurde\
   [WR_1:Act_state_of_charge] <  98  and                                                       ##    und der SOC unte 98 % gefallen ist\
   [{sunset_abs("HORIZON=+8.0",-7200,"15:00","21:00")}]) )                                     ##    zwei Stunden vor Sonnenuntergang eventuell wieder nachladen\
\
  {\
   if ([WR_1:Act_state_of_charge] < 98) {\
     CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual 100");;                              ## Eventuell noch mal nachladen\
     if (AttrVal("$SELF","verbose",0) >=3) {\
       Log 3, "$SELF cmd_11 : Battery_ExternControl_MaxSocRel auf 100 % nachladen";;\
     };;\
   } else {\
     CommandSetReading(undef, "$SELF SpeicherMaxSOC_Actual 95");;\
     CommandSetReading(undef, "$SELF SpeicherCmdRepeatRunning 1");;                             ## Start regelmäßiges senden der Kommandos\
     CommandSetReading(undef, "$SELF SpeicherMaxSOCControlRunning 1");;                         ## MaxSOC Begrenzung weil Speicher bereits 100 % hat\
     if (AttrVal("$SELF","verbose",0) >=3) {\
       Log 3, "$SELF cmd_11 : Battery_ExternControl_MaxSocRel auf 95 % reduziert";;\
     };;\
   }\
  }\
\

attr WR_1_Speicher_1_ExternControl DbLogExclude .*
attr WR_1_Speicher_1_ExternControl alias WR_1_Speicher_1_ExternControl
attr WR_1_Speicher_1_ExternControl comment Version 2021.09.09 14:50\
\
Hier können externe Trigger für die Ladung und Entladung Der Batterie gesetzt werden.\
Die Zeiten können z.B. durch den WeekDayTimer entsprechend an einen Stromtarif angepasst werden.\
Das reading SpeicherEntladung Automatik/Zeit/SpeicherTrigger ermöglicht es die Zeitsteuerung zu überschreiben.\
\
ExternTrigger\
Das reading dient dem Freigeben und Sperren der externen Trigger, z.B. um im Herbst/Winter das smart_laden zu steuern.\
Es verriegelt somit die Zeitsteuerung oder den SpeicherTrigger.\
\
SpeicherEntladung:Automatik,Zeit,SpeicherTrigger \
Automatik - Der Speicher wird vom Wechselrichter gesteuert, oder über die eigene ExternControl der API\
Zeit - Das Laden und Entladen wird mit den Zeitwerten beeinflusst\
SpeicherTrigger - beeinflusst das Laden und Entladen direkt ohne die Zeitsteuerung\
\
SpeicherTrigger:entladen,gesperrt\
Dieser Trigger kann durch ander Logik gesetzt werden.\
Auch hier wäre eine Zeitsteuerung denkbar, die entladen/gesperrt entsprechend umschaltet.\
\
SpeicherZeitStart/SpeicherZeitEnde\
Die Zeitangaben können manuell fest gesetzt werden, oder über zusätzliche Timer täglich neu überschrieben werden.\
Eine gültige Zeit und entsprechendes Timeing obliegt dem Anwender.\
Zwischen Start und Ende wird der Speicher zum Entladen freigegeben und zwischen Ende und Start gesperrt.\
\
Speicher*ControlActive\
Das jeweilige reading aktiviert diese Teilkomponente für die Steuerung.\
Ein jeweiliges Speicher*ControlRunning signalisiert, ob gerade die Bedingungen erfüllt sind.\
\
SpeicherCmdRepeatActive\
Es muss im WR die externe Speicher Steuerung aktiviert sein.\
Möchte man trotzdem die Sendung der ExternControl Kommandos stoppen, obwohl die Bedingungen erfüllt sind,\
kann man dieses reading zum Deaktivieren auf 0 setzen.\
\
SpeicherMiddayControl\
Über die Solar_forecast() Funktion wird ein Middayhigh ermittelt, wenn der WR nur 70% einspeisen darf.\
\
SpeicherMaxSOCControl\
Es wird versucht den Speicher am Abend nicht zu 100% zu laden, aber morgens noch mit 3* MinSOC aus der Nacht zu kommen.\
\
SpeicherMinSOC\
Dies gehört zur Basis Steuerung und schaltet den MinSOC von Sommer auf Winter Betrieb,\
um eine Notladung aus dem Netz zu vermeiden.
attr WR_1_Speicher_1_ExternControl do always
attr WR_1_Speicher_1_ExternControl group PV Eigenverbrauch
attr WR_1_Speicher_1_ExternControl icon measure_battery_100
attr WR_1_Speicher_1_ExternControl readingList SpeicherExternTrigger SpeicherCmdRepeatActive SpeicherZeitStart SpeicherZeitEnde SpeicherEntladung SpeicherTrigger SpeicherMiddayControlActive SpeicherMidday_Inverter_Max_Power SpeicherMidday_MaxChargePowerAbs_morning SpeicherMidday_MaxChargePowerAbs_midday SpeicherMidday_MaxSOC SpeicherMidday_NotBefore SpeicherMinSOC_Sommer SpeicherMinSOC_Winter SpeicherMinSOC_fc1_Limit SpeicherMaxSOCControlActive SpeicherMaxSOC_Actual SpeicherMaxSOC_DayBefore SpeicherMaxSOC_fc1_Limit
attr WR_1_Speicher_1_ExternControl room Strom->Photovoltaik
attr WR_1_Speicher_1_ExternControl setList SpeicherExternTrigger:frei,gesperrt SpeicherCmdRepeatActive:0,1 SpeicherZeitStart:time SpeicherZeitEnde:time SpeicherEntladung:Automatik,Zeit,Trigger SpeicherTrigger:entladen,gesperrt,none SpeicherMiddayControlActive:0,1 SpeicherMidday_Inverter_Max_Power:slider,3000,500,20000 SpeicherMidday_MaxChargePowerAbs_morning:slider,0,50,4700 SpeicherMidday_MaxChargePowerAbs_midday:slider,0,100,4700 SpeicherMidday_MaxSOC:slider,20,5,50 SpeicherMidday_NotBefore:time SpeicherMinSOC_Sommer:slider,5,1,20 SpeicherMinSOC_Winter:slider,5,1,20 SpeicherMinSOC_fc1_Limit:slider,7000,500,17000 SpeicherMaxSOCControlActive:0,1 SpeicherMaxSOC_Actual:slider,60,5,100 SpeicherMaxSOC_DayBefore:slider,15,5,100 SpeicherMaxSOC_fc1_Limit:slider,10000,2000,50000
attr WR_1_Speicher_1_ExternControl sortby 122
attr WR_1_Speicher_1_ExternControl verbose 3

setstate WR_1_Speicher_1_ExternControl 2021-09-08 17:49:10 SpeicherCmdRepeatActive 1
setstate WR_1_Speicher_1_ExternControl 2021-09-09 13:00:01 SpeicherCmdRepeatRunning 1
setstate WR_1_Speicher_1_ExternControl 2021-09-08 19:41:33 SpeicherEntladung Automatik
setstate WR_1_Speicher_1_ExternControl 2021-09-07 14:49:53 SpeicherExternTrigger none
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:23:15 SpeicherMaxSOCControlActive 1
setstate WR_1_Speicher_1_ExternControl 2021-09-09 13:00:01 SpeicherMaxSOCControlRunning 1
setstate WR_1_Speicher_1_ExternControl 2021-09-09 13:00:01 SpeicherMaxSOC_Actual 95
setstate WR_1_Speicher_1_ExternControl 2021-09-08 19:00:47 SpeicherMaxSOC_DayBefore 77.00
setstate WR_1_Speicher_1_ExternControl 2021-09-09 07:37:02 SpeicherMaxSOC_MinSOC_MinSOC 26
setstate WR_1_Speicher_1_ExternControl 2021-09-09 07:37:02 SpeicherMaxSOC_MinSOC_Time gefunden
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:23:44 SpeicherMaxSOC_fc1_Limit 30000
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:26:55 SpeicherMiddayControlActive 1
setstate WR_1_Speicher_1_ExternControl 2021-09-08 19:00:47 SpeicherMiddayControlRunning 0
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:22:22 SpeicherMidday_Inverter_Max_Power 8500
setstate WR_1_Speicher_1_ExternControl 2021-09-05 15:00:35 SpeicherMidday_MaxChargePowerAbs_midday 0
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:24:57 SpeicherMidday_MaxChargePowerAbs_morning 450
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:26:39 SpeicherMidday_MaxSOC 30
setstate WR_1_Speicher_1_ExternControl 2021-09-05 09:02:56 SpeicherMidday_NotBefore 09:00
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:26:15 SpeicherMinSOC_Sommer 5
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:26:03 SpeicherMinSOC_Winter 20
setstate WR_1_Speicher_1_ExternControl 2021-09-02 16:24:08 SpeicherMinSOC_fc1_Limit 14000
setstate WR_1_Speicher_1_ExternControl 2021-09-03 12:16:08 SpeicherTrigger entladen
setstate WR_1_Speicher_1_ExternControl 2021-09-03 12:15:57 SpeicherZeitEnde 16:00
setstate WR_1_Speicher_1_ExternControl 2021-09-03 12:06:33 SpeicherZeitStart 07:00

setstate WR_1_Speicher_1_ExternControl 2021-09-09 15:09:37 ui_command ---



Hier fehlen noch stateFormat und uiTable, aber der Post war zu lang :-)

RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Und hier kommt der Rest vom RAW...


attr WR_1_Speicher_1_ExternControl stateFormat {\
my $WR     = "WR_1";;\
my $DUMMY  = "";;\
\
my $Entladung                        = ReadingsVal($name,"SpeicherEntladung","n/a");;\
\
my $Power                            = ReadingsVal($WR,"Actual_Battery_charge_-minus_or_discharge_-plus_P","0");;\
my $Status                           = ($Power < -10) ? "<span style='color:#00FF00'>Laden</span>" : ($Power > 15) ?  "<span style='color:#FF0000'>Entladen</span>" : "<span style='color:orange'>Standby</span>";;\
    $Power                            = $Power." W";;\
\
my $Solar_Calculation_fc0_day        = ReadingsVal($WR,"Solar_Calculation_fc0_day","0");;\
        \
my $Trigger                          = ReadingsVal($name,"SpeicherTrigger","none");;\
my $ExternTrigger                    = ReadingsVal($name,"SpeicherExternTrigger","none");;\
my $ZeitStart                        = ReadingsVal($name,"SpeicherZeitStart","n/a");;\
my $ZeitEnde                         = ReadingsVal($name,"SpeicherZeitEnde","n/a");;\
                                                                                                             \
my $CmdRepeatActive                  = ReadingsVal($name,"SpeicherCmdRepeatActive","0");;\
my $CmdRepeatRunning                 = ReadingsVal($name,"SpeicherCmdRepeatRunning","0");;\
        \
my $MaxSOCControlActive              = ReadingsVal($name,"SpeicherMaxSOCControlActive","0");;\
my $MaxSOCControlRunning             = ReadingsVal($name,"SpeicherMaxSOCControlRunning","0");; \
        \
my $MiddayControlActive              = ReadingsVal($name,"SpeicherMiddayControlActive","0");;\
my $MiddayControlRunning             = ReadingsVal($name,"SpeicherMiddayControlRunning","0");;\
        \
my $Solar_middayhigh_fc0_start       = ReadingsVal($WR,"Solar_middayhigh_fc0_start","00:00");;\
    $Solar_middayhigh_fc0_start       = ($MaxSOCControlRunning == 1 and $MiddayControlRunning == 1) ? "12:00" : $Solar_middayhigh_fc0_start ;;\
\
my $Solar_middayhigh_fc0_stop        = ReadingsVal($WR,"Solar_middayhigh_fc0_stop","00:00");;\
my $MaxSOC_Actual                    = ReadingsVal($name,"SpeicherMaxSOC_Actual","0");;\
my $Act_state_of_charge              = sprintf("%d",ReadingsVal($WR,"Act_state_of_charge","0"));;\
my $MaxSOC_DayBefore                 = sprintf("%d %%",ReadingsVal($name,"SpeicherMaxSOC_DayBefore","0"));;\
my $MaxSOC_fc1_Limit                 = ReadingsVal($name,"SpeicherMaxSOC_fc1_Limit","0");;\
my $MaxSOC_MinSOC_Time               = POSIX::strftime("%H:%M",localtime(time_str2num(ReadingsTimestamp($name, "SpeicherMaxSOC_MinSOC_MinSOC",0))));;\
my $MaxSOC_MinSOC_MinSOC             = sprintf("%d %%",ReadingsVal($name,"SpeicherMaxSOC_MinSOC_MinSOC","0"));;\
\
my $Midday_NotBefore                 = ReadingsVal($name,"SpeicherMidday_NotBefore","0");;\
my $Midday_MaxSOC                    = ReadingsVal($name,"SpeicherMidday_MaxSOC","0");;\
\
my $Midday_MaxChargePowerAbs_morning = sprintf("%d W"   ,ReadingsVal($name,"SpeicherMidday_MaxChargePowerAbs_morning","0"));;\
\
    $Midday_MaxChargePowerAbs_morning = ( $MiddayControlRunning == 1 and\
                                              time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore") and\
                                          time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          $Midday_MaxSOC > $Act_state_of_charge ) ? "<span style='color:#00FF00'>$Midday_MaxChargePowerAbs_morning</span>" : $Midday_MaxChargePowerAbs_morning ;;\
\
my $Midday_MaxChargePowerAbs_midday  = sprintf("%d"   ,ReadingsVal($name,"SpeicherMidday_MaxChargePowerAbs_midday","0"));;\
    $Midday_MaxChargePowerAbs_midday  = ( $Midday_MaxChargePowerAbs_midday == 0) ? "dynamisch" : $Midday_MaxChargePowerAbs_midday." W" ;; \
    $Midday_MaxChargePowerAbs_midday  = ( $MiddayControlRunning == 1 and\
                                              time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Midday_MaxChargePowerAbs_midday</span>" : $Midday_MaxChargePowerAbs_midday ;;\
\
    $Midday_NotBefore                 = ( $MiddayControlRunning == 1 and\
                                              time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore") and\
                                              time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $MaxSOC_MinSOC_Time")) ? "< <span style='color:#FF0000'>$Midday_NotBefore</span>" :\
                                        ( $MiddayControlRunning == 1 and\
                                              time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") ) ? "> <span style='color:#00FF00'>$Midday_NotBefore</span>" : $Midday_NotBefore ;;\
\
    $Midday_MaxSOC                    = ( time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Midday_NotBefore")) ? $Midday_MaxSOC." %" :\
                                            ( $MiddayControlRunning == 1 and\
                                              time < time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          $Midday_MaxSOC > $Act_state_of_charge ) ? "<span style='color:#00FF00'>$Midday_MaxSOC %</span>" : \
                                                                                ( time > time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start")) ? $Midday_MaxSOC." %" : "<span style='color:#FF0000'>$Midday_MaxSOC %</span>" ;;\
\
    $Solar_middayhigh_fc0_start       = ( $MiddayControlRunning == 1 and\
                                              time >= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Solar_middayhigh_fc0_start</span>" : $Solar_middayhigh_fc0_start ;;\
    $Solar_middayhigh_fc0_stop        = ( $MiddayControlRunning == 1 and\
                                              time >= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_start") and\
                                          time <= time_str2num(POSIX::strftime("%Y-%m-%d",localtime(time))." $Solar_middayhigh_fc0_stop" ) ) ? "<span style='color:#00FF00'>$Solar_middayhigh_fc0_stop</span>" : $Solar_middayhigh_fc0_stop ;;\
\
\
my $Midday_Inverter_Max_Power        = sprintf("%d W"   ,ReadingsVal($name,"SpeicherMidday_Inverter_Max_Power","0"));;\
    $Midday_Inverter_Max_Power        = ($MiddayControlRunning      == 1                ) ? ">= <span style='color:#00FF00'> $Midday_Inverter_Max_Power</span>" : $Midday_Inverter_Max_Power ;;\
\
my $MinSOC_fc1_Limit                 = ReadingsVal($name,"SpeicherMinSOC_fc1_Limit","0");;\
my $MinSOC_Sommer                    = sprintf("%d %%"  ,ReadingsVal($name,"SpeicherMinSOC_Sommer","0"));;\
    $MinSOC_Sommer                    = ($Solar_Calculation_fc0_day >= $MinSOC_fc1_Limit) ? "<span style='color:#00FF00'>$MinSOC_Sommer</span>"             : $MinSOC_Sommer ;;\
\
my $MinSOC_Winter                    = sprintf("%d %%"  ,ReadingsVal($name,"SpeicherMinSOC_Winter","0"));;\
    $MinSOC_Winter                    = ($Solar_Calculation_fc0_day <  $MinSOC_fc1_Limit) ? "<span style='color:#00FF00'>$MinSOC_Winter</span>"             : $MinSOC_Winter ;;\
\
    $MinSOC_fc1_Limit                 = ($Solar_Calculation_fc0_day >= $MinSOC_fc1_Limit) ? ">= <span style='color:#00FF00'>$MinSOC_fc1_Limit Wh</span>"    : $MinSOC_fc1_Limit." Wh" ;;\
    $MaxSOC_fc1_Limit                 = ($Solar_Calculation_fc0_day >= $MaxSOC_fc1_Limit) ? ">= <span style='color:#00FF00'>$MaxSOC_fc1_Limit Wh</span>" : $MaxSOC_fc1_Limit." Wh" ;;\
\
    $MaxSOC_Actual                    = ($MaxSOCControlRunning == 1) ? "<span style='color:#00FF00'>$MaxSOC_Actual %</span>"      : $MaxSOC_Actual." %" ;;\
    $Act_state_of_charge              = $Act_state_of_charge." %";;\
    $CmdRepeatRunning                 = ($CmdRepeatRunning     == 1) ? "<span style='color:#00FF00'>$CmdRepeatRunning</span>"     : $CmdRepeatRunning ;;\
    $MaxSOCControlRunning             = ($MaxSOCControlRunning == 1) ? "<span style='color:#00FF00'>$MaxSOCControlRunning</span>" : $MaxSOCControlRunning ;;\
    $MiddayControlRunning             = ($MiddayControlRunning == 1) ? "<span style='color:#00FF00'>$MiddayControlRunning</span>" : $MiddayControlRunning ;;\
\
    $ZeitStart                        = ($Entladung eq "Zeit") ? "<span style='color:#00FF00'>$ZeitStart</span>" : $ZeitStart ;;\
    $ZeitEnde                         = ($Entladung eq "Zeit") ? "<span style='color:#00FF00'>$ZeitEnde</span>"  : $ZeitEnde  ;;\
\
"<html><table border=2 bordercolor='darkgreen' cellspacing=0 style='width: 100%'>\
<colgroup>\
   <col span='1' style='width: 52%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
   <col span='1' style='width: 12%;;'>\
</colgroup> <tr><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'> </td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td><td style='padding-right:5px;;padding-left:5px;;text-align:center;;font-weight:bold'></td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Speicher<dd>Steuerung / Status / Leistung / aktueller SOC</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Entladung."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Status."<br></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$Power."<br>".$Act_state_of_charge."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Trigger<dd>Status / ExternTrigger / Start / Ende</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Trigger."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ExternTrigger."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ZeitStart."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$ZeitEnde."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Kommando Wiederholung<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$CmdRepeatActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$CmdRepeatRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MaxSOC Kontrolle<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOCControlActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOCControlRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MaxSOC Limit<dd>fc1_Limit / Minimum SOC Zeit / gestern / Ziel</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_fc1_Limit."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'>".$MaxSOC_MinSOC_Time."<br>".$MaxSOC_MinSOC_MinSOC."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_DayBefore."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MaxSOC_Actual."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Mittags Kontrolle<dd>aktiviert / läuft</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MiddayControlActive."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MiddayControlRunning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>Mittags Limits<dd>Inverter_Max_Power / Laden nicht vor / Start /Stop<br><br>MaxSOC morgens / Power morgens / Power mittags</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Midday_Inverter_Max_Power."<br><br>".$Midday_MaxSOC."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Midday_NotBefore."<br><br>".$Midday_MaxChargePowerAbs_morning."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_middayhigh_fc0_start."<br><br>".$Midday_MaxChargePowerAbs_midday."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$Solar_middayhigh_fc0_stop."<br><br><br>".$DUMMY."</td></tr>\
<tr><td style='padding-right:5px;;padding-left:5px;;text-align:left;;font-weight:bold'>MinSOC Steuerung<dd>fc1_Limit / Winter / Sommer</dd></td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_fc1_Limit."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$DUMMY."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_Winter."</td><td style='padding-right:5px;;padding-left:5px;;text-align:center'><br>".$MinSOC_Sommer."</td></tr>\
</table>\
</html>"\
}\

attr WR_1_Speicher_1_ExternControl uiTable {\
package ui_Table;;\
$TC{1..5}="align='center'";;         ## Spalten 1 bis 5 werden zentriert\
}\
\
"Kommando<dd>Auswahl</dd>" | widget([$SELF:ui_command],"uzsuDropDown,---,smart_Laden start,smart_Laden beenden,3 Minuten Wiederholung")\
\
"Speicher<dd>Steuerung</dd>" | widget([$SELF:SpeicherEntladung],"uzsuDropDown,Automatik,Trigger,Zeit")\
\
"Trigger<dd>Status / ExternTrigger / Start / Ende</dd>" | widget([$SELF:SpeicherTrigger],"uzsuDropDown,entladen,gesperrt,none") | | widget([$SELF:SpeicherExternTrigger],"uzsuDropDown,frei,none") | widget([$SELF:SpeicherZeitStart],"time") | widget([$SELF:SpeicherZeitEnde],"time")\
\
"Kommando Wiederholung<dd>aktiviert / läuft</dd>" | widget([$SELF:SpeicherCmdRepeatActive],"uzsuToggle,0,1") | widget([$SELF:SpeicherCmdRepeatRunning],"uzsuToggle,0,1")\
\
"MaxSOC Kontrolle<dd>aktiviert / läuft</dd>" | widget([$SELF:SpeicherMaxSOCControlActive],"uzsuToggle,0,1") | widget([$SELF:SpeicherMaxSOCControlRunning],"uzsuToggle,0,1")\
\
"MaxSOC Limit<dd>fc1_Limit / Minimum SOC Zeit / gestern / Ziel</dd>" | widget([$SELF:SpeicherMaxSOC_fc1_Limit],"selectnumbers,2000,1000,40000,0,lin") | widget([$SELF:SpeicherMaxSOC_MinSOC_Time],"time")."<br>". widget([$SELF:SpeicherMaxSOC_MinSOC_MinSOC],"selectnumbers,5,1,100,0,lin") | "<br><br>".widget([$SELF:SpeicherMaxSOC_DayBefore],"selectnumbers,5,1,100,0,lin") | "<br><br>".widget([$SELF:SpeicherMaxSOC_Actual],"selectnumbers,5,1,100,0,lin")\
\
"Mittags Kontrolle<dd>aktiviert / läuft</dd>" |widget([$SELF:SpeicherMiddayControlActive],"uzsuToggle,0,1") | widget([$SELF:SpeicherMiddayControlRunning],"uzsuToggle,0,1")\
\
"Mittags Limits<dd>Inverter_Max_Power / Laden nicht vor / Start /Stop<br><br>MaxSOC morgens / Power morgens / Power mittags</dd>" |\
widget([$SELF:SpeicherMidday_Inverter_Max_Power],"selectnumbers,1000,250,15000,0,lin")."<br><br>".widget([$SELF:SpeicherMidday_MaxSOC],"selectnumbers,5,1,100,0,lin") | widget([$SELF:SpeicherMidday_NotBefore],"time")."<br><br>".widget([$SELF:SpeicherMidday_MaxChargePowerAbs_morning],"selectnumbers,0,50,2000,0,lin") | widget([WR_1:Solar_middayhigh_fc0_start],"time")."<br><br>".widget([$SELF:SpeicherMidday_MaxChargePowerAbs_midday],"selectnumbers,0,1,5000,0,lin") | widget([WR_1:Solar_middayhigh_fc0_stop],"time")."<br><br><br>"\
\
"MinSOC Steuerung<dd>fc1_Limit / Winter / Sommer</dd>" | widget([$SELF:SpeicherMinSOC_fc1_Limit],"selectnumbers,2000,1000,40000,0,lin") | |widget([$SELF:SpeicherMinSOC_Winter],"selectnumbers,10,1,30,0,lin") | widget([$SELF:SpeicherMinSOC_Sommer],"selectnumbers,5,1,10,0,lin")\

RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,
ich hätte gerne mal Eure Meinung zum Design , das ich jetzt mit uiTable erstellt habe.
Es vereint das stateFormat mit der Konfiguration über uiTable und widgets nun in einer Tabelle, sogar mit bunten Ladebalken :-)
Auch die anderen Devices würden dann bei begeisterten Rückmeldungen auch angepasst werden ;-) :-) :-)
VG
   Christian

P.S. zuerst mal nur als Bild und nicht als RAW, da es da noch einiges im Device zu tun gibt.
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ozwo

Zitatich hätte gerne mal Eure Meinung zum Design , das ich jetzt mit uiTable erstellt habe.
Sieht total super aus! Vielen Dank schonmal.

Eine Frage noch zum aktuellen Stand:
ZitatHierdurch wird das DUMMY WR_1_Speicher_1_ExternTrigger überflüssig werden und es verschwindet komplett.
Mit aktuellem Stand kann ich das WR_1_Speicher_1_ExternTrigger schon rauswerfen, oder?

Nochmal Danke und viele Grüße
Oliver

ch.eick

Zitat von: ozwo am 20 September 2021, 17:49:10
Sieht total super aus! Vielen Dank schonmal.
Vielen Dank

Zitat
Eine Frage noch zum aktuellen Stand:Mit aktuellem Stand kann ich das WR_1_Speicher_1_ExternTrigger schon rauswerfen, oder?
Nur wenn Du alles ins WR_1_Speicher_1_ExternControl übernommen hast, was ich hier im Thread beschrieben hatte.
Das Wiki hat noch den alten Stand!

VG
   Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Das neue WR_1_Speicher_1_ExternControl ist jetzt im Wiki zu finden.

Bitte achtet darauf, dass es auch im cmd_* Bereich diverse Anpassungen gegeben hat. Auch heute habe ich noch einiges korrigiert, was insbesondere mit den pull down Menüs zu tun hat. Einige reading Namen wurden angepasst und aus 0/1 wurde An/Aus und einiges was ich selber nicht mehr weis :-)
Im Anhang ist dann das Erscheinungsbild zu erkennen, das dann auch zu den anderen Devices passt.

Bitte beachtet, das ich bald auch mal Urlaub habe und es dann mit dem Support etwas warten muss...
Das alte Konstrukt mit dem WR_1_Speicher_1_ExternTrigger Device ist jetzt raus.

VG
    Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

misux

HI!

Ist es möglich vom Kostal Plenticore 10Plus einfach nur die aktuellen Daten abzufassen und im FHEM als Reading darzustellen? Also ohne ein dblog zu erstellen?

Ich würde gerne NUR die Aktuellen Wertr abgreifen (PV Leistung/Einspeisung/Eigenverbrauch/BAtterieladezustand). Viel mehr brauche ich nicht, möchte es nur in der FTUI Visualisieren...

Geht das relativ einfach?