2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00

59_Twilight.pm: Change Maintainership + remove senseless yahoo weather service requests

git-svn-id: https://svn.fhem.de/fhem/trunk@22737 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2020-09-06 04:56:20 +00:00
parent 995832ae06
commit 7c134f0992
3 changed files with 210 additions and 257 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- bugfix: 59_Twilight: deactivate yahoo service dependend routines
- change: 93_DbRep: the the blocking executed commands are monitored with an - change: 93_DbRep: the the blocking executed commands are monitored with an
adjustable timeout, adjustable timeout,
NOTE: get dbValue is deprecated and was changed to NOTE: get dbValue is deprecated and was changed to

View File

@ -35,30 +35,25 @@
package main; package main;
use strict; use strict;
use warnings; use warnings;
use POSIX; #use List::Util qw(max min);
use HttpUtils; use HttpUtils;
use Math::Trig; use Math::Trig;
use Time::Local 'timelocal_nocheck'; use Time::Local 'timelocal_nocheck';
sub Twilight_calc($$);
sub Twilight_my_gmt_offset();
sub Twilight_midnight_seconds($);
################################################################################ ################################################################################
sub Twilight_Initialize($) sub Twilight_Initialize {
{ my $hash = shift;
my ($hash) = @_;
# Consumer # Consumer
$hash->{DefFn} = "Twilight_Define"; $hash->{DefFn} = "Twilight_Define";
$hash->{UndefFn} = "Twilight_Undef"; $hash->{UndefFn} = "Twilight_Undef";
$hash->{GetFn} = "Twilight_Get"; $hash->{GetFn} = "Twilight_Get";
$hash->{AttrList}= "$readingFnAttributes " ."useExtWeather"; $hash->{AttrList}= "$readingFnAttributes " ."useExtWeather";
return undef; return;
} }
################################################################################ ################################################################################
sub Twilight_Get($@) sub Twilight_Get {
{
my ($hash, @a) = @_; my ($hash, @a) = @_;
return "argument is missing" if(int(@a) != 2); return "argument is missing" if(int(@a) != 2);
@ -73,54 +68,37 @@ sub Twilight_Get($@)
return "$a[0] $reading => $value"; return "$a[0] $reading => $value";
} }
################################################################################ ################################################################################
sub Twilight_Define($$) sub Twilight_Define
{ {
my ($hash, $def) = @_; my $hash = shift;
my $def = shift // return;
my @a = split("[ \t][ \t]*", $def); my @arr = split m{\s+}xms, $def;
return "syntax: define <name> Twilight <latitude> <longitude> [indoor_horizon [Weather]]" return "syntax: define <name> Twilight <latitude> <longitude> [indoor_horizon [Weather]]"
if(int(@a) < 4 && int(@a) > 6); if(int(@arr) < 1 && int(@arr) > 6);
$hash->{STATE} = "0"; $hash->{STATE} = "0";
my $name = shift @arr;
my $type = shift @arr;
my $latitude = shift @arr // AttrVal('global','latitude',50.112);
my $longitude = shift @arr // AttrVal('global','longitude',8.686);
my $indoor_horizon = shift @arr // 0;
my $weather = shift @arr // 0;
my $latitude; return "Argument Latitude is not a valid number" if !looks_like_number($latitude);
my $longitude; return "Argument Longitude is not a valid number" if !looks_like_number($longitude);
my $name = $a[0]; return "Argument Indoor_Horizon is not a valid number" if !looks_like_number($indoor_horizon);
if ($a[2] =~ /^[\+-]*[0-9]*\.*[0-9]*$/ && $a[2] !~ /^[\. ]*$/ ) {
$latitude = $a[2];
if($latitude > 90){$latitude = 90;}
if($latitude < -90){$latitude = -90;}
}else{
return "Argument Latitude is not a valid number";
}
if ($a[3] =~ /^[\+-]*[0-9]*\.*[0-9]*$/ && $a[3] !~ /^[\. ]*$/ ) { $latitude = List::Util::min( 90, List::Util::max( -90, $latitude));
$longitude = $a[3]; $longitude = List::Util::min( 180, List::Util::max(-180, $longitude));
if($longitude > 180){$longitude = 180;} $indoor_horizon = List::Util::min( 20, List::Util::max( -6, $indoor_horizon));
if($longitude < -180){$longitude = -180;}
}else{
return "Argument Longitude is not a valid number";
}
my $weather = 0;
my $indoor_horizon = 0;
if(int(@a)>5) { $weather=$a[5] }
if(int(@a)>4) { if ($a[4] =~ /^[\+-]*[0-9]*\.*[0-9]*$/ && $a[4] !~ /^[\. ]*$/ ) {
$indoor_horizon = $a[4];
if($indoor_horizon > 20) { $indoor_horizon=20;}
# minimal indoor_horizon makes values like civil_sunset and civil_sunrise
if($indoor_horizon < -6) { $indoor_horizon= -6;}
}else{
return "Argument Indoor_Horizon is not a valid number";}
}
$hash->{WEATHER_HORIZON} = 0; $hash->{WEATHER_HORIZON} = 0;
$hash->{INDOOR_HORIZON} = $indoor_horizon; $hash->{INDOOR_HORIZON} = $indoor_horizon;
$hash->{LATITUDE} = $latitude; $hash->{LATITUDE} = $latitude;
$hash->{LONGITUDE} = $longitude; $hash->{LONGITUDE} = $longitude;
$hash->{WEATHER} = $weather; $hash->{WEATHER} = $weather;
$hash->{VERSUCHE} = 0; #$hash->{VERSUCHE} = 0;
$hash->{DEFINE} = 1; $hash->{DEFINE} = 1;
$hash->{CONDITION} = 50; $hash->{CONDITION} = 50;
$hash->{SUNPOS_OFFSET} = 5*60; $hash->{SUNPOS_OFFSET} = 5*60;
@ -132,24 +110,26 @@ sub Twilight_Define($$)
Twilight_Midnight($mHash); Twilight_Midnight($mHash);
delete $hash->{DEFINE}; delete $hash->{DEFINE};
Log3 $hash, 2, "[$hash->{NAME}] Note: Twilight formerly used weather info from yahoo, but source is offline.";
return undef; return;
} }
################################################################################ ################################################################################
sub Twilight_Undef($$) { sub Twilight_Undef {
my ($hash, $arg) = @_; my $hash = shift;
my $arg = shift // return;
foreach my $key (keys %{$hash->{TW}}) { for my $key (keys %{$hash->{TW}}) {
myRemoveInternalTimer($key, $hash); myRemoveInternalTimer($key, $hash);
} }
myRemoveInternalTimer ("Midnight", $hash); myRemoveInternalTimer ("Midnight", $hash);
myRemoveInternalTimer ("weather", $hash); myRemoveInternalTimer ("weather", $hash);
myRemoveInternalTimer ("sunpos", $hash); myRemoveInternalTimer ("sunpos", $hash);
return undef; return;
} }
################################################################################ ################################################################################
sub myInternalTimer($$$$$) { sub myInternalTimer {
my ($modifier, $tim, $callback, $hash, $waitIfInitNotDone) = @_; my ($modifier, $tim, $callback, $hash, $waitIfInitNotDone) = @_;
my $timerName = "$hash->{NAME}_$modifier"; my $timerName = "$hash->{NAME}_$modifier";
@ -166,8 +146,9 @@ sub myInternalTimer($$$$$) {
return $mHash; return $mHash;
} }
################################################################################ ################################################################################
sub myRemoveInternalTimer($$) { sub myRemoveInternalTimer {
my ($modifier, $hash) = @_; my $modifier = shift;
my $hash = shift // return;
my $timerName = "$hash->{NAME}_$modifier"; my $timerName = "$hash->{NAME}_$modifier";
my $myHash = $hash->{TIMER}{$timerName}; my $myHash = $hash->{TIMER}{$timerName};
@ -176,55 +157,33 @@ sub myRemoveInternalTimer($$) {
Log3 $hash, 5, "[$hash->{NAME}] removing Timer: $timerName"; Log3 $hash, 5, "[$hash->{NAME}] removing Timer: $timerName";
RemoveInternalTimer($myHash); RemoveInternalTimer($myHash);
} }
return;
} }
################################################################################ ################################################################################
#sub myRemoveInternalTimerByName($){ sub myGetHashIndirekt {
# my ($name) = @_; my $myHash = shift;
# foreach my $a (keys %intAt) { my $function = shift // return;
# my $nam = "";
# my $arg = $intAt{$a}{ARG};
# if (ref($arg) eq "HASH" && defined($arg->{NAME}) ) {
# $nam = $arg->{NAME} if (ref($arg) eq "HASH" && defined($arg->{NAME}) );
# }
# delete($intAt{$a}) if($nam =~ m/^$name/g);
# }
#}
################################################################################
sub myGetHashIndirekt ($$) {
my ($myHash, $function) = @_;
if (!defined($myHash->{HASH})) { if (!defined($myHash->{HASH})) {
Log 3, "[$function] myHash not valid"; Log 3, "[$function] myHash not valid";
return undef; return;
}; };
return $myHash->{HASH}; return $myHash->{HASH};
} }
################################################################################ ################################################################################
sub Twilight_midnight_seconds($) {
my ($now) = @_; sub Twilight_midnight_seconds {
my $now = shift // return;
my @time = localtime($now); my @time = localtime($now);
my $secs = ($time[2] * 3600) + ($time[1] * 60) + $time[0]; my $secs = ($time[2] * 3600) + ($time[1] * 60) + $time[0];
return $secs; return $secs;
} }
################################################################################ ################################################################################
#sub Twilight_ssTimeAsEpoch($) { sub Twilight_calc {
# my ($zeit) = @_; my $deg = shift;
# my ($hour, $min, $sec) = split(":",$zeit); my $idx = shift // return;
#
# my $days=0;
# if ($hour>=24) {$days = 1; $hour -=24};
#
# my @jetzt_arr = localtime(time());
# #Stunden Minuten Sekunden
# $jetzt_arr[2] = $hour; $jetzt_arr[1] = $min; $jetzt_arr[0] = $sec;
# $jetzt_arr[3] += $days;
# my $next = timelocal_nocheck(@jetzt_arr);
#
# return $next;
#}
################################################################################
sub Twilight_calc($$) {
my ($deg, $idx) = @_;
my $midnight = time() - Twilight_midnight_seconds(time()); my $midnight = time() - Twilight_midnight_seconds(time());
@ -238,12 +197,10 @@ sub Twilight_calc($$) {
my $ss1 = $midnight + 3600*$sshour+60*$ssmin+$sssec; my $ss1 = $midnight + 3600*$sshour+60*$ssmin+$sssec;
return (0,0) if (abs ($sr1 - $ss1) < 30); return (0,0) if (abs ($sr1 - $ss1) < 30);
#return Twilight_ssTimeAsEpoch($sr) + 0.01*$idx,
# Twilight_ssTimeAsEpoch($ss) - 0.01*$idx;
return ($sr1 + 0.01*$idx), ($ss1 - 0.01*$idx); return ($sr1 + 0.01*$idx), ($ss1 - 0.01*$idx);
} }
################################################################################ ################################################################################
sub Twilight_TwilightTimes(@) { sub Twilight_TwilightTimes {
my ($hash, $whitchTimes, $xml) = @_; my ($hash, $whitchTimes, $xml) = @_;
my $Name = $hash->{NAME}; my $Name = $hash->{NAME};
@ -251,12 +208,12 @@ sub Twilight_TwilightTimes(@) {
my $horizon = $hash->{HORIZON}; my $horizon = $hash->{HORIZON};
my $swip = $hash->{SWIP} ; my $swip = $hash->{SWIP} ;
my $lat = $attr{global}{latitude}; $attr{global}{latitude} = $hash->{LATITUDE}; my $lat = $hash->{LATITUDE};
my $long = $attr{global}{longitude}; $attr{global}{longitude} = $hash->{LONGITUDE}; my $long = $hash->{LONGITUDE};
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
my $idx = -1; my $idx = -1;
my @horizons = ("_astro:-18", "_naut:-12", "_civil:-6",":0", "_indoor:$hash->{INDOOR_HORIZON}", "_weather:$hash->{WEATHER_HORIZON}"); my @horizons = ("_astro:-18", "_naut:-12", "_civil:-6",":0", "_indoor:$hash->{INDOOR_HORIZON}", "_weather:$hash->{WEATHER_HORIZON}");
foreach my $horizon (@horizons) { for my $horizon (@horizons) {
$idx++; next if ($whitchTimes eq "weather" && !($horizon =~ m/weather/) ); $idx++; next if ($whitchTimes eq "weather" && !($horizon =~ m/weather/) );
my ($name, $deg) = split(":", $horizon); my ($name, $deg) = split(":", $horizon);
@ -273,11 +230,11 @@ sub Twilight_TwilightTimes(@) {
Log3 $hash, 4, "[$Name] hint: $hash->{TW}{$sr}{NAME}, $hash->{TW}{$ss}{NAME} are not defined(HORIZON=$deg)"; Log3 $hash, 4, "[$Name] hint: $hash->{TW}{$sr}{NAME}, $hash->{TW}{$ss}{NAME} are not defined(HORIZON=$deg)";
} }
} }
$attr{global}{latitude} = $lat; #$attr{global}{latitude} = $lat;
$attr{global}{longitude} = $long; #$attr{global}{longitude} = $long;
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
readingsBeginUpdate ($hash); readingsBeginUpdate ($hash);
foreach my $ereignis (keys %{$hash->{TW}}) { for my $ereignis (keys %{$hash->{TW}}) {
next if ($whitchTimes eq "weather" && !($ereignis =~ m/weather/) ); next if ($whitchTimes eq "weather" && !($ereignis =~ m/weather/) );
readingsBulkUpdate($hash, $ereignis, $hash->{TW}{$ereignis}{TIME} == 0 ? "undefined" : FmtTime($hash->{TW}{$ereignis}{TIME})); readingsBulkUpdate($hash, $ereignis, $hash->{TW}{$ereignis}{TIME} == 0 ? "undefined" : FmtTime($hash->{TW}{$ereignis}{TIME}));
} }
@ -299,7 +256,7 @@ sub Twilight_TwilightTimes(@) {
my $jetztIstMitternacht = abs($now+5-$nextMitternacht)<=10; my $jetztIstMitternacht = abs($now+5-$nextMitternacht)<=10;
my @keyListe = qw "DEG LIGHT STATE SWIP TIME NAMENEXT"; my @keyListe = qw "DEG LIGHT STATE SWIP TIME NAMENEXT";
foreach my $ereignis (sort keys %{$hash->{TW}}) { for my $ereignis (sort keys %{$hash->{TW}}) {
next if ($whitchTimes eq "weather" && !($ereignis =~ m/weather/) ); next if ($whitchTimes eq "weather" && !($ereignis =~ m/weather/) );
myRemoveInternalTimer($ereignis, $hash); # if(!$jetztIstMitternacht); myRemoveInternalTimer($ereignis, $hash); # if(!$jetztIstMitternacht);
@ -312,8 +269,8 @@ sub Twilight_TwilightTimes(@) {
return 1; return 1;
} }
################################################################################ ################################################################################
sub Twilight_fireEvent($) { sub Twilight_fireEvent {
my ($myHash) = @_; my $myHash = shift // return;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]); my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -351,31 +308,34 @@ sub Twilight_fireEvent($) {
readingsBulkUpdate ($hash, "nextEvent", $nextEvent); readingsBulkUpdate ($hash, "nextEvent", $nextEvent);
readingsBulkUpdate ($hash, "nextEventTime", $nextEventTime); readingsBulkUpdate ($hash, "nextEventTime", $nextEventTime);
readingsEndUpdate ($hash, $doTrigger); return readingsEndUpdate ($hash, $doTrigger);
} }
################################################################################ ################################################################################
sub Twilight_Midnight($) { sub Twilight_Midnight {
my ($myHash) = @_; my $myHash = shift // return;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]); my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
$hash->{SWIP} = 0; $hash->{SWIP} = 0;
my $param = Twilight_CreateHttpParameterAndGetData($myHash, "Mid"); my $param = Twilight_CreateHttpParameterAndGetData($myHash, "Mid");
return;
} }
################################################################################ ################################################################################
# {Twilight_WeatherTimerUpdate( {HASH=$defs{"Twilight"}} ) } # {Twilight_WeatherTimerUpdate( {HASH=$defs{"Twilight"}} ) }
sub Twilight_WeatherTimerUpdate($) { sub Twilight_WeatherTimerUpdate {
my ($myHash) = @_; my $myHash = shift // return;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]); my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
$hash->{SWIP} = 1; $hash->{SWIP} = 1;
my $param = Twilight_CreateHttpParameterAndGetData($myHash, "weather"); my $param = Twilight_CreateHttpParameterAndGetData($myHash, "weather");
return;
} }
################################################################################ ################################################################################
sub Twilight_CreateHttpParameterAndGetData($$) { sub Twilight_CreateHttpParameterAndGetData {
my ($myHash, $mode) = @_; my $myHash = shift;
my $mode = shift // return;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]); my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -403,17 +363,19 @@ sub Twilight_CreateHttpParameterAndGetData($$) {
} else { } else {
HttpUtils_NonblockingGet($param); HttpUtils_NonblockingGet($param);
} }
return;
} }
################################################################################ ################################################################################
sub Twilight_WeatherCallback(@) { sub Twilight_WeatherCallback {
my ($param, $err, $result) = @_; my ($param, $err, $result) = @_;
my $hash = $param->{hash}; my $hash = $param->{hash};
return if (!defined($hash)); return if (!defined($hash));
if ($err) { if ($err) {
Log3 $hash, 3, "[$hash->{NAME}] got no weather info from yahoo. Error code: $err"; #Log3 $hash, 3, "[$hash->{NAME}] got no weather info from yahoo. Error code: $err";
#disabled due to yahoo
$result = undef; $result = undef;
} else { } else {
Log3 $hash, 4, "[$hash->{NAME}] got weather info from yahoo for $hash->{WEATHER}"; Log3 $hash, 4, "[$hash->{NAME}] got weather info from yahoo for $hash->{WEATHER}";
@ -423,49 +385,52 @@ sub Twilight_WeatherCallback(@) {
Twilight_getWeatherHorizon($hash, $result); Twilight_getWeatherHorizon($hash, $result);
#$hash->{CONDITION} = 50; #$hash->{CONDITION} = 50;
if ($hash->{CONDITION} == 50 && $hash->{VERSUCHE} <= 10) { ##repetition makes no longer sense...!
$hash->{VERSUCHE} += 1; #if ($hash->{CONDITION} == 50 && $hash->{VERSUCHE} <= 10) {
Twilight_RepeatTimerSet($hash, $param->{mode}); # $hash->{VERSUCHE} += 1;
return; # Twilight_RepeatTimerSet($hash, $param->{mode});
} # return;
#}
Twilight_TwilightTimes ($hash, $param->{mode}, $result); Twilight_TwilightTimes($hash, $param->{mode}, $result);
Log3 $hash, 3, "[$hash->{NAME}] " . ($hash->{VERSUCHE}+1) . " attempt(s) needed to get valid weather data from yahoo" if ($hash->{CONDITION} != 50 && $hash->{VERSUCHE} > 0); #Log3 $hash, 3, "[$hash->{NAME}] " . ($hash->{VERSUCHE}+1) . " attempt(s) needed to get valid weather data from yahoo" if ($hash->{CONDITION} != 50 && $hash->{VERSUCHE} > 0);
Log3 $hash, 3, "[$hash->{NAME}] " . ($hash->{VERSUCHE}+1) . " attempt(s) needed got NO valid weather data from yahoo" if ($hash->{CONDITION} == 50 && $hash->{VERSUCHE} > 0); #Log3 $hash, 3, "[$hash->{NAME}] " . ($hash->{VERSUCHE}+1) . " attempt(s) needed got NO valid weather data from yahoo" if ($hash->{CONDITION} == 50 && $hash->{VERSUCHE} > 0);
$hash->{VERSUCHE} = 0; #$hash->{VERSUCHE} = 0;
return Twilight_StandardTimerSet($hash);
Twilight_StandardTimerSet ($hash);
} }
################################################################################ ################################################################################
sub Twilight_RepeatTimerSet($$) { sub Twilight_RepeatTimerSet {
my ($hash, $mode) = @_; my $hash = shift;
my $mode = shift // return;
my $midnight = time() + 60; my $midnight = time() + 60;
myRemoveInternalTimer("Midnight", $hash); myRemoveInternalTimer("Midnight", $hash);
if ($mode eq "Mid") { return myInternalTimer ("Midnight", $midnight, "Twilight_Midnight", $hash, 0) if $mode eq "Mid";
myInternalTimer ("Midnight", $midnight, "Twilight_Midnight", $hash, 0);
} else {
myInternalTimer ("Midnight", $midnight, "Twilight_WeatherTimerUpdate", $hash, 0);
}
return myInternalTimer ("Midnight", $midnight, "Twilight_WeatherTimerUpdate", $hash, 0);
} }
################################################################################ ################################################################################
sub Twilight_StandardTimerSet($) { sub Twilight_StandardTimerSet {
my ($hash) = @_; my $hash = shift // return;
my $midnight = time() - Twilight_midnight_seconds(time()) + 24*3600 + 1; my $midnight = time() - Twilight_midnight_seconds(time()) + 24*3600 + 1;
myRemoveInternalTimer ("Midnight", $hash); myRemoveInternalTimer ("Midnight", $hash);
myInternalTimer ("Midnight", $midnight, "Twilight_Midnight", $hash, 0); myInternalTimer ("Midnight", $midnight, "Twilight_Midnight", $hash, 0);
Twilight_WeatherTimerSet ($hash); return Twilight_WeatherTimerSet($hash);
} }
################################################################################ ################################################################################
sub Twilight_WeatherTimerSet($) { sub Twilight_WeatherTimerSet {
my ($hash) = @_; my $hash = shift // return;
my $now = time(); my $now = time();
myRemoveInternalTimer ("weather", $hash); myRemoveInternalTimer ("weather", $hash);
foreach my $key ("sr_weather", "ss_weather") { for my $key ("sr_weather", "ss_weather") {
my $tim = $hash->{TW}{$key}{TIME}; my $tim = $hash->{TW}{$key}{TIME};
if ($tim-60*60>$now+60) { if ($tim-60*60>$now+60) {
myInternalTimer ("weather", $tim-60*60, "Twilight_WeatherTimerUpdate", $hash, 0); myInternalTimer ("weather", $tim-60*60, "Twilight_WeatherTimerUpdate", $hash, 0);
@ -474,17 +439,17 @@ sub Twilight_WeatherTimerSet($) {
} }
} }
################################################################################ ################################################################################
sub Twilight_sunposTimerSet($) { sub Twilight_sunposTimerSet {
my ($hash) = @_; my $hash = shift // return;
myRemoveInternalTimer ("sunpos", $hash);
myInternalTimer ("sunpos", time()+$hash->{SUNPOS_OFFSET}, "Twilight_sunpos", $hash, 0);
myRemoveInternalTimer("sunpos", $hash);
return myInternalTimer("sunpos", time()+$hash->{SUNPOS_OFFSET}, "Twilight_sunpos", $hash, 0);
} }
################################################################################ ################################################################################
sub Twilight_getWeatherHorizon(@) sub Twilight_getWeatherHorizon {
{ my $hash = shift;
my ($hash, $result) = @_; my $result = shift // return;
my $location=$hash->{WEATHER}; my $location=$hash->{WEATHER};
if ($location == 0) { if ($location == 0) {
@ -553,12 +518,12 @@ sub Twilight_getWeatherHorizon(@)
} }
return 1; return 1;
} }
################################################################################ ################################################################################
sub Twilight_sunpos($) sub Twilight_sunpos {
{ my $myHash = shift // return;
my ($myHash) = @_;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]); my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -660,8 +625,7 @@ sub Twilight_sunpos($)
} }
} }
$twilight_weather = 100 if ($twilight_weather>100); $twilight_weather = List::Util::min(100, List::Util::max($twilight_weather,0));
$twilight_weather = 0 if ($twilight_weather< 0);
# set readings # set readings
$dAzimuth = int(100*$dAzimuth )/100; $dAzimuth = int(100*$dAzimuth )/100;
@ -679,51 +643,33 @@ sub Twilight_sunpos($)
Twilight_sunposTimerSet($hash); Twilight_sunposTimerSet($hash);
return undef; return;
} }
################################################################################ ################################################################################
sub Twilight_CompassPoint($) { sub Twilight_CompassPoint {
my ($azimuth) = @_; my $azimuth = shift // return;
my $compassPoint = "unknown"; return "unknown" if !looks_like_number($azimuth) || $azimuth < 0;
return "north" if $azimuth < 22.5;
if ($azimuth < 22.5) { return "north-northeast" if $azimuth < 45;
$compassPoint = "north"; return "northeast" if $azimuth < 67.5;
} elsif ($azimuth < 45) { return "east-northeast" if $azimuth < 90;
$compassPoint = "north-northeast"; return "east" if $azimuth < 112.5;
} elsif ($azimuth < 67.5) { return "east-southeast" if $azimuth < 135;
$compassPoint = "northeast"; return "southeast" if $azimuth < 157.5;
} elsif ($azimuth < 90) { return "south-southeast" if $azimuth < 180;
$compassPoint = "east-northeast"; return "south" if $azimuth < 202.5;
} elsif ($azimuth < 112.5){ return "south-southwest" if $azimuth < 225;
$compassPoint = "east"; return "southwest" if $azimuth < 247.5;
} elsif ($azimuth < 135) { return "west-southwest" if $azimuth < 270;
$compassPoint = "east-southeast"; return "west" if $azimuth < 292.5;
} elsif ($azimuth < 157.5){ return "west-northwest" if $azimuth < 315;
$compassPoint = "southeast"; return "northwest" if $azimuth < 337.5;
} elsif ($azimuth < 180) { return "north-northwest" if $azimuth <= 361;
$compassPoint = "south-southeast"; return "unknown";
} elsif ($azimuth < 202.5){
$compassPoint = "south";
} elsif ($azimuth < 225) {
$compassPoint = "south-southwest";
} elsif ($azimuth < 247.5){
$compassPoint = "southwest";
} elsif ($azimuth < 270) {
$compassPoint = "west-southwest";
} elsif ($azimuth < 292.5){
$compassPoint = "west";
} elsif ($azimuth < 315) {
$compassPoint = "west-northwest";
} elsif ($azimuth < 337.5){
$compassPoint = "northwest";
} elsif ($azimuth <= 361) {
$compassPoint = "north-northwest";
}
return $compassPoint;
} }
sub twilight($$$$) { sub twilight {
my ($twilight, $reading, $min, $max) = @_; my ($twilight, $reading, $min, $max) = @_;
my $t = hms2h(ReadingsVal($twilight,$reading,0)); my $t = hms2h(ReadingsVal($twilight,$reading,0));
@ -738,25 +684,27 @@ sub twilight($$$$) {
=pod =pod
=item device =item device
=item summary delivers twilight and other sun related events for use in notify =item summary generate twilight & sun related events; check alternative Astro.
=item summary_DE liefert Dämmerungs Sonnen basierte Ereignisse, für notify =item summary_DE liefert Dämmerungs Sonnen basierte Events. Alternative: Astro
=begin html =begin html
<a name="Twilight"></a> <a name="Twilight"></a>
<h3>Twilight</h3> <h3>Twilight</h3>
<ul> <ul>
<br> <br>
<a name="Twilightgeneral"></a>
<b>General Remarks</b><br>
This module profited much from the use of the yahoo weather API. Unfortunately, this service is no longer available, so Twilight functionality is very limited nowerdays. To some extend, the use of <a href="#Twilightattr">useExtWeather</a> may compensate to dect cloudy skys. If you just want to have astronomical data available, consider using Astro instead.<br><br>
<a name="Twilightdefine"></a> <a name="Twilightdefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define &lt;name&gt; Twilight &lt;latitude&gt; &lt;longitude&gt; [&lt;indoor_horizon&gt; [&lt;Weather_Position&gt;]]</code><br> <code>define &lt;name&gt; Twilight [&lt;latitude&gt; &lt;longitude&gt; [&lt;indoor_horizon&gt; [&lt;Weather_Position&gt;]]]</code><br>
<br> <br>
Defines a virtual device for Twilight calculations <br><br> Defines a virtual device for Twilight calculations <br><br>
<b>latitude, longitude</b> <b>latitude, longitude</b>
<br> <br>
The parameters <b>latitude</b> and <b>longitude</b> are decimal numbers which give the position on earth for which the twilight states shall be calculated. The parameters <b>latitude</b> and <b>longitude</b> are decimal numbers which give the position on earth for which the twilight states shall be calculated. They are optional, if not set, global values will be used instead (global itself defaults to Frankfurt/Main).
<br><br> <br><br>
<b>indoor_horizon</b> <b>indoor_horizon</b>
<br> <br>
@ -767,7 +715,8 @@ sub twilight($$$$) {
<br> <br>
The parameter <b>Weather_Position</b> is the yahoo weather id used for getting the weather condition. Go to http://weather.yahoo.com/ and enter a city or zip code. In the upcoming webpage, the id is a the end of the URL. Example: Munich, Germany -> 676757 The parameter <b>Weather_Position</b> is the yahoo weather id used for getting the weather condition. Go to http://weather.yahoo.com/ and enter a city or zip code. In the upcoming webpage, the id is a the end of the URL. Example: Munich, Germany -> 676757
<br><br> <br><br>
NOTE: As yahoo weather service is no longer available, this setting will not be used any longer; consider using useExtWeather attribute to partly compensate.
<br>
A Twilight device periodically calculates the times of different twilight phases throughout the day. A Twilight device periodically calculates the times of different twilight phases throughout the day.
It calculates a virtual "light" element, that gives an indicator about the amount of the current daylight. It calculates a virtual "light" element, that gives an indicator about the amount of the current daylight.
Besides the location on earth it is influenced by a so called "indoor horizon" (e.g. if there are high buildings, mountains) as well as by weather conditions. Very bad weather conditions lead to a reduced daylight for nearly the whole day. Besides the location on earth it is influenced by a so called "indoor horizon" (e.g. if there are high buildings, mountains) as well as by weather conditions. Very bad weather conditions lead to a reduced daylight for nearly the whole day.
@ -885,18 +834,21 @@ Example:
<a name="Twilight"></a> <a name="Twilight"></a>
<h3>Twilight</h3> <h3>Twilight</h3>
<ul> <ul>
<b>Akkgemeine Hinweise</b><br>
Dieses Modul nutzte früher Daten von der Yahoo Wetter API. Diese ist leider nicht mehr verfügbar, daher ist die heutige Funktionalität deutlich eingeschränkt. Dies kann zu einem gewissen Grad kompensiert werden, indem man <a href="#Twilightattr">useExtWeather</a> setzt, um Bedeckungsgrade mit Wolken zu berücksichtigen. Falls Sie nur Astronomische Daten benötigen, wäre Astro hierfür eine genauere Alternative.<br><br>
<br> <br>
<a name="Twilightdefine"></a> <a name="Twilightdefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define &lt;name&gt; Twilight &lt;latitude&gt; &lt;longitude&gt; [&lt;indoor_horizon&gt; [&lt;Weather_Position&gt;]]</code><br> <code>define &lt;name&gt; Twilight [&lt;latitude&gt; &lt;longitude&gt; [&lt;indoor_horizon&gt; [&lt;Weather_Position&gt;]]]</code><br>
<br> <br>
Erstellt ein virtuelles Device f&uuml;r die D&auml;mmerungsberechnung (Zwielicht)<br><br> Erstellt ein virtuelles Device f&uuml;r die D&auml;mmerungsberechnung (Zwielicht)<br><br>
<b>latitude, longitude (geografische L&auml;nge & Breite)</b> <b>latitude, longitude (geografische L&auml;nge & Breite)</b>
<br> <br>
Die Parameter <b>latitude</b> und <b>longitude</b> sind Dezimalzahlen welche die Position auf der Erde bestimmen, f&uuml;r welche der Dämmerungs-Status berechnet werden soll. Die Parameter <b>latitude</b> und <b>longitude</b> sind Dezimalzahlen welche die Position auf der Erde bestimmen, f&uuml;r welche der Dämmerungs-Status berechnet werden soll. Sie sind optional, wenn nicht vorhanden, werden die Angaben in global berücksichtigt, bzw. ohne weitere Angaben die Daten von Frankfurt/Main.
<br><br> <br><br>
<b>indoor_horizon</b> <b>indoor_horizon</b>
<br> <br>
@ -907,7 +859,7 @@ Example:
<br> <br>
Der Parameter <b>Weather_Position</b> ist die Yahoo! Wetter-ID welche f&uuml;r den Bezug der Wetterinformationen gebraucht wird. Gehe auf http://weather.yahoo.com/ und gebe einen Ort (ggf. PLZ) ein. In der URL der daraufhin geladenen Seite ist an letzter Stelle die ID. Beispiel: München, Deutschland -> 676757 Der Parameter <b>Weather_Position</b> ist die Yahoo! Wetter-ID welche f&uuml;r den Bezug der Wetterinformationen gebraucht wird. Gehe auf http://weather.yahoo.com/ und gebe einen Ort (ggf. PLZ) ein. In der URL der daraufhin geladenen Seite ist an letzter Stelle die ID. Beispiel: München, Deutschland -> 676757
<br><br> <br><br>
Hinweis: Da der Yahoo-Wetterdienst nicht mehr zur Verfügung steht, ist dieses Attribut nutzlos. Siehe useExtWeather als Alternative.<br>
Ein Twilight-Device berechnet periodisch die D&auml;mmerungszeiten und -phasen w&auml;hrend des Tages. Ein Twilight-Device berechnet periodisch die D&auml;mmerungszeiten und -phasen w&auml;hrend des Tages.
Es berechnet ein virtuelles "Licht"-Element das einen Indikator f&uuml;r die momentane Tageslichtmenge ist. Es berechnet ein virtuelles "Licht"-Element das einen Indikator f&uuml;r die momentane Tageslichtmenge ist.
Neben der Position auf der Erde wird es vom sog. "indoor horizon" (Beispielsweise hohe Geb&auml;de oder Berge) Neben der Position auf der Erde wird es vom sog. "indoor horizon" (Beispielsweise hohe Geb&auml;de oder Berge)

View File

@ -303,7 +303,7 @@ FHEM/59_HCS.pm hjr Automatisierung (oder auch PM)
FHEM/59_LuftdatenInfo igami Bastelecke FHEM/59_LuftdatenInfo igami Bastelecke
FHEM/59_OPENWEATHER.pm tupol Unterstützende Dienste/Wettermodule (Link als PM an tupol) FHEM/59_OPENWEATHER.pm tupol Unterstützende Dienste/Wettermodule (Link als PM an tupol)
FHEM/59_PROPLANTA.pm tupol Unterstützende Dienste/Wettermodule (Link als PM an tupol) FHEM/59_PROPLANTA.pm tupol Unterstützende Dienste/Wettermodule (Link als PM an tupol)
FHEM/59_Twilight.pm rudolfkoenig Unterstützende Dienste/Wettermodule FHEM/59_Twilight.pm Beta-User/orphan https://forum.fhem.de/index.php/topic,114061.0.html
FHEM/59_Weather.pm neubert Unterstützende Dienste/Wettermodule FHEM/59_Weather.pm neubert Unterstützende Dienste/Wettermodule
FHEM/59_Wunderground.pm loredo (deprecated) FHEM/59_Wunderground.pm loredo (deprecated)
FHEM/59_WUup.pm mahowi Unterstützende Dienste/Wettermodule FHEM/59_WUup.pm mahowi Unterstützende Dienste/Wettermodule
@ -605,7 +605,7 @@ lib/FHEM/SynoModules/API.pm DS_Starter Sonstiges
lib/FHEM/SynoModules/SMUtils.pm DS_Starter Sonstiges lib/FHEM/SynoModules/SMUtils.pm DS_Starter Sonstiges
lib/FHEM/SynoModules/ErrCodes.pm DS_Starter Sonstiges lib/FHEM/SynoModules/ErrCodes.pm DS_Starter Sonstiges
contrib/sacha_gloor/* rudolfkoenig Sonstiges contrib/sacha_gloor/* rudolfkoenig/orphan Sonstiges
contrib/70_ONKYO_AVR_PULL.pm loredo (deprecated) contrib/70_ONKYO_AVR_PULL.pm loredo (deprecated)
contrib/DS_Starter/* DS_Starter Sonstiges contrib/DS_Starter/* DS_Starter Sonstiges
contrib/98_EDIPLUG.pm Wzut Sonstige Systeme contrib/98_EDIPLUG.pm Wzut Sonstige Systeme