From ca0faf97fbcf2ec9663c7bdf5a793152f92daaf7 Mon Sep 17 00:00:00 2001 From: DS_Starter Date: Sun, 7 May 2023 12:55:24 +0000 Subject: [PATCH] 76_SolarForecast: contrib 0.78.0 git-svn-id: https://svn.fhem.de/fhem/trunk@27528 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/76_SolarForecast.pm | 217 +++++++++++++------- 1 file changed, 143 insertions(+), 74 deletions(-) diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index cd358361a..fd25c3787 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -79,11 +79,11 @@ BEGIN { Debug fhemTimeLocal fhem - FmtDateTime FileWrite FileRead FileDelete FmtTime + FmtDateTime FW_makeImage getKeyValue HttpUtils_NonblockingGet @@ -136,6 +136,8 @@ BEGIN { # Versions History intern my %vNotesIntern = ( + "0.78.0" => "07.05.2023 activate NotifyFn Forum:https://forum.fhem.de/index.php?msg=1275005, new Consumerkey asynchron ", + "0.77.1" => "07.05.2023 rewrite function pageRefresh ", "0.77.0" => "03.05.2023 new attribute ctrlUserExitFn ", "0.76.0" => "01.05.2023 new ctrlStatisticReadings SunMinutes_Remain, SunHours_Remain ", "0.75.3" => "23.04.2023 fix Illegal division by zero at ./FHEM/76_SolarForecast.pm line 6199 ", @@ -427,6 +429,7 @@ my @dd = qw( none consumerSwitching consumption graphic + notifyHandling pvCorrection radiationProcess saveData2Cache @@ -840,7 +843,7 @@ sub Initialize { $hash->{ShutdownFn} = \&Shutdown; $hash->{DbLog_splitFn} = \&DbLogSplit; $hash->{AttrFn} = \&Attr; - # $hash->{NotifyFn} = \&Notify; # wird zur Zeit nicht genutzt/verwendet + $hash->{NotifyFn} = \&Notify; $hash->{AttrList} = "affect70percentRule:1,dynamic,0 ". "affectBatteryPreferredCharge:slider,0,1,100 ". "affectCloudfactorDamping:slider,0,1,100 ". @@ -1194,7 +1197,7 @@ sub _setcurrentForecastDev { ## no critic "not used" readingsSingleUpdate ($hash, "currentForecastDev", $prop, 1); createAssociatedWith ($hash); - writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben + writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben return; } @@ -1221,7 +1224,7 @@ sub _setcurrentRadiationDev { ## no critic "not used" readingsSingleUpdate ($hash, "currentRadiationDev", $prop, 1); createAssociatedWith ($hash); - writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben + writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben setModel ($hash); # Model setzen return; @@ -1328,7 +1331,7 @@ sub _setinverterDevice { ## no critic "not used" readingsSingleUpdate ($hash, "currentInverterDev", $arg, 1); createAssociatedWith ($hash); - writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben + writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben return; } @@ -1398,7 +1401,7 @@ sub _setmeterDevice { ## no critic "not used" readingsSingleUpdate ($hash, "currentMeterDev", $arg, 1); createAssociatedWith ($hash); - writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben + writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben return; } @@ -1439,7 +1442,7 @@ sub _setbatteryDevice { ## no critic "not used" readingsSingleUpdate ($hash, "currentBatteryDev", $arg, 1); createAssociatedWith ($hash); - writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben + writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben return; } @@ -1957,34 +1960,38 @@ sub _setclientAction { ## no critic "not used" my @args = @{$argsref}; - my $evt = shift @args; # Readings Event (state nicht gesteuert) + my $c = shift @args; # Consumer Index (Nummer) + my $evt = shift @args; # Readings Event (state wird nicht gesteuert) my $action = shift @args; # z.B. set, setreading my $cname = shift @args; # Consumername my $tail = join " ", map { my $p = $_; $p =~ s/\s//xg; $p; } @args; ## no critic 'Map blocks' # restliche Befehlsargumente Log3($name, 4, qq{$name - Client Action received / execute: "$action $cname $tail"}); - if($action eq "set") { + if($action eq 'set') { CommandSet (undef, "$cname $tail"); + my $async = ConsumerVal ($hash, $c, 'asynchron', 0); + centralTask ($hash, $evt) if(!$async); # nur wenn Consumer synchron arbeitet direkte Statusabfrage, sonst via Notify + return; } - if($action eq "get") { + if($action eq 'get') { if($tail eq 'data') { centralTask ($hash, $evt); return; } } - if($action eq "setreading") { + if($action eq 'setreading') { CommandSetReading (undef, "$cname $tail"); } - if($action eq "consumerImmediatePlanning") { + if($action eq 'consumerImmediatePlanning') { CommandSet (undef, "$name $action $cname $evt"); return; } - centralTask ($hash, $evt); + centralTask ($hash, $evt); return; } @@ -2587,15 +2594,20 @@ sub Attr { # $name is device name # aName and aVal are Attribute name and value - if($aName eq "disable") { - if($cmd eq "set") { - $do = ($aVal) ? 1 : 0; + if($aName eq 'disable') { + if($cmd eq 'set') { + $do = $aVal ? 1 : 0; } - $do = 0 if($cmd eq "del"); - $val = ($do == 1 ? "disabled" : "initialized"); + $do = 0 if($cmd eq 'del'); + $val = ($do == 1 ? 'disabled' : 'initialized'); singleUpdateState ( {hash => $hash, state => $val, evt => 1} ); } + if($aName eq 'ctrlAutoRefresh') { + delete $hash->{HELPER}{AREFRESH}; + delete $hash->{AUTOREFRESH}; + } + if($aName eq "ctrlNextDayForecastReadings") { deleteReadingspec ($hash, "Tomorrow_Hour.*"); } @@ -2631,7 +2643,6 @@ sub Attr { return $@ if ($@); } } - } my $params = { @@ -2756,7 +2767,7 @@ sub _attrconsumer { ## no critic "not used" writeCacheToFile ($hash, "consumers", $csmcache.$name); # Cache File Consumer schreiben - InternalTimer(gettimeofday()+5, "FHEM::SolarForecast::createAssociatedWith", $hash, 0); + InternalTimer(gettimeofday()+2, "FHEM::SolarForecast::createAssociatedWith", $hash, 0); return; } @@ -2791,14 +2802,13 @@ return; ################################################################################### # Eventverarbeitung -# (wird zur Zeit nicht genutzt/verwendet) +# - Aktualisierung Consumerstatus bei asynchronen Consumern ################################################################################### sub Notify { # Es werden nur die Events von Geräten verarbeitet die im Hash $hash->{NOTIFYDEV} gelistet sind (wenn definiert). # Dadurch kann die Menge der Events verringert werden. In sub DbRep_Define angeben. - return; # nicht genutzt zur Zeit - + #return; # nicht genutzt zur Zeit my $myHash = shift; my $dev_hash = shift; @@ -2810,7 +2820,7 @@ sub Notify { my $events = deviceEvents($dev_hash, 1); return if(!$events); - my $cdref = CurrentVal ($myHash, "consumerdevs", ""); # alle registrierten Consumer + my $cdref = CurrentVal ($myHash, 'consumerdevs', ''); # alle registrierten Consumer my @consumers = (); @consumers = @{$cdref} if(ref $cdref eq "ARRAY"); @@ -2819,6 +2829,7 @@ sub Notify { if($devName ~~ @consumers) { my $cindex; my $type = $myHash->{TYPE}; + for my $c (sort{$a<=>$b} keys %{$data{$type}{$myName}{consumers}}) { my $cname = ConsumerVal ($myHash, $c, "name", ""); if($devName eq $cname) { @@ -2827,19 +2838,52 @@ sub Notify { } } - my $autoreading = ConsumerVal ($myHash, $cindex, "autoreading", ""); + my $debug = AttrVal ($myName, 'ctrlDebug', 'none'); # Debug Mode + my $async = ConsumerVal ($myHash, $cindex, 'asynchron', 0); + my $rswstate = ConsumerVal ($myHash, $cindex, 'rswstate', ''); + + if ($debug =~ /notifyHandling/x) { + Log3 ($myName, 1, qq{$myName DEBUG> Event received - Consumer Device: $devName, asynchronous: $async}); + } + + return if(!$async); # Consumer synchron -> keine Weiterverarbeitung + + my ($reading,$value,$unit); for my $event (@{$events}) { $event = "" if(!defined($event)); - my @evl = split(/\s+/x, $event); + + my @parts = split(/: /,$event, 2); + $reading = shift @parts; - my @parts = split(/: /x,$event, 2); - my $reading = shift @parts; + if(@parts == 2) { + $value = $parts[0]; + $unit = $parts[1]; + } + else { + $value = join(": ", @parts); + $unit = ""; + } - if ($reading eq "state" || $reading eq $autoreading) { - Log3 ($myName, 4, qq{$myName - start centralTask by Notify - $devName:$reading}); - RemoveInternalTimer($myHash, "FHEM::SolarForecast::centralTask"); - InternalTimer (gettimeofday()+0.5, "FHEM::SolarForecast::centralTask", $myHash, 0); + if(!defined($reading)) { $reading = ""; } + if(!defined($value)) { $value = ""; } + if($value eq "") { + if($event =~ /^.*:\s$/) { + $reading = (split(":", $event))[0]; + } + else { + $reading = "state"; + $value = $event; + } + } + + if ($reading eq $rswstate) { + + if ($debug =~ /notifyHandling/x) { + Log3 ($myName, 1, qq{$myName DEBUG> start centralTask by Notify - $devName: $reading $value}); + } + + centralTask ($myHash, 0); # keine Events in SolarForeCast außer 'state' } } } @@ -5789,7 +5833,7 @@ sub _transferBatteryValues { $data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batin} = $batinthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350 $paref->{batinthishour} = $batinthishour; - $paref->{nhour} = sprintf("%02d",$nhour); + $paref->{nhour} = sprintf "%02d", $nhour; $paref->{histname} = "batinthishour"; setPVhistory ($paref); delete $paref->{histname}; @@ -6338,16 +6382,16 @@ sub saveEnergyConsumption { my $name = $paref->{name}; my $chour = $paref->{chour}; - my $pvrl = ReadingsNum($name, "Today_Hour".sprintf("%02d",$chour+1)."_PVreal", 0); - my $gfeedin = ReadingsNum($name, "Today_Hour".sprintf("%02d",$chour+1)."_GridFeedIn", 0); - my $gcon = ReadingsNum($name, "Today_Hour".sprintf("%02d",$chour+1)."_GridConsumption", 0); - my $batin = ReadingsNum($name, "Today_Hour".sprintf("%02d",$chour+1)."_BatIn", 0); - my $batout = ReadingsNum($name, "Today_Hour".sprintf("%02d",$chour+1)."_BatOut", 0); + my $pvrl = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$chour+1)."_PVreal", 0); + my $gfeedin = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$chour+1)."_GridFeedIn", 0); + my $gcon = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$chour+1)."_GridConsumption", 0); + my $batin = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$chour+1)."_BatIn", 0); + my $batout = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$chour+1)."_BatOut", 0); my $con = $pvrl - $gfeedin + $gcon - $batin + $batout; $paref->{con} = $con; - $paref->{nhour} = sprintf("%02d",$chour+1); + $paref->{nhour} = sprintf "%02d", $chour+1; $paref->{histname} = "con"; setPVhistory ($paref); delete $paref->{histname}; @@ -6454,11 +6498,16 @@ sub collectAllRegConsumers { ($rpcurr,$upcurr,$pthreshold) = split ":", $pcurr; } + my $asynchron; + if(exists $hc->{asynchron}) { + $asynchron = $hc->{asynchron}; + } + my ($rswstate,$onreg,$offreg); if(exists $hc->{swstate}) { ($rswstate,$onreg,$offreg) = split ":", $hc->{swstate}; } - + my ($dswoncond,$rswoncond,$swoncondregex); if(exists $hc->{swoncond}) { # zusätzliche Einschaltbedingung ($dswoncond,$rswoncond,$swoncondregex) = split ":", $hc->{swoncond}; @@ -6516,6 +6565,7 @@ sub collectAllRegConsumers { $data{$type}{$name}{consumers}{$c}{notbefore} = $hc->{notbefore} // q{}; # nicht einschalten vor Stunde in 24h Format (00-23) $data{$type}{$name}{consumers}{$c}{notafter} = $hc->{notafter} // q{}; # nicht einschalten nach Stunde in 24h Format (00-23) $data{$type}{$name}{consumers}{$c}{rswstate} = $rswstate // 'state'; # Schaltstatus Reading + $data{$type}{$name}{consumers}{$c}{asynchron} = $asynchron // 0; # Arbeitsweise FHEM Consumer Device $data{$type}{$name}{consumers}{$c}{onreg} = $onreg // 'on'; # Regex für 'ein' $data{$type}{$name}{consumers}{$c}{offreg} = $offreg // 'off'; # Regex für 'aus' $data{$type}{$name}{consumers}{$c}{dswoncond} = $dswoncond // q{}; # Device zur Lieferung einer zusätzliche Einschaltbedingung @@ -6542,7 +6592,6 @@ sub FwFn { my ($FW_wname, $name, $room, $pageHash) = @_; # pageHash is set for summaryFn. my $hash = $defs{$name}; - RemoveInternalTimer($hash, \&pageRefresh); $hash->{HELPER}{FW} = $FW_wname; my $ret = ""; @@ -6550,32 +6599,42 @@ sub FwFn { $ret .= ""; # Autorefresh nur des aufrufenden FHEMWEB-Devices - my $al = AttrVal($name, "ctrlAutoRefresh", 0); + my $al = AttrVal ($name, 'ctrlAutoRefresh', 0); if($al) { - InternalTimer(gettimeofday()+$al, \&pageRefresh, $hash, 0); - Log3 ($name, 5, "$name - next start of autoRefresh: ".FmtDateTime(gettimeofday()+$al)); + pageRefresh ($hash); } return $ret; } -################################################################ +########################################################################### +# Seitenrefresh festgelegt durch SolarForecast-Attribut "ctrlAutoRefresh" +# und "ctrlAutoRefreshFW" +########################################################################### sub pageRefresh { my $hash = shift; my $name = $hash->{NAME}; - - # Seitenrefresh festgelegt durch SolarForecast-Attribut "ctrlAutoRefresh" und "ctrlAutoRefreshFW" - my $rd = AttrVal($name, "ctrlAutoRefreshFW", $hash->{HELPER}{FW}); - { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } $rd } ## no critic 'Map blocks' - - my $al = AttrVal($name, "ctrlAutoRefresh", 0); + + my $al = AttrVal($name, 'ctrlAutoRefresh', 0); if($al) { - InternalTimer(gettimeofday()+$al, \&pageRefresh, $hash, 0); - Log3 ($name, 5, "$name - next start of autoRefresh: ".FmtDateTime(gettimeofday()+$al)); + my $rftime = gettimeofday()+$al; + + if (!$hash->{HELPER}{AREFRESH} || $hash->{HELPER}{AREFRESH} <= gettimeofday()) { + RemoveInternalTimer ($hash, \&pageRefresh); + InternalTimer($rftime, \&pageRefresh, $hash, 0); + + my $rd = AttrVal ($name, 'ctrlAutoRefreshFW', $hash->{HELPER}{FW}); + { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } $rd } ## no critic 'Map blocks' + + $hash->{HELPER}{AREFRESH} = $rftime; + $hash->{AUTOREFRESH} = FmtDateTime($rftime); + } } else { - RemoveInternalTimer($hash, \&pageRefresh); + delete $hash->{HELPER}{AREFRESH}; + delete $hash->{AUTOREFRESH}; + RemoveInternalTimer ($hash, \&pageRefresh); } return; @@ -6947,10 +7006,10 @@ sub _graphicHeader { $lup = "$day.$month.$year $time"; } - my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction 0 get $name data')"}; # Update Button generieren + my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"}; # Update Button generieren if ($ftui eq "ftui") { - $cmdupdate = qq{"ftui.setFhemStatus('set $name clientAction 0 get $name data')"}; + $cmdupdate = qq{"ftui.setFhemStatus('set $name clientAction - 0 get $name data')"}; } my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"}; # Plant Check Button generieren @@ -7310,18 +7369,18 @@ sub _graphicConsumerLegend { my $autord = ConsumerVal ($hash, $c, "autoreading", ""); # Readingname f. Automatiksteuerung my $auto = ConsumerVal ($hash, $c, "auto", 1); # Automatic Mode - my $cmdon = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction 0 set $cname $oncom')"}; - my $cmdoff = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction 0 set $cname $offcom')"}; - my $cmdautoon = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction 0 setreading $cname $autord 1')"}; - my $cmdautooff = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction 0 setreading $cname $autord 0')"}; - my $implan = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction 0 consumerImmediatePlanning $c')"}; + my $cmdon = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $cname $oncom')"}; + my $cmdoff = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 set $cname $offcom')"}; + my $cmdautoon = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $cname $autord 1')"}; + my $cmdautooff = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 setreading $cname $autord 0')"}; + my $implan = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction $c 0 consumerImmediatePlanning $c')"}; if ($ftui eq "ftui") { - $cmdon = qq{"ftui.setFhemStatus('set $name clientAction 0 set $cname $oncom')"}; - $cmdoff = qq{"ftui.setFhemStatus('set $name clientAction 0 set $cname $offcom')"}; - $cmdautoon = qq{"ftui.setFhemStatus('set $name clientAction 0 setreading $cname $autord 1')"}; - $cmdautooff = qq{"ftui.setFhemStatus('set $name clientAction 0 setreading $cname $autord 0')"}; - $implan = qq{"ftui.setFhemStatus('set $name clientAction 0 consumerImmediatePlanning $c')"}; + $cmdon = qq{"ftui.setFhemStatus('set $name clientAction $c 0 set $cname $oncom')"}; + $cmdoff = qq{"ftui.setFhemStatus('set $name clientAction $c 0 set $cname $offcom')"}; + $cmdautoon = qq{"ftui.setFhemStatus('set $name clientAction $c 0 setreading $cname $autord 1')"}; + $cmdautooff = qq{"ftui.setFhemStatus('set $name clientAction $c 0 setreading $cname $autord 0')"}; + $implan = qq{"ftui.setFhemStatus('set $name clientAction $c 0 consumerImmediatePlanning $c')"}; } $cmdon = q{} if(!$oncom); @@ -10069,8 +10128,8 @@ sub createAssociatedWith { RemoveInternalTimer($hash, "FHEM::SolarForecast::createAssociatedWith"); - if($init_done == 1) { - my @nd; + if($init_done) { + my (@cd,@nd); my ($afc,$ara,$ain,$ame,$aba,$h); my $fcdev = ReadingsVal($name, "currentForecastDev", ""); # Weather forecast Device @@ -10098,8 +10157,10 @@ sub createAssociatedWith { my ($ac,$hc) = parseParams ($codev); $codev = $ac->[0] // ""; - push @nd, $codev if($codev); + push @cd, $codev if($codev); } + + @nd = @cd; push @nd, $fcdev; push @nd, $radev if($radev ne $fcdev && $radev !~ /SolCast-API/xs); @@ -10108,7 +10169,7 @@ sub createAssociatedWith { push @nd, $badev; if(@nd) { - # $hash->{NOTIFYDEV} = join ",", @nd; # zur Zeit nicht benutzt + $hash->{NOTIFYDEV} = join ",", @cd if(@cd); readingsSingleUpdate ($hash, ".associatedWith", join(" ",@nd), 0); } } @@ -10832,6 +10893,7 @@ return $def; # oncom - Einschaltkommando # offcom - Ausschaltkommando # onoff - logischer ein/aus Zustand des am Consumer angeschlossenen Endverbrauchers +# asynchron - Arbeitsweise des FHEM Consumer Devices # retotal - Reading der Leistungsmessung # uetotal - Unit der Leistungsmessung # rpcurr - Readingname des aktuellen Verbrauchs @@ -11883,10 +11945,12 @@ Planung und Steuerung von PV Überschuß abhängigen Verbraucherschaltungen.
  • consumerXX <Device Name> type=<type> power=<power>
    - [mode=<mode>] [icon=<Icon>] [mintime=<minutes> | SunPath[:<Offset_Sunrise>:<Offset_Sunset>]]
    - [on=<Kommando>] [off=<Kommando>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [notbefore=<Stunde>] [notafter=<Stunde>]
    + [mode=<mode>] [icon=<Icon>] [mintime=<minutes> | SunPath[:<Offset_Sunrise>:<Offset_Sunset>]]
    + [on=<Kommando>] [off=<Kommando>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>]
    + [notbefore=<Stunde>] [notafter=<Stunde>]
    [auto=<Readingname>] [pcurr=<Readingname>:<Einheit>[:<Schwellenwert>]] [etotal=<Readingname>:<Einheit>[:<Schwellenwert>]]
    - [swoncond=<Device>:<Reading>:<Regex>] [swoffcond=<Device>:<Reading>:<Regex>] [interruptable=<Option>]


    + [swoncond=<Device>:<Reading>:<Regex>] [swoffcond=<Device>:<Reading>:<Regex>] [interruptable=<Option>]
    +
    Registriert einen Verbraucher <Device Name> beim SolarForecast Device. Dabei ist <Device Name> ein in FHEM bereits angelegtes Verbraucher Device, z.B. eine Schaltsteckdose. @@ -11942,7 +12006,7 @@ Planung und Steuerung von PV Überschuß abhängigen Verbraucherschaltungen. SunPath[:<Offset_Sunrise>:<Offset_Sunset>] - die Einplanung erfolgt von Sonnenaufgang bis Sonnenuntergang. Optional kann eine positive / negative Verschiebung (Minuten) der Planungszeit bzgl. Sonnenaufgang bzw. Sonnenuntergang angegeben werden. - Ist mintime nicht angegeben, wird eine Standard Einplanungsdauer gemaäß nachfolgender Tabelle verwendet. + Ist mintime nicht angegeben, wird eine Standard Einplanungsdauer gemäß nachfolgender Tabelle verwendet. Default mintime nach Verbrauchertyp: - dishwasher: 180 Minuten @@ -11956,6 +12020,10 @@ Planung und Steuerung von PV Überschuß abhängigen Verbraucherschaltungen. swstate Reading welches den Schaltzustand des Consumers anzeigt (default: 'state'). on-Regex - regulärer Ausdruck für den Zustand 'ein' (default: 'on') off-Regex - regulärer Ausdruck für den Zustand 'aus' (default: 'off') + asynchron die Art der Schaltstatus Ermittlung im Verbraucher Device. Die Statusermittlung des Verbrauchers nach einem Schaltbefehl erfolgt nur + durch Abfrage innerhalb eines Datensammelintervals (synchron) oder zusätzlich durch Eventverarbeitung (asynchron). + 0 - ausschließlich synchrone Verarbeitung von Schaltzuständen (default) + 1 - zusätzlich asynchrone Verarbeitung von Schaltzuständen durch Eventverarbeitung notbefore Startzeitpunkt Verbraucher nicht vor angegebener Stunde (01..23) einplanen (optional) notafter Startzeitpunkt Verbraucher nicht nach angegebener Stunde (01..23) einplanen (optional) auto Reading im Verbraucherdevice welches das Schalten des Verbrauchers freigibt bzw. blockiert (optional) @@ -12036,6 +12104,7 @@ Planung und Steuerung von PV Überschuß abhängigen Verbraucherschaltungen. consumerSwitching Operationen des internen Consumer Schaltmodul consumption Verbrauchskalkulation und -nutzung graphic Informationen der Modulgrafik + notifyHandling Ablauf der Eventverarbeitung im Modul pvCorrection Erstellung und Anwendung der Autokorrektur radiationProcess Sammlung und Verarbeitung der Solarstrahlungsdaten saveData2Cache Datenspeicherung in internen Speicherstrukturen