Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
00c0a2a87e | |||
0a47226436 | |||
e9fb9357a9 | |||
ce875a8beb | |||
d0157fb2c7 | |||
eb134a19e9 | |||
cfd255569f | |||
b1de4b52da | |||
6b6c066a9b | |||
530fc01d57 | |||
7d7cbef4ed | |||
8b9bbd4f98 | |||
2a06821252 | |||
9868f74a86 | |||
d2e93a6d5a | |||
c27d51534c | |||
5bfd1c49d9 | |||
0f1af75a9e | |||
70a402f096 | |||
245fc455e1 | |||
1683fab2d4 | |||
33763032c6 | |||
2afb98f9b9 | |||
38091aacd1 | |||
30dd03cbea | |||
43e3fcb237 | |||
5f611555e3 | |||
a3fa194cdd | |||
baa48a79a4 | |||
2601a42643 | |||
cfd8ff9ea1 | |||
be3352e462 | |||
fb5087803b |
123
CHANGELOG.md
123
CHANGELOG.md
@ -1,4 +1,123 @@
|
|||||||
### build: v2.2.22 (HEAD -> patch-package)
|
### docs: change versions and add copyright (HEAD -> patch-fixforecast)
|
||||||
|
>Fri, 11 Oct 2024 12:04:07 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### docs: Changelog (origin/patch-fixforecast)
|
||||||
|
>Fri, 11 Oct 2024 07:07:57 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
[Ticket: no]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### fix: Update forecast with cachemaxage after API calls are down. special thanks to stefanru (forum)
|
||||||
|
>Fri, 11 Oct 2024 06:59:53 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
[Ticket: no]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### test: add new CHANGELOG
|
||||||
|
>Sat, 21 Oct 2023 08:59:11 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### feat: new reading owmAPICode for original code
|
||||||
|
>Tue, 11 Jul 2023 14:10:13 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
[Ticket: no]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### feat: add human-readable text of daily forecast
|
||||||
|
>Tue, 6 Jun 2023 08:35:06 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
add the proper human-readable text description of the daily forecast
|
||||||
|
|
||||||
|
[Ticket: no]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### add temperatur reading and fix weblink
|
||||||
|
>Tue, 23 May 2023 08:08:42 +0200
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (oldenburg@b1-systems.de)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (oldenburg@b1-systems.de)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### fix: missing perl modules
|
||||||
|
>Sun, 5 Feb 2023 09:26:04 +0100
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### fix: failed then Readonly is missing
|
||||||
|
>Sun, 5 Feb 2023 09:20:20 +0100
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### fix: : Undefined subroutine
|
||||||
|
>Thu, 2 Feb 2023 22:58:40 +0100
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
&FHEM::Core::Weather::DeleteForecastreadings
|
||||||
|
|
||||||
|
[Ticket: #46]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### docs: add new entry in CHANGELOG.md (tag: v2.2.22)
|
||||||
|
>Tue, 10 Jan 2023 21:44:20 +0100
|
||||||
|
|
||||||
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
>Commiter: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### build: v2.2.22
|
||||||
>Tue, 10 Jan 2023 21:43:26 +0100
|
>Tue, 10 Jan 2023 21:43:26 +0100
|
||||||
|
|
||||||
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
@ -8,7 +127,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### docs: add new modul path in to pre-commit (origin/patch-package)
|
### docs: add new modul path in to pre-commit
|
||||||
>Tue, 10 Jan 2023 21:37:10 +0100
|
>Tue, 10 Jan 2023 21:37:10 +0100
|
||||||
|
|
||||||
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
>Author: Marko Oldenburg (fhemdevelopment@cooltux.net)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -2,12 +2,13 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# 59_Weather.pm
|
# 59_Weather.pm
|
||||||
# (c) 2009-2023 Copyright by Dr. Boris Neubert
|
# (c) 2009-2024 Copyright by Dr. Boris Neubert
|
||||||
# e-mail: omega at online dot de
|
# e-mail: omega at online dot de
|
||||||
#
|
#
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# - Marko Oldenburg (CoolTux)
|
# - Marko Oldenburg (CoolTux)
|
||||||
# - Lippie
|
# - Lippie
|
||||||
|
# - stefanru (wundergroundAPI)
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# This file is part of fhem.
|
# This file is part of fhem.
|
||||||
@ -543,7 +544,7 @@ __END__
|
|||||||
],
|
],
|
||||||
"release_status": "stable",
|
"release_status": "stable",
|
||||||
"license": "GPL_2",
|
"license": "GPL_2",
|
||||||
"version": "v2.2.22",
|
"version": "v2.2.30",
|
||||||
"author": [
|
"author": [
|
||||||
"Marko Oldenburg <fhemdevelopment@cooltux.net>"
|
"Marko Oldenburg <fhemdevelopment@cooltux.net>"
|
||||||
],
|
],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
UPD 2023-01-10_21:41:34 25809 FHEM/59_Weather.pm
|
UPD 2024-10-11_12:02:22 25848 FHEM/59_Weather.pm
|
||||||
UPD 2023-01-10_21:20:58 33948 lib/FHEM/Core/Weather.pm
|
UPD 2024-10-11_11:59:21 34293 lib/FHEM/Core/Weather.pm
|
||||||
UPD 2023-01-10_21:25:52 50106 lib/FHEM/APIs/Weather/DarkSkyAPI.pm
|
UPD 2023-01-29_16:14:48 50106 lib/FHEM/APIs/Weather/DarkSkyAPI.pm
|
||||||
UPD 2023-01-10_21:25:49 33422 lib/FHEM/APIs/Weather/OpenWeatherMapAPI.pm
|
UPD 2023-07-11_14:08:00 33779 lib/FHEM/APIs/Weather/OpenWeatherMapAPI.pm
|
||||||
UPD 2023-01-10_21:25:53 36101 lib/FHEM/APIs/Weather/wundergroundAPI.pm
|
UPD 2024-10-11_12:02:42 37627 lib/FHEM/APIs/Weather/wundergroundAPI.pm
|
||||||
|
@ -591,6 +591,7 @@ sub _FillSelfHashWithWeatherResponseForWeatherCurrent {
|
|||||||
'wind_direction' => $data->{wind}->{deg},
|
'wind_direction' => $data->{wind}->{deg},
|
||||||
'cloudCover' => $data->{clouds}->{all},
|
'cloudCover' => $data->{clouds}->{all},
|
||||||
'code' => $codes{ $data->{weather}->[0]->{id} },
|
'code' => $codes{ $data->{weather}->[0]->{id} },
|
||||||
|
'owmAPICode' => $data->{weather}->[0]->{id},
|
||||||
'iconAPI' => $data->{weather}->[0]->{icon},
|
'iconAPI' => $data->{weather}->[0]->{icon},
|
||||||
'sunsetTime' => _strftimeWrapper(
|
'sunsetTime' => _strftimeWrapper(
|
||||||
"%a, %e %b %Y %H:%M",
|
"%a, %e %b %Y %H:%M",
|
||||||
@ -670,8 +671,9 @@ sub _FillSelfHashWithWeatherResponseForForecastHourly {
|
|||||||
),
|
),
|
||||||
'cloudCover' => $data->{list}->[$i]->{clouds}->{all},
|
'cloudCover' => $data->{list}->[$i]->{clouds}->{all},
|
||||||
'code' => $codes{ $data->{list}->[$i]->{weather}->[0]->{id} },
|
'code' => $codes{ $data->{list}->[$i]->{weather}->[0]->{id} },
|
||||||
'iconAPI' => $data->{list}->[$i]->{weather}->[0]->{icon},
|
'owmAPICode' => $data->{list}->[$i]->{weather}->[0]->{id},
|
||||||
'rain1h' => (
|
'iconAPI' => $data->{list}->[$i]->{weather}->[0]->{icon},
|
||||||
|
'rain1h' => (
|
||||||
$data->{list}->[$i]->{rain}->{'1h'}
|
$data->{list}->[$i]->{rain}->{'1h'}
|
||||||
? $data->{list}->[$i]->{rain}->{'1h'}
|
? $data->{list}->[$i]->{rain}->{'1h'}
|
||||||
: 0
|
: 0
|
||||||
@ -732,6 +734,7 @@ sub _FillSelfHashWithWeatherResponseForOnecallCurrent {
|
|||||||
'rain_1h' => ( $data->{rain}->{'1h'} ? $data->{rain}->{'1h'} : 0 ),
|
'rain_1h' => ( $data->{rain}->{'1h'} ? $data->{rain}->{'1h'} : 0 ),
|
||||||
'cloudCover' => $data->{current}->{clouds},
|
'cloudCover' => $data->{current}->{clouds},
|
||||||
'code' => $codes{ $data->{current}->{weather}->[0]->{id} },
|
'code' => $codes{ $data->{current}->{weather}->[0]->{id} },
|
||||||
|
'owmAPICode' => $data->{current}->{weather}->[0]->{id},
|
||||||
'iconAPI' => $data->{current}->{weather}->[0]->{icon},
|
'iconAPI' => $data->{current}->{weather}->[0]->{icon},
|
||||||
'condition' =>
|
'condition' =>
|
||||||
encode_utf8( $data->{current}->{weather}->[0]->{description} ),
|
encode_utf8( $data->{current}->{weather}->[0]->{description} ),
|
||||||
@ -788,6 +791,7 @@ sub _FillSelfHashWithWeatherResponseForOnecallDaily {
|
|||||||
'moonset' => strftime(
|
'moonset' => strftime(
|
||||||
"%a, %H:%M", localtime( $data->{daily}->[$i]->{moonset} )
|
"%a, %H:%M", localtime( $data->{daily}->[$i]->{moonset} )
|
||||||
),
|
),
|
||||||
|
'summary' => $data->{daily}->[$i]->{summary},
|
||||||
'temperature' =>
|
'temperature' =>
|
||||||
int( sprintf( "%.0f", $data->{daily}->[$i]->{temp}->{day} ) ),
|
int( sprintf( "%.0f", $data->{daily}->[$i]->{temp}->{day} ) ),
|
||||||
'temperature_morn' => int(
|
'temperature_morn' => int(
|
||||||
@ -833,8 +837,9 @@ sub _FillSelfHashWithWeatherResponseForOnecallDaily {
|
|||||||
$data->{daily}->[$i]->{weather}->[0]->{description}
|
$data->{daily}->[$i]->{weather}->[0]->{description}
|
||||||
),
|
),
|
||||||
'code' => $codes{ $data->{daily}->[$i]->{weather}->[0]->{id} },
|
'code' => $codes{ $data->{daily}->[$i]->{weather}->[0]->{id} },
|
||||||
'iconAPI' => $data->{daily}->[$i]->{weather}->[0]->{icon},
|
'owmAPICode' => $data->{daily}->[$i]->{weather}->[0]->{id},
|
||||||
'pressure' => int(
|
'iconAPI' => $data->{daily}->[$i]->{weather}->[0]->{icon},
|
||||||
|
'pressure' => int(
|
||||||
sprintf( "%.1f", $data->{daily}->[$i]->{pressure} ) + 0.5
|
sprintf( "%.1f", $data->{daily}->[$i]->{pressure} ) + 0.5
|
||||||
),
|
),
|
||||||
'wind' => int(
|
'wind' => int(
|
||||||
@ -853,8 +858,7 @@ sub _FillSelfHashWithWeatherResponseForOnecallDaily {
|
|||||||
sprintf( "%.1f", ( $data->{daily}->[$i]->{wind_deg} ) )
|
sprintf( "%.1f", ( $data->{daily}->[$i]->{wind_deg} ) )
|
||||||
),
|
),
|
||||||
'cloudCover' => $data->{daily}->[$i]->{clouds},
|
'cloudCover' => $data->{daily}->[$i]->{clouds},
|
||||||
'code' => $codes{ $data->{daily}->[$i]->{weather}->[0]->{id} },
|
'rain' => (
|
||||||
'rain' => (
|
|
||||||
$data->{daily}->[$i]->{rain} ? $data->{daily}->[$i]->{rain}
|
$data->{daily}->[$i]->{rain} ? $data->{daily}->[$i]->{rain}
|
||||||
: 0
|
: 0
|
||||||
),
|
),
|
||||||
@ -920,8 +924,9 @@ sub _FillSelfHashWithWeatherResponseForOnecallHourly {
|
|||||||
'wind_direction' => $data->{hourly}->[$i]->{wind_deg},
|
'wind_direction' => $data->{hourly}->[$i]->{wind_deg},
|
||||||
'cloudCover' => $data->{hourly}->[$i]->{clouds},
|
'cloudCover' => $data->{hourly}->[$i]->{clouds},
|
||||||
'code' => $codes{ $data->{hourly}->[$i]->{weather}->[0]->{id} },
|
'code' => $codes{ $data->{hourly}->[$i]->{weather}->[0]->{id} },
|
||||||
'iconAPI' => $data->{hourly}->[$i]->{weather}->[0]->{icon},
|
'owmAPICode' => $data->{hourly}->[$i]->{weather}->[0]->{id},
|
||||||
'rain1h' => (
|
'iconAPI' => $data->{hourly}->[$i]->{weather}->[0]->{icon},
|
||||||
|
'rain1h' => (
|
||||||
$data->{hourly}->[$i]->{rain}->{'1h'}
|
$data->{hourly}->[$i]->{rain}->{'1h'}
|
||||||
? $data->{hourly}->[$i]->{rain}->{'1h'}
|
? $data->{hourly}->[$i]->{rain}->{'1h'}
|
||||||
: 0
|
: 0
|
||||||
@ -1031,7 +1036,7 @@ sub _strftimeWrapper {
|
|||||||
],
|
],
|
||||||
"release_status": "stable",
|
"release_status": "stable",
|
||||||
"license": "GPL_2",
|
"license": "GPL_2",
|
||||||
"version": "v3.2.6",
|
"version": "v3.2.7",
|
||||||
"author": [
|
"author": [
|
||||||
"Marko Oldenburg <fhemdevelopment@cooltux.net>"
|
"Marko Oldenburg <fhemdevelopment@cooltux.net>"
|
||||||
],
|
],
|
||||||
|
@ -15,9 +15,9 @@ return "$@" if ($@);
|
|||||||
return $ret if ($ret);
|
return $ret if ($ret);
|
||||||
$::packages{wundergroundAPI}{META} = $META;
|
$::packages{wundergroundAPI}{META} = $META;
|
||||||
|
|
||||||
use version 0.77; our $VERSION = $META->{version};
|
use version 0.80; our $VERSION = $META->{version};
|
||||||
|
|
||||||
# use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
# try to use JSON::MaybeXS wrapper
|
# try to use JSON::MaybeXS wrapper
|
||||||
# for chance of better performance + open code
|
# for chance of better performance + open code
|
||||||
@ -103,10 +103,11 @@ sub new {
|
|||||||
? $argsRef->{apikey}
|
? $argsRef->{apikey}
|
||||||
: 'none'
|
: 'none'
|
||||||
),
|
),
|
||||||
lang => $argsRef->{language},
|
lang => $argsRef->{language},
|
||||||
lat => ( split( ',', $argsRef->{location} ) )[0],
|
lat => ( split( ',', $argsRef->{location} ) )[0],
|
||||||
long => ( split( ',', $argsRef->{location} ) )[1],
|
long => ( split( ',', $argsRef->{location} ) )[1],
|
||||||
fetchTime => 0,
|
fetchTime => 0,
|
||||||
|
forecastFetchTime => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
$self->{cachemaxage} = (
|
$self->{cachemaxage} = (
|
||||||
@ -210,29 +211,66 @@ sub _RetrieveDataFromWU {
|
|||||||
return 0 unless ( __PACKAGE__ eq caller(0) );
|
return 0 unless ( __PACKAGE__ eq caller(0) );
|
||||||
|
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
my $paramRef;
|
||||||
# retrieve data from cache
|
my $options;
|
||||||
if ( ( time() - $self->{fetchTime} ) < $self->{cachemaxage}
|
|
||||||
and $self->{cached}->{lat} == $self->{lat}
|
|
||||||
and $self->{cached}->{long} == $self->{long} )
|
|
||||||
{
|
|
||||||
return _CallWeatherCallbackFn($self);
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->{cached}->{lat} = $self->{lat}
|
$self->{cached}->{lat} = $self->{lat}
|
||||||
unless ( $self->{cached}->{lat} == $self->{lat} );
|
unless ( $self->{cached}->{lat} == $self->{lat} );
|
||||||
$self->{cached}->{long} = $self->{long}
|
$self->{cached}->{long} = $self->{long}
|
||||||
unless ( $self->{cached}->{long} == $self->{long} );
|
unless ( $self->{cached}->{long} == $self->{long} );
|
||||||
|
|
||||||
my $paramRef = {
|
# retrieve forecast data from cache
|
||||||
timeout => 15,
|
if ( ( time() - $self->{forecastFetchTime} ) < $self->{cachemaxage}
|
||||||
self => $self,
|
and $self->{cached}->{lat} == $self->{lat}
|
||||||
callback => (
|
and $self->{cached}->{long} == $self->{long} )
|
||||||
$self->{stationId}
|
{
|
||||||
? \&_RetrieveDataFromPWS
|
# old: return _CallWeatherCallbackFn($self);
|
||||||
: \&_RetrieveDataFinished
|
# Do not just return but get PWS data without forecast
|
||||||
),
|
$paramRef = {
|
||||||
};
|
timeout => 15,
|
||||||
|
self => $self,
|
||||||
|
callback => \&_RetrieveDataFinished,
|
||||||
|
};
|
||||||
|
|
||||||
|
#Build station URL
|
||||||
|
$options = 'stationId=' . $self->{stationId};
|
||||||
|
$options .= '&format=json';
|
||||||
|
$options .= '&units=' . $self->{units};
|
||||||
|
$options .= '&numericPrecision=decimal';
|
||||||
|
$options .= '&apiKey=' . $self->{key};
|
||||||
|
|
||||||
|
$paramRef->{url} = $URL . 'v2/pws/observations/current?' . $options;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Get the complete data station and forecast
|
||||||
|
$paramRef = {
|
||||||
|
timeout => 15,
|
||||||
|
self => $self,
|
||||||
|
callback => (
|
||||||
|
$self->{stationId}
|
||||||
|
? \&_RetrieveDataFromPWS
|
||||||
|
: \&_RetrieveDataFinished
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
# Build forecast URL
|
||||||
|
$options = 'geocode=' . $self->{lat} . ',' . $self->{long};
|
||||||
|
$options .= '&format=json';
|
||||||
|
$options .= '&units=' . $self->{units};
|
||||||
|
$options .= '&language='
|
||||||
|
. (
|
||||||
|
$self->{lang} eq 'en'
|
||||||
|
? 'en-US'
|
||||||
|
: $self->{lang} . '-' . uc( $self->{lang} )
|
||||||
|
);
|
||||||
|
$options .= '&apiKey=' . $self->{key};
|
||||||
|
|
||||||
|
$paramRef->{url} =
|
||||||
|
$URL
|
||||||
|
. 'v3/wx/forecast/daily/'
|
||||||
|
. $self->{days} . 'day' . '?'
|
||||||
|
. $options;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $self->{lat} eq 'error'
|
if ( $self->{lat} eq 'error'
|
||||||
or $self->{long} eq 'error'
|
or $self->{long} eq 'error'
|
||||||
@ -250,23 +288,6 @@ sub _RetrieveDataFromWU {
|
|||||||
if ( $self->{key} eq 'none' );
|
if ( $self->{key} eq 'none' );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $options = 'geocode=' . $self->{lat} . ',' . $self->{long};
|
|
||||||
$options .= '&format=json';
|
|
||||||
$options .= '&units=' . $self->{units};
|
|
||||||
$options .= '&language='
|
|
||||||
. (
|
|
||||||
$self->{lang} eq 'en'
|
|
||||||
? 'en-US'
|
|
||||||
: $self->{lang} . '-' . uc( $self->{lang} )
|
|
||||||
);
|
|
||||||
$options .= '&apiKey=' . $self->{key};
|
|
||||||
|
|
||||||
$paramRef->{url} =
|
|
||||||
$URL
|
|
||||||
. 'v3/wx/forecast/daily/'
|
|
||||||
. $self->{days} . 'day' . '?'
|
|
||||||
. $options;
|
|
||||||
|
|
||||||
if ( lc( $self->{key} ) eq 'demo' ) {
|
if ( lc( $self->{key} ) eq 'demo' ) {
|
||||||
_RetrieveDataFinished( $paramRef, undef, 'DEMODATA' . $DEMODATA );
|
_RetrieveDataFinished( $paramRef, undef, 'DEMODATA' . $DEMODATA );
|
||||||
}
|
}
|
||||||
@ -352,10 +373,20 @@ sub _RetrieveDataFinished {
|
|||||||
$self->{cached}{status} = 'ok';
|
$self->{cached}{status} = 'ok';
|
||||||
$self->{cached}{validity} = 'up-to-date';
|
$self->{cached}{validity} = 'up-to-date';
|
||||||
$self->{fetchTime} = time();
|
$self->{fetchTime} = time();
|
||||||
|
|
||||||
|
#print Dumper $response; ## for debugging
|
||||||
|
#print Dumper $data; ## for debugging
|
||||||
|
#if (exists( $response->{daily} )) {
|
||||||
|
if ( $response =~ /{"daily":/ ) {
|
||||||
|
$self->{forecastFetchTime} = time();
|
||||||
|
}
|
||||||
_ProcessingRetrieveData( $self, $response );
|
_ProcessingRetrieveData( $self, $response );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->{fetchTime} = time() if ( not defined( $self->{fetchTime} ) );
|
$self->{fetchTime} = time() if ( not defined( $self->{fetchTime} ) );
|
||||||
|
$self->{forecastFetchTime} = time()
|
||||||
|
if ( not defined( $self->{forecastFetchTime} ) );
|
||||||
|
|
||||||
_ErrorHandling( $self, $err );
|
_ErrorHandling( $self, $err );
|
||||||
_ProcessingRetrieveData( $self, $response );
|
_ProcessingRetrieveData( $self, $response );
|
||||||
}
|
}
|
||||||
@ -389,12 +420,15 @@ sub _ProcessingRetrieveData {
|
|||||||
# 'Code: ' . $data->{code} . ' Error: ' . $data->{error} );
|
# 'Code: ' . $data->{code} . ' Error: ' . $data->{error} );
|
||||||
# }
|
# }
|
||||||
else {
|
else {
|
||||||
# print Dumper $response; ## für Debugging
|
# print Dumper $response; ## for debugging
|
||||||
# print Dumper $data; ## für Debugging
|
# print Dumper $data; ## for debugging
|
||||||
|
|
||||||
$self->{cached}{current_date_time} =
|
$self->{cached}{current_date_time} =
|
||||||
_strftimeWrapper( "%a, %e %b %Y %H:%M",
|
_strftimeWrapper( "%a, %e %b %Y %H:%M",
|
||||||
localtime( $self->{fetchTime} ) );
|
localtime( $self->{fetchTime} ) );
|
||||||
|
$self->{cached}{current_forecast_date_time} =
|
||||||
|
_strftimeWrapper( "%a, %e %b %Y %H:%M",
|
||||||
|
localtime( $self->{forecastFetchTime} ) );
|
||||||
|
|
||||||
# $self->{cached}{timezone} = $data->{timezone};
|
# $self->{cached}{timezone} = $data->{timezone};
|
||||||
$self->{cached}{license}{text} =
|
$self->{cached}{license}{text} =
|
||||||
@ -423,34 +457,22 @@ sub _ProcessingRetrieveData {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$self->{cached}{current} = {
|
$self->{cached}{current} = {
|
||||||
'dewPoint' =>
|
'dewPoint' => sprintf( "%.1f", $data->{$unit}{dewpt} ),
|
||||||
int( sprintf( "%.1f", $data->{$unit}{dewpt} ) + 0.5 ),
|
'heatIndex' => $data->{$unit}{heatIndex},
|
||||||
'heatIndex' => $data->{$unit}{heatIndex},
|
|
||||||
'precipRate' => $data->{$unit}{precipRate},
|
'precipRate' => $data->{$unit}{precipRate},
|
||||||
'precipTotal' => $data->{$unit}{precipTotal},
|
'precipTotal' => $data->{$unit}{precipTotal},
|
||||||
'pressure' => int(
|
'pressure' =>
|
||||||
sprintf( "%.1f", $data->{$unit}{pressure} ) + 0.5
|
sprintf( "%.1f", $data->{$unit}{pressure} ),
|
||||||
),
|
|
||||||
'temperature' =>
|
'temperature' =>
|
||||||
int( sprintf( "%.1f", $data->{$unit}{temp} ) + 0.5 ),
|
sprintf( "%.1f", $data->{$unit}{temp} ),
|
||||||
'temp_c' =>
|
'temp_c' => sprintf( "%.1f", $data->{$unit}{temp} ),
|
||||||
int( sprintf( "%.1f", $data->{$unit}{temp} ) + 0.5 ),
|
'wind_chill' =>
|
||||||
'wind_chill' => int(
|
sprintf( "%.1f", $data->{$unit}{windChill} ),
|
||||||
sprintf( "%.1f", ( $data->{$unit}{windChill} ) ) +
|
'windGust' =>
|
||||||
0.5
|
sprintf( "%.1f", $data->{$unit}{windGust} ),
|
||||||
),
|
'wind' => sprintf( "%.1f", $data->{$unit}{windSpeed} ),
|
||||||
'windGust' => int(
|
'wind_speed' =>
|
||||||
sprintf( "%.1f", ( $data->{$unit}{windGust} ) ) +
|
sprintf( "%.1f", $data->{$unit}{windSpeed} ),
|
||||||
0.5
|
|
||||||
),
|
|
||||||
'wind' => int(
|
|
||||||
sprintf( "%.1f", ( $data->{$unit}{windSpeed} ) ) +
|
|
||||||
0.5
|
|
||||||
),
|
|
||||||
'wind_speed' => int(
|
|
||||||
sprintf( "%.1f", ( $data->{$unit}{windSpeed} ) ) +
|
|
||||||
0.5
|
|
||||||
),
|
|
||||||
'wind_direction' => $data->{winddir},
|
'wind_direction' => $data->{winddir},
|
||||||
'solarRadiation' => $data->{solarRadiation},
|
'solarRadiation' => $data->{solarRadiation},
|
||||||
'uvIndex' => $data->{uv},
|
'uvIndex' => $data->{uv},
|
||||||
@ -542,6 +564,16 @@ sub _ProcessingRetrieveData {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
'temperature' => int(
|
||||||
|
sprintf(
|
||||||
|
"%.1f",
|
||||||
|
(
|
||||||
|
$data->{temperatureMax}[$i]
|
||||||
|
? $data->{temperatureMax}[$i]
|
||||||
|
: 0
|
||||||
|
)
|
||||||
|
) + 0.5
|
||||||
|
),
|
||||||
'low_c' => int(
|
'low_c' => int(
|
||||||
sprintf( "%.1f",
|
sprintf( "%.1f",
|
||||||
$data->{temperatureMin}[$i] ) + 0.5
|
$data->{temperatureMin}[$i] ) + 0.5
|
||||||
@ -732,7 +764,7 @@ sub _CallWeatherCallbackFn {
|
|||||||
|
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
# ## Aufruf der callbackFn
|
## Aufruf der callbackFn
|
||||||
return FHEM::Core::Weather::RetrieveCallbackFn( $self->{devName} );
|
return FHEM::Core::Weather::RetrieveCallbackFn( $self->{devName} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,6 +776,9 @@ sub _ErrorHandling {
|
|||||||
|
|
||||||
$self->{cached}{current_date_time} =
|
$self->{cached}{current_date_time} =
|
||||||
_strftimeWrapper( "%a, %e %b %Y %H:%M", localtime( $self->{fetchTime} ) );
|
_strftimeWrapper( "%a, %e %b %Y %H:%M", localtime( $self->{fetchTime} ) );
|
||||||
|
$self->{cached}{current_forecast_date_time} =
|
||||||
|
_strftimeWrapper( "%a, %e %b %Y %H:%M",
|
||||||
|
localtime( $self->{forecastFetchTime} ) );
|
||||||
$self->{cached}{status} = $err;
|
$self->{cached}{status} = $err;
|
||||||
$self->{cached}{validity} = 'stale';
|
$self->{cached}{validity} = 'stale';
|
||||||
|
|
||||||
@ -805,7 +840,7 @@ sub _strftimeWrapper {
|
|||||||
"abstract": "Wetter API für Weather Underground"
|
"abstract": "Wetter API für Weather Underground"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version": "v1.2.0",
|
"version": "v1.3.0",
|
||||||
"author": [
|
"author": [
|
||||||
"Julian Pawlowski <julian.pawlowski@gmail.com>"
|
"Julian Pawlowski <julian.pawlowski@gmail.com>"
|
||||||
],
|
],
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# 59_Weather.pm
|
# 59_Weather.pm
|
||||||
# (c) 2009-2023 Copyright by Dr. Boris Neubert
|
# (c) 2009-2024 Copyright by Dr. Boris Neubert
|
||||||
# e-mail: omega at online dot de
|
# e-mail: omega at online dot de
|
||||||
#
|
#
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# - Marko Oldenburg (CoolTux)
|
# - Marko Oldenburg (CoolTux)
|
||||||
# - Lippie
|
# - Lippie
|
||||||
|
# - stefanru (wundergroundAPI)
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# This file is part of fhem.
|
# This file is part of fhem.
|
||||||
@ -32,9 +33,18 @@ package FHEM::Core::Weather;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Time::HiRes qw(gettimeofday);
|
my $missingModul = '';
|
||||||
|
|
||||||
|
eval { use Time::HiRes qw /gettimeofday/; 1 }
|
||||||
|
or $missingModul .= "libtime-hires-perl ";
|
||||||
|
|
||||||
|
eval { use Readonly; 1 }
|
||||||
|
or $missingModul .= "libreadonly-perl ";
|
||||||
|
|
||||||
|
#use Time::HiRes qw(gettimeofday);
|
||||||
use experimental qw /switch/;
|
use experimental qw /switch/;
|
||||||
use Readonly;
|
|
||||||
|
#use Readonly;
|
||||||
|
|
||||||
use FHEM::Meta;
|
use FHEM::Meta;
|
||||||
|
|
||||||
@ -317,9 +327,7 @@ sub _ReturnWithError {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _DeleteForecastreadings {
|
sub DeleteForecastreadings {
|
||||||
return 0 unless ( __PACKAGE__ eq caller(0) );
|
|
||||||
|
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
@ -770,6 +778,12 @@ sub Define {
|
|||||||
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
return $@ unless ( FHEM::Meta::SetInternals($hash) );
|
||||||
use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
||||||
|
|
||||||
|
return
|
||||||
|
'Cannot define Weather device. Please use "apt install '
|
||||||
|
. ${missingModul}
|
||||||
|
. ' to install missing perl modules'
|
||||||
|
if ($missingModul);
|
||||||
|
|
||||||
my $usage =
|
my $usage =
|
||||||
"syntax: define <name> Weather [API=<API>] [apikey=<apikey>] [location=<location>] [interval=<interval>] [lang=<lang>]";
|
"syntax: define <name> Weather [API=<API>] [apikey=<apikey>] [location=<location>] [interval=<interval>] [lang=<lang>]";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user