new OpenWeatherMapAPI onecall v3 Support
This commit is contained in:
parent
714c95d6d0
commit
ddefbac55a
@ -269,8 +269,9 @@ sub Weather_Initialize($) {
|
|||||||
$hash->{SetFn} = 'Weather_Set';
|
$hash->{SetFn} = 'Weather_Set';
|
||||||
$hash->{AttrList} =
|
$hash->{AttrList} =
|
||||||
'disable:0,1 '
|
'disable:0,1 '
|
||||||
. 'forecast:hourly,daily,every,off '
|
. 'forecast:multiple-strict,hourly,daily '
|
||||||
. 'forecastLimit '
|
. 'forecastLimit '
|
||||||
|
. 'alerts:0,1 '
|
||||||
. $readingFnAttributes;
|
. $readingFnAttributes;
|
||||||
$hash->{NotifyFn} = 'Weather_Notify';
|
$hash->{NotifyFn} = 'Weather_Notify';
|
||||||
|
|
||||||
@ -328,7 +329,12 @@ sub Weather_RetrieveCallbackFn($) {
|
|||||||
|
|
||||||
sub Weather_WriteReadings($$) {
|
sub Weather_WriteReadings($$) {
|
||||||
my ( $hash, $dataRef ) = @_;
|
my ( $hash, $dataRef ) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
my $hourly = ( AttrVal( $name, 'forecast', '' ) =~ m{hourly}xms ? 1: 0 );
|
||||||
|
my $daily = ( AttrVal( $name, 'forecast', '' ) =~ m{daily}xms ? 1 : 0 );
|
||||||
|
my $alerts = ( AttrVal( $name, 'forecast', '' ) =~ m{alerts}xms ? 1 : 0 );
|
||||||
|
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
# delete some unused readings
|
# delete some unused readings
|
||||||
@ -381,16 +387,15 @@ sub Weather_WriteReadings($$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
### forecast
|
### forecast
|
||||||
if ( ref( $dataRef->{forecast} ) eq 'HASH'
|
if ( ref( $dataRef->{forecast} ) eq 'HASH'
|
||||||
and AttrVal( $name, 'forecast', 'every' ) ne 'off' )
|
and ($hourly or $daily) )
|
||||||
{
|
{
|
||||||
## hourly
|
## hourly
|
||||||
if (
|
if (
|
||||||
defined( $dataRef->{forecast}->{hourly} )
|
defined( $dataRef->{forecast}->{hourly} )
|
||||||
and ref( $dataRef->{forecast}->{hourly} ) eq 'ARRAY'
|
and ref( $dataRef->{forecast}->{hourly} ) eq 'ARRAY'
|
||||||
and scalar( @{ $dataRef->{forecast}->{hourly} } ) > 0
|
and scalar( @{ $dataRef->{forecast}->{hourly} } ) > 0
|
||||||
and ( AttrVal( $name, 'forecast', 'every' ) eq 'every'
|
and $hourly
|
||||||
or AttrVal( $name, 'forecast', 'hourly' ) eq 'hourly' )
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
my $i = 0;
|
my $i = 0;
|
||||||
@ -445,8 +450,7 @@ sub Weather_WriteReadings($$) {
|
|||||||
defined( $dataRef->{forecast}->{daily} )
|
defined( $dataRef->{forecast}->{daily} )
|
||||||
and ref( $dataRef->{forecast}->{daily} ) eq 'ARRAY'
|
and ref( $dataRef->{forecast}->{daily} ) eq 'ARRAY'
|
||||||
and scalar( @{ $dataRef->{forecast}->{daily} } ) > 0
|
and scalar( @{ $dataRef->{forecast}->{daily} } ) > 0
|
||||||
and ( AttrVal( $name, 'forecast', 'every' ) eq 'every'
|
and $daily
|
||||||
or AttrVal( $name, 'forecast', 'daily' ) eq 'daily' )
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
my $i = 0;
|
my $i = 0;
|
||||||
@ -496,6 +500,16 @@ sub Weather_WriteReadings($$) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ref( $dataRef->{alerts} ) eq 'HASH'
|
||||||
|
and $alerts )
|
||||||
|
{
|
||||||
|
while ( my ( $r, $v ) = each %{ $dataRef->{alerts} } ) {
|
||||||
|
readingsBulkUpdate( $hash, $r, $v )
|
||||||
|
if ( ref( $dataRef->{$r} ) ne 'HASH'
|
||||||
|
and ref( $dataRef->{$r} ) ne 'ARRAY' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $val = 'T: '
|
my $val = 'T: '
|
||||||
. $dataRef->{current}->{temperature} . ' °C' . ' '
|
. $dataRef->{current}->{temperature} . ' °C' . ' '
|
||||||
. substr( $status_items_txt_i18n{1}, 0, 1 ) . ': '
|
. substr( $status_items_txt_i18n{1}, 0, 1 ) . ': '
|
||||||
@ -529,7 +543,7 @@ sub Weather_GetUpdate($) {
|
|||||||
Weather_RearmTimer( $hash, gettimeofday() + $hash->{INTERVAL} );
|
Weather_RearmTimer( $hash, gettimeofday() + $hash->{INTERVAL} );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Weather_RetrieveData($name, 0);
|
$hash->{fhem}->{api}->{exclude} = Weather_parseForcastAttr($hash);
|
||||||
$hash->{fhem}->{api}->setRetrieveData;
|
$hash->{fhem}->{api}->setRetrieveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,6 +551,20 @@ sub Weather_GetUpdate($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
|
sub Weather_parseForcastAttr {
|
||||||
|
my $hash = shift;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my @exclude = qw 'alerts minutely hourly daily';
|
||||||
|
my @forecast = split(',',AttrVal($name,'forcast','') . (AttrVal($name,'alerts',0) ? ',alerts' : ''));
|
||||||
|
my %exclude =();
|
||||||
|
|
||||||
|
@exclude{@exclude} = @exclude;
|
||||||
|
delete @exclude{@forecast};
|
||||||
|
|
||||||
|
return join(',',keys %exclude);
|
||||||
|
}
|
||||||
|
|
||||||
sub Weather_Get($@) {
|
sub Weather_Get($@) {
|
||||||
my ( $hash, @a ) = @_;
|
my ( $hash, @a ) = @_;
|
||||||
|
|
||||||
@ -712,6 +740,7 @@ sub Weather_Define($$) {
|
|||||||
location => $hash->{fhem}->{LOCATION},
|
location => $hash->{fhem}->{LOCATION},
|
||||||
apioptions => $hash->{APIOPTIONS},
|
apioptions => $hash->{APIOPTIONS},
|
||||||
language => $hash->{LANG}
|
language => $hash->{LANG}
|
||||||
|
exclude => Weather_parseForcastAttr($hash),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1373,7 +1402,7 @@ sub WeatherCheckOptions($@) {
|
|||||||
],
|
],
|
||||||
"release_status": "stable",
|
"release_status": "stable",
|
||||||
"license": "GPL_2",
|
"license": "GPL_2",
|
||||||
"version": "v2.1.4",
|
"version": "v2.2.5",
|
||||||
"author": [
|
"author": [
|
||||||
"Marko Oldenburg <leongaultier@gmail.com>"
|
"Marko Oldenburg <leongaultier@gmail.com>"
|
||||||
],
|
],
|
||||||
|
@ -118,7 +118,7 @@ eval { use Readonly; 1 }
|
|||||||
|
|
||||||
Readonly my $URL => 'https://api.openweathermap.org/data/2.5/';
|
Readonly my $URL => 'https://api.openweathermap.org/data/2.5/';
|
||||||
## URL . 'weather?' for current data
|
## URL . 'weather?' for current data
|
||||||
## URL . 'forecast?' for forecast data
|
## URL . 'onecall?' for forecast data
|
||||||
|
|
||||||
my %codes = (
|
my %codes = (
|
||||||
200 => 45,
|
200 => 45,
|
||||||
@ -194,6 +194,7 @@ sub new {
|
|||||||
long => ( split( ',', $argsRef->{location} ) )[1],
|
long => ( split( ',', $argsRef->{location} ) )[1],
|
||||||
fetchTime => 0,
|
fetchTime => 0,
|
||||||
endpoint => 'none',
|
endpoint => 'none',
|
||||||
|
exclude => $argsRef->{exclude},
|
||||||
};
|
};
|
||||||
|
|
||||||
$self->{cachemaxage} = (
|
$self->{cachemaxage} = (
|
||||||
@ -201,8 +202,9 @@ sub new {
|
|||||||
? $apioptions->{cachemaxage}
|
? $apioptions->{cachemaxage}
|
||||||
: 900
|
: 900
|
||||||
);
|
);
|
||||||
$self->{cached} = _CreateForecastRef($self);
|
|
||||||
|
|
||||||
|
$self->{cached} = _CreateForecastRef($self);
|
||||||
|
|
||||||
bless $self, $class;
|
bless $self, $class;
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
@ -315,7 +317,8 @@ sub _RetrieveDataFromOpenWeatherMap {
|
|||||||
. $self->{long} . '&'
|
. $self->{long} . '&'
|
||||||
. 'APPID='
|
. 'APPID='
|
||||||
. $self->{key} . '&' . 'lang='
|
. $self->{key} . '&' . 'lang='
|
||||||
. $self->{lang};
|
. $self->{lang} . '&' . 'exclude='
|
||||||
|
. $self->{exclude};
|
||||||
|
|
||||||
::HttpUtils_NonblockingGet($paramRef);
|
::HttpUtils_NonblockingGet($paramRef);
|
||||||
}
|
}
|
||||||
@ -369,7 +372,8 @@ sub _ProcessingRetrieveData {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
### Debug
|
### Debug
|
||||||
# print 'Response: ' . Dumper $data;
|
# print '!!! DEBUG !!! - Endpoint: ' . $self->{endpoint} . "\n";
|
||||||
|
# print '!!! DEBUG !!! - Response: ' . Dumper $data;
|
||||||
###### Ab hier wird die ResponseHash Referenze für die Rückgabe zusammen gestellt
|
###### Ab hier wird die ResponseHash Referenze für die Rückgabe zusammen gestellt
|
||||||
$self->{cached}->{current_date_time} =
|
$self->{cached}->{current_date_time} =
|
||||||
strftimeWrapper( "%a, %e %b %Y %H:%M",
|
strftimeWrapper( "%a, %e %b %Y %H:%M",
|
||||||
@ -489,7 +493,7 @@ sub _ProcessingRetrieveData {
|
|||||||
"%.1f",
|
"%.1f",
|
||||||
(
|
(
|
||||||
$data->{hourly}->[$i]
|
$data->{hourly}->[$i]
|
||||||
->{main}->{temp} - 273.15
|
->{temp} - 273.15
|
||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
@ -498,52 +502,12 @@ sub _ProcessingRetrieveData {
|
|||||||
"%.1f",
|
"%.1f",
|
||||||
(
|
(
|
||||||
$data->{hourly}->[$i]
|
$data->{hourly}->[$i]
|
||||||
->{main}->{temp} - 273.15
|
->{temp} - 273.15
|
||||||
)
|
|
||||||
) + 0.5
|
|
||||||
),
|
|
||||||
'low_c' => int(
|
|
||||||
sprintf(
|
|
||||||
"%.1f",
|
|
||||||
(
|
|
||||||
$data->{hourly}->[$i]
|
|
||||||
->{main}->{temp_min} -
|
|
||||||
273.15
|
|
||||||
)
|
|
||||||
) + 0.5
|
|
||||||
),
|
|
||||||
'high_c' => int(
|
|
||||||
sprintf(
|
|
||||||
"%.1f",
|
|
||||||
(
|
|
||||||
$data->{hourly}->[$i]
|
|
||||||
->{main}->{temp_max} -
|
|
||||||
273.15
|
|
||||||
)
|
|
||||||
) + 0.5
|
|
||||||
),
|
|
||||||
'tempLow' => int(
|
|
||||||
sprintf(
|
|
||||||
"%.1f",
|
|
||||||
(
|
|
||||||
$data->{hourly}->[$i]
|
|
||||||
->{main}->{temp_min} -
|
|
||||||
273.15
|
|
||||||
)
|
|
||||||
) + 0.5
|
|
||||||
),
|
|
||||||
'tempHigh' => int(
|
|
||||||
sprintf(
|
|
||||||
"%.1f",
|
|
||||||
(
|
|
||||||
$data->{hourly}->[$i]
|
|
||||||
->{main}->{temp_max} -
|
|
||||||
273.15
|
|
||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
'humidity' =>
|
'humidity' =>
|
||||||
$data->{hourly}->[$i]->{main}
|
$data->{hourly}->[$i]
|
||||||
->{humidity},
|
->{humidity},
|
||||||
'condition' => encode_utf8(
|
'condition' => encode_utf8(
|
||||||
$data->{hourly}->[$i]->{weather}
|
$data->{hourly}->[$i]->{weather}
|
||||||
@ -551,7 +515,7 @@ sub _ProcessingRetrieveData {
|
|||||||
),
|
),
|
||||||
'pressure' => int(
|
'pressure' => int(
|
||||||
sprintf( "%.1f",
|
sprintf( "%.1f",
|
||||||
$data->{hourly}->[$i]->{main}
|
$data->{hourly}->[$i]
|
||||||
->{pressure} ) + 0.5
|
->{pressure} ) + 0.5
|
||||||
),
|
),
|
||||||
'wind' => int(
|
'wind' => int(
|
||||||
@ -559,7 +523,7 @@ sub _ProcessingRetrieveData {
|
|||||||
"%.1f",
|
"%.1f",
|
||||||
(
|
(
|
||||||
$data->{hourly}->[$i]
|
$data->{hourly}->[$i]
|
||||||
->{wind}->{speed} * 3.6
|
->{wind_speed} * 3.6
|
||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
@ -568,7 +532,7 @@ sub _ProcessingRetrieveData {
|
|||||||
"%.1f",
|
"%.1f",
|
||||||
(
|
(
|
||||||
$data->{hourly}->[$i]
|
$data->{hourly}->[$i]
|
||||||
->{wind}->{speed} * 3.6
|
->{wind_speed} * 3.6
|
||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
@ -577,13 +541,13 @@ sub _ProcessingRetrieveData {
|
|||||||
"%.1f",
|
"%.1f",
|
||||||
(
|
(
|
||||||
$data->{hourly}->[$i]
|
$data->{hourly}->[$i]
|
||||||
->{wind}->{gust} * 3.6
|
->{wind_gust} * 3.6
|
||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
'cloudCover' =>
|
'cloudCover' =>
|
||||||
$data->{hourly}->[$i]->{clouds}
|
$data->{hourly}->[$i]
|
||||||
->{all},
|
->{clouds},
|
||||||
'code' => $codes{
|
'code' => $codes{
|
||||||
$data->{hourly}->[$i]->{weather}
|
$data->{hourly}->[$i]->{weather}
|
||||||
->[0]->{id}
|
->[0]->{id}
|
||||||
@ -592,13 +556,9 @@ sub _ProcessingRetrieveData {
|
|||||||
$data->{hourly}->[$i]->{weather}->[0]
|
$data->{hourly}->[$i]->{weather}->[0]
|
||||||
->{icon},
|
->{icon},
|
||||||
'rain1h' =>
|
'rain1h' =>
|
||||||
$data->{hourly}->[$i]->{rain}->{'1h'},
|
$data->{hourly}->[$i]->{rain}->{'1h'},
|
||||||
'rain3h' =>
|
|
||||||
$data->{hourly}->[$i]->{rain}->{'3h'},
|
|
||||||
'snow1h' =>
|
'snow1h' =>
|
||||||
$data->{hourly}->[$i]->{snow}->{'1h'},
|
$data->{hourly}->[$i]->{snow}->{'1h'},
|
||||||
'snow3h' =>
|
|
||||||
$data->{hourly}->[$i]->{snow}->{'3h'},
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -673,6 +633,69 @@ sub _ProcessingRetrieveData {
|
|||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
|
'temperature_morn' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{temp}->{morn} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
|
'temperature_eve' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{temp}->{eve} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
|
'temperature_night' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{temp}->{night} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
|
'tempFeelsLike_morn' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{feels_like}->{morn} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
|
'tempFeelsLike_eve' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{feels_like}->{eve} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
|
'tempFeelsLike_night' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{feels_like}->{night} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
|
'tempFeelsLike_day' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]
|
||||||
|
->{feels_like}->{day} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
'temp_c' => int(
|
'temp_c' => int(
|
||||||
sprintf(
|
sprintf(
|
||||||
"%.1f",
|
"%.1f",
|
||||||
@ -718,6 +741,14 @@ sub _ProcessingRetrieveData {
|
|||||||
)
|
)
|
||||||
) + 0.5
|
) + 0.5
|
||||||
),
|
),
|
||||||
|
'dew_point' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{daily}->[$i]->{dew_point} - 273.15
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
'humidity' =>
|
'humidity' =>
|
||||||
$data->{daily}->[$i]->{humidity},
|
$data->{daily}->[$i]->{humidity},
|
||||||
'condition' => encode_utf8(
|
'condition' => encode_utf8(
|
||||||
@ -783,6 +814,47 @@ sub _ProcessingRetrieveData {
|
|||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ref( $data->{alerts} ) eq "ARRAY"
|
||||||
|
&& scalar( @{ $data->{alerts} } ) > 0 )
|
||||||
|
{
|
||||||
|
## löschen des alten Datensatzes
|
||||||
|
delete $self->{cached}->{alerts};
|
||||||
|
|
||||||
|
my $i = 0;
|
||||||
|
for ( @{ $data->{alerts} } ) {
|
||||||
|
push(
|
||||||
|
@{ $self->{cached}->{alerts} },
|
||||||
|
{
|
||||||
|
'warn_'.$i.'_End' => strftimeWrapper(
|
||||||
|
"%a, %e %b %Y %H:%M",
|
||||||
|
localtime(
|
||||||
|
( $data->{alerts}->[$i]->{end} )
|
||||||
|
- 3600
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'warn_'.$i.'_Start' => strftimeWrapper(
|
||||||
|
"%a, %e %b %Y %H:%M",
|
||||||
|
localtime(
|
||||||
|
( $data->{alerts}->[$i]->{start} )
|
||||||
|
- 3600
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'warn_'.$i.'_Description' => encode_utf8(
|
||||||
|
$data->{alerts}->[$i]->{description}
|
||||||
|
),
|
||||||
|
'warn_'.$i.'_SenderName' => encode_utf8(
|
||||||
|
$data->{alerts}->[$i]->{sender_name}
|
||||||
|
),
|
||||||
|
'warn_'.$i.'_Event' => encode_utf8(
|
||||||
|
$data->{alerts}->[$i]->{event}
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1523
fhem-2022-11.log
1523
fhem-2022-11.log
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user