2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

36_Shelly: suppress status calls of disabled devices

git-svn-id: https://svn.fhem.de/fhem/trunk@28413 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Starkstrombastler 2024-01-24 20:15:23 +00:00
parent e297d9054e
commit 44fd898d6b

View File

@ -65,6 +65,7 @@
# 5.17 Add: Roller devices: 'set ... position' equivalent to 'pct' # 5.17 Add: Roller devices: 'set ... position' equivalent to 'pct'
# 5.18 Bug Fix: function of all Gen1 relay devices # 5.18 Bug Fix: function of all Gen1 relay devices
# 5.19 change back: roller devices: use 'set ... pct' as command # 5.19 change back: roller devices: use 'set ... pct' as command
# 5.20 Bug Fix: suppress status calls for disabled devices
package main; package main;
@ -83,7 +84,7 @@ sub Log($$);
sub Shelly_Set ($@); sub Shelly_Set ($@);
#-- globals on start #-- globals on start
my $version = "5.19 11.01.2024"; my $version = "5.20 24.01.2024";
my $defaultINTERVAL = 60; my $defaultINTERVAL = 60;
my $secndIntervalMulti = 4; # Multiplier for 'long update' my $secndIntervalMulti = 4; # Multiplier for 'long update'
@ -610,6 +611,17 @@ my %si_units = (
"ISO" => [ "kJ", 3.6, 0 ] "ISO" => [ "kJ", 3.6, 0 ]
); );
my %peripherals = (
# Peripheral type => Component Type
"analog_in" => "input",
"digital_in" => "input",
"dht22" => "humidity",
"ds18b20" => "temperature",
"voltmeter" => "voltmeter"
);
######################################################################################## ########################################################################################
# #
# Shelly_Initialize # Shelly_Initialize
@ -868,7 +880,7 @@ if(0){
###################################################################################### ######################################################################################
readingsSingleUpdate($hash,"state","initialized",1); readingsSingleUpdate($hash,"state","initialized",1);
InternalTimer(gettimeofday()+6, "Refresh", $hash); InternalTimer(time()+6, "Refresh", $hash);
delete($attr{$hash->{NAME}}{mode}) if( $shelly_models{$model}[8]<2 ); # no multi-mode device delete($attr{$hash->{NAME}}{mode}) if( $shelly_models{$model}[8]<2 ); # no multi-mode device
delete($hash->{helper}{Sets}); # build up the sets-dropdown with next refresh delete($hash->{helper}{Sets}); # build up the sets-dropdown with next refresh
return; return;
@ -1331,10 +1343,11 @@ sub Shelly_Attr(@) {
Log3 $name,1,"[Shelly_Attr] $name\: $error model=shelly2/2.5/plus2/pro2 and mode=roller"; ##R Log3 $name,1,"[Shelly_Attr] $name\: $error model=shelly2/2.5/plus2/pro2 and mode=roller"; ##R
return $error; return $error;
} }
# perform an update of the position related readings if($init_done){
RemoveInternalTimer($hash,"Shelly_status"); # perform an update of the position related readings
InternalTimer(gettimeofday()+1, "Shelly_status", $hash); ##ü RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(time()+1, "Shelly_status", $hash); ##ü
}
#--------------------------------------- #---------------------------------------
}elsif( $attrName =~ /Energymeter/ ){ }elsif( $attrName =~ /Energymeter/ ){
if($cmd eq "set" ){ if($cmd eq "set" ){
@ -1498,12 +1511,12 @@ sub Shelly_Attr(@) {
$hash->{CMD}="Check"; $hash->{CMD}="Check";
} }
} }
# calling Shelly_webhook() via timer, otherwise settings are not available if( $hash->{INTERVAL} != 0 ){
Log3 $name,3,"[Shelly_Attr:webhook] we will call Shelly_webhook for device $name, command is ".$hash->{CMD}; # calling Shelly_webhook() via timer, otherwise settings are not available
RemoveInternalTimer($hash,"Shelly_webhook"); Log3 $name,3,"[Shelly_Attr:webhook] we will call Shelly_webhook for device $name, command is ".$hash->{CMD};
InternalTimer(gettimeofday()+3, "Shelly_webhook", $hash, 0); RemoveInternalTimer($hash,"Shelly_webhook");
InternalTimer(time()+3, "Shelly_webhook", $hash, 0);
}
#--------------------------------------- #---------------------------------------
}elsif( $attrName eq "interval" ){ }elsif( $attrName eq "interval" ){
if( $cmd eq "set" ){ if( $cmd eq "set" ){
@ -1511,7 +1524,7 @@ sub Shelly_Attr(@) {
if( $model eq "shellypro3em" && $attrVal > 0 ){ if( $model eq "shellypro3em" && $attrVal > 0 ){
# restart the 2nd timer (only when stopped) # restart the 2nd timer (only when stopped)
# adjust the timer to one second after the full minute # adjust the timer to one second after the full minute
InternalTimer(int((gettimeofday()+60)/60)*60+1, "Shelly_shelly", $hash, 1) InternalTimer(int((time()+60)/60)*60+1, "Shelly_shelly", $hash, 1)
if( AttrVal($name,"interval",-1) == 0 ); if( AttrVal($name,"interval",-1) == 0 );
# adjust the 1st timer to 60 # adjust the 1st timer to 60
@ -1524,9 +1537,9 @@ sub Shelly_Attr(@) {
}elsif( $cmd eq "del" ){ }elsif( $cmd eq "del" ){
$hash->{INTERVAL}=60; $hash->{INTERVAL}=60;
} }
if($init_done) { if($init_done){
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "Shelly_status", $hash, 0) InternalTimer(time()+$hash->{INTERVAL}, "Shelly_status", $hash, 0)
if( $hash->{INTERVAL} != 0 ); if( $hash->{INTERVAL} != 0 );
} }
#--------------------------------------- #---------------------------------------
@ -1781,7 +1794,7 @@ sub Shelly_Set ($@) {
readingsBulkUpdateMonitored($hash, "input$subs\_actionS",$fhem_events{$cmd}, 1 ); readingsBulkUpdateMonitored($hash, "input$subs\_actionS",$fhem_events{$cmd}, 1 );
# after a second, the pushbuttons state is back to OFF resp. 'unknown', call status of inputs # after a second, the pushbuttons state is back to OFF resp. 'unknown', call status of inputs
RemoveInternalTimer($hash,"Shelly_inputstatus"); RemoveInternalTimer($hash,"Shelly_inputstatus");
InternalTimer(gettimeofday()+1.4, "Shelly_inputstatus", $hash,1); InternalTimer(time()+1.4, "Shelly_inputstatus", $hash,1);
}elsif( $signal eq "touch" ){ # devices with an touch-display }elsif( $signal eq "touch" ){ # devices with an touch-display
#$subs = ($shelly_models{$model}[5] == 1) ? "" : "_".$value; #$subs = ($shelly_models{$model}[5] == 1) ? "" : "_".$value;
readingsBulkUpdateMonitored($hash, "touch", $isWhat, 1 ); readingsBulkUpdateMonitored($hash, "touch", $isWhat, 1 );
@ -1840,7 +1853,7 @@ sub Shelly_Set ($@) {
#-- Call status after switch.n #-- Call status after switch.n
if( $signal !~ /^(Active_Power|Voltage|Current|apower|voltage|current)/ ){ if( $signal !~ /^(Active_Power|Voltage|Current|apower|voltage|current)/ ){
RemoveInternalTimer($hash,"Shelly_status"); Log3 $name,6,"shelly_set 1715 removed Timer Shelly_status, now calling in 1.5 sec"; RemoveInternalTimer($hash,"Shelly_status"); Log3 $name,6,"shelly_set 1715 removed Timer Shelly_status, now calling in 1.5 sec";
InternalTimer(gettimeofday()+1.5, "Shelly_status", $hash); InternalTimer(time()+1.5, "Shelly_status", $hash);
} }
return undef; return undef;
} }
@ -2109,7 +2122,7 @@ sub Shelly_Set ($@) {
$hash->{DURATION} = 0; $hash->{DURATION} = 0;
$hash->{CMD}=$cmd; $hash->{CMD}=$cmd;
RemoveInternalTimer($hash,"Shelly_Set"); RemoveInternalTimer($hash,"Shelly_Set");
InternalTimer(gettimeofday()+1.0, "Shelly_Set", $hash, 1); InternalTimer(time()+1.0, "Shelly_Set", $hash, 1);
$cmd = "?go=stop"; $cmd = "?go=stop";
#-- is moving !!! #-- is moving !!!
@ -2265,12 +2278,12 @@ sub Shelly_Set ($@) {
if( $hash->{INTERVAL} ){ if( $hash->{INTERVAL} ){
Log3 $name,2,"[Shelly_Set] Starting cyclic timers for $name ($model)"; Log3 $name,2,"[Shelly_Set] Starting cyclic timers for $name ($model)";
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "Shelly_status", $hash, 0); InternalTimer(time()+$hash->{INTERVAL}, "Shelly_status", $hash, 0);
RemoveInternalTimer($hash,"Shelly_shelly"); RemoveInternalTimer($hash,"Shelly_shelly");
InternalTimer(gettimeofday()+$defaultINTERVAL*$secndIntervalMulti, "Shelly_shelly", $hash,0); InternalTimer(time()+$defaultINTERVAL*$secndIntervalMulti, "Shelly_shelly", $hash,0);
if( $model eq "shellypro3em" ){ if( $model eq "shellypro3em" ){
RemoveInternalTimer($hash,"Shelly_EMData"); RemoveInternalTimer($hash,"Shelly_EMData");
InternalTimer(int((gettimeofday()+60)/60)*60+1, "Shelly_EMData", $hash,0); InternalTimer(int((time()+60)/60)*60+1, "Shelly_EMData", $hash,0);
Log3 $name,2,"[Shelly_Set] Starting cyclic EM-Data timers for $name"; Log3 $name,2,"[Shelly_Set] Starting cyclic EM-Data timers for $name";
} }
}else{ }else{
@ -2282,11 +2295,11 @@ sub Shelly_Set ($@) {
if( $hash->{INTERVAL} ){ if( $hash->{INTERVAL} ){
Log3 $name,2,"[Shelly_Set] Starting cyclic timers for $name"; Log3 $name,2,"[Shelly_Set] Starting cyclic timers for $name";
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "Shelly_status", $hash, 0); InternalTimer(time()+$hash->{INTERVAL}, "Shelly_status", $hash, 0);
RemoveInternalTimer($hash,"Shelly_shelly"); RemoveInternalTimer($hash,"Shelly_shelly");
InternalTimer(gettimeofday()+$defaultINTERVAL*$secndIntervalMulti, "Shelly_shelly", $hash,0); InternalTimer(time()+$defaultINTERVAL*$secndIntervalMulti, "Shelly_shelly", $hash,0);
RemoveInternalTimer($hash,"Shelly_EMData"); RemoveInternalTimer($hash,"Shelly_EMData");
InternalTimer(int((gettimeofday()+60)/60)*60+1, "Shelly_EMData", $hash,0); InternalTimer(int((time()+60)/60)*60+1, "Shelly_EMData", $hash,0);
}else{ }else{
Log3 $name,2,"[Shelly_Set] No timer started for $name"; Log3 $name,2,"[Shelly_Set] No timer started for $name";
} }
@ -2646,6 +2659,7 @@ sub Shelly_inputstatus {
sub Shelly_status { sub Shelly_status {
my ($hash, $comp, $err, $data) = @_; my ($hash, $comp, $err, $data) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
return if( $hash->{INTERVAL} == 0 );
my $state = $hash->{READINGS}{state}{VAL}; my $state = $hash->{READINGS}{state}{VAL};
my $model = AttrVal($name,"model","generic"); my $model = AttrVal($name,"model","generic");
@ -2660,7 +2674,7 @@ sub Shelly_status {
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
my $interval=minNum($hash->{INTERVAL},$defaultINTERVAL*$secndIntervalMulti); my $interval=minNum($hash->{INTERVAL},$defaultINTERVAL*$secndIntervalMulti);
Log3 $name,3,"[Shelly_status] $name: Error in callback, update in $interval seconds"; Log3 $name,3,"[Shelly_status] $name: Error in callback, update in $interval seconds";
InternalTimer(gettimeofday()+$interval, "Shelly_status", $hash, 1); InternalTimer(time()+$interval, "Shelly_status", $hash, 1);
} }
# in any cases check for error in non blocking call # in any cases check for error in non blocking call
@ -2782,7 +2796,7 @@ sub Shelly_status {
Log3 $name,4,"[Shelly_status] $name: next update in $next seconds".(defined($comp)?" for Comp=$comp":""); #4 Log3 $name,4,"[Shelly_status] $name: next update in $next seconds".(defined($comp)?" for Comp=$comp":""); #4
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+$next, "Shelly_status", $hash, 1) InternalTimer(time()+$next, "Shelly_status", $hash, 1)
if( $hash->{INTERVAL} != 0 ); if( $hash->{INTERVAL} != 0 );
return undef; return undef;
} }
@ -2802,7 +2816,7 @@ sub Shelly_shelly {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $state = $hash->{READINGS}{state}{VAL}; my $state = $hash->{READINGS}{state}{VAL};
return if( $hash->{INTERVAL} == 0 );
my $model = AttrVal($name,"model","generic"); my $model = AttrVal($name,"model","generic");
my $creds = Shelly_pwd($hash); my $creds = Shelly_pwd($hash);
my $url = "http://$creds".$hash->{TCPIP}; my $url = "http://$creds".$hash->{TCPIP};
@ -2866,10 +2880,10 @@ sub Shelly_shelly {
# updates at every multiple of 60 seconds # updates at every multiple of 60 seconds
$offset = $hash->{INTERVAL}<=60 ? 60 : int($hash->{INTERVAL}/60)*60 ; $offset = $hash->{INTERVAL}<=60 ? 60 : int($hash->{INTERVAL}/60)*60 ;
# adjust to get readings 2sec after full minute # adjust to get readings 2sec after full minute
$offset = $offset + 2 - gettimeofday() % 60; $offset = $offset + 2 - time() % 60;
} }
Log3 $name,4,"[Shelly_shelly] $name: long update in $offset seconds, Timer is Shelly_shelly"; #4 Log3 $name,4,"[Shelly_shelly] $name: long update in $offset seconds, Timer is Shelly_shelly"; #4
InternalTimer(gettimeofday()+$offset, "Shelly_shelly", $hash, 1); InternalTimer(time()+$offset, "Shelly_shelly", $hash, 1);
return undef; return undef;
} }
@ -3837,7 +3851,7 @@ sub Shelly_EMData {
#-- cyclic update nevertheless #-- cyclic update nevertheless
RemoveInternalTimer($hash,"Shelly_EMData"); RemoveInternalTimer($hash,"Shelly_EMData");
# adjust timer to one second after full minute # adjust timer to one second after full minute
my $Tupdate = int((gettimeofday()+60)/60)*60+1; my $Tupdate = int((time()+60)/60)*60+1;
Log3 $name,4,"[Shelly_EMData] $name: next EMData update at $Tupdate = ".strftime("%H:%M:%S",localtime($Tupdate) )." Timer is Shelly_EMdata"; Log3 $name,4,"[Shelly_EMData] $name: next EMData update at $Tupdate = ".strftime("%H:%M:%S",localtime($Tupdate) )." Timer is Shelly_EMdata";
InternalTimer($Tupdate, "Shelly_EMData", $hash, 1) InternalTimer($Tupdate, "Shelly_EMData", $hash, 1)
if( $hash->{INTERVAL} != 0 ); if( $hash->{INTERVAL} != 0 );
@ -4241,9 +4255,9 @@ sub shelly_energy_fmt {
#-- Call status after switch. #-- Call status after switch.
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+0.5, "Shelly_status", $hash,0); InternalTimer(time()+0.5, "Shelly_status", $hash,0);
my $duration=ReadingsNum($name,"transition",10000)/1000; my $duration=ReadingsNum($name,"transition",10000)/1000;
InternalTimer(gettimeofday()+$duration, "Shelly_status2", $hash,0); InternalTimer(time()+$duration, "Shelly_status2", $hash,0);
return undef; return undef;
} }
@ -4322,9 +4336,9 @@ sub shelly_energy_fmt {
#-- perform first update after starting of drive #-- perform first update after starting of drive
$hash->{DURATION} = 5 if( !$hash->{DURATION} ); # duration not provided by Gen2 $hash->{DURATION} = 5 if( !$hash->{DURATION} ); # duration not provided by Gen2
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+0.5, "Shelly_status", $hash); # update after starting InternalTimer(time()+0.5, "Shelly_status", $hash); # update after starting
# next update after expected stopping of drive + offset (at least 1 sec) # next update after expected stopping of drive + offset (at least 1 sec)
InternalTimer(gettimeofday()+$hash->{DURATION}+1.5, "Shelly_status2", $hash,1); InternalTimer(time()+$hash->{DURATION}+1.5, "Shelly_status2", $hash,1);
} }
return undef; return undef;
} }
@ -4363,14 +4377,14 @@ sub Shelly_status2($){
if( $hash && !$err && !$data ){ if( $hash && !$err && !$data ){
my $callback; my $callback;
my $url = "http://$creds".$hash->{TCPIP}; my $url = "http://$creds".$hash->{TCPIP};
if($shelly_models{$model}[4]<2){ if($shelly_models{$model}[4]<2){
$url .= "/relay/$channel$cmd"; $url .= "/relay/$channel$cmd";
$callback="/relay/$channel$cmd"; $callback="/relay/$channel$cmd";
}else{ # eg Wall-Display }else{ # eg Wall-Display
$cmd =~ /\?id=(\d)/; $cmd =~ /\?id=(\d)/;
$callback = $url."/rpc/Switch.GetStatus?id=".$1; $callback = $url."/rpc/Switch.GetStatus?id=".$1;
$url .= $cmd; $url .= $cmd;
} }
Log3 $name,4,"[Shelly_onoff] issue a non-blocking call to $url; callback to Shelly_onoff with command $callback"; Log3 $name,4,"[Shelly_onoff] issue a non-blocking call to $url; callback to Shelly_onoff with command $callback";
HttpUtils_NonblockingGet({ HttpUtils_NonblockingGet({
url => $url, url => $url,
@ -4455,7 +4469,7 @@ if($shelly_models{$model}[4]<2){
$onofftimer = ($onofftimer % $hash->{INTERVAL}) + 0.5; #modulus $onofftimer = ($onofftimer % $hash->{INTERVAL}) + 0.5; #modulus
} }
RemoveInternalTimer($hash,"Shelly_status"); RemoveInternalTimer($hash,"Shelly_status");
InternalTimer(gettimeofday()+$onofftimer, "Shelly_status", $hash,0); InternalTimer(time()+$onofftimer, "Shelly_status", $hash,0);
return undef; return undef;
} }
@ -4475,6 +4489,7 @@ if($shelly_models{$model}[4]<2){
sub Shelly_webhook { sub Shelly_webhook {
my ($hash, $cmd, $err, $data) = @_; my ($hash, $cmd, $err, $data) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
return if( $hash->{INTERVAL} == 0 );
my $state = $hash->{READINGS}{state}{VAL}; my $state = $hash->{READINGS}{state}{VAL};
my $net = $hash->{READINGS}{network}{VAL}; my $net = $hash->{READINGS}{network}{VAL};
@ -5055,6 +5070,7 @@ Shelly_readingsBulkUpdate($$$@) # derived from fhem.pl readingsBulkUpdateIfChang
return undef; return undef;
} }
# #
@ -5125,6 +5141,8 @@ Shelly_readingsBulkUpdate($$$@) # derived from fhem.pl readingsBulkUpdateIfChang
<br>This is the only way to set the password for the Shelly web interface. <br>This is the only way to set the password for the Shelly web interface.
</li> </li>
For Shelly devices first gen, the attribute 'shellyuser' must be defined For Shelly devices first gen, the attribute 'shellyuser' must be defined
To remove a password, use:
<code>set &lt;name&gt; password </code>
<li> <li>
<a id="Shelly-set-reboot"></a> <a id="Shelly-set-reboot"></a>
<code>set &lt;name&gt; reboot</code> <code>set &lt;name&gt; reboot</code>
@ -5664,6 +5682,9 @@ Shelly_readingsBulkUpdate($$$@) # derived from fhem.pl readingsBulkUpdateIfChang
<code>set &lt;name&gt; password &lt;password&gt;</code> <code>set &lt;name&gt; password &lt;password&gt;</code>
<br>Setzen des Passwortes für das Shelly Web Interface <br>Setzen des Passwortes für das Shelly Web Interface
</li> </li>
Bei Shelly-Geräten der 1. Generation muss zuvor das Attribut 'shellyuser' gesetzt sein.
Ein in Fhem gespeichertes Passwort wird durch Aufruf ohne Parameter entfernt:
<code>set &lt;name&gt; password </code>
Hinweis: Beim Umbenennen des Devices mit 'rename' geht das Passwort verloren Hinweis: Beim Umbenennen des Devices mit 'rename' geht das Passwort verloren
<li> <li>
<a id="Shelly-set-reboot"></a> <a id="Shelly-set-reboot"></a>